diff --git a/.github/workflows/server.yml b/.github/workflows/server.yml index b7e1289e..545cf330 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 + # 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" \ + "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 + # 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. + 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/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 f13f8168..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,11 +27,8 @@ 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.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>=24.11,<24.12; python_version>='3.8'", ] 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