Drop Python2 and Django1 support

This commit is contained in:
2020-09-25 12:43:40 +02:00
parent 45d8b7cf21
commit 0d7cd64218
12 changed files with 29 additions and 60 deletions

View File

@@ -6,7 +6,7 @@ into a django project.
REQUIREMENTS REQUIREMENTS
============ ============
- python >= 2.7 - python >= 3
- Django - Django
(will be pulled in by pip, if you haven't installed it already. (will be pulled in by pip, if you haven't installed it already.
Probably this is why you are interested in this project) Probably this is why you are interested in this project)

View File

@@ -30,12 +30,7 @@ class CreatePythonEnvironment(MyCommand):
def run(): def run():
python_bin = sys.executable if sys.executable else 'python' python_bin = sys.executable if sys.executable else 'python'
python_ver = sys.version_info.major python_ver = sys.version_info.major
if python_ver == 2: if python_ver == 3:
path = os.path.join('env', 'python2')
symlink_path = os.path.join('env', 'python')
venv_module = 'virtualenv'
prompt = '(py2) '
elif python_ver == 3:
path = os.path.join('env', 'python3') path = os.path.join('env', 'python3')
symlink_path = os.path.join('env', 'python') symlink_path = os.path.join('env', 'python')
venv_module = 'venv' venv_module = 'venv'
@@ -67,7 +62,7 @@ class CreatePythonEnvironment(MyCommand):
setup( setup(
name='django-deploy', name='django-deploy',
version='0.2.dev0', version='0.3.dev0',
description='A helper to deploy reusable django apps into a django project.', description='A helper to deploy reusable django apps into a django project.',
long_description=long_description(), long_description=long_description(),
long_description_content_type='text/x-rst', long_description_content_type='text/x-rst',
@@ -95,7 +90,7 @@ setup(
'django-deploy.py = django_deploy:main', 'django-deploy.py = django_deploy:main',
], ],
}, },
python_requires='>=2.7', python_requires='>=3',
install_requires=[ install_requires=[
'django', 'django',
], ],

View File

@@ -42,7 +42,7 @@ class DjangoProjectHooksConfig(OrderedDict):
'Keyword arguments project_dir and settings_dir' \ 'Keyword arguments project_dir and settings_dir' \
' are mutually exclusive.' ' are mutually exclusive.'
super(DjangoProjectHooksConfig, self).__init__() super().__init__()
if project_dir is not None: if project_dir is not None:
settings_dir = os.path.join(project_dir, DJANGO_SETTINGS_DIR) settings_dir = os.path.join(project_dir, DJANGO_SETTINGS_DIR)
@@ -68,7 +68,7 @@ class DjangoProject(object):
try: try:
app_obj = importlib.import_module(module_path) app_obj = importlib.import_module(module_path)
except ImportError as e: except ImportError as e:
raise DjangoDeployError(e, code=errno.ENOPKG) raise DjangoDeployError(e, code=errno.ENOPKG) from e
try: try:
hooks_config = getattr(app_obj, hooks_config_name) hooks_config = getattr(app_obj, hooks_config_name)
@@ -76,7 +76,7 @@ class DjangoProject(object):
try: try:
hooks_config = importlib.import_module('{}.{}'.format(module_path, hooks_config_name)) hooks_config = importlib.import_module('{}.{}'.format(module_path, hooks_config_name))
except ImportError as e: except ImportError as e:
raise DjangoDeployError('In {}: {}'.format(module_path, e), code=errno.ENOENT) raise DjangoDeployError('In {}: {}'.format(module_path, e), code=errno.ENOENT) from e
return hooks_config return hooks_config
@@ -215,13 +215,13 @@ class DjangoProject(object):
try: try:
subprocess.check_output(cmd, stderr=subprocess.STDOUT) subprocess.check_output(cmd, stderr=subprocess.STDOUT)
except subprocess.CalledProcessError as e: except subprocess.CalledProcessError as e:
raise DjangoDeployError(e.output.decode('utf8'), exitval=e.returncode) raise DjangoDeployError(e.output.decode('utf8'), exitval=e.returncode) from e
else: else:
cmd = [management_script, 'migrate'] cmd = [management_script, 'migrate']
try: try:
subprocess.check_output(cmd, stderr=subprocess.STDOUT) subprocess.check_output(cmd, stderr=subprocess.STDOUT)
except subprocess.CalledProcessError as e: # pragma: no cover except subprocess.CalledProcessError as e: # pragma: no cover
raise DjangoDeployError(e.output.decode('utf8'), exitval=e.returncode) raise DjangoDeployError(e.output.decode('utf8'), exitval=e.returncode) from e
def __init__(self, project_dir): def __init__(self, project_dir):
self._project_dir = project_dir self._project_dir = project_dir

View File

@@ -3,7 +3,7 @@ class DjangoDeployError(Exception):
self._message = message self._message = message
self._code = code self._code = code
self._exitval = exitval self._exitval = exitval
super(DjangoDeployError, self).__init__(message) super().__init__(message)
@property @property
def message(self): def message(self):

View File

@@ -1,5 +1,5 @@
import os import os
from django.conf.urls import url, include from django.urls import re_path, include
from .api import DjangoProjectHooksConfig from .api import DjangoProjectHooksConfig
@@ -27,6 +27,6 @@ def get_urlpatterns(file_path, urlpatterns):
pattern = '^' pattern = '^'
else: else:
pattern = '^{}'.format(route) pattern = '^{}'.format(route)
url_obj = url(pattern, include(urlconf_module)) url_obj = re_path(pattern, include(urlconf_module))
urls_list.append(url_obj) urls_list.append(url_obj)
return urls_list return urls_list

View File

@@ -18,10 +18,7 @@ class DjangoDeployTestCase(unittest.TestCase):
def _import_from_dir(module_name, directory): def _import_from_dir(module_name, directory):
sys.path.insert(0, directory) sys.path.insert(0, directory)
module = importlib.import_module(module_name) module = importlib.import_module(module_name)
if sys.version_info.major == 2: # pragma: no cover importlib.reload(module)
reload(module) # pylint: disable=undefined-variable
else: # pragma: no cover
importlib.reload(module) # pylint: disable=no-member
sys.path.pop(0) sys.path.pop(0)
return module return module
@@ -136,15 +133,9 @@ class DjangoDeployTestCase(unittest.TestCase):
def assert_urlpatterns(self, project_dir, patterns): def assert_urlpatterns(self, project_dir, patterns):
root_urlconf = self.get_django_root_urlconf(project_dir) root_urlconf = self.get_django_root_urlconf(project_dir)
# Django 2 vs Django 1
if hasattr(root_urlconf, 'path'): # pragma: no cover
expected_urlpatterns = [ expected_urlpatterns = [
('URLPattern', 'admin/', 'django.contrib.admin.site.urls'), ('URLPattern', 'admin/', 'django.contrib.admin.site.urls'),
] ]
else: # pragma: no cover
expected_urlpatterns = [
('URLPattern', '^admin/', 'django.contrib.admin.site.urls'),
]
expected_urlpatterns += patterns expected_urlpatterns += patterns
real_urlpatterns = root_urlconf.urlpatterns real_urlpatterns = root_urlconf.urlpatterns
@@ -154,19 +145,12 @@ class DjangoDeployTestCase(unittest.TestCase):
real = real_urlpatterns[i] real = real_urlpatterns[i]
real_class_name = real.__class__.__name__ real_class_name = real.__class__.__name__
self.assertTrue(real_class_name.endswith(expected[0])) self.assertTrue(real_class_name.endswith(expected[0]))
# Django 2 vs. Django 1 if real_class_name == 'URLPattern':
if real_class_name == 'URLPattern': # pragma: no cover
self.assertEqual(expected[1], str(real.pattern)) self.assertEqual(expected[1], str(real.pattern))
self.assertTrue(real.callback.startswith("<Mock name='{}' id=".format(expected[2]))) self.assertTrue(real.callback.startswith("<Mock name='{}' id=".format(expected[2])))
elif real_class_name == 'RegexURLPattern': # pragma: no cover elif real_class_name == 'URLResolver':
self.assertEqual(expected[1], real.regex.pattern)
self.assertTrue(real.callback.startswith("<Mock name='{}' id=".format(expected[2])))
elif real_class_name == 'URLResolver': # pragma: no cover
self.assertEqual(expected[1], str(real.pattern)) self.assertEqual(expected[1], str(real.pattern))
self.assertEqual(expected[2], real.urlconf_name.__name__) self.assertEqual(expected[2], real.urlconf_name.__name__)
elif real_class_name == 'RegexURLResolver': # pragma: no cover
self.assertEqual(expected[1], real.regex.pattern)
self.assertEqual(expected[2], real.urlconf_name.__name__)
else: # pragma: no cover else: # pragma: no cover
self.fail('Unknown urlpattern class: {}'.format(real_class_name)) self.fail('Unknown urlpattern class: {}'.format(real_class_name))

View File

@@ -1,6 +1,5 @@
import errno import errno
import os import os
import django
from ..api import DjangoProjectHooksConfig, DjangoProject from ..api import DjangoProjectHooksConfig, DjangoProject
from ..exceptions import DjangoDeployError from ..exceptions import DjangoDeployError
@@ -283,9 +282,6 @@ class DjangoProjectMigrateAppTestCase(AbstractDjangoProjectTestCase):
try: try:
project.migrate_apps(['django_deploy.tests.fake_app1']) project.migrate_apps(['django_deploy.tests.fake_app1'])
except DjangoDeployError as e: except DjangoDeployError as e:
if django.VERSION[0] < 2: # pragma: no cover
expected_msg = "CommandError: App 'fake_app1' does not have migrations.\n"
else: # pragma: no cover
expected_msg = "CommandError: No installed app with label 'fake_app1'.\n" expected_msg = "CommandError: No installed app with label 'fake_app1'.\n"
self.assertEqual(expected_msg, e.message) self.assertEqual(expected_msg, e.message)
else: # pragma: no cover else: # pragma: no cover

View File

@@ -1,5 +1,5 @@
import unittest import unittest
from django.conf.urls import url, include from django.urls import re_path, include
from ..hooks import get_installed_apps, get_urlpatterns from ..hooks import get_installed_apps, get_urlpatterns
@@ -19,8 +19,8 @@ class HooksTestCase(unittest.TestCase):
( (
__file__, __file__,
[ [
url('/app1', include('django_deploy.tests.fake_app1.urls')), re_path('/app1', include('django_deploy.tests.fake_app1.urls')),
url('/app2', include('django_deploy.tests.fake_app2.urls')), re_path('/app2', include('django_deploy.tests.fake_app2.urls')),
], ],
), ),
] ]

View File

@@ -1,5 +1,4 @@
import os import os
import django
import pytest import pytest
from ..config import DJANGO_SETTINGS_DIR from ..config import DJANGO_SETTINGS_DIR
@@ -219,9 +218,6 @@ class ProgramMigrateTestCase(AbstractProgramTestCase):
self.assertNotEqual(os.EX_OK, exitval) self.assertNotEqual(os.EX_OK, exitval)
captured = self.capsys.readouterr() captured = self.capsys.readouterr()
if django.VERSION[0] < 2: # pragma: no cover
expected_msg = "CommandError: App 'fake_app1' does not have migrations.\n"
else: # pragma: no cover
expected_msg = "CommandError: No installed app with label 'fake_app1'.\n" expected_msg = "CommandError: No installed app with label 'fake_app1'.\n"
self.assertEqual(expected_msg, captured.err) self.assertEqual(expected_msg, captured.err)

View File

@@ -1 +1 @@
VERSION = '0.2.dev0' VERSION = '0.3.dev0'

View File

@@ -1,10 +1,8 @@
[tox] [tox]
envlist = py3-django3,py3-django2,py2-django1 envlist = py3-django3,py3-django2
[testenv] [testenv]
deps = coverage deps = coverage
py2-django1: django<2
py2-django1: pylint-django<2
py3-django2: django<3 py3-django2: django<3
py3-django2: pylint-django py3-django2: pylint-django
py3-django3: django py3-django3: django