diff --git a/.github/workflows/tox.yml b/.github/workflows/tox.yml index 2f11703..66eee24 100644 --- a/.github/workflows/tox.yml +++ b/.github/workflows/tox.yml @@ -22,7 +22,7 @@ jobs: strategy: max-parallel: 5 matrix: - python-version: [3.6, 3.7, 3.8, 3.9, '3.10', '3.11'] + python-version: [ 3.6, 3.7, 3.8, 3.9, '3.10', '3.11', '3.12' ] steps: - uses: actions/checkout@v2 @@ -54,7 +54,7 @@ jobs: strategy: max-parallel: 5 matrix: - python-version: [ 3.6, 3.7, 3.8, 3.9, '3.10', '3.11' ] + python-version: [ 3.6, 3.7, 3.8, 3.9, '3.10', '3.11', '3.12' ] steps: - uses: actions/checkout@v2 @@ -77,7 +77,7 @@ jobs: if: ${{ needs.pre_job.outputs.should_skip != 'true' }} uses: actions/cache@v2 with: - path: ${{ github.workspace }}/.tox/py${{ matrix.python-version }} + path: ${{ github.workspace }}/.tox/py${{ matrix.python-version }}-cryptography${{ env.cryptography_version }} key: ${{ runner.os }}-tox-py${{ matrix.python-version }}-crypto${{ env.cryptography_version }}-${{ hashFiles('setup.py', 'requirements/*.txt') }} - name: Test with tox if: ${{ needs.pre_job.outputs.should_skip != 'true' }} @@ -121,8 +121,8 @@ jobs: if: ${{ needs.pre_job.outputs.should_skip != 'true' }} uses: actions/cache@v2 with: - path: ${{ github.workspace }}/.tox/py3.6 - key: ${{ runner.os }}-tox-py3.6-${{ hashFiles('setup.py', 'requirements/*.txt') }} + path: ${{ github.workspace }}/.tox/py3.9-postgres + key: ${{ runner.os }}-tox-py3.9-postgres-${{ hashFiles('setup.py', 'requirements/*.txt') }} - name: Test with tox if: ${{ needs.pre_job.outputs.should_skip != 'true' }} run: tox -e postgres diff --git a/morango/__init__.py b/morango/__init__.py index d2d00e1..777f190 100644 --- a/morango/__init__.py +++ b/morango/__init__.py @@ -1,2 +1 @@ -default_app_config = "morango.apps.MorangoConfig" __version__ = "0.8.0" diff --git a/morango/apps.py b/morango/apps.py index 2d78870..d3f73fb 100644 --- a/morango/apps.py +++ b/morango/apps.py @@ -7,6 +7,7 @@ class MorangoConfig(AppConfig): name = "morango" verbose_name = "Morango" + default_auto_field = "django.db.models.AutoField" def ready(self): from morango.models.signals import add_to_deleted_models # noqa: F401 diff --git a/morango/constants/transfer_stages.py b/morango/constants/transfer_stages.py index a93c69e..a1a4499 100644 --- a/morango/constants/transfer_stages.py +++ b/morango/constants/transfer_stages.py @@ -1,7 +1,7 @@ """ This module contains constants representing the possible stages of a transfer session. """ -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ INITIALIZING = "initializing" SERIALIZING = "serializing" diff --git a/morango/constants/transfer_statuses.py b/morango/constants/transfer_statuses.py index ee896c8..f2547f1 100644 --- a/morango/constants/transfer_statuses.py +++ b/morango/constants/transfer_statuses.py @@ -1,7 +1,7 @@ """ This module contains constants representing the possible statuses of a transfer session stage. """ -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ PENDING = "pending" STARTED = "started" diff --git a/morango/migrations/0001_squashed_0024_auto_20240129_1757.py b/morango/migrations/0001_squashed_0024_auto_20240129_1757.py index 34ab977..193fd77 100644 --- a/morango/migrations/0001_squashed_0024_auto_20240129_1757.py +++ b/morango/migrations/0001_squashed_0024_auto_20240129_1757.py @@ -1,12 +1,9 @@ # Generated by Django 3.2.24 on 2024-06-25 21:45 -import datetime - import django.db.models.deletion import django.db.models.manager import django.utils.timezone from django.db import migrations from django.db import models -from django.utils.timezone import utc import morango.models.fields.crypto import morango.models.fields.uuids @@ -129,9 +126,6 @@ class Migration(migrations.Migration): ( "source_id", models.CharField( - default=datetime.datetime( - 2017, 10, 18, 21, 15, 6, 842850, tzinfo=utc - ), max_length=96, ), ), @@ -166,17 +160,13 @@ class Migration(migrations.Migration): ( "connection_kind", models.CharField( - choices=[("network", "Network"), ("disk", "Disk")], - default="", + choices=[('network', 'Network'), ('disk', 'Disk')], max_length=10, ), ), ( "connection_path", models.CharField( - default=datetime.datetime( - 2017, 10, 18, 21, 15, 21, 147686, tzinfo=utc - ), max_length=1000, ), ), @@ -186,9 +176,6 @@ class Migration(migrations.Migration): ( "profile", models.CharField( - default=datetime.datetime( - 2017, 10, 18, 21, 15, 27, 811735, tzinfo=utc - ), max_length=40, ), ), @@ -220,9 +207,6 @@ class Migration(migrations.Migration): "last_activity_timestamp", models.DateTimeField( blank=True, - default=datetime.datetime( - 2017, 10, 18, 21, 15, 30, 154629, tzinfo=utc - ), ), ), ("client_fsic", models.TextField(blank=True, default="{}")), @@ -338,10 +322,10 @@ class Migration(migrations.Migration): "private_key", morango.models.fields.crypto.PrivateKeyField(blank=True, null=True), ), - ("lft", models.PositiveIntegerField(db_index=True, editable=False)), - ("rght", models.PositiveIntegerField(db_index=True, editable=False)), + ("lft", models.PositiveIntegerField(editable=False)), + ("rght", models.PositiveIntegerField(editable=False)), ("tree_id", models.PositiveIntegerField(db_index=True, editable=False)), - ("level", models.PositiveIntegerField(db_index=True, editable=False)), + ("level", models.PositiveIntegerField(editable=False)), ( "parent", models.ForeignKey( @@ -550,9 +534,6 @@ class Migration(migrations.Migration): ( "source_id", models.CharField( - default=datetime.datetime( - 2017, 10, 18, 21, 13, 11, 488565, tzinfo=utc - ), max_length=96, ), ), diff --git a/pytest.ini b/pytest.ini index ed6c86c..75bc470 100644 --- a/pytest.ini +++ b/pytest.ini @@ -2,3 +2,5 @@ testpaths = tests/ morango/ DJANGO_SETTINGS_MODULE = testapp.settings norecursedirs = dist tmp* .svn .* +markers = + windows: mark a test as a windows test diff --git a/requirements/test.txt b/requirements/test.txt index aa53f8a..80c9409 100644 --- a/requirements/test.txt +++ b/requirements/test.txt @@ -1,10 +1,8 @@ # These are for testing factory-boy==2.7.0 fake-factory==0.5.7 -coverage==4.5.1 mock==2.0.0 -pytest==3.10.1 -pytest-cov==2.8.1 -pytest-django==3.8.0 +pytest==6.2.5 +pytest-django==4.5.2 more-itertools<=8.10.0 typing diff --git a/setup.py b/setup.py index d433fc9..d867f6f 100644 --- a/setup.py +++ b/setup.py @@ -45,6 +45,7 @@ 'Programming Language :: Python :: 3.9', 'Programming Language :: Python :: 3.10', 'Programming Language :: Python :: 3.11', + 'Programming Language :: Python :: 3.12', ], - python_requires=">=3.6, <3.12", + python_requires=">=3.6, <3.13", ) diff --git a/tests/patch_pytest.py b/tests/patch_pytest.py deleted file mode 100644 index 5033d22..0000000 --- a/tests/patch_pytest.py +++ /dev/null @@ -1,57 +0,0 @@ -""" -This script backports this Python 3.10 compatibility fix https://github.com/pytest-dev/pytest/pull/8540 -in order to allow pytest to run in Python 3.10 without upgrading to version 6.2.5 which does not support 2.7 -Copied from: -https://github.com/learningequality/kolibri/blob/8f9e78572d140a8e70e4d790903fe5acaf4f1a9a/test/patch_pytest.py -""" -import os -import subprocess -import sys - -import pytest - - -def patch(): - site_packages_dir = os.path.dirname(pytest.__file__) - - patch_file = os.path.join(os.path.dirname(__file__), "pytest_3.10.patch") - - print("Applying patch: " + str(patch_file)) - - # -N: insist this is FORWARD patch, don't reverse apply - # -p1: strip first path component - # -t: batch mode, don't ask questions - patch_command = [ - "patch", - "-N", - "-p1", - "-d", - site_packages_dir, - "-t", - "-i", - patch_file, - ] - print(" ".join(patch_command)) - try: - # Use a dry run to establish whether the patch is already applied. - # If we don't check this, the patch may be partially applied (which is bad!) - subprocess.check_output(patch_command + ["--dry-run"]) - except subprocess.CalledProcessError as e: - if e.returncode == 1: - # Return code 1 means not all hunks could be applied, this usually - # means the patch is already applied. - print( - "Warning: failed to apply patch (exit code 1), " - "assuming it is already applied: ", - str(patch_file), - ) - else: - raise e - else: - # The dry run worked, so do the real thing - subprocess.check_output(patch_command) - - -if __name__ == "__main__": - if sys.version_info >= (3, 10): - patch() diff --git a/tests/pytest_3.10.patch b/tests/pytest_3.10.patch deleted file mode 100644 index 4c933e9..0000000 --- a/tests/pytest_3.10.patch +++ /dev/null @@ -1,38 +0,0 @@ -diff --git a/_pytest/assertion/rewrite.py b/_pytest/assertion/rewrite.py -index 4f96b9e8c..1aa5b12de 100644 ---- a/_pytest/assertion/rewrite.py -+++ b/_pytest/assertion/rewrite.py -@@ -587,10 +587,6 @@ class AssertionRewriter(ast.NodeVisitor): - return - # Insert some special imports at the top of the module but after any - # docstrings and __future__ imports. -- aliases = [ -- ast.alias(py.builtin.builtins.__name__, "@py_builtins"), -- ast.alias("_pytest.assertion.rewrite", "@pytest_ar"), -- ] - doc = getattr(mod, "docstring", None) - expect_docstring = doc is None - if doc is not None and self.is_rewrite_disabled(doc): -@@ -617,6 +613,22 @@ class AssertionRewriter(ast.NodeVisitor): - pos += 1 - else: - lineno = item.lineno -+ # Now actually insert the special imports. -+ if sys.version_info >= (3, 10): -+ aliases = [ -+ ast.alias("builtins", "@py_builtins", lineno=lineno, col_offset=0), -+ ast.alias( -+ "_pytest.assertion.rewrite", -+ "@pytest_ar", -+ lineno=lineno, -+ col_offset=0, -+ ), -+ ] -+ else: -+ aliases = [ -+ ast.alias("builtins", "@py_builtins"), -+ ast.alias("_pytest.assertion.rewrite", "@pytest_ar"), -+ ] - imports = [ - ast.Import([alias], lineno=lineno, col_offset=0) for alias in aliases - ] diff --git a/tests/testapp/tests/test_uuid_utilities.py b/tests/testapp/tests/test_uuid_utilities.py index 74c7c1c..de48dfd 100644 --- a/tests/testapp/tests/test_uuid_utilities.py +++ b/tests/testapp/tests/test_uuid_utilities.py @@ -1,5 +1,4 @@ import hashlib -import sys import uuid import mock @@ -100,6 +99,7 @@ def test_same_node_id(self): @mock.patch("platform.platform", return_value="Windows 3.1") @mock.patch("platform.node", return_value="myhost") @mock.patch("morango.models.utils._get_database_path", return_value="") + @mock.patch('sys.version', '2.7.333') def test_consistent_with_0_4_instance_id_calculation(self, *args): """ This test ensures that we don't accidentally make changes that impact how we calculate @@ -108,8 +108,6 @@ def test_consistent_with_0_4_instance_id_calculation(self, *args): from morango.models.utils import _get_database_path - sys.version = "2.7.333" - DatabaseIDModel.objects.all().update(current=False) database_id = DatabaseIDModel.objects.create( id="6fe445b75cea11858c00fb97bdee8878", current=True diff --git a/tox.ini b/tox.ini index a5de8a7..5b64f89 100644 --- a/tox.ini +++ b/tox.ini @@ -1,6 +1,6 @@ [tox] envlist = - py{3.6,3.7,3.8,3.9,3.10,3.11}-cryptography{40.0.2} + py{3.6,3.7,3.8,3.9,3.10,3.11,3.12}-cryptography{40.0.2} postgres windows @@ -19,6 +19,7 @@ basepython = py3.9: python3.9 py3.10: python3.10 py3.11: python3.11 + py3.12: python3.12 postgres: python3.9 windows: python3.8 @@ -26,9 +27,8 @@ deps = -r{toxinidir}/requirements/test.txt cryptography40.0.2: cryptography==40.0.2 commands = - sh -c '! tests/testapp/manage.py makemigrations --dry-run --exit --noinput' - python tests/patch_pytest.py - python -O -m pytest {posargs:--cov=morango --color=no} + sh -c 'tests/testapp/manage.py makemigrations --check' + python -O -m pytest {posargs: --color=no} [testenv:postgres] deps = @@ -38,8 +38,7 @@ setenv = PYTHONPATH = {toxinidir}:{toxinidir}/tests/testapp DJANGO_SETTINGS_MODULE = testapp.postgres_settings commands = - python tests/patch_pytest.py - python -O -m pytest {posargs:--cov=morango --color=no} + python -O -m pytest {posargs: --color=no} [testenv:windows] deps = @@ -47,5 +46,4 @@ deps = setenv = PYTHONPATH = {toxinidir}{:}{toxinidir}/tests/testapp commands = - python tests/patch_pytest.py - python -O -m pytest {posargs:--cov=morango --color=no} -m windows + python -O -m pytest {posargs: --color=no} -m windows