Skip to content

Commit d7f68ae

Browse files
committed
dj4
1 parent 97a9984 commit d7f68ae

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+160
-207
lines changed

.github/workflows/tests.yaml

+1-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ jobs:
2727
fail-fast: false
2828
matrix:
2929
python-version: [ "3.8", "3.9", "3.10"]
30-
django-version: [ "2.2", "3.2", ]
30+
django-version: [ "2.2", "3.2", "4.0"]
3131
db-engine: ["pg", "mysql"]
3232
env:
3333
PY_VER: ${{ matrix.python-version}}

Makefile

+1-2
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,6 @@ test:
2828

2929
lint:
3030
pre-commit run --all-files
31-
pipenv run isort -rc src/ --check-only
32-
pipenv run check-manifest
3331

3432
travis:
3533
docker run --privileged --name travis-debug -it -u travis travisci/ci-amethyst:packer-1512508255-986baf0 /bin/bash -l
@@ -48,6 +46,7 @@ fullclean:
4846

4947
docs: .mkbuilddir
5048
mkdir -p ${BUILDDIR}/docs
49+
rm -fr ${BUILDDIR}/docs/*
5150
sphinx-build -aE docs/ ${BUILDDIR}/docs
5251
ifdef BROWSE
5352
firefox ${BUILDDIR}/docs/index.html

docs/_ext/version.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@
22

33
from docutils.parsers.rst import Directive, directives
44
from sphinx import addnodes, roles
5+
from sphinx.errors import ExtensionError
56
from sphinx.util.console import bold
67
# RE for option descriptions without a '--' prefix
78
from sphinx.writers.html import HTMLTranslator
8-
from sphinx.errors import ExtensionError
99

1010
simple_option_desc_re = re.compile(
1111
r'([-_a-zA-Z0-9]+)(\s*.*?)(?=,\s+(?:/|-|--)|$)')

docs/settings.rst

-3
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,3 @@ Default::
173173

174174

175175
dict to customise :ref:`TriggerFactory`. Use this to customise the SQL clause to create triggers.
176-
177-
178-

setup.cfg

+10-12
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,15 @@
11
[isort]
2-
line_length=120
32
combine_as_imports = true
4-
multi_line_output = 5
5-
default_section = FIRSTPARTY
6-
indent=' '
7-
8-
known_future_library=
9-
known_standard_library=six
10-
known_third_party=django
11-
known_first_party=demo
12-
13-
known_concurrency=concurrency
14-
sections=FUTURE,STDLIB,THIRDPARTY,FIRSTPARTY,CONCURRENCY,LOCALFOLDER
3+
default_section = THIRDPARTY
4+
include_trailing_comma = true
5+
line_length = 80
6+
known_future_library = future,pies
7+
known_standard_library =
8+
known_third_party = django
9+
known_first_party = sos
10+
multi_line_output = 0
11+
balanced_wrapping = true
12+
sections = FUTURE,STDLIB,THIRDPARTY,FIRSTPARTY,LOCALFOLDER
1513

1614
[flake8]
1715
max-complexity = 12

setup.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,10 @@ def finalize_options(self):
2828

2929
def run_tests(self):
3030
# import here, cause outside the eggs aren't loaded
31-
import pytest
3231
import sys
3332

33+
import pytest
34+
3435
sys.path.insert(0, os.path.join(ROOT, 'tests', 'demoapp'))
3536
errno = pytest.main(self.test_args)
3637
sys.exit(errno)

src/concurrency/admin.py

+28-10
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,24 @@
1+
import operator
2+
import re
3+
from functools import reduce
4+
5+
import django
16
from django.contrib import admin, messages
27
from django.contrib.admin import helpers
38
from django.core.checks import Error
49
from django.core.exceptions import ImproperlyConfigured, ValidationError
510
from django.db.models import Q
6-
from django.forms.formsets import INITIAL_FORM_COUNT, MAX_NUM_FORM_COUNT, TOTAL_FORM_COUNT, ManagementForm
11+
from django.forms.formsets import (INITIAL_FORM_COUNT, MAX_NUM_FORM_COUNT,
12+
TOTAL_FORM_COUNT, ManagementForm,)
713
from django.forms.models import BaseModelFormSet
814
from django.http import HttpResponse, HttpResponseRedirect
915
from django.utils.encoding import force_str
1016
from django.utils.safestring import mark_safe
1117
from django.utils.translation import ngettext
1218

13-
import operator
14-
import re
15-
from functools import reduce
16-
1719
from concurrency import core, forms
1820
from concurrency.api import get_revision_of_object
21+
from concurrency.compat import concurrency_param_name
1922
from concurrency.config import CONCURRENCY_LIST_EDITABLE_POLICY_ABORT_ALL, conf
2023
from concurrency.exceptions import RecordModifiedError
2124
from concurrency.forms import ConcurrentForm, VersionWidget
@@ -132,12 +135,27 @@ def __init__(self, *args, **kwargs):
132135
self._versions = kwargs.pop('versions', [])
133136
super().__init__(*args, **kwargs)
134137

135-
def _html_output(self, normal_row, error_row, row_ender, help_text_html, errors_on_separate_row):
136-
ret = super()._html_output(normal_row, error_row, row_ender, help_text_html, errors_on_separate_row)
138+
def _get_concurrency_fields(self):
137139
v = []
138140
for pk, version in self._versions:
139-
v.append('<input type="hidden" name="_concurrency_version_{0}" value="{1}">'.format(pk, version))
140-
return mark_safe("{0}{1}".format(ret, "".join(v)))
141+
v.append(f'<input type="hidden" name="{concurrency_param_name}_{pk}" value="{version}">')
142+
return mark_safe("".join(v))
143+
144+
def render(self, template_name=None, context=None, renderer=None):
145+
out = super().render(template_name, context, renderer)
146+
return out + self._get_concurrency_fields()
147+
148+
def __str__(self):
149+
if django.VERSION[:2] >= (4, 0):
150+
return self.render()
151+
else:
152+
return super().__str__()
153+
154+
__html__ = __str__
155+
156+
def _html_output(self, normal_row, error_row, row_ender, help_text_html, errors_on_separate_row):
157+
ret = super()._html_output(normal_row, error_row, row_ender, help_text_html, errors_on_separate_row)
158+
return mark_safe("{0}{1}".format(ret, self._get_concurrency_fields()))
141159

142160

143161
class ConcurrentBaseModelFormSet(BaseModelFormSet):
@@ -183,7 +201,7 @@ def _get_conflicts(self, request):
183201
def save_model(self, request, obj, form, change):
184202
try:
185203
if change:
186-
version = request.POST.get('_concurrency_version_{0.pk}'.format(obj), None)
204+
version = request.POST.get(f'{concurrency_param_name}_{obj.pk}', None)
187205
if version:
188206
core._set_version(obj, version)
189207
super().save_model(request, obj, form, change)

src/concurrency/api.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
from django.db.models import Model
2-
31
import logging
42

3+
from django.db.models import Model
4+
55
from concurrency.config import conf
66
from concurrency.core import get_version_fieldname # _wrap_model_save
77
from concurrency.exceptions import RecordModifiedError

src/concurrency/compat.py

+6
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,8 @@
1+
import django
12
from django.template.exceptions import TemplateDoesNotExist # noqa
23
from django.urls.utils import get_callable # noqa
4+
5+
if django.VERSION[:2] >= (4, 0):
6+
concurrency_param_name = 'form-_concurrency_version'
7+
else:
8+
concurrency_param_name = '_concurrency_version'

src/concurrency/config.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1+
import warnings
2+
13
from django.core.exceptions import ImproperlyConfigured
24
from django.test.signals import setting_changed
35
from django.utils.module_loading import import_string
46

5-
import warnings
6-
77
from .compat import get_callable
88

99
# List Editable Policy

src/concurrency/fields.py

+7-8
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,3 @@
1-
from django.db import models
2-
from django.db.models import signals
3-
from django.db.models.fields import Field
4-
from django.db.models.signals import class_prepared, post_migrate
5-
from django.utils.encoding import force_str
6-
from django.utils.translation import gettext_lazy as _
7-
81
import copy
92
import functools
103
import hashlib
@@ -13,6 +6,13 @@
136
from collections import OrderedDict
147
from functools import update_wrapper
158

9+
from django.db import models
10+
from django.db.models import signals
11+
from django.db.models.fields import Field
12+
from django.db.models.signals import class_prepared, post_migrate
13+
from django.utils.encoding import force_str
14+
from django.utils.translation import gettext_lazy as _
15+
1616
from concurrency import forms
1717
from concurrency.api import get_revision_of_object
1818
from concurrency.config import conf
@@ -134,7 +134,6 @@ def _wrap_do_update(self, func):
134134
def _do_update(model_instance, base_qs, using, pk_val, values, update_fields, forced_update):
135135
version_field = model_instance._concurrencymeta.field
136136
old_version = get_revision_of_object(model_instance)
137-
138137
if not version_field.model._meta.abstract:
139138
if version_field.model is not base_qs.model:
140139
return func(model_instance, base_qs, using, pk_val, values, update_fields, forced_update)

src/concurrency/forms.py

+4-3
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
1+
from importlib import import_module
2+
13
from django import forms
2-
from django.core.exceptions import NON_FIELD_ERRORS, ImproperlyConfigured, ValidationError
4+
from django.core.exceptions import (NON_FIELD_ERRORS, ImproperlyConfigured,
5+
ValidationError,)
36
from django.core.signing import BadSignature, Signer
47
from django.forms import HiddenInput, ModelForm
58
from django.utils.safestring import mark_safe
69
from django.utils.translation import gettext as _
710

8-
from importlib import import_module
9-
1011
from concurrency.config import conf
1112
from concurrency.core import _select_lock
1213
from concurrency.exceptions import RecordModifiedError, VersionError

src/concurrency/management/commands/triggers.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1+
from functools import partial
2+
13
import django
24
from django.core.exceptions import ImproperlyConfigured
35
from django.core.management.base import BaseCommand
46
from django.db import connections
57
from django.db.transaction import atomic
68

7-
from functools import partial
8-
99
from concurrency.triggers import create_triggers, drop_triggers, get_triggers
1010

1111

src/concurrency/triggers.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1+
from collections import defaultdict
2+
13
from django.apps import apps
24
from django.db import connections, router
35
from django.db.utils import DatabaseError
46

5-
from collections import defaultdict
6-
77
# from .fields import _TRIGGERS # noqa
88

99

tests/conftest.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
import os
22
import platform
3-
import pytest
43
import sys
54

5+
import pytest
6+
67
py_impl = getattr(platform, 'python_implementation', lambda: None)
78
PYPY = py_impl() == 'PyPy'
89
PURE_PYTHON = os.environ.get('PURE_PYTHON', False)

tests/demoapp/demo/admin.py

+3-5
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,9 @@
1+
from demo.models import (InheritedModel, ListEditableConcurrentModel,
2+
NoActionsConcurrentModel, ProxyModel,
3+
ReversionConcurrentModel, SimpleConcurrentModel,)
14
from django.contrib import admin
25
from django.contrib.admin.sites import NotRegistered
36

4-
from demo.models import (
5-
InheritedModel, ListEditableConcurrentModel, NoActionsConcurrentModel, ProxyModel, ReversionConcurrentModel,
6-
SimpleConcurrentModel
7-
)
8-
97
from concurrency.admin import ConcurrentModelAdmin
108
from concurrency.api import disable_concurrency
119

tests/demoapp/demo/base.py

+1-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
1+
from demo.admin import admin_register_models
12
from django.contrib.auth.models import Group, User
23
from django.test import TransactionTestCase
34
from django.utils import timezone
4-
5-
from demo.admin import admin_register_models
65
from django_webtest import WebTestMixin
76

87
from concurrency.api import apply_concurrency_check

tests/demoapp/demo/models.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
from django.contrib.auth.models import Group, User
22
from django.db import models
33

4-
from concurrency.fields import AutoIncVersionField, ConditionalVersionField, IntegerVersionField, TriggerVersionField
4+
from concurrency.fields import (AutoIncVersionField, ConditionalVersionField,
5+
IntegerVersionField, TriggerVersionField,)
56

67
__all__ = ['SimpleConcurrentModel', 'AutoIncConcurrentModel',
78
'ProxyModel', 'InheritedModel', 'CustomSaveModel',

tests/demoapp/demo/settings.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -116,8 +116,8 @@
116116
'default': {
117117
'ENGINE': 'django.db.backends.postgresql_psycopg2',
118118
'NAME': dbname,
119-
'HOST': '127.0.0.1',
120-
'PORT': '5432',
119+
'HOST': os.environ.get('PGHOST', '127.0.0.1'),
120+
'PORT': os.environ.get('PGPORT', '5432'),
121121
'USER': 'postgres',
122122
'PASSWORD': 'postgres'}}
123123
elif db == 'mysql':

tests/demoapp/demo/urls.py

+1-2
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
1+
from demo.models import SimpleConcurrentModel
12
from django.contrib import admin
23
from django.urls import re_path
34
from django.views.generic.edit import UpdateView
45

5-
from demo.models import SimpleConcurrentModel
6-
76
admin.autodiscover()
87

98
urlpatterns = (re_path(r'cm/(?P<pk>\d+)/',

tests/demoapp/demo/util.py

+6-7
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,14 @@
1-
from django import db
2-
31
import itertools
4-
import pytest
52
from contextlib import contextmanager
6-
from demo.models import (
7-
AutoIncConcurrentModel, ConcreteModel, CustomSaveModel, InheritedModel, ProxyModel, SimpleConcurrentModel,
8-
TriggerConcurrentModel
9-
)
103
from functools import partial, update_wrapper
114
from itertools import count
125

6+
import pytest
7+
from demo.models import (AutoIncConcurrentModel, ConcreteModel,
8+
CustomSaveModel, InheritedModel, ProxyModel,
9+
SimpleConcurrentModel, TriggerConcurrentModel,)
10+
from django import db
11+
1312
from concurrency.config import conf
1413

1514

tests/test_admin_actions.py

+1-2
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
1-
from django.urls import reverse
2-
31
import pytest
42
from demo.base import SENTINEL, AdminTestCase
53
from demo.models import SimpleConcurrentModel
64
from demo.util import unique_id
5+
from django.urls import reverse
76

87

98
class TestAdminActions(AdminTestCase):

tests/test_admin_edit.py

+2-3
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
1-
from django.urls import reverse
2-
from django.utils.translation import gettext as _
3-
41
import pytest
52
from demo.base import SENTINEL, AdminTestCase
63
from demo.models import SimpleConcurrentModel
74
from demo.util import nextname
5+
from django.urls import reverse
6+
from django.utils.translation import gettext as _
87

98
from concurrency.forms import VersionFieldSigner
109

0 commit comments

Comments
 (0)