diff --git a/djxml/xmlmodels/base.py b/djxml/xmlmodels/base.py index 0ac3946..17cdf04 100644 --- a/djxml/xmlmodels/base.py +++ b/djxml/xmlmodels/base.py @@ -9,8 +9,7 @@ from django.core.exceptions import (ObjectDoesNotExist, FieldError, MultipleObjectsReturned,) from django.db.models.base import subclass_exception -from django.utils.encoding import force_text -from django.utils.encoding import smart_bytes, smart_str +from django.utils.encoding import smart_str from .signals import xmlclass_prepared from .options import Options, DEFAULT_NAMES diff --git a/djxml/xmlmodels/fields.py b/djxml/xmlmodels/fields.py index e96a174..d9c1e22 100644 --- a/djxml/xmlmodels/fields.py +++ b/djxml/xmlmodels/fields.py @@ -4,11 +4,7 @@ from lxml import etree, isoschematron from django.core.exceptions import ValidationError -try: - from django.utils.encoding import force_text as force_unicode -except ImportError: - from django.utils.encoding import force_unicode - +from django.utils.encoding import force_str from .descriptors import ImmutableFieldBase, XPathFieldBase, XsltFieldBase from .exceptions import XmlSchemaValidationError from .utils import parse_datetime @@ -105,7 +101,7 @@ def get_default(self): if self.has_default(): if callable(self.default): return self.default() - return force_unicode(self.default, strings_only=True) + return force_str(self.default, strings_only=True) return None @@ -297,7 +293,7 @@ class XPathTextField(XPathSingleNodeField): def __init__(self, *args, **kwargs): none_vals = kwargs.pop('none_vals', None) if none_vals is not None: - self.none_vals = [force_unicode(v) for v in none_vals] + self.none_vals = [force_str(v) for v in none_vals] super(XPathTextField, self).__init__(*args, **kwargs) def validate(self, value, model_instance): @@ -316,9 +312,9 @@ def to_python(self, value): if value is None: return value if isinstance(value, etree._Element): - return force_unicode(value.text) + return force_str(value.text) else: - return force_unicode(value) + return force_str(value) class XPathIntegerField(XPathTextField): @@ -410,7 +406,7 @@ def to_python(self, value): if value is None: return value else: - return [force_unicode(getattr(v, "text", v)) for v in value] + return [force_str(getattr(v, "text", v)) for v in value] class XPathIntegerListField(XPathTextListField): diff --git a/djxml/xmlmodels/signals.py b/djxml/xmlmodels/signals.py index c8fe0c5..94e4a67 100644 --- a/djxml/xmlmodels/signals.py +++ b/djxml/xmlmodels/signals.py @@ -1,4 +1,5 @@ from __future__ import absolute_import from django.dispatch import Signal -xmlclass_prepared = Signal(providing_args=["class"]) +# Arguments: "class" +xmlclass_prepared = Signal() diff --git a/setup.py b/setup.py index 4cf3682..be9ecc6 100644 --- a/setup.py +++ b/setup.py @@ -33,11 +33,14 @@ 'Programming Language :: Python', 'Programming Language :: Python :: 3.7', 'Programming Language :: Python :: 3.8', + 'Programming Language :: Python :: 3.9', + 'Programming Language :: Python :: 3.10', 'Framework :: Django', 'Framework :: Django :: 2.2', 'Framework :: Django :: 3.0', 'Framework :: Django :: 3.1', 'Framework :: Django :: 3.2', + 'Framework :: Django :: 4.0', ], include_package_data=True, zip_safe=False, diff --git a/tox.ini b/tox.ini index 126a8cf..0e46dc5 100644 --- a/tox.ini +++ b/tox.ini @@ -1,6 +1,7 @@ [tox] envlist = py{37,38}-django{22,30,31,32} + py{38,39,310}-django{40} [testenv] commands = @@ -10,6 +11,7 @@ deps = django30: Django>=3.0.13,<3.1 django31: Django>=3.1.7,<3.2 django32: Django>=3.2rc1,<4.0 + django40: Django>=4.0,<4.1 [testenv:pep8] description = Run PEP8 pycodestyle (flake8) against the djxml/ package directory @@ -36,3 +38,5 @@ commands = python = 3.7: py37 3.8: py38 + 3.9: py39 + 3.10: py310