Drop Python2 and Django1 support
This commit is contained in:
@@ -7,10 +7,10 @@ load-plugins=pylint_django
|
|||||||
[MESSAGES CONTROL]
|
[MESSAGES CONTROL]
|
||||||
|
|
||||||
disable=missing-docstring,
|
disable=missing-docstring,
|
||||||
missing-module-docstring,
|
missing-module-docstring,
|
||||||
missing-class-docstring,
|
missing-class-docstring,
|
||||||
missing-function-docstring,
|
missing-function-docstring,
|
||||||
useless-object-inheritance,
|
useless-object-inheritance,
|
||||||
|
|
||||||
[BASIC]
|
[BASIC]
|
||||||
|
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
11
setup.py
11
setup.py
@@ -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',
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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):
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
expected_urlpatterns = [
|
||||||
if hasattr(root_urlconf, 'path'): # pragma: no cover
|
('URLPattern', 'admin/', 'django.contrib.admin.site.urls'),
|
||||||
expected_urlpatterns = [
|
]
|
||||||
('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))
|
||||||
|
|
||||||
|
|||||||
@@ -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,10 +282,7 @@ 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: No installed app with label 'fake_app1'.\n"
|
||||||
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"
|
|
||||||
self.assertEqual(expected_msg, e.message)
|
self.assertEqual(expected_msg, e.message)
|
||||||
else: # pragma: no cover
|
else: # pragma: no cover
|
||||||
self.fail('DjangoDeployError not raised')
|
self.fail('DjangoDeployError not raised')
|
||||||
|
|||||||
@@ -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')),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -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,10 +218,7 @@ 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: No installed app with label 'fake_app1'.\n"
|
||||||
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"
|
|
||||||
self.assertEqual(expected_msg, captured.err)
|
self.assertEqual(expected_msg, captured.err)
|
||||||
|
|
||||||
def test_migrate_app_without_create(self):
|
def test_migrate_app_without_create(self):
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
VERSION = '0.2.dev0'
|
VERSION = '0.3.dev0'
|
||||||
|
|||||||
4
tox.ini
4
tox.ini
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user