diff --git a/.github/workflows/doc.yml b/.github/workflows/doc.yml index c71125c90..44c55b8fd 100644 --- a/.github/workflows/doc.yml +++ b/.github/workflows/doc.yml @@ -14,11 +14,11 @@ jobs: - name: Setup Python uses: actions/setup-python@v4 with: - python-version: 3.9 + python-version: '3.10' - name: Install dependencies with pipenv run: | - pip install pipenv + pip install pipenv==2023.4.20 pipenv sync pipenv run pip install pdoc3 diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 4e63f8923..e5d5c8323 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -18,7 +18,7 @@ jobs: - name: Setup Python uses: actions/setup-python@v4 with: - python-version: 3.9 + python-version: '3.10' - name: Install dependencies run: pip install isort @@ -30,6 +30,11 @@ jobs: steps: - uses: actions/checkout@v3 + - name: Setup Python + uses: actions/setup-python@v4 + with: + python-version: '3.10' + - uses: TrueBrain/actions-flake8@v2 with: flake8_version: 6.0.0 diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index a2cf15435..d67c18f5f 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -62,7 +62,7 @@ jobs: - name: Setup Python uses: actions/setup-python@v4 with: - python-version: 3.9 + python-version: '3.10' - name: Run flyway db migrations env: @@ -81,7 +81,7 @@ jobs: - name: Install dependencies with pipenv run: | - pip install pipenv + pip install pipenv==2023.4.20 pipenv sync --dev pipenv run pip install pytest-github-actions-annotate-failures diff --git a/DEVELOPMENT.md b/DEVELOPMENT.md index eed9c0630..851d3e1ce 100644 --- a/DEVELOPMENT.md +++ b/DEVELOPMENT.md @@ -9,7 +9,7 @@ project to build on Windows using the WSL.* You will need the following software installed on your system: - [Docker](https://docs.docker.com/engine/) - [Docker Compose](https://github.com/docker/compose) -- [Python 3.9](https://www.python.org/downloads/) +- [Python 3.10](https://www.python.org/downloads/) - [Pipenv](https://github.com/pypa/pipenv/) Once you have Docker installed, make sure to add yourself to the `docker` group diff --git a/Dockerfile b/Dockerfile index 5892d8ad0..ce44f206c 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,13 +1,13 @@ ############### # Build image # ############### -FROM python:3.9-slim as builder +FROM python:3.10-slim as builder # Need git for installing aiomysql RUN apt-get update RUN apt-get install -y --no-install-recommends git -RUN pip install pipenv==2023.2.18 +RUN pip install pipenv==2023.4.20 WORKDIR /code/ @@ -22,7 +22,7 @@ RUN PIPENV_VENV_IN_PROJECT=1 pipenv run pip install . ################# # Runtime image # ################# -FROM python:3.9-slim +FROM python:3.10-slim ARG GITHUB_REF ENV VERSION=$GITHUB_REF diff --git a/Pipfile b/Pipfile index f4aa91e8c..818700743 100644 --- a/Pipfile +++ b/Pipfile @@ -29,7 +29,7 @@ twilio = ">=7.0.0" uvloop = {version = "*", markers = "sys_platform != 'win32'"} [dev-packages] -hypothesis = "<=6.47.1" # Later versions add a prerelease dependency. See https://github.com/pypa/pipenv/issues/1760 +hypothesis = "*" # Versions between 6.47.1 and 6.56.4 added a prerelease dependency. See https://github.com/pypa/pipenv/issues/1760 pdoc3 = "*" pytest = "*" pytest-asyncio = "*" @@ -38,4 +38,4 @@ pytest-mock = "*" vulture = "*" [requires] -python_version = "3.9" +python_version = "3.10" diff --git a/Pipfile.lock b/Pipfile.lock index 530ef5dd9..80d8f40df 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,11 +1,11 @@ { "_meta": { "hash": { - "sha256": "fa98af79c90891d7caf4245c1d28f9598d4f37a3247ebb53b8067cdecda24b15" + "sha256": "b3da1b047f70a6659401f07cd87ba09dbec53472d498b333134e4e7e4db7d9f6" }, "pipfile-spec": 6, "requires": { - "python_version": "3.9" + "python_version": "3.10" }, "sources": [ { @@ -644,7 +644,6 @@ "sha256:8ee45429555515e1f6b185e78100aea234072576aa43ab53aefcae078162fca9", "sha256:e644fdec12f7872f86c58ff790da456218b10f863970249516d60a5eaca77206" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", "version": "==2.21" }, "pyjwt": { @@ -671,7 +670,7 @@ "sha256:0123cacc1627ae19ddf3c27a5de5bd67ee4586fbdd6440d9748f8abb483d3e86", "sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2'", "version": "==2.8.2" }, "pytz": { @@ -748,7 +747,7 @@ "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926", "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2'", "version": "==1.16.0" }, "sortedcontainers": { @@ -1050,19 +1049,11 @@ }, "hypothesis": { "hashes": [ - "sha256:4ad26c5d434171ffc02aba569dd52255573d615554c062bc30734dbe6f318c61", - "sha256:69978811f1d9c19710c7d2bf8233dc43c80efa964251b72efbe8274044e073b4" + "sha256:1901688aac1fc8d78d5431c4a1d48cc50940e247dd8b6ebc3d4167ef31204e10", + "sha256:2fd2c9640ea4b64d06fafc8d9aa8e9cbae365879d109a859afd37dda5c1ffb55" ], "index": "pypi", - "version": "==6.47.1" - }, - "importlib-metadata": { - "hashes": [ - "sha256:43dd286a2cd8995d5eaef7fee2066340423b818ed3fd70adf0bad5f1fac53fed", - "sha256:92501cdf9cc66ebd3e612f1b4f0c0765dfa42f0fa38ffb319b6bd84dd675d705" - ], - "markers": "python_version < '3.10'", - "version": "==6.6.0" + "version": "==6.72.1" }, "iniconfig": { "hashes": [ @@ -1213,7 +1204,7 @@ "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b", "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f" ], - "markers": "python_version >= '2.6' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "markers": "python_version >= '2.6' and python_version not in '3.0, 3.1, 3.2'", "version": "==0.10.2" }, "tomli": { @@ -1231,14 +1222,6 @@ ], "index": "pypi", "version": "==2.7" - }, - "zipp": { - "hashes": [ - "sha256:112929ad649da941c23de50f356a2b5570c954b65150642bccdd66bf194d224b", - "sha256:48904fc76a60e542af151aded95726c1a5c34ed43ab4134b597665c86d7ad556" - ], - "markers": "python_version >= '3.7'", - "version": "==3.15.0" } } } diff --git a/README.md b/README.md index 71c543fbf..2b1b97581 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ [![Codacy Badge](https://app.codacy.com/project/badge/Grade/ada42f6e09a341a88f3dae262a43e86e)](https://www.codacy.com/gh/FAForever/server/dashboard?utm_source=github.com&utm_medium=referral&utm_content=FAForever/server&utm_campaign=Badge_Grade) [![docs](https://img.shields.io/badge/docs-latest-purple)](https://faforever.github.io/server/) [![license](https://img.shields.io/badge/license-GPLv3-blue)](license.txt) -![python](https://img.shields.io/badge/python-3.9-3776AB) +![python](https://img.shields.io/badge/python-3.10-3776AB) This is the source code for the [Forged Alliance Forever](https://www.faforever.com/) lobby server. diff --git a/tests/utils/hypothesis.py b/tests/utils/hypothesis.py index d1dc0a154..f6cb81163 100644 --- a/tests/utils/hypothesis.py +++ b/tests/utils/hypothesis.py @@ -1,11 +1,12 @@ import asyncio import contextlib -import inspect import itertools +from inspect import Parameter, Signature import pytest from hypothesis.internal.reflection import ( define_function_signature, + get_signature, impersonate ) @@ -18,13 +19,13 @@ def autocontext(*auto_args): that requires the `request` fixture won't work. """ def decorate_test(test): - original_argspec = inspect.getfullargspec(test) - argspec = new_argspec(original_argspec, auto_args) + original_signature = get_signature(test) + signature = new_signature(original_signature, auto_args) if asyncio.iscoroutinefunction(test): @pytest.mark.asyncio @impersonate(test) - @define_function_signature(test.__name__, test.__doc__, argspec) + @define_function_signature(test.__name__, test.__doc__, signature) async def wrapped_test(*args, **kwargs): # Tell pytest to omit the body of this function from tracebacks __tracebackhide__ = True @@ -54,7 +55,7 @@ async def wrapped_test(*args, **kwargs): return wrapped_test else: @impersonate(test) - @define_function_signature(test.__name__, test.__doc__, argspec) + @define_function_signature(test.__name__, test.__doc__, signature) def wrapped_test(*args, **kwargs): # Tell pytest to omit the body of this function from tracebacks __tracebackhide__ = True @@ -77,25 +78,19 @@ def wrapped_test(*args, **kwargs): return decorate_test -def new_argspec(original_argspec, auto_args): - """Make an updated argspec for the wrapped test.""" - replaced_args = { - original_arg: auto_arg - for original_arg, auto_arg in zip( - original_argspec.args[:len(auto_args)], - auto_args - ) - } - new_args = tuple(itertools.chain( - auto_args, - original_argspec.args[len(auto_args):] +def new_signature(original_signature: Signature, auto_args): + """Make an updated signature for the wrapped test.""" + # Replace the parameter names in the original signature with the names + # of the fixtures given to @autocontext(...) so that pytest will inject the + # right fixtures. + new_parameters = tuple(itertools.chain( + [ + Parameter(name, Parameter.POSITIONAL_OR_KEYWORD) + for name in auto_args + ], + list(original_signature.parameters.values())[len(auto_args):] )) - annots = { - replaced_args.get(k) or k: v - for k, v in original_argspec.annotations.items() - } - annots["return"] = None - return original_argspec._replace( - args=new_args, - annotations=annots + return original_signature.replace( + parameters=new_parameters, + return_annotation=None )