mirror of https://github.com/django/django.git
Refs #23919 -- Removed misc Python 2/3 references.
This commit is contained in:
parent
11856ea44e
commit
1c466994d9
|
@ -57,8 +57,8 @@ class AppConfig:
|
||||||
"""Attempt to determine app's filesystem path from its module."""
|
"""Attempt to determine app's filesystem path from its module."""
|
||||||
# See #21874 for extended discussion of the behavior of this method in
|
# See #21874 for extended discussion of the behavior of this method in
|
||||||
# various cases.
|
# various cases.
|
||||||
# Convert paths to list because Python 3's _NamespacePath does not
|
# Convert paths to list because Python's _NamespacePath doesn't support
|
||||||
# support indexing.
|
# indexing.
|
||||||
paths = list(getattr(module, '__path__', []))
|
paths = list(getattr(module, '__path__', []))
|
||||||
if len(paths) != 1:
|
if len(paths) != 1:
|
||||||
filename = getattr(module, '__file__', None)
|
filename = getattr(module, '__file__', None)
|
||||||
|
|
|
@ -419,8 +419,7 @@ class BCryptSHA256PasswordHasher(BasePasswordHasher):
|
||||||
# Hash the password prior to using bcrypt to prevent password
|
# Hash the password prior to using bcrypt to prevent password
|
||||||
# truncation as described in #20138.
|
# truncation as described in #20138.
|
||||||
if self.digest is not None:
|
if self.digest is not None:
|
||||||
# Use binascii.hexlify() because a hex encoded bytestring is
|
# Use binascii.hexlify() because a hex encoded bytestring is str.
|
||||||
# Unicode on Python 3.
|
|
||||||
password = binascii.hexlify(self.digest(force_bytes(password)).digest())
|
password = binascii.hexlify(self.digest(force_bytes(password)).digest())
|
||||||
else:
|
else:
|
||||||
password = force_bytes(password)
|
password = force_bytes(password)
|
||||||
|
|
|
@ -298,7 +298,7 @@ def password_reset_confirm(request, uidb64=None, token=None,
|
||||||
else:
|
else:
|
||||||
post_reset_redirect = resolve_url(post_reset_redirect)
|
post_reset_redirect = resolve_url(post_reset_redirect)
|
||||||
try:
|
try:
|
||||||
# urlsafe_base64_decode() decodes to bytestring on Python 3
|
# urlsafe_base64_decode() decodes to bytestring
|
||||||
uid = force_text(urlsafe_base64_decode(uidb64))
|
uid = force_text(urlsafe_base64_decode(uidb64))
|
||||||
user = UserModel._default_manager.get(pk=uid)
|
user = UserModel._default_manager.get(pk=uid)
|
||||||
except (TypeError, ValueError, OverflowError, UserModel.DoesNotExist):
|
except (TypeError, ValueError, OverflowError, UserModel.DoesNotExist):
|
||||||
|
@ -442,7 +442,7 @@ class PasswordResetConfirmView(PasswordContextMixin, FormView):
|
||||||
|
|
||||||
def get_user(self, uidb64):
|
def get_user(self, uidb64):
|
||||||
try:
|
try:
|
||||||
# urlsafe_base64_decode() decodes to bytestring on Python 3
|
# urlsafe_base64_decode() decodes to bytestring
|
||||||
uid = force_text(urlsafe_base64_decode(uidb64))
|
uid = force_text(urlsafe_base64_decode(uidb64))
|
||||||
user = UserModel._default_manager.get(pk=uid)
|
user = UserModel._default_manager.get(pk=uid)
|
||||||
except (TypeError, ValueError, OverflowError, UserModel.DoesNotExist):
|
except (TypeError, ValueError, OverflowError, UserModel.DoesNotExist):
|
||||||
|
|
|
@ -324,8 +324,8 @@ class EmailMessage:
|
||||||
try:
|
try:
|
||||||
content = content.decode('utf-8')
|
content = content.decode('utf-8')
|
||||||
except UnicodeDecodeError:
|
except UnicodeDecodeError:
|
||||||
# If mimetype suggests the file is text but it's actually
|
# If mimetype suggests the file is text but it's
|
||||||
# binary, read() will raise a UnicodeDecodeError on Python 3.
|
# actually binary, read() raises a UnicodeDecodeError.
|
||||||
mimetype = DEFAULT_ATTACHMENT_MIME_TYPE
|
mimetype = DEFAULT_ATTACHMENT_MIME_TYPE
|
||||||
|
|
||||||
self.attachments.append((filename, content, mimetype))
|
self.attachments.append((filename, content, mimetype))
|
||||||
|
|
|
@ -53,7 +53,7 @@ class Command(BaseCommand):
|
||||||
import rlcompleter
|
import rlcompleter
|
||||||
readline.set_completer(rlcompleter.Completer(imported_objects).complete)
|
readline.set_completer(rlcompleter.Completer(imported_objects).complete)
|
||||||
# Enable tab completion on systems using libedit (e.g. Mac OSX).
|
# Enable tab completion on systems using libedit (e.g. Mac OSX).
|
||||||
# These lines are copied from Lib/site.py on Python 3.4.
|
# These lines are copied from Python's Lib/site.py.
|
||||||
readline_doc = getattr(readline, '__doc__', '')
|
readline_doc = getattr(readline, '__doc__', '')
|
||||||
if readline_doc is not None and 'libedit' in readline_doc:
|
if readline_doc is not None and 'libedit' in readline_doc:
|
||||||
readline.parse_and_bind("bind ^I rl_complete")
|
readline.parse_and_bind("bind ^I rl_complete")
|
||||||
|
|
|
@ -322,8 +322,7 @@ class OracleParam:
|
||||||
param = Oracle_datetime.from_datetime(param)
|
param = Oracle_datetime.from_datetime(param)
|
||||||
|
|
||||||
string_size = 0
|
string_size = 0
|
||||||
# Oracle doesn't recognize True and False correctly in Python 3.
|
# Oracle doesn't recognize True and False correctly.
|
||||||
# The conversion done below works both in 2 and 3.
|
|
||||||
if param is True:
|
if param is True:
|
||||||
param = 1
|
param = 1
|
||||||
elif param is False:
|
elif param is False:
|
||||||
|
|
|
@ -8,7 +8,6 @@ import math
|
||||||
import re
|
import re
|
||||||
import types
|
import types
|
||||||
import uuid
|
import uuid
|
||||||
from importlib import import_module
|
|
||||||
|
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from django.db.migrations.operations.base import Operation
|
from django.db.migrations.operations.base import Operation
|
||||||
|
@ -155,20 +154,15 @@ class FunctionTypeSerializer(BaseSerializer):
|
||||||
raise ValueError("Cannot serialize function: lambda")
|
raise ValueError("Cannot serialize function: lambda")
|
||||||
if self.value.__module__ is None:
|
if self.value.__module__ is None:
|
||||||
raise ValueError("Cannot serialize function %r: No module" % self.value)
|
raise ValueError("Cannot serialize function %r: No module" % self.value)
|
||||||
# Python 3 is a lot easier, and only uses this branch if it's not local.
|
|
||||||
if getattr(self.value, "__qualname__", None) and getattr(self.value, "__module__", None):
|
|
||||||
if "<" not in self.value.__qualname__: # Qualname can include <locals>
|
|
||||||
return "%s.%s" % \
|
|
||||||
(self.value.__module__, self.value.__qualname__), {"import %s" % self.value.__module__}
|
|
||||||
# Fallback version
|
|
||||||
module_name = self.value.__module__
|
module_name = self.value.__module__
|
||||||
# Make sure it's actually there
|
|
||||||
module = import_module(module_name)
|
if '<' not in self.value.__qualname__: # Qualname can include <locals>
|
||||||
if not hasattr(module, self.value.__name__):
|
return '%s.%s' % (module_name, self.value.__qualname__), {'import %s' % self.value.__module__}
|
||||||
raise ValueError(
|
|
||||||
"Could not find function %s in %s.\n" % (self.value.__name__, module_name)
|
raise ValueError(
|
||||||
)
|
'Could not find function %s in %s.\n' % (self.value.__name__, module_name)
|
||||||
return "%s.%s" % (module_name, self.value.__name__), {"import %s" % module_name}
|
)
|
||||||
|
|
||||||
|
|
||||||
class FunctoolsPartialSerializer(BaseSerializer):
|
class FunctoolsPartialSerializer(BaseSerializer):
|
||||||
|
|
|
@ -258,8 +258,7 @@ def default_test_processes():
|
||||||
"""
|
"""
|
||||||
# The current implementation of the parallel test runner requires
|
# The current implementation of the parallel test runner requires
|
||||||
# multiprocessing to start subprocesses with fork().
|
# multiprocessing to start subprocesses with fork().
|
||||||
# On Python 3.4+: if multiprocessing.get_start_method() != 'fork':
|
if multiprocessing.get_start_method() != 'fork':
|
||||||
if not hasattr(os, 'fork'):
|
|
||||||
return 1
|
return 1
|
||||||
try:
|
try:
|
||||||
return int(os.environ['DJANGO_TEST_PROCESSES'])
|
return int(os.environ['DJANGO_TEST_PROCESSES'])
|
||||||
|
|
|
@ -303,7 +303,7 @@ Now you're ready to actually put the release out there. To do this:
|
||||||
$ pip install https://www.djangoproject.com/m/releases/$MAJOR_VERSION/Django-$RELEASE_VERSION.tar.gz
|
$ pip install https://www.djangoproject.com/m/releases/$MAJOR_VERSION/Django-$RELEASE_VERSION.tar.gz
|
||||||
$ deactivate
|
$ deactivate
|
||||||
$ mktmpenv
|
$ mktmpenv
|
||||||
$ pip install https://www.djangoproject.com/m/releases/$MAJOR_VERSION/Django-$RELEASE_VERSION-py2.py3-none-any.whl
|
$ pip install https://www.djangoproject.com/m/releases/$MAJOR_VERSION/Django-$RELEASE_VERSION-py3-none-any.whl
|
||||||
$ deactivate
|
$ deactivate
|
||||||
|
|
||||||
This just tests that the tarballs are available (i.e. redirects are up) and
|
This just tests that the tarballs are available (i.e. redirects are up) and
|
||||||
|
|
|
@ -1,8 +0,0 @@
|
||||||
set OSGEO4W_ROOT=C:\OSGeo4W
|
|
||||||
set PYTHON_ROOT=C:\Python27
|
|
||||||
set GDAL_DATA=%OSGEO4W_ROOT%\share\gdal
|
|
||||||
set PROJ_LIB=%OSGEO4W_ROOT%\share\proj
|
|
||||||
set PATH=%PATH%;%PYTHON_ROOT%;%OSGEO4W_ROOT%\bin
|
|
||||||
reg ADD "HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment" /v Path /t REG_EXPAND_SZ /f /d "%PATH%"
|
|
||||||
reg ADD "HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment" /v GDAL_DATA /t REG_EXPAND_SZ /f /d "%GDAL_DATA%"
|
|
||||||
reg ADD "HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment" /v PROJ_LIB /t REG_EXPAND_SZ /f /d "%PROJ_LIB%"
|
|
|
@ -463,7 +463,7 @@ executable with ``cmd.exe``, will set this up:
|
||||||
.. code-block:: bat
|
.. code-block:: bat
|
||||||
|
|
||||||
set OSGEO4W_ROOT=C:\OSGeo4W
|
set OSGEO4W_ROOT=C:\OSGeo4W
|
||||||
set PYTHON_ROOT=C:\Python27
|
set PYTHON_ROOT=C:\Python3X
|
||||||
set GDAL_DATA=%OSGEO4W_ROOT%\share\gdal
|
set GDAL_DATA=%OSGEO4W_ROOT%\share\gdal
|
||||||
set PROJ_LIB=%OSGEO4W_ROOT%\share\proj
|
set PROJ_LIB=%OSGEO4W_ROOT%\share\proj
|
||||||
set PATH=%PATH%;%PYTHON_ROOT%;%OSGEO4W_ROOT%\bin
|
set PATH=%PATH%;%PYTHON_ROOT%;%OSGEO4W_ROOT%\bin
|
||||||
|
@ -471,15 +471,12 @@ executable with ``cmd.exe``, will set this up:
|
||||||
reg ADD "HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment" /v GDAL_DATA /t REG_EXPAND_SZ /f /d "%GDAL_DATA%"
|
reg ADD "HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment" /v GDAL_DATA /t REG_EXPAND_SZ /f /d "%GDAL_DATA%"
|
||||||
reg ADD "HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment" /v PROJ_LIB /t REG_EXPAND_SZ /f /d "%PROJ_LIB%"
|
reg ADD "HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment" /v PROJ_LIB /t REG_EXPAND_SZ /f /d "%PROJ_LIB%"
|
||||||
|
|
||||||
For your convenience, these commands are available in the executable batch
|
|
||||||
script, :download:`geodjango_setup.bat`.
|
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
|
|
||||||
Administrator privileges are required to execute these commands.
|
Administrator privileges are required to execute these commands.
|
||||||
To do this, right-click on :download:`geodjango_setup.bat` and select
|
To do this, create a ``bat`` script with the commands, right-click it, and
|
||||||
:menuselection:`Run as administrator`. You need to log out and log back in again
|
select :menuselection:`Run as administrator`. You need to log out and log
|
||||||
for the settings to take effect.
|
back in again for the settings to take effect.
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,3 @@ not_skip = __init__.py
|
||||||
|
|
||||||
[metadata]
|
[metadata]
|
||||||
license-file = LICENSE
|
license-file = LICENSE
|
||||||
|
|
||||||
[wheel]
|
|
||||||
universal = 1
|
|
||||||
|
|
2
setup.py
2
setup.py
|
@ -61,8 +61,6 @@ setup(
|
||||||
'License :: OSI Approved :: BSD License',
|
'License :: OSI Approved :: BSD License',
|
||||||
'Operating System :: OS Independent',
|
'Operating System :: OS Independent',
|
||||||
'Programming Language :: Python',
|
'Programming Language :: Python',
|
||||||
'Programming Language :: Python :: 2',
|
|
||||||
'Programming Language :: Python :: 2.7',
|
|
||||||
'Programming Language :: Python :: 3',
|
'Programming Language :: Python :: 3',
|
||||||
'Programming Language :: Python :: 3.4',
|
'Programming Language :: Python :: 3.4',
|
||||||
'Programming Language :: Python :: 3.5',
|
'Programming Language :: Python :: 3.5',
|
||||||
|
|
|
@ -3,7 +3,7 @@ install some requirements and run the tests::
|
||||||
|
|
||||||
$ cd tests
|
$ cd tests
|
||||||
$ pip install -e ..
|
$ pip install -e ..
|
||||||
$ pip install -r requirements/py3.txt # or py2.txt
|
$ pip install -r requirements/py3.txt
|
||||||
$ ./runtests.py
|
$ ./runtests.py
|
||||||
|
|
||||||
For more information about the test suite, see
|
For more information about the test suite, see
|
||||||
|
|
|
@ -434,7 +434,6 @@ class TestUtilsHashPass(SimpleTestCase):
|
||||||
|
|
||||||
def test_load_library_importerror(self):
|
def test_load_library_importerror(self):
|
||||||
PlainHasher = type('PlainHasher', (BasePasswordHasher,), {'algorithm': 'plain', 'library': 'plain'})
|
PlainHasher = type('PlainHasher', (BasePasswordHasher,), {'algorithm': 'plain', 'library': 'plain'})
|
||||||
# Python 3 adds quotes around module name
|
|
||||||
msg = "Couldn't load 'PlainHasher' algorithm library: No module named 'plain'"
|
msg = "Couldn't load 'PlainHasher' algorithm library: No module named 'plain'"
|
||||||
with self.assertRaisesMessage(ValueError, msg):
|
with self.assertRaisesMessage(ValueError, msg):
|
||||||
PlainHasher()._load_library()
|
PlainHasher()._load_library()
|
||||||
|
|
|
@ -1912,10 +1912,6 @@ class CacheI18nTest(TestCase):
|
||||||
get_cache_data = FetchFromCacheMiddleware().process_request(request)
|
get_cache_data = FetchFromCacheMiddleware().process_request(request)
|
||||||
self.assertIsNone(get_cache_data)
|
self.assertIsNone(get_cache_data)
|
||||||
|
|
||||||
# This test passes on Python < 3.3 even without the corresponding code
|
|
||||||
# in UpdateCacheMiddleware, because pickling a StreamingHttpResponse
|
|
||||||
# fails (http://bugs.python.org/issue14288). LocMemCache silently
|
|
||||||
# swallows the exception and doesn't store the response in cache.
|
|
||||||
content = ['Check for cache with streaming content.']
|
content = ['Check for cache with streaming content.']
|
||||||
response = StreamingHttpResponse(content)
|
response = StreamingHttpResponse(content)
|
||||||
UpdateCacheMiddleware().process_response(request, response)
|
UpdateCacheMiddleware().process_response(request, response)
|
||||||
|
|
|
@ -16,6 +16,7 @@ from django.core.management.commands.makemessages import \
|
||||||
from django.core.management.utils import find_command
|
from django.core.management.utils import find_command
|
||||||
from django.test import SimpleTestCase, override_settings
|
from django.test import SimpleTestCase, override_settings
|
||||||
from django.test.utils import captured_stderr, captured_stdout
|
from django.test.utils import captured_stderr, captured_stdout
|
||||||
|
from django.utils._os import symlinks_supported
|
||||||
from django.utils.translation import TranslatorCommentWarning
|
from django.utils.translation import TranslatorCommentWarning
|
||||||
|
|
||||||
from .utils import POFileAssertionMixin, RunInTmpDirMixin, copytree
|
from .utils import POFileAssertionMixin, RunInTmpDirMixin, copytree
|
||||||
|
@ -382,7 +383,10 @@ class BasicExtractorTests(ExtractorTests):
|
||||||
cmd.gettext_version
|
cmd.gettext_version
|
||||||
|
|
||||||
def test_po_file_encoding_when_updating(self):
|
def test_po_file_encoding_when_updating(self):
|
||||||
"""Update of PO file doesn't corrupt it with non-UTF-8 encoding on Python3+Windows (#23271)"""
|
"""
|
||||||
|
Update of PO file doesn't corrupt it with non-UTF-8 encoding on Windows
|
||||||
|
(#23271).
|
||||||
|
"""
|
||||||
BR_PO_BASE = 'locale/pt_BR/LC_MESSAGES/django'
|
BR_PO_BASE = 'locale/pt_BR/LC_MESSAGES/django'
|
||||||
shutil.copyfile(BR_PO_BASE + '.pristine', BR_PO_BASE + '.po')
|
shutil.copyfile(BR_PO_BASE + '.pristine', BR_PO_BASE + '.po')
|
||||||
management.call_command('makemessages', locale=['pt_BR'], verbosity=0)
|
management.call_command('makemessages', locale=['pt_BR'], verbosity=0)
|
||||||
|
@ -472,29 +476,20 @@ class SymlinkExtractorTests(ExtractorTests):
|
||||||
self.symlinked_dir = os.path.join(self.test_dir, 'templates_symlinked')
|
self.symlinked_dir = os.path.join(self.test_dir, 'templates_symlinked')
|
||||||
|
|
||||||
def test_symlink(self):
|
def test_symlink(self):
|
||||||
# On Python < 3.2 os.symlink() exists only on Unix
|
if os.path.exists(self.symlinked_dir):
|
||||||
if hasattr(os, 'symlink'):
|
self.assertTrue(os.path.islink(self.symlinked_dir))
|
||||||
if os.path.exists(self.symlinked_dir):
|
|
||||||
self.assertTrue(os.path.islink(self.symlinked_dir))
|
|
||||||
else:
|
|
||||||
# On Python >= 3.2) os.symlink() exists always but then can
|
|
||||||
# fail at runtime when user hasn't the needed permissions on
|
|
||||||
# Windows versions that support symbolink links (>= 6/Vista).
|
|
||||||
# See Python issue 9333 (http://bugs.python.org/issue9333).
|
|
||||||
# Skip the test in that case
|
|
||||||
try:
|
|
||||||
os.symlink(os.path.join(self.test_dir, 'templates'), self.symlinked_dir)
|
|
||||||
except (OSError, NotImplementedError):
|
|
||||||
self.skipTest("os.symlink() is available on this OS but can't be used by this user.")
|
|
||||||
os.chdir(self.test_dir)
|
|
||||||
management.call_command('makemessages', locale=[LOCALE], verbosity=0, symlinks=True)
|
|
||||||
self.assertTrue(os.path.exists(self.PO_FILE))
|
|
||||||
with open(self.PO_FILE, 'r') as fp:
|
|
||||||
po_contents = fp.read()
|
|
||||||
self.assertMsgId('This literal should be included.', po_contents)
|
|
||||||
self.assertLocationCommentPresent(self.PO_FILE, None, 'templates_symlinked', 'test.html')
|
|
||||||
else:
|
else:
|
||||||
self.skipTest("os.symlink() not available on this OS + Python version combination.")
|
if symlinks_supported():
|
||||||
|
os.symlink(os.path.join(self.test_dir, 'templates'), self.symlinked_dir)
|
||||||
|
else:
|
||||||
|
self.skipTest("os.symlink() not available on this OS + Python version combination.")
|
||||||
|
os.chdir(self.test_dir)
|
||||||
|
management.call_command('makemessages', locale=[LOCALE], verbosity=0, symlinks=True)
|
||||||
|
self.assertTrue(os.path.exists(self.PO_FILE))
|
||||||
|
with open(self.PO_FILE, 'r') as fp:
|
||||||
|
po_contents = fp.read()
|
||||||
|
self.assertMsgId('This literal should be included.', po_contents)
|
||||||
|
self.assertLocationCommentPresent(self.PO_FILE, None, 'templates_symlinked', 'test.html')
|
||||||
|
|
||||||
|
|
||||||
class CopyPluralFormsExtractorTests(ExtractorTests):
|
class CopyPluralFormsExtractorTests(ExtractorTests):
|
||||||
|
|
|
@ -192,7 +192,6 @@ class MailTests(HeadersCheckMixin, SimpleTestCase):
|
||||||
'Content', 'from@example.com', ['to@example.com']
|
'Content', 'from@example.com', ['to@example.com']
|
||||||
)
|
)
|
||||||
message = email.message()
|
message = email.message()
|
||||||
# Note that in Python 3, maximum line length has increased from 76 to 78
|
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
message['Subject'].encode(),
|
message['Subject'].encode(),
|
||||||
b'Long subject lines that get wrapped should contain a space continuation\n'
|
b'Long subject lines that get wrapped should contain a space continuation\n'
|
||||||
|
@ -1157,8 +1156,8 @@ class FakeSMTPServer(smtpd.SMTPServer, threading.Thread):
|
||||||
|
|
||||||
if mailfrom != maddr:
|
if mailfrom != maddr:
|
||||||
# According to the spec, mailfrom does not necessarily match the
|
# According to the spec, mailfrom does not necessarily match the
|
||||||
# From header - on Python 3 this is the case where the local part
|
# From header - this is the case where the local part isn't
|
||||||
# isn't encoded, so try to correct that.
|
# encoded, so try to correct that.
|
||||||
lp, domain = mailfrom.split('@', 1)
|
lp, domain = mailfrom.split('@', 1)
|
||||||
lp = Header(lp, 'utf-8').encode()
|
lp = Header(lp, 'utf-8').encode()
|
||||||
mailfrom = '@'.join([lp, domain])
|
mailfrom = '@'.join([lp, domain])
|
||||||
|
|
|
@ -672,8 +672,8 @@ class MakeMigrationsTests(MigrationTestBase):
|
||||||
module = 'migrations.test_migrations_order'
|
module = 'migrations.test_migrations_order'
|
||||||
with self.temporary_migration_module(module=module) as migration_dir:
|
with self.temporary_migration_module(module=module) as migration_dir:
|
||||||
if hasattr(importlib, 'invalidate_caches'):
|
if hasattr(importlib, 'invalidate_caches'):
|
||||||
# Python 3 importlib caches os.listdir() on some platforms like
|
# importlib caches os.listdir() on some platforms like Mac OS X
|
||||||
# Mac OS X (#23850).
|
# (#23850).
|
||||||
importlib.invalidate_caches()
|
importlib.invalidate_caches()
|
||||||
call_command('makemigrations', 'migrations', '--empty', '-n', 'a', '-v', '0')
|
call_command('makemigrations', 'migrations', '--empty', '-n', 'a', '-v', '0')
|
||||||
self.assertTrue(os.path.exists(os.path.join(migration_dir, '0002_a.py')))
|
self.assertTrue(os.path.exists(os.path.join(migration_dir, '0002_a.py')))
|
||||||
|
@ -1202,8 +1202,8 @@ class MakeMigrationsTests(MigrationTestBase):
|
||||||
content = cmd("0001", migration_name_0001)
|
content = cmd("0001", migration_name_0001)
|
||||||
self.assertIn("dependencies=[\n]", content)
|
self.assertIn("dependencies=[\n]", content)
|
||||||
|
|
||||||
# Python 3 importlib caches os.listdir() on some platforms like
|
# importlib caches os.listdir() on some platforms like Mac OS X
|
||||||
# Mac OS X (#23850).
|
# (#23850).
|
||||||
if hasattr(importlib, 'invalidate_caches'):
|
if hasattr(importlib, 'invalidate_caches'):
|
||||||
importlib.invalidate_caches()
|
importlib.invalidate_caches()
|
||||||
|
|
||||||
|
|
|
@ -40,6 +40,12 @@ class Money(decimal.Decimal):
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class TestModel1(object):
|
||||||
|
def upload_to(self):
|
||||||
|
return '/somewhere/dynamic/'
|
||||||
|
thing = models.FileField(upload_to=upload_to)
|
||||||
|
|
||||||
|
|
||||||
class OperationWriterTests(SimpleTestCase):
|
class OperationWriterTests(SimpleTestCase):
|
||||||
|
|
||||||
def test_empty_signature(self):
|
def test_empty_signature(self):
|
||||||
|
@ -472,21 +478,12 @@ class WriterTests(SimpleTestCase):
|
||||||
self.assertEqual(string, 'range')
|
self.assertEqual(string, 'range')
|
||||||
self.assertEqual(imports, set())
|
self.assertEqual(imports, set())
|
||||||
|
|
||||||
def test_serialize_local_function_reference(self):
|
def test_serialize_unbound_method_reference(self):
|
||||||
"""
|
"""An unbound method used within a class body can be serialized."""
|
||||||
Neither py2 or py3 can serialize a reference in a local scope.
|
self.serialize_round_trip(TestModel1.thing)
|
||||||
"""
|
|
||||||
class TestModel2:
|
|
||||||
def upload_to(self):
|
|
||||||
return "somewhere dynamic"
|
|
||||||
thing = models.FileField(upload_to=upload_to)
|
|
||||||
with self.assertRaises(ValueError):
|
|
||||||
self.serialize_round_trip(TestModel2.thing)
|
|
||||||
|
|
||||||
def test_serialize_local_function_reference_message(self):
|
def test_serialize_local_function_reference(self):
|
||||||
"""
|
"""A reference in a local scope can't be serialized."""
|
||||||
Make sure user is seeing which module/function is the issue
|
|
||||||
"""
|
|
||||||
class TestModel2:
|
class TestModel2:
|
||||||
def upload_to(self):
|
def upload_to(self):
|
||||||
return "somewhere dynamic"
|
return "somewhere dynamic"
|
||||||
|
|
|
@ -1,19 +1,10 @@
|
||||||
import gzip
|
import gzip
|
||||||
import io
|
|
||||||
|
|
||||||
from django.http import HttpRequest, HttpResponse, StreamingHttpResponse
|
from django.http import HttpRequest, HttpResponse, StreamingHttpResponse
|
||||||
from django.test import SimpleTestCase
|
from django.test import SimpleTestCase
|
||||||
from django.test.client import conditional_content_removal
|
from django.test.client import conditional_content_removal
|
||||||
|
|
||||||
|
|
||||||
# based on Python 3.3's gzip.compress
|
|
||||||
def gzip_compress(data):
|
|
||||||
buf = io.BytesIO()
|
|
||||||
with gzip.GzipFile(fileobj=buf, mode='wb', compresslevel=0) as f:
|
|
||||||
f.write(data)
|
|
||||||
return buf.getvalue()
|
|
||||||
|
|
||||||
|
|
||||||
class ConditionalContentTests(SimpleTestCase):
|
class ConditionalContentTests(SimpleTestCase):
|
||||||
|
|
||||||
def test_conditional_content_removal(self):
|
def test_conditional_content_removal(self):
|
||||||
|
@ -43,7 +34,7 @@ class ConditionalContentTests(SimpleTestCase):
|
||||||
self.assertEqual(b''.join(res), b'')
|
self.assertEqual(b''.join(res), b'')
|
||||||
|
|
||||||
# Issue #20472
|
# Issue #20472
|
||||||
abc = gzip_compress(b'abc')
|
abc = gzip.compress(b'abc')
|
||||||
res = HttpResponse(abc, status=304)
|
res = HttpResponse(abc, status=304)
|
||||||
res['Content-Encoding'] = 'gzip'
|
res['Content-Encoding'] = 'gzip'
|
||||||
conditional_content_removal(req, res)
|
conditional_content_removal(req, res)
|
||||||
|
|
9
tox.ini
9
tox.ini
|
@ -11,10 +11,7 @@ envlist =
|
||||||
docs
|
docs
|
||||||
isort
|
isort
|
||||||
|
|
||||||
# Add environments to use default python2 and python3 installations
|
# Add environment to use the default python3 installation
|
||||||
[testenv:py2]
|
|
||||||
basepython = python2
|
|
||||||
|
|
||||||
[testenv:py3]
|
[testenv:py3]
|
||||||
basepython = python3
|
basepython = python3
|
||||||
|
|
||||||
|
@ -24,7 +21,6 @@ passenv = DJANGO_SETTINGS_MODULE PYTHONPATH HOME DISPLAY
|
||||||
setenv =
|
setenv =
|
||||||
PYTHONDONTWRITEBYTECODE=1
|
PYTHONDONTWRITEBYTECODE=1
|
||||||
deps =
|
deps =
|
||||||
py{2,27}: -rtests/requirements/py2.txt
|
|
||||||
py{3,34,35,36}: -rtests/requirements/py3.txt
|
py{3,34,35,36}: -rtests/requirements/py3.txt
|
||||||
postgres: -rtests/requirements/postgres.txt
|
postgres: -rtests/requirements/postgres.txt
|
||||||
mysql: -rtests/requirements/mysql.txt
|
mysql: -rtests/requirements/mysql.txt
|
||||||
|
@ -41,8 +37,7 @@ changedir = {toxinidir}
|
||||||
commands = flake8 .
|
commands = flake8 .
|
||||||
|
|
||||||
[testenv:docs]
|
[testenv:docs]
|
||||||
# On OS X, as of pyenchant 1.6.6, the docs build only works under Python 2.
|
basepython = python3
|
||||||
basepython = python2
|
|
||||||
usedevelop = false
|
usedevelop = false
|
||||||
whitelist_externals =
|
whitelist_externals =
|
||||||
make
|
make
|
||||||
|
|
Loading…
Reference in New Issue