From c1ee84f7de620972a5bd05d6491c51f2e71336ab Mon Sep 17 00:00:00 2001 From: Tynan Ford Date: Wed, 5 Aug 2026 11:29:11 -0700 Subject: [PATCH 1/2] Restore python 3.6 and update CI to import module after installing --- .github/workflows/server.yml | 19 ++++++++++++++++++- server/pyproject.toml | 4 ++-- server/recceiver/processors.py | 5 +++-- server/recceiver/recast.py | 11 ++++++----- 4 files changed, 29 insertions(+), 10 deletions(-) diff --git a/.github/workflows/server.yml b/.github/workflows/server.yml index b7e1289e..85cadf69 100644 --- a/.github/workflows/server.yml +++ b/.github/workflows/server.yml @@ -44,10 +44,27 @@ jobs: minor=$(python3 --version | cut -d. -f2) if [ "$minor" -ge 7 ]; then python -m pip install --upgrade "pip==24.0" --only-binary=:all: + python -m pip install . else + # Python 3.6 runs from a checkout (see README), not a pip install. + # Just install the runtime deps, pinned per pyproject.toml. python -m pip install --upgrade "pip==21.3.1" --only-binary=:all: + python -m pip install \ + "channelfinder @ https://github.com/ChannelFinder/pyCFClient/archive/refs/tags/v3.2.0.zip#sha256=ec89537f336c4cb8db18909c4b02176dd5fbd03f5872a6527129879cbf3f7c85" \ + "dataclasses==0.8" \ + "requests==2.27.1" \ + "twisted==21.7.0" + fi + - name: Import smoke test + run: | + minor=$(python3 --version | cut -d. -f2) + if [ "$minor" -lt 7 ]; then + # Intentional for 3.6: run from the checkout, as documented. + PYTHONPATH=. python -c "from twisted.plugins import recceiver_plugin" + else + # Run outside the checkout so this fails if pip didn't install it. + cd /tmp && python -c "from twisted.plugins import recceiver_plugin" fi - python -m pip install --no-deps . test-unit: runs-on: ubuntu-latest needs: build-server diff --git a/server/pyproject.toml b/server/pyproject.toml index f13f8168..6d19a201 100644 --- a/server/pyproject.toml +++ b/server/pyproject.toml @@ -30,10 +30,10 @@ dependencies = [ "channelfinder @ https://github.com/ChannelFinder/pyCFClient/archive/refs/tags/v3.2.0.zip", "dataclasses; python_version<'3.7'", "requests>=2.27.1,<2.28; python_version<'3.7'", - "requests>=2.31,<2.32; python_version<'3.8'", + "requests>=2.31,<2.32; python_version>='3.7' and python_version<'3.8'", "requests>=2.32.3,<2.33; python_version>='3.8'", "twisted>=21.7,<22; python_version<'3.7'", - "twisted>=22.10,<23; python_version<'3.8'", + "twisted>=22.10,<23; python_version>='3.7' and python_version<'3.8'", "twisted>=24.11,<24.12; python_version>='3.8'", ] optional-dependencies.metrics = [ "prometheus-client" ] diff --git a/server/recceiver/processors.py b/server/recceiver/processors.py index a5be62d5..29549164 100644 --- a/server/recceiver/processors.py +++ b/server/recceiver/processors.py @@ -3,6 +3,7 @@ import os from configparser import ConfigParser as Parser from os.path import expanduser +from typing import Dict from twisted.application import service from twisted.internet import defer, task @@ -20,9 +21,9 @@ ] -def _env_vars(section: str) -> dict[str, str]: +def _env_vars(section: str) -> Dict[str, str]: prefix = "RECCEIVER_" + section.upper() + "_" - return {k.removeprefix(prefix).lower(): v for k, v in os.environ.items() if k.startswith(prefix)} + return {k[len(prefix) :].lower(): v for k, v in os.environ.items() if k.startswith(prefix)} class ConfigAdapter(object): diff --git a/server/recceiver/recast.py b/server/recceiver/recast.py index 94dfa00a..e2790537 100644 --- a/server/recceiver/recast.py +++ b/server/recceiver/recast.py @@ -2,6 +2,7 @@ import logging import random import time +from typing import DefaultDict, Dict, List, Set, Tuple from twisted.internet import defer, protocol from twisted.internet.interfaces import IAddress @@ -210,11 +211,11 @@ class Transaction: connected: bool initial: bool srcid: int - records_to_add: dict[int, tuple[str, str]] - client_infos: dict[str, str] - record_infos_to_add: dict[int, dict[str, str]] - aliases: collections.defaultdict[int, list[str]] - records_to_delete: set[int] + records_to_add: Dict[int, Tuple[str, str]] + client_infos: Dict[str, str] + record_infos_to_add: Dict[int, Dict[str, str]] + aliases: DefaultDict[int, List[str]] + records_to_delete: Set[int] def __init__(self, ep: IAddress, id: int) -> None: self.connected = True From ef6cedc89e21bd3da6e73f597894deb18b7a7262 Mon Sep 17 00:00:00 2001 From: Tynan Ford Date: Mon, 10 Aug 2026 12:12:58 -0700 Subject: [PATCH 2/2] Remove py36 from pyproject.toml file and update README setuptools (59.6.0) on py36 is too old for the current pyproject.toml file and has been this way for a while. Update the project to specify that pip-installing recceiver is not supported on 3.6 --- .github/workflows/server.yml | 6 +++--- README.md | 2 ++ server/pyproject.toml | 10 +++------- 3 files changed, 8 insertions(+), 10 deletions(-) diff --git a/.github/workflows/server.yml b/.github/workflows/server.yml index 85cadf69..545cf330 100644 --- a/.github/workflows/server.yml +++ b/.github/workflows/server.yml @@ -46,8 +46,8 @@ jobs: python -m pip install --upgrade "pip==24.0" --only-binary=:all: python -m pip install . else - # Python 3.6 runs from a checkout (see README), not a pip install. - # Just install the runtime deps, pinned per pyproject.toml. + # setuptools on 3.6 is too old for install with pyproject.toml + # So just install the runtime dependencies manually python -m pip install --upgrade "pip==21.3.1" --only-binary=:all: python -m pip install \ "channelfinder @ https://github.com/ChannelFinder/pyCFClient/archive/refs/tags/v3.2.0.zip#sha256=ec89537f336c4cb8db18909c4b02176dd5fbd03f5872a6527129879cbf3f7c85" \ @@ -59,7 +59,7 @@ jobs: run: | minor=$(python3 --version | cut -d. -f2) if [ "$minor" -lt 7 ]; then - # Intentional for 3.6: run from the checkout, as documented. + # Since 3.6 is not installed as package per comment above PYTHONPATH=. python -c "from twisted.plugins import recceiver_plugin" else # Run outside the checkout so this fails if pip didn't install it. diff --git a/README.md b/README.md index 56646b71..0977482e 100644 --- a/README.md +++ b/README.md @@ -33,6 +33,8 @@ The RecCeiver server in the `server/` directory is a Python script using the [Twisted][twisted] networking library. It requires Python 3.6 or above. The supported Twisted version depends on the Python version; see `server/pyproject.toml`. +Note that `pip install` (via `pyproject.toml`) requires Python 3.7 +or above; on Python 3.6, run recceiver directly instead. [twisted]: http://twistedmatrix.com/ diff --git a/server/pyproject.toml b/server/pyproject.toml index 6d19a201..c9cb2235 100644 --- a/server/pyproject.toml +++ b/server/pyproject.toml @@ -13,10 +13,9 @@ readme = "README.md" authors = [ { name = "Michael Davidsaver", email = "mdavidsaver@gmail.com" }, ] -requires-python = ">=3.6" +requires-python = ">=3.7" classifiers = [ "Programming Language :: Python :: 3 :: Only", - "Programming Language :: Python :: 3.6", "Programming Language :: Python :: 3.7", "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", @@ -28,12 +27,9 @@ classifiers = [ ] dependencies = [ "channelfinder @ https://github.com/ChannelFinder/pyCFClient/archive/refs/tags/v3.2.0.zip", - "dataclasses; python_version<'3.7'", - "requests>=2.27.1,<2.28; python_version<'3.7'", - "requests>=2.31,<2.32; python_version>='3.7' and python_version<'3.8'", + "requests>=2.31,<2.32; python_version<'3.8'", "requests>=2.32.3,<2.33; python_version>='3.8'", - "twisted>=21.7,<22; python_version<'3.7'", - "twisted>=22.10,<23; python_version>='3.7' and python_version<'3.8'", + "twisted>=22.10,<23; python_version<'3.8'", "twisted>=24.11,<24.12; python_version>='3.8'", ] optional-dependencies.metrics = [ "prometheus-client" ]