mirror of
https://github.com/django/django.git
synced 2024-12-22 17:16:24 +00:00
Refs #23919 -- Removed six.PY2/PY3 usage
Thanks Tim Graham for the review.
This commit is contained in:
parent
e63d98b7be
commit
c716fe8782
@ -15,7 +15,6 @@ from django.db import models
|
|||||||
from django.http import Http404
|
from django.http import Http404
|
||||||
from django.template.engine import Engine
|
from django.template.engine import Engine
|
||||||
from django.urls import get_mod_func, get_resolver, get_urlconf, reverse
|
from django.urls import get_mod_func, get_resolver, get_urlconf, reverse
|
||||||
from django.utils import six
|
|
||||||
from django.utils.decorators import method_decorator
|
from django.utils.decorators import method_decorator
|
||||||
from django.utils.inspect import (
|
from django.utils.inspect import (
|
||||||
func_accepts_kwargs, func_accepts_var_args, func_has_no_args,
|
func_accepts_kwargs, func_accepts_var_args, func_has_no_args,
|
||||||
@ -132,12 +131,7 @@ class ViewIndexView(BaseAdminDocsView):
|
|||||||
@staticmethod
|
@staticmethod
|
||||||
def _get_full_name(func):
|
def _get_full_name(func):
|
||||||
mod_name = func.__module__
|
mod_name = func.__module__
|
||||||
if six.PY3:
|
return '%s.%s' % (mod_name, func.__qualname__)
|
||||||
return '%s.%s' % (mod_name, func.__qualname__)
|
|
||||||
else:
|
|
||||||
# PY2 does not support __qualname__
|
|
||||||
func_name = getattr(func, '__name__', func.__class__.__name__)
|
|
||||||
return '%s.%s' % (mod_name, func_name)
|
|
||||||
|
|
||||||
def get_context_data(self, **kwargs):
|
def get_context_data(self, **kwargs):
|
||||||
views = []
|
views = []
|
||||||
|
@ -8,8 +8,6 @@ from django.apps import apps as global_apps
|
|||||||
from django.contrib.auth import get_permission_codename
|
from django.contrib.auth import get_permission_codename
|
||||||
from django.core import exceptions
|
from django.core import exceptions
|
||||||
from django.db import DEFAULT_DB_ALIAS, router
|
from django.db import DEFAULT_DB_ALIAS, router
|
||||||
from django.utils import six
|
|
||||||
from django.utils.encoding import DEFAULT_LOCALE_ENCODING
|
|
||||||
|
|
||||||
|
|
||||||
def _get_all_permissions(opts):
|
def _get_all_permissions(opts):
|
||||||
@ -98,12 +96,6 @@ def get_system_username():
|
|||||||
# if there is no corresponding entry in the /etc/passwd file
|
# if there is no corresponding entry in the /etc/passwd file
|
||||||
# (a very restricted chroot environment, for example).
|
# (a very restricted chroot environment, for example).
|
||||||
return ''
|
return ''
|
||||||
if six.PY2:
|
|
||||||
try:
|
|
||||||
result = result.decode(DEFAULT_LOCALE_ENCODING)
|
|
||||||
except UnicodeDecodeError:
|
|
||||||
# UnicodeDecodeError - preventive treatment for non-latin Windows.
|
|
||||||
return ''
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import django.contrib.auth.models
|
import django.contrib.auth.models
|
||||||
from django.contrib.auth import validators
|
from django.contrib.auth import validators
|
||||||
from django.db import migrations, models
|
from django.db import migrations, models
|
||||||
from django.utils import six, timezone
|
from django.utils import timezone
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
@ -63,9 +63,7 @@ class Migration(migrations.Migration):
|
|||||||
('username', models.CharField(
|
('username', models.CharField(
|
||||||
help_text='Required. 30 characters or fewer. Letters, digits and @/./+/-/_ only.', unique=True,
|
help_text='Required. 30 characters or fewer. Letters, digits and @/./+/-/_ only.', unique=True,
|
||||||
max_length=30, verbose_name='username',
|
max_length=30, verbose_name='username',
|
||||||
validators=[
|
validators=[validators.UnicodeUsernameValidator()],
|
||||||
validators.UnicodeUsernameValidator() if six.PY3 else validators.ASCIIUsernameValidator()
|
|
||||||
],
|
|
||||||
)),
|
)),
|
||||||
('first_name', models.CharField(max_length=30, verbose_name='first name', blank=True)),
|
('first_name', models.CharField(max_length=30, verbose_name='first name', blank=True)),
|
||||||
('last_name', models.CharField(max_length=30, verbose_name='last name', blank=True)),
|
('last_name', models.CharField(max_length=30, verbose_name='last name', blank=True)),
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
from django.contrib.auth import validators
|
from django.contrib.auth import validators
|
||||||
from django.db import migrations, models
|
from django.db import migrations, models
|
||||||
from django.utils import six
|
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
@ -16,7 +15,7 @@ class Migration(migrations.Migration):
|
|||||||
name='username',
|
name='username',
|
||||||
field=models.CharField(
|
field=models.CharField(
|
||||||
error_messages={'unique': 'A user with that username already exists.'}, max_length=30,
|
error_messages={'unique': 'A user with that username already exists.'}, max_length=30,
|
||||||
validators=[validators.UnicodeUsernameValidator() if six.PY3 else validators.ASCIIUsernameValidator()],
|
validators=[validators.UnicodeUsernameValidator()],
|
||||||
help_text='Required. 30 characters or fewer. Letters, digits and @/./+/-/_ only.',
|
help_text='Required. 30 characters or fewer. Letters, digits and @/./+/-/_ only.',
|
||||||
unique=True, verbose_name='username'
|
unique=True, verbose_name='username'
|
||||||
),
|
),
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
from django.contrib.auth import validators
|
from django.contrib.auth import validators
|
||||||
from django.db import migrations, models
|
from django.db import migrations, models
|
||||||
from django.utils import six
|
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
@ -18,7 +17,7 @@ class Migration(migrations.Migration):
|
|||||||
help_text='Required. 30 characters or fewer. Letters, digits and @/./+/-/_ only.',
|
help_text='Required. 30 characters or fewer. Letters, digits and @/./+/-/_ only.',
|
||||||
max_length=30,
|
max_length=30,
|
||||||
unique=True,
|
unique=True,
|
||||||
validators=[validators.UnicodeUsernameValidator() if six.PY3 else validators.ASCIIUsernameValidator()],
|
validators=[validators.UnicodeUsernameValidator()],
|
||||||
verbose_name='username',
|
verbose_name='username',
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
from django.contrib.auth import validators
|
from django.contrib.auth import validators
|
||||||
from django.db import migrations, models
|
from django.db import migrations, models
|
||||||
from django.utils import six
|
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
@ -18,7 +17,7 @@ class Migration(migrations.Migration):
|
|||||||
help_text='Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only.',
|
help_text='Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only.',
|
||||||
max_length=150,
|
max_length=150,
|
||||||
unique=True,
|
unique=True,
|
||||||
validators=[validators.UnicodeUsernameValidator() if six.PY3 else validators.ASCIIUsernameValidator()],
|
validators=[validators.UnicodeUsernameValidator()],
|
||||||
verbose_name='username',
|
verbose_name='username',
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@ -9,7 +9,7 @@ from django.db.models.manager import EmptyManager
|
|||||||
from django.utils import six, timezone
|
from django.utils import six, timezone
|
||||||
from django.utils.translation import ugettext_lazy as _
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
|
||||||
from .validators import ASCIIUsernameValidator, UnicodeUsernameValidator
|
from .validators import UnicodeUsernameValidator
|
||||||
|
|
||||||
|
|
||||||
def update_last_login(sender, user, **kwargs):
|
def update_last_login(sender, user, **kwargs):
|
||||||
@ -297,7 +297,7 @@ class AbstractUser(AbstractBaseUser, PermissionsMixin):
|
|||||||
|
|
||||||
Username and password are required. Other fields are optional.
|
Username and password are required. Other fields are optional.
|
||||||
"""
|
"""
|
||||||
username_validator = UnicodeUsernameValidator() if six.PY3 else ASCIIUsernameValidator()
|
username_validator = UnicodeUsernameValidator()
|
||||||
|
|
||||||
username = models.CharField(
|
username = models.CharField(
|
||||||
_('username'),
|
_('username'),
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
import re
|
import re
|
||||||
|
|
||||||
from django.core import validators
|
from django.core import validators
|
||||||
from django.utils import six
|
|
||||||
from django.utils.deconstruct import deconstructible
|
from django.utils.deconstruct import deconstructible
|
||||||
from django.utils.translation import ugettext_lazy as _
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
|
||||||
@ -13,7 +12,7 @@ class ASCIIUsernameValidator(validators.RegexValidator):
|
|||||||
'Enter a valid username. This value may contain only English letters, '
|
'Enter a valid username. This value may contain only English letters, '
|
||||||
'numbers, and @/./+/-/_ characters.'
|
'numbers, and @/./+/-/_ characters.'
|
||||||
)
|
)
|
||||||
flags = re.ASCII if six.PY3 else 0
|
flags = re.ASCII
|
||||||
|
|
||||||
|
|
||||||
@deconstructible
|
@deconstructible
|
||||||
@ -23,4 +22,4 @@ class UnicodeUsernameValidator(validators.RegexValidator):
|
|||||||
'Enter a valid username. This value may contain only letters, '
|
'Enter a valid username. This value may contain only letters, '
|
||||||
'numbers, and @/./+/-/_ characters.'
|
'numbers, and @/./+/-/_ characters.'
|
||||||
)
|
)
|
||||||
flags = re.UNICODE if six.PY2 else 0
|
flags = 0
|
||||||
|
@ -235,5 +235,4 @@ def _ogrinspect(data_source, model_name, geom_name='geom', layer_key=0, srid=Non
|
|||||||
|
|
||||||
if name_field:
|
if name_field:
|
||||||
yield ''
|
yield ''
|
||||||
yield ' def __%s__(self): return self.%s' % (
|
yield ' def __str__(self): return self.%s' % name_field
|
||||||
'str' if six.PY3 else 'unicode', name_field)
|
|
||||||
|
@ -1,18 +1,13 @@
|
|||||||
from psycopg2 import ProgrammingError
|
from psycopg2 import ProgrammingError
|
||||||
from psycopg2.extras import register_hstore
|
from psycopg2.extras import register_hstore
|
||||||
|
|
||||||
from django.utils import six
|
|
||||||
|
|
||||||
|
|
||||||
def register_hstore_handler(connection, **kwargs):
|
def register_hstore_handler(connection, **kwargs):
|
||||||
if connection.vendor != 'postgresql':
|
if connection.vendor != 'postgresql':
|
||||||
return
|
return
|
||||||
|
|
||||||
try:
|
try:
|
||||||
if six.PY2:
|
register_hstore(connection.connection, globally=True)
|
||||||
register_hstore(connection.connection, globally=True, unicode=True)
|
|
||||||
else:
|
|
||||||
register_hstore(connection.connection, globally=True)
|
|
||||||
except ProgrammingError:
|
except ProgrammingError:
|
||||||
# Hstore is not available on the database.
|
# Hstore is not available on the database.
|
||||||
#
|
#
|
||||||
|
6
django/core/cache/backends/db.py
vendored
6
django/core/cache/backends/db.py
vendored
@ -5,7 +5,7 @@ from datetime import datetime
|
|||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.core.cache.backends.base import DEFAULT_TIMEOUT, BaseCache
|
from django.core.cache.backends.base import DEFAULT_TIMEOUT, BaseCache
|
||||||
from django.db import DatabaseError, connections, models, router, transaction
|
from django.db import DatabaseError, connections, models, router, transaction
|
||||||
from django.utils import six, timezone
|
from django.utils import timezone
|
||||||
from django.utils.encoding import force_bytes
|
from django.utils.encoding import force_bytes
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@ -112,11 +112,9 @@ class DatabaseCache(BaseDatabaseCache):
|
|||||||
if num > self._max_entries:
|
if num > self._max_entries:
|
||||||
self._cull(db, cursor, now)
|
self._cull(db, cursor, now)
|
||||||
pickled = pickle.dumps(value, pickle.HIGHEST_PROTOCOL)
|
pickled = pickle.dumps(value, pickle.HIGHEST_PROTOCOL)
|
||||||
b64encoded = base64.b64encode(pickled)
|
|
||||||
# The DB column is expecting a string, so make sure the value is a
|
# The DB column is expecting a string, so make sure the value is a
|
||||||
# string, not bytes. Refs #19274.
|
# string, not bytes. Refs #19274.
|
||||||
if six.PY3:
|
b64encoded = base64.b64encode(pickled).decode('latin1')
|
||||||
b64encoded = b64encoded.decode('latin1')
|
|
||||||
try:
|
try:
|
||||||
# Note: typecasting for datetimes is needed by some 3rd party
|
# Note: typecasting for datetimes is needed by some 3rd party
|
||||||
# database backends. All core backends work without typecasting,
|
# database backends. All core backends work without typecasting,
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
"""
|
"""
|
||||||
Global Django exception and warning classes.
|
Global Django exception and warning classes.
|
||||||
"""
|
"""
|
||||||
from django.utils import six
|
|
||||||
from django.utils.encoding import force_text
|
from django.utils.encoding import force_text
|
||||||
|
|
||||||
|
|
||||||
@ -115,10 +114,7 @@ class ValidationError(Exception):
|
|||||||
if isinstance(message, ValidationError):
|
if isinstance(message, ValidationError):
|
||||||
if hasattr(message, 'error_dict'):
|
if hasattr(message, 'error_dict'):
|
||||||
message = message.error_dict
|
message = message.error_dict
|
||||||
# PY2 has a `message` property which is always there so we can't
|
elif not hasattr(message, 'message'):
|
||||||
# duck-type on it. It was introduced in Python 2.5 and already
|
|
||||||
# deprecated in Python 2.6.
|
|
||||||
elif not hasattr(message, 'message' if six.PY3 else 'code'):
|
|
||||||
message = message.error_list
|
message = message.error_list
|
||||||
else:
|
else:
|
||||||
message, code, params = message.message, message.code, message.params
|
message, code, params = message.message, message.code, message.params
|
||||||
|
@ -3,7 +3,7 @@ from io import BytesIO, StringIO, UnsupportedOperation
|
|||||||
|
|
||||||
from django.core.files.utils import FileProxyMixin
|
from django.core.files.utils import FileProxyMixin
|
||||||
from django.utils import six
|
from django.utils import six
|
||||||
from django.utils.encoding import force_bytes, force_str, force_text
|
from django.utils.encoding import force_str, force_text
|
||||||
|
|
||||||
|
|
||||||
class File(FileProxyMixin):
|
class File(FileProxyMixin):
|
||||||
@ -140,11 +140,7 @@ class ContentFile(File):
|
|||||||
A File-like object that takes just raw content, rather than an actual file.
|
A File-like object that takes just raw content, rather than an actual file.
|
||||||
"""
|
"""
|
||||||
def __init__(self, content, name=None):
|
def __init__(self, content, name=None):
|
||||||
if six.PY3:
|
stream_class = StringIO if isinstance(content, six.text_type) else BytesIO
|
||||||
stream_class = StringIO if isinstance(content, six.text_type) else BytesIO
|
|
||||||
else:
|
|
||||||
stream_class = BytesIO
|
|
||||||
content = force_bytes(content)
|
|
||||||
super(ContentFile, self).__init__(stream_class(content), name=name)
|
super(ContentFile, self).__init__(stream_class(content), name=name)
|
||||||
self.size = len(content)
|
self.size = len(content)
|
||||||
|
|
||||||
|
@ -8,7 +8,6 @@ from django.conf import settings
|
|||||||
from django.core import signals
|
from django.core import signals
|
||||||
from django.core.handlers import base
|
from django.core.handlers import base
|
||||||
from django.urls import set_script_prefix
|
from django.urls import set_script_prefix
|
||||||
from django.utils import six
|
|
||||||
from django.utils.encoding import (
|
from django.utils.encoding import (
|
||||||
force_str, force_text, repercent_broken_unicode,
|
force_str, force_text, repercent_broken_unicode,
|
||||||
)
|
)
|
||||||
@ -212,22 +211,20 @@ def get_bytes_from_wsgi(environ, key, default):
|
|||||||
"""
|
"""
|
||||||
Get a value from the WSGI environ dictionary as bytes.
|
Get a value from the WSGI environ dictionary as bytes.
|
||||||
|
|
||||||
key and default should be str objects. Under Python 2 they may also be
|
key and default should be str objects.
|
||||||
unicode objects provided they only contain ASCII characters.
|
|
||||||
"""
|
"""
|
||||||
value = environ.get(str(key), str(default))
|
value = environ.get(str(key), str(default))
|
||||||
# Under Python 3, non-ASCII values in the WSGI environ are arbitrarily
|
# Non-ASCII values in the WSGI environ are arbitrarily decoded with
|
||||||
# decoded with ISO-8859-1. This is wrong for Django websites where UTF-8
|
# ISO-8859-1. This is wrong for Django websites where UTF-8 is the default.
|
||||||
# is the default. Re-encode to recover the original bytestring.
|
# Re-encode to recover the original bytestring.
|
||||||
return value.encode(ISO_8859_1) if six.PY3 else value
|
return value.encode(ISO_8859_1)
|
||||||
|
|
||||||
|
|
||||||
def get_str_from_wsgi(environ, key, default):
|
def get_str_from_wsgi(environ, key, default):
|
||||||
"""
|
"""
|
||||||
Get a value from the WSGI environ dictionary as str.
|
Get a value from the WSGI environ dictionary as str.
|
||||||
|
|
||||||
key and default should be str objects. Under Python 2 they may also be
|
key and default should be str objects.
|
||||||
unicode objects provided they only contain ASCII characters.
|
|
||||||
"""
|
"""
|
||||||
value = get_bytes_from_wsgi(environ, key, default)
|
value = get_bytes_from_wsgi(environ, key, default)
|
||||||
return value.decode(UTF_8, errors='replace') if six.PY3 else value
|
return value.decode(UTF_8, errors='replace')
|
||||||
|
@ -5,7 +5,6 @@ import sys
|
|||||||
import threading
|
import threading
|
||||||
|
|
||||||
from django.core.mail.backends.base import BaseEmailBackend
|
from django.core.mail.backends.base import BaseEmailBackend
|
||||||
from django.utils import six
|
|
||||||
|
|
||||||
|
|
||||||
class EmailBackend(BaseEmailBackend):
|
class EmailBackend(BaseEmailBackend):
|
||||||
@ -17,9 +16,8 @@ class EmailBackend(BaseEmailBackend):
|
|||||||
def write_message(self, message):
|
def write_message(self, message):
|
||||||
msg = message.message()
|
msg = message.message()
|
||||||
msg_data = msg.as_bytes()
|
msg_data = msg.as_bytes()
|
||||||
if six.PY3:
|
charset = msg.get_charset().get_output_charset() if msg.get_charset() else 'utf-8'
|
||||||
charset = msg.get_charset().get_output_charset() if msg.get_charset() else 'utf-8'
|
msg_data = msg_data.decode(charset)
|
||||||
msg_data = msg_data.decode(charset)
|
|
||||||
self.stream.write('%s\n' % msg_data)
|
self.stream.write('%s\n' % msg_data)
|
||||||
self.stream.write('-' * 79)
|
self.stream.write('-' * 79)
|
||||||
self.stream.write('\n')
|
self.stream.write('\n')
|
||||||
|
@ -5,7 +5,9 @@ import time
|
|||||||
from email import (
|
from email import (
|
||||||
charset as Charset, encoders as Encoders, generator, message_from_string,
|
charset as Charset, encoders as Encoders, generator, message_from_string,
|
||||||
)
|
)
|
||||||
|
from email.errors import InvalidHeaderDefect, NonASCIILocalPartDefect
|
||||||
from email.header import Header
|
from email.header import Header
|
||||||
|
from email.headerregistry import Address
|
||||||
from email.message import Message
|
from email.message import Message
|
||||||
from email.mime.base import MIMEBase
|
from email.mime.base import MIMEBase
|
||||||
from email.mime.message import MIMEMessage
|
from email.mime.message import MIMEMessage
|
||||||
@ -139,18 +141,8 @@ def sanitize_address(addr, encoding):
|
|||||||
except UnicodeEncodeError: # IDN or non-ascii in the local part
|
except UnicodeEncodeError: # IDN or non-ascii in the local part
|
||||||
localpart, domain = split_addr(addr, encoding)
|
localpart, domain = split_addr(addr, encoding)
|
||||||
|
|
||||||
if six.PY2:
|
# An `email.headerregistry.Address` object is used since
|
||||||
# On Python 2, use the stdlib since `email.headerregistry` doesn't exist.
|
|
||||||
from email.utils import formataddr
|
|
||||||
if localpart and domain:
|
|
||||||
addr = '@'.join([localpart, domain])
|
|
||||||
return formataddr((nm, addr))
|
|
||||||
|
|
||||||
# On Python 3, an `email.headerregistry.Address` object is used since
|
|
||||||
# email.utils.formataddr() naively encodes the name as ascii (see #25986).
|
# email.utils.formataddr() naively encodes the name as ascii (see #25986).
|
||||||
from email.headerregistry import Address
|
|
||||||
from email.errors import InvalidHeaderDefect, NonASCIILocalPartDefect
|
|
||||||
|
|
||||||
if localpart and domain:
|
if localpart and domain:
|
||||||
address = Address(nm, username=localpart, domain=domain)
|
address = Address(nm, username=localpart, domain=domain)
|
||||||
return str(address)
|
return str(address)
|
||||||
@ -174,27 +166,21 @@ class MIMEMixin():
|
|||||||
"""
|
"""
|
||||||
fp = six.StringIO()
|
fp = six.StringIO()
|
||||||
g = generator.Generator(fp, mangle_from_=False)
|
g = generator.Generator(fp, mangle_from_=False)
|
||||||
if six.PY2:
|
g.flatten(self, unixfrom=unixfrom, linesep=linesep)
|
||||||
g.flatten(self, unixfrom=unixfrom)
|
|
||||||
else:
|
|
||||||
g.flatten(self, unixfrom=unixfrom, linesep=linesep)
|
|
||||||
return fp.getvalue()
|
return fp.getvalue()
|
||||||
|
|
||||||
if six.PY2:
|
def as_bytes(self, unixfrom=False, linesep='\n'):
|
||||||
as_bytes = as_string
|
"""Return the entire formatted message as bytes.
|
||||||
else:
|
Optional `unixfrom' when True, means include the Unix From_ envelope
|
||||||
def as_bytes(self, unixfrom=False, linesep='\n'):
|
header.
|
||||||
"""Return the entire formatted message as bytes.
|
|
||||||
Optional `unixfrom' when True, means include the Unix From_ envelope
|
|
||||||
header.
|
|
||||||
|
|
||||||
This overrides the default as_bytes() implementation to not mangle
|
This overrides the default as_bytes() implementation to not mangle
|
||||||
lines that begin with 'From '. See bug #13433 for details.
|
lines that begin with 'From '. See bug #13433 for details.
|
||||||
"""
|
"""
|
||||||
fp = BytesIO()
|
fp = BytesIO()
|
||||||
g = generator.BytesGenerator(fp, mangle_from_=False)
|
g = generator.BytesGenerator(fp, mangle_from_=False)
|
||||||
g.flatten(self, unixfrom=unixfrom, linesep=linesep)
|
g.flatten(self, unixfrom=unixfrom, linesep=linesep)
|
||||||
return fp.getvalue()
|
return fp.getvalue()
|
||||||
|
|
||||||
|
|
||||||
class SafeMIMEMessage(MIMEMixin, MIMEMessage):
|
class SafeMIMEMessage(MIMEMixin, MIMEMessage):
|
||||||
@ -450,8 +436,6 @@ class EmailMessage(object):
|
|||||||
try:
|
try:
|
||||||
filename.encode('ascii')
|
filename.encode('ascii')
|
||||||
except UnicodeEncodeError:
|
except UnicodeEncodeError:
|
||||||
if six.PY2:
|
|
||||||
filename = filename.encode('utf-8')
|
|
||||||
filename = ('utf-8', '', filename)
|
filename = ('utf-8', '', filename)
|
||||||
attachment.add_header('Content-Disposition', 'attachment',
|
attachment.add_header('Content-Disposition', 'attachment',
|
||||||
filename=filename)
|
filename=filename)
|
||||||
|
@ -20,7 +20,6 @@ from django.utils import lru_cache
|
|||||||
from django.utils._os import upath
|
from django.utils._os import upath
|
||||||
from django.utils.encoding import force_text
|
from django.utils.encoding import force_text
|
||||||
from django.utils.functional import cached_property
|
from django.utils.functional import cached_property
|
||||||
from django.utils.glob import glob_escape
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
import bz2
|
import bz2
|
||||||
@ -238,7 +237,7 @@ class Command(BaseCommand):
|
|||||||
self.stdout.write("Checking %s for fixtures..." % humanize(fixture_dir))
|
self.stdout.write("Checking %s for fixtures..." % humanize(fixture_dir))
|
||||||
fixture_files_in_dir = []
|
fixture_files_in_dir = []
|
||||||
path = os.path.join(fixture_dir, fixture_name)
|
path = os.path.join(fixture_dir, fixture_name)
|
||||||
for candidate in glob.iglob(glob_escape(path) + '*'):
|
for candidate in glob.iglob(glob.escape(path) + '*'):
|
||||||
if os.path.basename(candidate) in targets:
|
if os.path.basename(candidate) in targets:
|
||||||
# Save the fixture_dir and fixture_name for future error messages.
|
# Save the fixture_dir and fixture_name for future error messages.
|
||||||
fixture_files_in_dir.append((candidate, fixture_dir, fixture_name))
|
fixture_files_in_dir.append((candidate, fixture_dir, fixture_name))
|
||||||
|
@ -10,8 +10,8 @@ from django.core.management.base import BaseCommand, CommandError
|
|||||||
from django.core.servers.basehttp import (
|
from django.core.servers.basehttp import (
|
||||||
WSGIServer, get_internal_wsgi_application, run,
|
WSGIServer, get_internal_wsgi_application, run,
|
||||||
)
|
)
|
||||||
from django.utils import autoreload, six
|
from django.utils import autoreload
|
||||||
from django.utils.encoding import force_text, get_system_encoding
|
from django.utils.encoding import force_text
|
||||||
|
|
||||||
|
|
||||||
naiveip_re = re.compile(r"""^(?:
|
naiveip_re = re.compile(r"""^(?:
|
||||||
@ -125,8 +125,6 @@ class Command(BaseCommand):
|
|||||||
# requires_migrations_check attribute.
|
# requires_migrations_check attribute.
|
||||||
self.check_migrations()
|
self.check_migrations()
|
||||||
now = datetime.now().strftime('%B %d, %Y - %X')
|
now = datetime.now().strftime('%B %d, %Y - %X')
|
||||||
if six.PY2:
|
|
||||||
now = now.decode(get_system_encoding())
|
|
||||||
self.stdout.write(now)
|
self.stdout.write(now)
|
||||||
self.stdout.write((
|
self.stdout.write((
|
||||||
"Django version %(version)s, using settings %(settings)r\n"
|
"Django version %(version)s, using settings %(settings)r\n"
|
||||||
|
@ -16,7 +16,7 @@ from django.conf import settings
|
|||||||
from django.core.management.base import BaseCommand, CommandError
|
from django.core.management.base import BaseCommand, CommandError
|
||||||
from django.core.management.utils import handle_extensions
|
from django.core.management.utils import handle_extensions
|
||||||
from django.template import Context, Engine
|
from django.template import Context, Engine
|
||||||
from django.utils import archive, six
|
from django.utils import archive
|
||||||
from django.utils.six.moves.urllib.request import urlretrieve
|
from django.utils.six.moves.urllib.request import urlretrieve
|
||||||
from django.utils.version import get_docs_version
|
from django.utils.version import get_docs_version
|
||||||
|
|
||||||
@ -218,21 +218,11 @@ class TemplateCommand(BaseCommand):
|
|||||||
raise CommandError("you must provide %s %s name" % (
|
raise CommandError("you must provide %s %s name" % (
|
||||||
"an" if app_or_project == "app" else "a", app_or_project))
|
"an" if app_or_project == "app" else "a", app_or_project))
|
||||||
# If it's not a valid directory name.
|
# If it's not a valid directory name.
|
||||||
if six.PY2:
|
if not name.isidentifier():
|
||||||
if not re.search(r'^[_a-zA-Z]\w*$', name):
|
raise CommandError(
|
||||||
# Provide a smart error message, depending on the error.
|
"%r is not a valid %s name. Please make sure the name is "
|
||||||
if not re.search(r'^[_a-zA-Z]', name):
|
"a valid identifier." % (name, app_or_project)
|
||||||
message = 'make sure the name begins with a letter or underscore'
|
)
|
||||||
else:
|
|
||||||
message = 'use only numbers, letters and underscores'
|
|
||||||
raise CommandError("%r is not a valid %s name. Please %s." %
|
|
||||||
(name, app_or_project, message))
|
|
||||||
else:
|
|
||||||
if not name.isidentifier():
|
|
||||||
raise CommandError(
|
|
||||||
"%r is not a valid %s name. Please make sure the name is "
|
|
||||||
"a valid identifier." % (name, app_or_project)
|
|
||||||
)
|
|
||||||
|
|
||||||
def download(self, url):
|
def download(self, url):
|
||||||
"""
|
"""
|
||||||
|
@ -219,8 +219,6 @@ class DatabaseWrapper(BaseDatabaseWrapper):
|
|||||||
'conv': django_conversions,
|
'conv': django_conversions,
|
||||||
'charset': 'utf8',
|
'charset': 'utf8',
|
||||||
}
|
}
|
||||||
if six.PY2:
|
|
||||||
kwargs['use_unicode'] = True
|
|
||||||
settings_dict = self.settings_dict
|
settings_dict = self.settings_dict
|
||||||
if settings_dict['USER']:
|
if settings_dict['USER']:
|
||||||
kwargs['user'] = settings_dict['USER']
|
kwargs['user'] = settings_dict['USER']
|
||||||
|
@ -252,8 +252,6 @@ WHEN (new.%(col_name)s IS NULL)
|
|||||||
# https://cx-oracle.readthedocs.io/en/latest/cursor.html#Cursor.statement
|
# https://cx-oracle.readthedocs.io/en/latest/cursor.html#Cursor.statement
|
||||||
# The DB API definition does not define this attribute.
|
# The DB API definition does not define this attribute.
|
||||||
statement = cursor.statement
|
statement = cursor.statement
|
||||||
if statement and six.PY2 and not isinstance(statement, unicode): # NOQA: unicode undefined on PY3
|
|
||||||
statement = statement.decode('utf-8')
|
|
||||||
# Unlike Psycopg's `query` and MySQLdb`'s `_last_executed`, CxOracle's
|
# Unlike Psycopg's `query` and MySQLdb`'s `_last_executed`, CxOracle's
|
||||||
# `statement` doesn't contain the query parameters. refs #20010.
|
# `statement` doesn't contain the query parameters. refs #20010.
|
||||||
return super(DatabaseOperations, self).last_executed_query(cursor, statement, params)
|
return super(DatabaseOperations, self).last_executed_query(cursor, statement, params)
|
||||||
|
@ -12,7 +12,6 @@ from django.core.exceptions import ImproperlyConfigured
|
|||||||
from django.db import DEFAULT_DB_ALIAS
|
from django.db import DEFAULT_DB_ALIAS
|
||||||
from django.db.backends.base.base import BaseDatabaseWrapper
|
from django.db.backends.base.base import BaseDatabaseWrapper
|
||||||
from django.db.utils import DatabaseError as WrappedDatabaseError
|
from django.db.utils import DatabaseError as WrappedDatabaseError
|
||||||
from django.utils import six
|
|
||||||
from django.utils.encoding import force_str
|
from django.utils.encoding import force_str
|
||||||
from django.utils.functional import cached_property
|
from django.utils.functional import cached_property
|
||||||
from django.utils.safestring import SafeBytes, SafeText
|
from django.utils.safestring import SafeBytes, SafeText
|
||||||
@ -46,9 +45,6 @@ from .schema import DatabaseSchemaEditor # NOQA isort:skip
|
|||||||
from .utils import utc_tzinfo_factory # NOQA isort:skip
|
from .utils import utc_tzinfo_factory # NOQA isort:skip
|
||||||
from .version import get_version # NOQA isort:skip
|
from .version import get_version # NOQA isort:skip
|
||||||
|
|
||||||
if six.PY2:
|
|
||||||
psycopg2.extensions.register_type(psycopg2.extensions.UNICODE)
|
|
||||||
psycopg2.extensions.register_type(psycopg2.extensions.UNICODEARRAY)
|
|
||||||
psycopg2.extensions.register_adapter(SafeBytes, psycopg2.extensions.QuotedString)
|
psycopg2.extensions.register_adapter(SafeBytes, psycopg2.extensions.QuotedString)
|
||||||
psycopg2.extensions.register_adapter(SafeText, psycopg2.extensions.QuotedString)
|
psycopg2.extensions.register_adapter(SafeText, psycopg2.extensions.QuotedString)
|
||||||
psycopg2.extras.register_uuid()
|
psycopg2.extras.register_uuid()
|
||||||
|
@ -19,7 +19,6 @@ from django.utils.dateparse import (
|
|||||||
parse_date, parse_datetime, parse_duration, parse_time,
|
parse_date, parse_datetime, parse_duration, parse_time,
|
||||||
)
|
)
|
||||||
from django.utils.encoding import force_text
|
from django.utils.encoding import force_text
|
||||||
from django.utils.safestring import SafeBytes
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
try:
|
try:
|
||||||
@ -55,9 +54,6 @@ Database.register_converter(str("TIMESTAMP"), decoder(parse_datetime))
|
|||||||
Database.register_converter(str("decimal"), decoder(backend_utils.typecast_decimal))
|
Database.register_converter(str("decimal"), decoder(backend_utils.typecast_decimal))
|
||||||
|
|
||||||
Database.register_adapter(decimal.Decimal, backend_utils.rev_typecast_decimal)
|
Database.register_adapter(decimal.Decimal, backend_utils.rev_typecast_decimal)
|
||||||
if six.PY2:
|
|
||||||
Database.register_adapter(str, lambda s: s.decode('utf-8'))
|
|
||||||
Database.register_adapter(SafeBytes, lambda s: s.decode('utf-8'))
|
|
||||||
|
|
||||||
|
|
||||||
class DatabaseWrapper(BaseDatabaseWrapper):
|
class DatabaseWrapper(BaseDatabaseWrapper):
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
from django.db import utils
|
from django.db import utils
|
||||||
from django.db.backends.base.features import BaseDatabaseFeatures
|
from django.db.backends.base.features import BaseDatabaseFeatures
|
||||||
from django.utils import six
|
|
||||||
from django.utils.functional import cached_property
|
from django.utils.functional import cached_property
|
||||||
|
|
||||||
from .base import Database
|
from .base import Database
|
||||||
@ -48,7 +47,6 @@ class DatabaseFeatures(BaseDatabaseFeatures):
|
|||||||
@cached_property
|
@cached_property
|
||||||
def can_share_in_memory_db(self):
|
def can_share_in_memory_db(self):
|
||||||
return (
|
return (
|
||||||
six.PY3 and
|
|
||||||
Database.__name__ == 'sqlite3.dbapi2' and
|
Database.__name__ == 'sqlite3.dbapi2' and
|
||||||
Database.sqlite_version_info >= (3, 7, 13)
|
Database.sqlite_version_info >= (3, 7, 13)
|
||||||
)
|
)
|
||||||
|
@ -4,7 +4,7 @@ import sys
|
|||||||
|
|
||||||
from django.apps import apps
|
from django.apps import apps
|
||||||
from django.db.models.fields import NOT_PROVIDED
|
from django.db.models.fields import NOT_PROVIDED
|
||||||
from django.utils import datetime_safe, six, timezone
|
from django.utils import datetime_safe, timezone
|
||||||
from django.utils.six.moves import input
|
from django.utils.six.moves import input
|
||||||
|
|
||||||
from .loader import MigrationLoader
|
from .loader import MigrationLoader
|
||||||
@ -125,13 +125,7 @@ class InteractiveMigrationQuestioner(MigrationQuestioner):
|
|||||||
prompt = "[default: {}] >>> ".format(default)
|
prompt = "[default: {}] >>> ".format(default)
|
||||||
else:
|
else:
|
||||||
prompt = ">>> "
|
prompt = ">>> "
|
||||||
if six.PY3:
|
code = input(prompt)
|
||||||
# Six does not correctly abstract over the fact that
|
|
||||||
# py3 input returns a unicode string, while py2 raw_input
|
|
||||||
# returns a bytestring.
|
|
||||||
code = input(prompt)
|
|
||||||
else:
|
|
||||||
code = input(prompt).decode(sys.stdin.encoding)
|
|
||||||
if not code and default:
|
if not code and default:
|
||||||
code = default
|
code = default
|
||||||
if not code:
|
if not code:
|
||||||
|
@ -53,11 +53,7 @@ class BaseSimpleSerializer(BaseSerializer):
|
|||||||
|
|
||||||
class ByteTypeSerializer(BaseSerializer):
|
class ByteTypeSerializer(BaseSerializer):
|
||||||
def serialize(self):
|
def serialize(self):
|
||||||
value_repr = repr(self.value)
|
return repr(self.value), set()
|
||||||
if six.PY2:
|
|
||||||
# Prepend the `b` prefix since we're importing unicode_literals
|
|
||||||
value_repr = 'b' + value_repr
|
|
||||||
return value_repr, set()
|
|
||||||
|
|
||||||
|
|
||||||
class DatetimeSerializer(BaseSerializer):
|
class DatetimeSerializer(BaseSerializer):
|
||||||
@ -276,11 +272,7 @@ class SettingsReferenceSerializer(BaseSerializer):
|
|||||||
|
|
||||||
class TextTypeSerializer(BaseSerializer):
|
class TextTypeSerializer(BaseSerializer):
|
||||||
def serialize(self):
|
def serialize(self):
|
||||||
value_repr = repr(self.value)
|
return repr(self.value), set()
|
||||||
if six.PY2:
|
|
||||||
# Strip the `u` prefix since we're importing unicode_literals
|
|
||||||
value_repr = value_repr[1:]
|
|
||||||
return value_repr, set()
|
|
||||||
|
|
||||||
|
|
||||||
class TimedeltaSerializer(BaseSerializer):
|
class TimedeltaSerializer(BaseSerializer):
|
||||||
|
@ -510,9 +510,7 @@ class Model(six.with_metaclass(ModelBase)):
|
|||||||
return force_str('<%s: %s>' % (self.__class__.__name__, u))
|
return force_str('<%s: %s>' % (self.__class__.__name__, u))
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
if six.PY2 and hasattr(self, '__unicode__'):
|
return '%s object' % self.__class__.__name__
|
||||||
return force_text(self).encode('utf-8')
|
|
||||||
return str('%s object' % self.__class__.__name__)
|
|
||||||
|
|
||||||
def __eq__(self, other):
|
def __eq__(self, other):
|
||||||
if not isinstance(other, Model):
|
if not isinstance(other, Model):
|
||||||
|
@ -107,7 +107,6 @@ class RelatedField(Field):
|
|||||||
return errors
|
return errors
|
||||||
|
|
||||||
def _check_related_name_is_valid(self):
|
def _check_related_name_is_valid(self):
|
||||||
import re
|
|
||||||
import keyword
|
import keyword
|
||||||
related_name = self.remote_field.related_name
|
related_name = self.remote_field.related_name
|
||||||
if related_name is None:
|
if related_name is None:
|
||||||
@ -115,12 +114,8 @@ class RelatedField(Field):
|
|||||||
is_valid_id = True
|
is_valid_id = True
|
||||||
if keyword.iskeyword(related_name):
|
if keyword.iskeyword(related_name):
|
||||||
is_valid_id = False
|
is_valid_id = False
|
||||||
if six.PY3:
|
if not related_name.isidentifier():
|
||||||
if not related_name.isidentifier():
|
is_valid_id = False
|
||||||
is_valid_id = False
|
|
||||||
else:
|
|
||||||
if not re.match(r'^[a-zA-Z_][a-zA-Z0-9_]*\Z', related_name):
|
|
||||||
is_valid_id = False
|
|
||||||
if not (is_valid_id or related_name.endswith('+')):
|
if not (is_valid_id or related_name.endswith('+')):
|
||||||
return [
|
return [
|
||||||
checks.Error(
|
checks.Error(
|
||||||
|
@ -4,7 +4,6 @@ from importlib import import_module
|
|||||||
|
|
||||||
from django.db import router
|
from django.db import router
|
||||||
from django.db.models.query import QuerySet
|
from django.db.models.query import QuerySet
|
||||||
from django.utils import six
|
|
||||||
|
|
||||||
|
|
||||||
class BaseManager(object):
|
class BaseManager(object):
|
||||||
@ -86,9 +85,7 @@ class BaseManager(object):
|
|||||||
return manager_method
|
return manager_method
|
||||||
|
|
||||||
new_methods = {}
|
new_methods = {}
|
||||||
# Refs http://bugs.python.org/issue1785.
|
for name, method in inspect.getmembers(queryset_class, predicate=inspect.isfunction):
|
||||||
predicate = inspect.isfunction if six.PY3 else inspect.ismethod
|
|
||||||
for name, method in inspect.getmembers(queryset_class, predicate=predicate):
|
|
||||||
# Only copy missing methods.
|
# Only copy missing methods.
|
||||||
if hasattr(cls, name):
|
if hasattr(cls, name):
|
||||||
continue
|
continue
|
||||||
|
@ -14,7 +14,7 @@ DEFAULT_DB_ALIAS = 'default'
|
|||||||
DJANGO_VERSION_PICKLE_KEY = '_django_version'
|
DJANGO_VERSION_PICKLE_KEY = '_django_version'
|
||||||
|
|
||||||
|
|
||||||
class Error(Exception if six.PY3 else StandardError): # NOQA: StandardError undefined on PY3
|
class Error(Exception):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
@ -2,15 +2,9 @@ import sys
|
|||||||
import threading
|
import threading
|
||||||
import weakref
|
import weakref
|
||||||
|
|
||||||
from django.utils import six
|
|
||||||
from django.utils.inspect import func_accepts_kwargs
|
from django.utils.inspect import func_accepts_kwargs
|
||||||
from django.utils.six.moves import range
|
from django.utils.six.moves import range
|
||||||
|
|
||||||
if six.PY2:
|
|
||||||
from .weakref_backports import WeakMethod
|
|
||||||
else:
|
|
||||||
from weakref import WeakMethod
|
|
||||||
|
|
||||||
|
|
||||||
def _make_id(target):
|
def _make_id(target):
|
||||||
if hasattr(target, '__func__'):
|
if hasattr(target, '__func__'):
|
||||||
@ -107,13 +101,10 @@ class Signal(object):
|
|||||||
receiver_object = receiver
|
receiver_object = receiver
|
||||||
# Check for bound methods
|
# Check for bound methods
|
||||||
if hasattr(receiver, '__self__') and hasattr(receiver, '__func__'):
|
if hasattr(receiver, '__self__') and hasattr(receiver, '__func__'):
|
||||||
ref = WeakMethod
|
ref = weakref.WeakMethod
|
||||||
receiver_object = receiver.__self__
|
receiver_object = receiver.__self__
|
||||||
if six.PY3:
|
receiver = ref(receiver)
|
||||||
receiver = ref(receiver)
|
weakref.finalize(receiver_object, self._remove_receiver)
|
||||||
weakref.finalize(receiver_object, self._remove_receiver)
|
|
||||||
else:
|
|
||||||
receiver = ref(receiver, self._remove_receiver)
|
|
||||||
|
|
||||||
with self.lock:
|
with self.lock:
|
||||||
self._clear_dead_receivers()
|
self._clear_dead_receivers()
|
||||||
|
@ -1,67 +0,0 @@
|
|||||||
"""
|
|
||||||
weakref_backports is a partial backport of the weakref module for python
|
|
||||||
versions below 3.4.
|
|
||||||
|
|
||||||
Copyright (C) 2013 Python Software Foundation, see LICENSE.python for details.
|
|
||||||
|
|
||||||
The following changes were made to the original sources during backporting:
|
|
||||||
|
|
||||||
* Added `self` to `super` calls.
|
|
||||||
* Removed `from None` when raising exceptions.
|
|
||||||
|
|
||||||
"""
|
|
||||||
from weakref import ref
|
|
||||||
|
|
||||||
|
|
||||||
class WeakMethod(ref):
|
|
||||||
"""
|
|
||||||
A custom `weakref.ref` subclass which simulates a weak reference to
|
|
||||||
a bound method, working around the lifetime problem of bound methods.
|
|
||||||
"""
|
|
||||||
|
|
||||||
__slots__ = "_func_ref", "_meth_type", "_alive", "__weakref__"
|
|
||||||
|
|
||||||
def __new__(cls, meth, callback=None):
|
|
||||||
try:
|
|
||||||
obj = meth.__self__
|
|
||||||
func = meth.__func__
|
|
||||||
except AttributeError:
|
|
||||||
raise TypeError("argument should be a bound method, not {}"
|
|
||||||
.format(type(meth)))
|
|
||||||
def _cb(arg):
|
|
||||||
# The self-weakref trick is needed to avoid creating a reference
|
|
||||||
# cycle.
|
|
||||||
self = self_wr()
|
|
||||||
if self._alive:
|
|
||||||
self._alive = False
|
|
||||||
if callback is not None:
|
|
||||||
callback(self)
|
|
||||||
self = ref.__new__(cls, obj, _cb)
|
|
||||||
self._func_ref = ref(func, _cb)
|
|
||||||
self._meth_type = type(meth)
|
|
||||||
self._alive = True
|
|
||||||
self_wr = ref(self)
|
|
||||||
return self
|
|
||||||
|
|
||||||
def __call__(self):
|
|
||||||
obj = super(WeakMethod, self).__call__()
|
|
||||||
func = self._func_ref()
|
|
||||||
if obj is None or func is None:
|
|
||||||
return None
|
|
||||||
return self._meth_type(func, obj)
|
|
||||||
|
|
||||||
def __eq__(self, other):
|
|
||||||
if isinstance(other, WeakMethod):
|
|
||||||
if not self._alive or not other._alive:
|
|
||||||
return self is other
|
|
||||||
return ref.__eq__(self, other) and self._func_ref == other._func_ref
|
|
||||||
return False
|
|
||||||
|
|
||||||
def __ne__(self, other):
|
|
||||||
if isinstance(other, WeakMethod):
|
|
||||||
if not self._alive or not other._alive:
|
|
||||||
return self is not other
|
|
||||||
return ref.__ne__(self, other) or self._func_ref != other._func_ref
|
|
||||||
return True
|
|
||||||
|
|
||||||
__hash__ = ref.__hash__
|
|
@ -1,12 +1,7 @@
|
|||||||
import sys
|
import sys
|
||||||
|
|
||||||
from django.utils import six
|
|
||||||
from django.utils.encoding import force_str
|
|
||||||
from django.utils.six.moves import http_cookies
|
from django.utils.six.moves import http_cookies
|
||||||
|
|
||||||
# http://bugs.python.org/issue2193 is fixed in Python 3.3+.
|
|
||||||
_cookie_allows_colon_in_names = six.PY3
|
|
||||||
|
|
||||||
# Cookie pickling bug is fixed in Python 2.7.9 and Python 3.4.3+
|
# Cookie pickling bug is fixed in Python 2.7.9 and Python 3.4.3+
|
||||||
# http://bugs.python.org/issue22775
|
# http://bugs.python.org/issue22775
|
||||||
cookie_pickles_properly = (
|
cookie_pickles_properly = (
|
||||||
@ -14,7 +9,7 @@ cookie_pickles_properly = (
|
|||||||
sys.version_info >= (3, 4, 3)
|
sys.version_info >= (3, 4, 3)
|
||||||
)
|
)
|
||||||
|
|
||||||
if _cookie_allows_colon_in_names and cookie_pickles_properly:
|
if cookie_pickles_properly:
|
||||||
SimpleCookie = http_cookies.SimpleCookie
|
SimpleCookie = http_cookies.SimpleCookie
|
||||||
else:
|
else:
|
||||||
Morsel = http_cookies.Morsel
|
Morsel = http_cookies.Morsel
|
||||||
@ -30,37 +25,12 @@ else:
|
|||||||
else:
|
else:
|
||||||
super(SimpleCookie, self).__setitem__(key, value)
|
super(SimpleCookie, self).__setitem__(key, value)
|
||||||
|
|
||||||
if not _cookie_allows_colon_in_names:
|
|
||||||
def load(self, rawdata):
|
|
||||||
self.bad_cookies = set()
|
|
||||||
if isinstance(rawdata, six.text_type):
|
|
||||||
rawdata = force_str(rawdata)
|
|
||||||
super(SimpleCookie, self).load(rawdata)
|
|
||||||
for key in self.bad_cookies:
|
|
||||||
del self[key]
|
|
||||||
|
|
||||||
# override private __set() method:
|
|
||||||
# (needed for using our Morsel, and for laxness with CookieError
|
|
||||||
def _BaseCookie__set(self, key, real_value, coded_value):
|
|
||||||
key = force_str(key)
|
|
||||||
try:
|
|
||||||
M = self.get(key, Morsel())
|
|
||||||
M.set(key, real_value, coded_value)
|
|
||||||
dict.__setitem__(self, key, M)
|
|
||||||
except http_cookies.CookieError:
|
|
||||||
if not hasattr(self, 'bad_cookies'):
|
|
||||||
self.bad_cookies = set()
|
|
||||||
self.bad_cookies.add(key)
|
|
||||||
dict.__setitem__(self, key, http_cookies.Morsel())
|
|
||||||
|
|
||||||
|
|
||||||
def parse_cookie(cookie):
|
def parse_cookie(cookie):
|
||||||
"""
|
"""
|
||||||
Return a dictionary parsed from a `Cookie:` header string.
|
Return a dictionary parsed from a `Cookie:` header string.
|
||||||
"""
|
"""
|
||||||
cookiedict = {}
|
cookiedict = {}
|
||||||
if six.PY2:
|
|
||||||
cookie = force_str(cookie)
|
|
||||||
for chunk in cookie.split(str(';')):
|
for chunk in cookie.split(str(';')):
|
||||||
if str('=') in chunk:
|
if str('=') in chunk:
|
||||||
key, val = chunk.split(str('='), 1)
|
key, val = chunk.split(str('='), 1)
|
||||||
|
@ -40,8 +40,6 @@ RAW = "raw"
|
|||||||
FILE = "file"
|
FILE = "file"
|
||||||
FIELD = "field"
|
FIELD = "field"
|
||||||
|
|
||||||
_BASE64_DECODE_ERROR = TypeError if six.PY2 else binascii.Error
|
|
||||||
|
|
||||||
|
|
||||||
class MultiPartParser(object):
|
class MultiPartParser(object):
|
||||||
"""
|
"""
|
||||||
@ -190,7 +188,7 @@ class MultiPartParser(object):
|
|||||||
num_bytes_read += len(raw_data)
|
num_bytes_read += len(raw_data)
|
||||||
try:
|
try:
|
||||||
data = base64.b64decode(raw_data)
|
data = base64.b64decode(raw_data)
|
||||||
except _BASE64_DECODE_ERROR:
|
except binascii.Error:
|
||||||
data = raw_data
|
data = raw_data
|
||||||
else:
|
else:
|
||||||
data = field_stream.read(size=read_size)
|
data = field_stream.read(size=read_size)
|
||||||
@ -684,10 +682,7 @@ def parse_header(line):
|
|||||||
value = p[i + 1:].strip()
|
value = p[i + 1:].strip()
|
||||||
if has_encoding:
|
if has_encoding:
|
||||||
encoding, lang, value = value.split(b"'")
|
encoding, lang, value = value.split(b"'")
|
||||||
if six.PY3:
|
value = unquote(value.decode(), encoding=encoding.decode())
|
||||||
value = unquote(value.decode(), encoding=encoding.decode())
|
|
||||||
else:
|
|
||||||
value = unquote(value).decode(encoding)
|
|
||||||
if len(value) >= 2 and value[:1] == value[-1:] == b'"':
|
if len(value) >= 2 and value[:1] == value[-1:] == b'"':
|
||||||
value = value[1:-1]
|
value = value[1:-1]
|
||||||
value = value.replace(b'\\\\', b'\\').replace(b'\\"', b'"')
|
value = value.replace(b'\\\\', b'\\').replace(b'\\"', b'"')
|
||||||
|
@ -14,7 +14,7 @@ from django.http.multipartparser import MultiPartParser, MultiPartParserError
|
|||||||
from django.utils import six
|
from django.utils import six
|
||||||
from django.utils.datastructures import ImmutableList, MultiValueDict
|
from django.utils.datastructures import ImmutableList, MultiValueDict
|
||||||
from django.utils.encoding import (
|
from django.utils.encoding import (
|
||||||
escape_uri_path, force_bytes, force_str, force_text, iri_to_uri,
|
escape_uri_path, force_bytes, force_str, iri_to_uri,
|
||||||
)
|
)
|
||||||
from django.utils.http import is_same_domain, limited_parse_qsl
|
from django.utils.http import is_same_domain, limited_parse_qsl
|
||||||
from django.utils.six.moves.urllib.parse import (
|
from django.utils.six.moves.urllib.parse import (
|
||||||
@ -381,24 +381,15 @@ class QueryDict(MultiValueDict):
|
|||||||
'fields_limit': settings.DATA_UPLOAD_MAX_NUMBER_FIELDS,
|
'fields_limit': settings.DATA_UPLOAD_MAX_NUMBER_FIELDS,
|
||||||
'encoding': encoding,
|
'encoding': encoding,
|
||||||
}
|
}
|
||||||
if six.PY3:
|
if isinstance(query_string, bytes):
|
||||||
if isinstance(query_string, bytes):
|
# query_string normally contains URL-encoded data, a subset of ASCII.
|
||||||
# query_string normally contains URL-encoded data, a subset of ASCII.
|
try:
|
||||||
try:
|
query_string = query_string.decode(encoding)
|
||||||
query_string = query_string.decode(encoding)
|
except UnicodeDecodeError:
|
||||||
except UnicodeDecodeError:
|
# ... but some user agents are misbehaving :-(
|
||||||
# ... but some user agents are misbehaving :-(
|
query_string = query_string.decode('iso-8859-1')
|
||||||
query_string = query_string.decode('iso-8859-1')
|
for key, value in limited_parse_qsl(query_string, **parse_qsl_kwargs):
|
||||||
for key, value in limited_parse_qsl(query_string, **parse_qsl_kwargs):
|
self.appendlist(key, value)
|
||||||
self.appendlist(key, value)
|
|
||||||
else:
|
|
||||||
for key, value in limited_parse_qsl(query_string, **parse_qsl_kwargs):
|
|
||||||
try:
|
|
||||||
value = value.decode(encoding)
|
|
||||||
except UnicodeDecodeError:
|
|
||||||
value = value.decode('iso-8859-1')
|
|
||||||
self.appendlist(force_text(key, encoding, errors='replace'),
|
|
||||||
value)
|
|
||||||
self._mutable = mutable
|
self._mutable = mutable
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
|
@ -100,10 +100,7 @@ class HttpResponseBase(six.Iterator):
|
|||||||
]
|
]
|
||||||
return b'\r\n'.join(headers)
|
return b'\r\n'.join(headers)
|
||||||
|
|
||||||
if six.PY3:
|
__bytes__ = serialize_headers
|
||||||
__bytes__ = serialize_headers
|
|
||||||
else:
|
|
||||||
__str__ = serialize_headers
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def _content_type_for_repr(self):
|
def _content_type_for_repr(self):
|
||||||
@ -122,20 +119,12 @@ class HttpResponseBase(six.Iterator):
|
|||||||
isinstance(value, six.text_type) and ('\n' in value or '\r' in value)):
|
isinstance(value, six.text_type) and ('\n' in value or '\r' in value)):
|
||||||
raise BadHeaderError("Header values can't contain newlines (got %r)" % value)
|
raise BadHeaderError("Header values can't contain newlines (got %r)" % value)
|
||||||
try:
|
try:
|
||||||
if six.PY3:
|
if isinstance(value, str):
|
||||||
if isinstance(value, str):
|
# Ensure string is valid in given charset
|
||||||
# Ensure string is valid in given charset
|
value.encode(charset)
|
||||||
value.encode(charset)
|
|
||||||
else:
|
|
||||||
# Convert bytestring using given charset
|
|
||||||
value = value.decode(charset)
|
|
||||||
else:
|
else:
|
||||||
if isinstance(value, str):
|
# Convert bytestring using given charset
|
||||||
# Ensure string is valid in given charset
|
value = value.decode(charset)
|
||||||
value.decode(charset)
|
|
||||||
else:
|
|
||||||
# Convert unicode string to given charset
|
|
||||||
value = value.encode(charset)
|
|
||||||
except UnicodeError as e:
|
except UnicodeError as e:
|
||||||
if mime_encode:
|
if mime_encode:
|
||||||
# Wrapping in str() is a workaround for #12422 under Python 2.
|
# Wrapping in str() is a workaround for #12422 under Python 2.
|
||||||
@ -311,10 +300,7 @@ class HttpResponse(HttpResponseBase):
|
|||||||
"""Full HTTP message, including headers, as a bytestring."""
|
"""Full HTTP message, including headers, as a bytestring."""
|
||||||
return self.serialize_headers() + b'\r\n\r\n' + self.content
|
return self.serialize_headers() + b'\r\n\r\n' + self.content
|
||||||
|
|
||||||
if six.PY3:
|
__bytes__ = serialize
|
||||||
__bytes__ = serialize
|
|
||||||
else:
|
|
||||||
__str__ = serialize
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def content(self):
|
def content(self):
|
||||||
|
@ -322,10 +322,10 @@ class RequestFactory(object):
|
|||||||
if parsed[3]:
|
if parsed[3]:
|
||||||
path += str(";") + force_str(parsed[3])
|
path += str(";") + force_str(parsed[3])
|
||||||
path = uri_to_iri(path).encode(UTF_8)
|
path = uri_to_iri(path).encode(UTF_8)
|
||||||
# Under Python 3, non-ASCII values in the WSGI environ are arbitrarily
|
# Replace the behavior where non-ASCII values in the WSGI environ are
|
||||||
# decoded with ISO-8859-1. We replicate this behavior here.
|
# arbitrarily decoded with ISO-8859-1.
|
||||||
# Refs comment in `get_bytes_from_wsgi()`.
|
# Refs comment in `get_bytes_from_wsgi()`.
|
||||||
return path.decode(ISO_8859_1) if six.PY3 else path
|
return path.decode(ISO_8859_1)
|
||||||
|
|
||||||
def get(self, path, data=None, secure=False, **extra):
|
def get(self, path, data=None, secure=False, **extra):
|
||||||
"Construct a GET request."
|
"Construct a GET request."
|
||||||
@ -406,10 +406,8 @@ class RequestFactory(object):
|
|||||||
r.update(extra)
|
r.update(extra)
|
||||||
# If QUERY_STRING is absent or empty, we want to extract it from the URL.
|
# If QUERY_STRING is absent or empty, we want to extract it from the URL.
|
||||||
if not r.get('QUERY_STRING'):
|
if not r.get('QUERY_STRING'):
|
||||||
query_string = force_bytes(parsed[4])
|
|
||||||
# WSGI requires latin-1 encoded strings. See get_path_info().
|
# WSGI requires latin-1 encoded strings. See get_path_info().
|
||||||
if six.PY3:
|
query_string = force_bytes(parsed[4]).decode('iso-8859-1')
|
||||||
query_string = query_string.decode('iso-8859-1')
|
|
||||||
r['QUERY_STRING'] = query_string
|
r['QUERY_STRING'] = query_string
|
||||||
return self.request(**r)
|
return self.request(**r)
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@ from django.core.signals import setting_changed
|
|||||||
from django.db import connections, router
|
from django.db import connections, router
|
||||||
from django.db.utils import ConnectionRouter
|
from django.db.utils import ConnectionRouter
|
||||||
from django.dispatch import Signal, receiver
|
from django.dispatch import Signal, receiver
|
||||||
from django.utils import six, timezone
|
from django.utils import timezone
|
||||||
from django.utils.formats import FORMAT_SETTINGS, reset_format_cache
|
from django.utils.formats import FORMAT_SETTINGS, reset_format_cache
|
||||||
from django.utils.functional import empty
|
from django.utils.functional import empty
|
||||||
|
|
||||||
@ -139,7 +139,7 @@ def complex_setting_changed(**kwargs):
|
|||||||
# Considering the current implementation of the signals framework,
|
# Considering the current implementation of the signals framework,
|
||||||
# this stacklevel shows the line containing the override_settings call.
|
# this stacklevel shows the line containing the override_settings call.
|
||||||
warnings.warn("Overriding setting %s can lead to unexpected behavior."
|
warnings.warn("Overriding setting %s can lead to unexpected behavior."
|
||||||
% kwargs['setting'], stacklevel=5 if six.PY2 else 6)
|
% kwargs['setting'], stacklevel=6)
|
||||||
|
|
||||||
|
|
||||||
@receiver(setting_changed)
|
@receiver(setting_changed)
|
||||||
|
@ -775,12 +775,6 @@ class SimpleTestCase(unittest.TestCase):
|
|||||||
standardMsg = '%s == %s' % (safe_repr(xml1, True), safe_repr(xml2, True))
|
standardMsg = '%s == %s' % (safe_repr(xml1, True), safe_repr(xml2, True))
|
||||||
self.fail(self._formatMessage(msg, standardMsg))
|
self.fail(self._formatMessage(msg, standardMsg))
|
||||||
|
|
||||||
if six.PY2:
|
|
||||||
assertCountEqual = unittest.TestCase.assertItemsEqual
|
|
||||||
assertNotRegex = unittest.TestCase.assertNotRegexpMatches
|
|
||||||
assertRaisesRegex = unittest.TestCase.assertRaisesRegexp
|
|
||||||
assertRegex = unittest.TestCase.assertRegexpMatches
|
|
||||||
|
|
||||||
|
|
||||||
class TransactionTestCase(SimpleTestCase):
|
class TransactionTestCase(SimpleTestCase):
|
||||||
|
|
||||||
|
@ -6,6 +6,7 @@ import time
|
|||||||
import warnings
|
import warnings
|
||||||
from contextlib import contextmanager
|
from contextlib import contextmanager
|
||||||
from functools import wraps
|
from functools import wraps
|
||||||
|
from types import SimpleNamespace
|
||||||
from unittest import TestCase, skipIf, skipUnless
|
from unittest import TestCase, skipIf, skipUnless
|
||||||
from xml.dom.minidom import Node, parseString
|
from xml.dom.minidom import Node, parseString
|
||||||
|
|
||||||
@ -25,12 +26,6 @@ from django.utils.decorators import available_attrs
|
|||||||
from django.utils.encoding import force_str
|
from django.utils.encoding import force_str
|
||||||
from django.utils.translation import deactivate
|
from django.utils.translation import deactivate
|
||||||
|
|
||||||
if six.PY3:
|
|
||||||
from types import SimpleNamespace
|
|
||||||
else:
|
|
||||||
class SimpleNamespace(object):
|
|
||||||
pass
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
import jinja2
|
import jinja2
|
||||||
except ImportError:
|
except ImportError:
|
||||||
@ -615,7 +610,7 @@ def strip_quotes(want, got):
|
|||||||
|
|
||||||
|
|
||||||
def str_prefix(s):
|
def str_prefix(s):
|
||||||
return s % {'_': '' if six.PY3 else 'u'}
|
return s % {'_': ''}
|
||||||
|
|
||||||
|
|
||||||
class CaptureQueriesContext(object):
|
class CaptureQueriesContext(object):
|
||||||
|
@ -209,11 +209,7 @@ class RegexURLPattern(LocaleRegexProvider):
|
|||||||
callback = callback.func
|
callback = callback.func
|
||||||
if not hasattr(callback, '__name__'):
|
if not hasattr(callback, '__name__'):
|
||||||
return callback.__module__ + "." + callback.__class__.__name__
|
return callback.__module__ + "." + callback.__class__.__name__
|
||||||
elif six.PY3:
|
return callback.__module__ + "." + callback.__qualname__
|
||||||
return callback.__module__ + "." + callback.__qualname__
|
|
||||||
else:
|
|
||||||
# PY2 does not support __qualname__
|
|
||||||
return callback.__module__ + "." + callback.__name__
|
|
||||||
|
|
||||||
|
|
||||||
class RegexURLResolver(LocaleRegexProvider):
|
class RegexURLResolver(LocaleRegexProvider):
|
||||||
|
@ -1,41 +1,18 @@
|
|||||||
import os
|
import os
|
||||||
import sys
|
|
||||||
import tempfile
|
import tempfile
|
||||||
from os.path import abspath, dirname, isabs, join, normcase, normpath, sep
|
from os.path import abspath, dirname, join, normcase, sep
|
||||||
|
|
||||||
from django.core.exceptions import SuspiciousFileOperation
|
from django.core.exceptions import SuspiciousFileOperation
|
||||||
from django.utils import six
|
|
||||||
from django.utils.encoding import force_text
|
from django.utils.encoding import force_text
|
||||||
|
|
||||||
if six.PY2:
|
|
||||||
fs_encoding = sys.getfilesystemencoding() or sys.getdefaultencoding()
|
|
||||||
|
|
||||||
|
abspathu = abspath
|
||||||
# Under Python 2, define our own abspath function that can handle joining
|
|
||||||
# unicode paths to a current working directory that has non-ASCII characters
|
|
||||||
# in it. This isn't necessary on Windows since the Windows version of abspath
|
|
||||||
# handles this correctly. It also handles drive letters differently than the
|
|
||||||
# pure Python implementation, so it's best not to replace it.
|
|
||||||
if six.PY3 or os.name == 'nt':
|
|
||||||
abspathu = abspath
|
|
||||||
else:
|
|
||||||
def abspathu(path):
|
|
||||||
"""
|
|
||||||
Version of os.path.abspath that uses the unicode representation
|
|
||||||
of the current working directory, thus avoiding a UnicodeDecodeError
|
|
||||||
in join when the cwd has non-ASCII characters.
|
|
||||||
"""
|
|
||||||
if not isabs(path):
|
|
||||||
path = join(os.getcwdu(), path)
|
|
||||||
return normpath(path)
|
|
||||||
|
|
||||||
|
|
||||||
def upath(path):
|
def upath(path):
|
||||||
"""
|
"""
|
||||||
Always return a unicode path.
|
Always return a unicode path.
|
||||||
"""
|
"""
|
||||||
if six.PY2 and not isinstance(path, six.text_type):
|
|
||||||
return path.decode(fs_encoding)
|
|
||||||
return path
|
return path
|
||||||
|
|
||||||
|
|
||||||
@ -44,8 +21,6 @@ def npath(path):
|
|||||||
Always return a native path, that is unicode on Python 3 and bytestring on
|
Always return a native path, that is unicode on Python 3 and bytestring on
|
||||||
Python 2.
|
Python 2.
|
||||||
"""
|
"""
|
||||||
if six.PY2 and not isinstance(path, bytes):
|
|
||||||
return path.encode(fs_encoding)
|
|
||||||
return path
|
return path
|
||||||
|
|
||||||
|
|
||||||
|
@ -9,7 +9,6 @@ import struct
|
|||||||
import time
|
import time
|
||||||
|
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.utils import six
|
|
||||||
from django.utils.encoding import force_bytes
|
from django.utils.encoding import force_bytes
|
||||||
from django.utils.six.moves import range
|
from django.utils.six.moves import range
|
||||||
|
|
||||||
@ -94,7 +93,7 @@ else:
|
|||||||
if len(val1) != len(val2):
|
if len(val1) != len(val2):
|
||||||
return False
|
return False
|
||||||
result = 0
|
result = 0
|
||||||
if six.PY3 and isinstance(val1, bytes) and isinstance(val2, bytes):
|
if isinstance(val1, bytes) and isinstance(val2, bytes):
|
||||||
for x, y in zip(val1, val2):
|
for x, y in zip(val1, val2):
|
||||||
result |= x ^ y
|
result |= x ^ y
|
||||||
else:
|
else:
|
||||||
|
@ -179,7 +179,7 @@ class MultiValueDict(dict):
|
|||||||
"""Appends an item to the internal list associated with key."""
|
"""Appends an item to the internal list associated with key."""
|
||||||
self.setlistdefault(key).append(value)
|
self.setlistdefault(key).append(value)
|
||||||
|
|
||||||
def _iteritems(self):
|
def items(self):
|
||||||
"""
|
"""
|
||||||
Yields (key, value) pairs, where value is the last item in the list
|
Yields (key, value) pairs, where value is the last item in the list
|
||||||
associated with the key.
|
associated with the key.
|
||||||
@ -187,33 +187,15 @@ class MultiValueDict(dict):
|
|||||||
for key in self:
|
for key in self:
|
||||||
yield key, self[key]
|
yield key, self[key]
|
||||||
|
|
||||||
def _iterlists(self):
|
def lists(self):
|
||||||
"""Yields (key, list) pairs."""
|
"""Yields (key, list) pairs."""
|
||||||
return six.iteritems(super(MultiValueDict, self))
|
return six.iteritems(super(MultiValueDict, self))
|
||||||
|
|
||||||
def _itervalues(self):
|
def values(self):
|
||||||
"""Yield the last value on every key list."""
|
"""Yield the last value on every key list."""
|
||||||
for key in self:
|
for key in self:
|
||||||
yield self[key]
|
yield self[key]
|
||||||
|
|
||||||
if six.PY3:
|
|
||||||
items = _iteritems
|
|
||||||
lists = _iterlists
|
|
||||||
values = _itervalues
|
|
||||||
else:
|
|
||||||
iteritems = _iteritems
|
|
||||||
iterlists = _iterlists
|
|
||||||
itervalues = _itervalues
|
|
||||||
|
|
||||||
def items(self):
|
|
||||||
return list(self.iteritems())
|
|
||||||
|
|
||||||
def lists(self):
|
|
||||||
return list(self.iterlists())
|
|
||||||
|
|
||||||
def values(self):
|
|
||||||
return list(self.itervalues())
|
|
||||||
|
|
||||||
def copy(self):
|
def copy(self):
|
||||||
"""Returns a shallow copy of this object."""
|
"""Returns a shallow copy of this object."""
|
||||||
return copy.copy(self)
|
return copy.copy(self)
|
||||||
|
@ -7,8 +7,6 @@ except ImportError:
|
|||||||
|
|
||||||
from functools import WRAPPER_ASSIGNMENTS, update_wrapper, wraps
|
from functools import WRAPPER_ASSIGNMENTS, update_wrapper, wraps
|
||||||
|
|
||||||
from django.utils import six
|
|
||||||
|
|
||||||
|
|
||||||
class classonlymethod(classmethod):
|
class classonlymethod(classmethod):
|
||||||
def __get__(self, instance, cls=None):
|
def __get__(self, instance, cls=None):
|
||||||
@ -121,13 +119,10 @@ def decorator_from_middleware(middleware_class):
|
|||||||
def available_attrs(fn):
|
def available_attrs(fn):
|
||||||
"""
|
"""
|
||||||
Return the list of functools-wrappable attributes on a callable.
|
Return the list of functools-wrappable attributes on a callable.
|
||||||
This is required as a workaround for http://bugs.python.org/issue3445
|
This was required as a workaround for http://bugs.python.org/issue3445
|
||||||
under Python 2.
|
under Python 2.
|
||||||
"""
|
"""
|
||||||
if six.PY3:
|
return WRAPPER_ASSIGNMENTS
|
||||||
return WRAPPER_ASSIGNMENTS
|
|
||||||
else:
|
|
||||||
return tuple(a for a in WRAPPER_ASSIGNMENTS if hasattr(fn, a))
|
|
||||||
|
|
||||||
|
|
||||||
def make_middleware_decorator(middleware_class):
|
def make_middleware_decorator(middleware_class):
|
||||||
|
@ -2,13 +2,11 @@ import codecs
|
|||||||
import datetime
|
import datetime
|
||||||
import locale
|
import locale
|
||||||
from decimal import Decimal
|
from decimal import Decimal
|
||||||
|
from urllib.parse import unquote_to_bytes
|
||||||
|
|
||||||
from django.utils import six
|
from django.utils import six
|
||||||
from django.utils.functional import Promise
|
from django.utils.functional import Promise
|
||||||
from django.utils.six.moves.urllib.parse import quote, unquote
|
from django.utils.six.moves.urllib.parse import quote
|
||||||
|
|
||||||
if six.PY3:
|
|
||||||
from urllib.parse import unquote_to_bytes
|
|
||||||
|
|
||||||
|
|
||||||
class DjangoUnicodeDecodeError(UnicodeDecodeError):
|
class DjangoUnicodeDecodeError(UnicodeDecodeError):
|
||||||
@ -66,15 +64,10 @@ def force_text(s, encoding='utf-8', strings_only=False, errors='strict'):
|
|||||||
return s
|
return s
|
||||||
try:
|
try:
|
||||||
if not issubclass(type(s), six.string_types):
|
if not issubclass(type(s), six.string_types):
|
||||||
if six.PY3:
|
if isinstance(s, bytes):
|
||||||
if isinstance(s, bytes):
|
s = six.text_type(s, encoding, errors)
|
||||||
s = six.text_type(s, encoding, errors)
|
|
||||||
else:
|
|
||||||
s = six.text_type(s)
|
|
||||||
elif hasattr(s, '__unicode__'):
|
|
||||||
s = six.text_type(s)
|
|
||||||
else:
|
else:
|
||||||
s = six.text_type(bytes(s), encoding, errors)
|
s = six.text_type(s)
|
||||||
else:
|
else:
|
||||||
# Note: We use .decode() here, instead of six.text_type(s, encoding,
|
# Note: We use .decode() here, instead of six.text_type(s, encoding,
|
||||||
# errors), so that if s is a SafeBytes, it ends up being a
|
# errors), so that if s is a SafeBytes, it ends up being a
|
||||||
@ -127,10 +120,7 @@ def force_bytes(s, encoding='utf-8', strings_only=False, errors='strict'):
|
|||||||
return six.text_type(s).encode(encoding, errors)
|
return six.text_type(s).encode(encoding, errors)
|
||||||
if not isinstance(s, six.string_types):
|
if not isinstance(s, six.string_types):
|
||||||
try:
|
try:
|
||||||
if six.PY3:
|
return six.text_type(s).encode(encoding)
|
||||||
return six.text_type(s).encode(encoding)
|
|
||||||
else:
|
|
||||||
return bytes(s)
|
|
||||||
except UnicodeEncodeError:
|
except UnicodeEncodeError:
|
||||||
if isinstance(s, Exception):
|
if isinstance(s, Exception):
|
||||||
# An Exception subclass containing non-ASCII data that doesn't
|
# An Exception subclass containing non-ASCII data that doesn't
|
||||||
@ -143,15 +133,8 @@ def force_bytes(s, encoding='utf-8', strings_only=False, errors='strict'):
|
|||||||
return s.encode(encoding, errors)
|
return s.encode(encoding, errors)
|
||||||
|
|
||||||
|
|
||||||
if six.PY3:
|
smart_str = smart_text
|
||||||
smart_str = smart_text
|
force_str = force_text
|
||||||
force_str = force_text
|
|
||||||
else:
|
|
||||||
smart_str = smart_bytes
|
|
||||||
force_str = force_bytes
|
|
||||||
# backwards compatibility for Python 2
|
|
||||||
smart_unicode = smart_text
|
|
||||||
force_unicode = force_text
|
|
||||||
|
|
||||||
smart_str.__doc__ = """
|
smart_str.__doc__ = """
|
||||||
Apply smart_text in Python 3 and smart_bytes in Python 2.
|
Apply smart_text in Python 3 and smart_bytes in Python 2.
|
||||||
@ -207,7 +190,7 @@ def uri_to_iri(uri):
|
|||||||
if uri is None:
|
if uri is None:
|
||||||
return uri
|
return uri
|
||||||
uri = force_bytes(uri)
|
uri = force_bytes(uri)
|
||||||
iri = unquote_to_bytes(uri) if six.PY3 else unquote(uri)
|
iri = unquote_to_bytes(uri)
|
||||||
return repercent_broken_unicode(iri).decode('utf-8')
|
return repercent_broken_unicode(iri).decode('utf-8')
|
||||||
|
|
||||||
|
|
||||||
|
@ -23,7 +23,7 @@ http://web.archive.org/web/20110718035220/http://diveintomark.org/archives/2004/
|
|||||||
"""
|
"""
|
||||||
import datetime
|
import datetime
|
||||||
|
|
||||||
from django.utils import datetime_safe, six
|
from django.utils import datetime_safe
|
||||||
from django.utils.encoding import force_text, iri_to_uri
|
from django.utils.encoding import force_text, iri_to_uri
|
||||||
from django.utils.six import StringIO
|
from django.utils.six import StringIO
|
||||||
from django.utils.six.moves.urllib.parse import urlparse
|
from django.utils.six.moves.urllib.parse import urlparse
|
||||||
@ -42,8 +42,6 @@ def rfc2822_date(date):
|
|||||||
dow = days[date.weekday()]
|
dow = days[date.weekday()]
|
||||||
month = months[date.month - 1]
|
month = months[date.month - 1]
|
||||||
time_str = date.strftime('%s, %%d %s %%Y %%H:%%M:%%S ' % (dow, month))
|
time_str = date.strftime('%s, %%d %s %%Y %%H:%%M:%%S ' % (dow, month))
|
||||||
if six.PY2: # strftime returns a byte string in Python 2
|
|
||||||
time_str = time_str.decode('utf-8')
|
|
||||||
offset = date.utcoffset()
|
offset = date.utcoffset()
|
||||||
# Historically, this function assumes that naive datetimes are in UTC.
|
# Historically, this function assumes that naive datetimes are in UTC.
|
||||||
if offset is None:
|
if offset is None:
|
||||||
@ -58,8 +56,6 @@ def rfc3339_date(date):
|
|||||||
# Support datetime objects older than 1900
|
# Support datetime objects older than 1900
|
||||||
date = datetime_safe.new_datetime(date)
|
date = datetime_safe.new_datetime(date)
|
||||||
time_str = date.strftime('%Y-%m-%dT%H:%M:%S')
|
time_str = date.strftime('%Y-%m-%dT%H:%M:%S')
|
||||||
if six.PY2: # strftime returns a byte string in Python 2
|
|
||||||
time_str = time_str.decode('utf-8')
|
|
||||||
offset = date.utcoffset()
|
offset = date.utcoffset()
|
||||||
# Historically, this function assumes that naive datetimes are in UTC.
|
# Historically, this function assumes that naive datetimes are in UTC.
|
||||||
if offset is None:
|
if offset is None:
|
||||||
|
@ -92,16 +92,9 @@ def lazy(func, *resultclasses):
|
|||||||
assert not (cls._delegate_bytes and cls._delegate_text), (
|
assert not (cls._delegate_bytes and cls._delegate_text), (
|
||||||
"Cannot call lazy() with both bytes and text return types.")
|
"Cannot call lazy() with both bytes and text return types.")
|
||||||
if cls._delegate_text:
|
if cls._delegate_text:
|
||||||
if six.PY3:
|
cls.__str__ = cls.__text_cast
|
||||||
cls.__str__ = cls.__text_cast
|
|
||||||
else:
|
|
||||||
cls.__unicode__ = cls.__text_cast
|
|
||||||
cls.__str__ = cls.__bytes_cast_encoded
|
|
||||||
elif cls._delegate_bytes:
|
elif cls._delegate_bytes:
|
||||||
if six.PY3:
|
cls.__bytes__ = cls.__bytes_cast
|
||||||
cls.__bytes__ = cls.__bytes_cast
|
|
||||||
else:
|
|
||||||
cls.__str__ = cls.__bytes_cast
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def __promise__(cls, method_name):
|
def __promise__(cls, method_name):
|
||||||
@ -154,9 +147,7 @@ def lazy(func, *resultclasses):
|
|||||||
return hash(self.__cast())
|
return hash(self.__cast())
|
||||||
|
|
||||||
def __mod__(self, rhs):
|
def __mod__(self, rhs):
|
||||||
if self._delegate_bytes and six.PY2:
|
if self._delegate_text:
|
||||||
return bytes(self) % rhs
|
|
||||||
elif self._delegate_text:
|
|
||||||
return six.text_type(self) % rhs
|
return six.text_type(self) % rhs
|
||||||
return self.__cast() % rhs
|
return self.__cast() % rhs
|
||||||
|
|
||||||
@ -316,14 +307,9 @@ class LazyObject(object):
|
|||||||
return result
|
return result
|
||||||
return copy.deepcopy(self._wrapped, memo)
|
return copy.deepcopy(self._wrapped, memo)
|
||||||
|
|
||||||
if six.PY3:
|
__bytes__ = new_method_proxy(bytes)
|
||||||
__bytes__ = new_method_proxy(bytes)
|
__str__ = new_method_proxy(str)
|
||||||
__str__ = new_method_proxy(str)
|
__bool__ = new_method_proxy(bool)
|
||||||
__bool__ = new_method_proxy(bool)
|
|
||||||
else:
|
|
||||||
__str__ = new_method_proxy(str)
|
|
||||||
__unicode__ = new_method_proxy(unicode) # NOQA: unicode undefined on PY3
|
|
||||||
__nonzero__ = new_method_proxy(bool)
|
|
||||||
|
|
||||||
# Introspection support
|
# Introspection support
|
||||||
__dir__ = new_method_proxy(dir)
|
__dir__ = new_method_proxy(dir)
|
||||||
|
@ -1,19 +0,0 @@
|
|||||||
import os.path
|
|
||||||
import re
|
|
||||||
|
|
||||||
from django.utils import six
|
|
||||||
|
|
||||||
# backport of Python 3.4's glob.escape
|
|
||||||
|
|
||||||
if six.PY3:
|
|
||||||
from glob import escape as glob_escape
|
|
||||||
else:
|
|
||||||
_magic_check = re.compile('([*?[])')
|
|
||||||
|
|
||||||
def glob_escape(pathname):
|
|
||||||
"""
|
|
||||||
Escape all special characters.
|
|
||||||
"""
|
|
||||||
drive, pathname = os.path.splitdrive(pathname)
|
|
||||||
pathname = _magic_check.sub(r'[\1]', pathname)
|
|
||||||
return drive + pathname
|
|
@ -363,22 +363,12 @@ def html_safe(klass):
|
|||||||
"can't apply @html_safe to %s because it defines "
|
"can't apply @html_safe to %s because it defines "
|
||||||
"__html__()." % klass.__name__
|
"__html__()." % klass.__name__
|
||||||
)
|
)
|
||||||
if six.PY2:
|
if '__str__' not in klass.__dict__:
|
||||||
if '__unicode__' not in klass.__dict__:
|
raise ValueError(
|
||||||
raise ValueError(
|
"can't apply @html_safe to %s because it doesn't "
|
||||||
"can't apply @html_safe to %s because it doesn't "
|
"define __str__()." % klass.__name__
|
||||||
"define __unicode__()." % klass.__name__
|
)
|
||||||
)
|
klass_str = klass.__str__
|
||||||
klass_unicode = klass.__unicode__
|
klass.__str__ = lambda self: mark_safe(klass_str(self))
|
||||||
klass.__unicode__ = lambda self: mark_safe(klass_unicode(self))
|
klass.__html__ = lambda self: str(self)
|
||||||
klass.__html__ = lambda self: unicode(self) # NOQA: unicode undefined on PY3
|
|
||||||
else:
|
|
||||||
if '__str__' not in klass.__dict__:
|
|
||||||
raise ValueError(
|
|
||||||
"can't apply @html_safe to %s because it doesn't "
|
|
||||||
"define __str__()." % klass.__name__
|
|
||||||
)
|
|
||||||
klass_str = klass.__str__
|
|
||||||
klass.__str__ = lambda self: mark_safe(klass_str(self))
|
|
||||||
klass.__html__ = lambda self: str(self)
|
|
||||||
return klass
|
return klass
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
from django.utils import six
|
|
||||||
from django.utils.six.moves import html_parser as _html_parser
|
from django.utils.six.moves import html_parser as _html_parser
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@ -8,15 +7,13 @@ except AttributeError:
|
|||||||
class HTMLParseError(Exception):
|
class HTMLParseError(Exception):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
if six.PY3:
|
|
||||||
class HTMLParser(_html_parser.HTMLParser):
|
|
||||||
"""Explicitly set convert_charrefs to be False.
|
|
||||||
|
|
||||||
This silences a deprecation warning on Python 3.4, but we can't do
|
class HTMLParser(_html_parser.HTMLParser):
|
||||||
it at call time because Python 2.7 does not have the keyword
|
"""Explicitly set convert_charrefs to be False.
|
||||||
argument.
|
|
||||||
"""
|
This silences a deprecation warning on Python 3.4, but we can't do
|
||||||
def __init__(self, convert_charrefs=False, **kwargs):
|
it at call time because Python 2.7 does not have the keyword
|
||||||
_html_parser.HTMLParser.__init__(self, convert_charrefs=convert_charrefs, **kwargs)
|
argument.
|
||||||
else:
|
"""
|
||||||
HTMLParser = _html_parser.HTMLParser
|
def __init__(self, convert_charrefs=False, **kwargs):
|
||||||
|
_html_parser.HTMLParser.__init__(self, convert_charrefs=convert_charrefs, **kwargs)
|
||||||
|
@ -189,12 +189,7 @@ def base36_to_int(s):
|
|||||||
# is sufficient to base36-encode any 64-bit integer)
|
# is sufficient to base36-encode any 64-bit integer)
|
||||||
if len(s) > 13:
|
if len(s) > 13:
|
||||||
raise ValueError("Base36 input too large")
|
raise ValueError("Base36 input too large")
|
||||||
value = int(s, 36)
|
return int(s, 36)
|
||||||
# ... then do a final check that the value will fit into an int to avoid
|
|
||||||
# returning a long (#15067). The long type was removed in Python 3.
|
|
||||||
if six.PY2 and value > sys.maxint:
|
|
||||||
raise ValueError("Base36 input too large")
|
|
||||||
return value
|
|
||||||
|
|
||||||
|
|
||||||
def int_to_base36(i):
|
def int_to_base36(i):
|
||||||
@ -204,11 +199,6 @@ def int_to_base36(i):
|
|||||||
char_set = '0123456789abcdefghijklmnopqrstuvwxyz'
|
char_set = '0123456789abcdefghijklmnopqrstuvwxyz'
|
||||||
if i < 0:
|
if i < 0:
|
||||||
raise ValueError("Negative base36 conversion input.")
|
raise ValueError("Negative base36 conversion input.")
|
||||||
if six.PY2:
|
|
||||||
if not isinstance(i, six.integer_types):
|
|
||||||
raise TypeError("Non-integer base36 conversion input.")
|
|
||||||
if i > sys.maxint:
|
|
||||||
raise ValueError("Base36 conversion input too large.")
|
|
||||||
if i < 36:
|
if i < 36:
|
||||||
return char_set[i]
|
return char_set[i]
|
||||||
b36 = ''
|
b36 = ''
|
||||||
@ -296,11 +286,6 @@ def is_safe_url(url, host=None, allowed_hosts=None, require_https=False):
|
|||||||
url = url.strip()
|
url = url.strip()
|
||||||
if not url:
|
if not url:
|
||||||
return False
|
return False
|
||||||
if six.PY2:
|
|
||||||
try:
|
|
||||||
url = force_text(url)
|
|
||||||
except UnicodeDecodeError:
|
|
||||||
return False
|
|
||||||
if allowed_hosts is None:
|
if allowed_hosts is None:
|
||||||
allowed_hosts = set()
|
allowed_hosts = set()
|
||||||
if host:
|
if host:
|
||||||
@ -388,13 +373,9 @@ def limited_parse_qsl(qs, keep_blank_values=False, encoding='utf-8',
|
|||||||
else:
|
else:
|
||||||
continue
|
continue
|
||||||
if len(nv[1]) or keep_blank_values:
|
if len(nv[1]) or keep_blank_values:
|
||||||
if six.PY3:
|
name = nv[0].replace('+', ' ')
|
||||||
name = nv[0].replace('+', ' ')
|
name = unquote(name, encoding=encoding, errors=errors)
|
||||||
name = unquote(name, encoding=encoding, errors=errors)
|
value = nv[1].replace('+', ' ')
|
||||||
value = nv[1].replace('+', ' ')
|
value = unquote(value, encoding=encoding, errors=errors)
|
||||||
value = unquote(value, encoding=encoding, errors=errors)
|
|
||||||
else:
|
|
||||||
name = unquote(nv[0].replace(b'+', b' '))
|
|
||||||
value = unquote(nv[1].replace(b'+', b' '))
|
|
||||||
r.append((name, value))
|
r.append((name, value))
|
||||||
return r
|
return r
|
||||||
|
@ -1,12 +1,7 @@
|
|||||||
import inspect
|
import inspect
|
||||||
|
|
||||||
from django.utils import six
|
|
||||||
|
|
||||||
|
|
||||||
def getargspec(func):
|
def getargspec(func):
|
||||||
if six.PY2:
|
|
||||||
return inspect.getargspec(func)
|
|
||||||
|
|
||||||
sig = inspect.signature(func)
|
sig = inspect.signature(func)
|
||||||
args = [
|
args = [
|
||||||
p.name for p in sig.parameters.values()
|
p.name for p in sig.parameters.values()
|
||||||
@ -30,10 +25,6 @@ def getargspec(func):
|
|||||||
|
|
||||||
|
|
||||||
def get_func_args(func):
|
def get_func_args(func):
|
||||||
if six.PY2:
|
|
||||||
argspec = inspect.getargspec(func)
|
|
||||||
return argspec.args[1:] # ignore 'self'
|
|
||||||
|
|
||||||
sig = inspect.signature(func)
|
sig = inspect.signature(func)
|
||||||
return [
|
return [
|
||||||
arg_name for arg_name, param in sig.parameters.items()
|
arg_name for arg_name, param in sig.parameters.items()
|
||||||
@ -47,20 +38,6 @@ def get_func_full_args(func):
|
|||||||
does not have a default value, omit it in the tuple. Arguments such as
|
does not have a default value, omit it in the tuple. Arguments such as
|
||||||
*args and **kwargs are also included.
|
*args and **kwargs are also included.
|
||||||
"""
|
"""
|
||||||
if six.PY2:
|
|
||||||
argspec = inspect.getargspec(func)
|
|
||||||
args = argspec.args[1:] # ignore 'self'
|
|
||||||
defaults = argspec.defaults or []
|
|
||||||
# Split args into two lists depending on whether they have default value
|
|
||||||
no_default = args[:len(args) - len(defaults)]
|
|
||||||
with_default = args[len(args) - len(defaults):]
|
|
||||||
# Join the two lists and combine it with default values
|
|
||||||
args = [(arg,) for arg in no_default] + zip(with_default, defaults)
|
|
||||||
# Add possible *args and **kwargs and prepend them with '*' or '**'
|
|
||||||
varargs = [('*' + argspec.varargs,)] if argspec.varargs else []
|
|
||||||
kwargs = [('**' + argspec.keywords,)] if argspec.keywords else []
|
|
||||||
return args + varargs + kwargs
|
|
||||||
|
|
||||||
sig = inspect.signature(func)
|
sig = inspect.signature(func)
|
||||||
args = []
|
args = []
|
||||||
for arg_name, param in sig.parameters.items():
|
for arg_name, param in sig.parameters.items():
|
||||||
@ -80,20 +57,6 @@ def get_func_full_args(func):
|
|||||||
|
|
||||||
|
|
||||||
def func_accepts_kwargs(func):
|
def func_accepts_kwargs(func):
|
||||||
if six.PY2:
|
|
||||||
# Not all callables are inspectable with getargspec, so we'll
|
|
||||||
# try a couple different ways but in the end fall back on assuming
|
|
||||||
# it is -- we don't want to prevent registration of valid but weird
|
|
||||||
# callables.
|
|
||||||
try:
|
|
||||||
argspec = inspect.getargspec(func)
|
|
||||||
except TypeError:
|
|
||||||
try:
|
|
||||||
argspec = inspect.getargspec(func.__call__)
|
|
||||||
except (TypeError, AttributeError):
|
|
||||||
argspec = None
|
|
||||||
return not argspec or argspec[2] is not None
|
|
||||||
|
|
||||||
return any(
|
return any(
|
||||||
p for p in inspect.signature(func).parameters.values()
|
p for p in inspect.signature(func).parameters.values()
|
||||||
if p.kind == p.VAR_KEYWORD
|
if p.kind == p.VAR_KEYWORD
|
||||||
@ -104,9 +67,6 @@ def func_accepts_var_args(func):
|
|||||||
"""
|
"""
|
||||||
Return True if function 'func' accepts positional arguments *args.
|
Return True if function 'func' accepts positional arguments *args.
|
||||||
"""
|
"""
|
||||||
if six.PY2:
|
|
||||||
return inspect.getargspec(func)[1] is not None
|
|
||||||
|
|
||||||
return any(
|
return any(
|
||||||
p for p in inspect.signature(func).parameters.values()
|
p for p in inspect.signature(func).parameters.values()
|
||||||
if p.kind == p.VAR_POSITIONAL
|
if p.kind == p.VAR_POSITIONAL
|
||||||
@ -114,7 +74,7 @@ def func_accepts_var_args(func):
|
|||||||
|
|
||||||
|
|
||||||
def func_has_no_args(func):
|
def func_has_no_args(func):
|
||||||
args = inspect.getargspec(func)[0] if six.PY2 else [
|
args = [
|
||||||
p for p in inspect.signature(func).parameters.values()
|
p for p in inspect.signature(func).parameters.values()
|
||||||
if p.kind == p.POSITIONAL_OR_KEYWORD
|
if p.kind == p.POSITIONAL_OR_KEYWORD
|
||||||
]
|
]
|
||||||
@ -122,8 +82,4 @@ def func_has_no_args(func):
|
|||||||
|
|
||||||
|
|
||||||
def func_supports_parameter(func, parameter):
|
def func_supports_parameter(func, parameter):
|
||||||
if six.PY3:
|
return parameter in inspect.signature(func).parameters
|
||||||
return parameter in inspect.signature(func).parameters
|
|
||||||
else:
|
|
||||||
args, varargs, varkw, defaults = inspect.getargspec(func)
|
|
||||||
return parameter in args
|
|
||||||
|
@ -2,6 +2,7 @@ import copy
|
|||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
from importlib import import_module
|
from importlib import import_module
|
||||||
|
from importlib.util import find_spec as importlib_find
|
||||||
|
|
||||||
from django.utils import six
|
from django.utils import six
|
||||||
|
|
||||||
@ -63,88 +64,17 @@ def autodiscover_modules(*args, **kwargs):
|
|||||||
raise
|
raise
|
||||||
|
|
||||||
|
|
||||||
if six.PY3:
|
def module_has_submodule(package, module_name):
|
||||||
from importlib.util import find_spec as importlib_find
|
"""See if 'module' is in 'package'."""
|
||||||
|
try:
|
||||||
|
package_name = package.__name__
|
||||||
|
package_path = package.__path__
|
||||||
|
except AttributeError:
|
||||||
|
# package isn't a package.
|
||||||
|
return False
|
||||||
|
|
||||||
def module_has_submodule(package, module_name):
|
full_module_name = package_name + '.' + module_name
|
||||||
"""See if 'module' is in 'package'."""
|
return importlib_find(full_module_name, package_path) is not None
|
||||||
try:
|
|
||||||
package_name = package.__name__
|
|
||||||
package_path = package.__path__
|
|
||||||
except AttributeError:
|
|
||||||
# package isn't a package.
|
|
||||||
return False
|
|
||||||
|
|
||||||
full_module_name = package_name + '.' + module_name
|
|
||||||
return importlib_find(full_module_name, package_path) is not None
|
|
||||||
|
|
||||||
else:
|
|
||||||
import imp
|
|
||||||
|
|
||||||
def module_has_submodule(package, module_name):
|
|
||||||
"""See if 'module' is in 'package'."""
|
|
||||||
name = ".".join([package.__name__, module_name])
|
|
||||||
try:
|
|
||||||
# None indicates a cached miss; see mark_miss() in Python/import.c.
|
|
||||||
return sys.modules[name] is not None
|
|
||||||
except KeyError:
|
|
||||||
pass
|
|
||||||
try:
|
|
||||||
package_path = package.__path__ # No __path__, then not a package.
|
|
||||||
except AttributeError:
|
|
||||||
# Since the remainder of this function assumes that we're dealing with
|
|
||||||
# a package (module with a __path__), so if it's not, then bail here.
|
|
||||||
return False
|
|
||||||
for finder in sys.meta_path:
|
|
||||||
if finder.find_module(name, package_path):
|
|
||||||
return True
|
|
||||||
for entry in package_path:
|
|
||||||
try:
|
|
||||||
# Try the cached finder.
|
|
||||||
finder = sys.path_importer_cache[entry]
|
|
||||||
if finder is None:
|
|
||||||
# Implicit import machinery should be used.
|
|
||||||
try:
|
|
||||||
file_, _, _ = imp.find_module(module_name, [entry])
|
|
||||||
if file_:
|
|
||||||
file_.close()
|
|
||||||
return True
|
|
||||||
except ImportError:
|
|
||||||
continue
|
|
||||||
# Else see if the finder knows of a loader.
|
|
||||||
elif finder.find_module(name):
|
|
||||||
return True
|
|
||||||
else:
|
|
||||||
continue
|
|
||||||
except KeyError:
|
|
||||||
# No cached finder, so try and make one.
|
|
||||||
for hook in sys.path_hooks:
|
|
||||||
try:
|
|
||||||
finder = hook(entry)
|
|
||||||
# XXX Could cache in sys.path_importer_cache
|
|
||||||
if finder.find_module(name):
|
|
||||||
return True
|
|
||||||
else:
|
|
||||||
# Once a finder is found, stop the search.
|
|
||||||
break
|
|
||||||
except ImportError:
|
|
||||||
# Continue the search for a finder.
|
|
||||||
continue
|
|
||||||
else:
|
|
||||||
# No finder found.
|
|
||||||
# Try the implicit import machinery if searching a directory.
|
|
||||||
if os.path.isdir(entry):
|
|
||||||
try:
|
|
||||||
file_, _, _ = imp.find_module(module_name, [entry])
|
|
||||||
if file_:
|
|
||||||
file_.close()
|
|
||||||
return True
|
|
||||||
except ImportError:
|
|
||||||
pass
|
|
||||||
# XXX Could insert None or NullImporter
|
|
||||||
else:
|
|
||||||
# Exhausted the search, so the module cannot be found.
|
|
||||||
return False
|
|
||||||
|
|
||||||
|
|
||||||
def module_dir(module):
|
def module_dir(module):
|
||||||
|
@ -83,12 +83,7 @@ class SafeText(six.text_type, SafeData):
|
|||||||
encode = curry(_proxy_method, method=six.text_type.encode)
|
encode = curry(_proxy_method, method=six.text_type.encode)
|
||||||
|
|
||||||
|
|
||||||
if six.PY3:
|
SafeString = SafeText
|
||||||
SafeString = SafeText
|
|
||||||
else:
|
|
||||||
SafeString = SafeBytes
|
|
||||||
# backwards compatibility for Python 2
|
|
||||||
SafeUnicode = SafeText
|
|
||||||
|
|
||||||
|
|
||||||
def _safety_decorator(safety_marker, func):
|
def _safety_decorator(safety_marker, func):
|
||||||
|
@ -12,11 +12,6 @@ from django.utils.safestring import SafeText, mark_safe
|
|||||||
from django.utils.six.moves import html_entities
|
from django.utils.six.moves import html_entities
|
||||||
from django.utils.translation import pgettext, ugettext as _, ugettext_lazy
|
from django.utils.translation import pgettext, ugettext as _, ugettext_lazy
|
||||||
|
|
||||||
if six.PY2:
|
|
||||||
# Import force_unicode even though this module doesn't use it, because some
|
|
||||||
# people rely on it being here.
|
|
||||||
from django.utils.encoding import force_unicode # NOQA
|
|
||||||
|
|
||||||
|
|
||||||
@keep_lazy_text
|
@keep_lazy_text
|
||||||
def capfirst(x):
|
def capfirst(x):
|
||||||
|
@ -5,7 +5,6 @@ from django.template.base import (
|
|||||||
TOKEN_BLOCK, TOKEN_COMMENT, TOKEN_TEXT, TOKEN_VAR, TRANSLATOR_COMMENT_MARK,
|
TOKEN_BLOCK, TOKEN_COMMENT, TOKEN_TEXT, TOKEN_VAR, TRANSLATOR_COMMENT_MARK,
|
||||||
Lexer,
|
Lexer,
|
||||||
)
|
)
|
||||||
from django.utils import six
|
|
||||||
from django.utils.encoding import force_text
|
from django.utils.encoding import force_text
|
||||||
from django.utils.six import StringIO
|
from django.utils.six import StringIO
|
||||||
|
|
||||||
@ -57,7 +56,7 @@ def templatize(src, origin=None, charset='utf-8'):
|
|||||||
comment_lineno_cache = None
|
comment_lineno_cache = None
|
||||||
# Adding the u prefix allows gettext to recognize the Unicode string
|
# Adding the u prefix allows gettext to recognize the Unicode string
|
||||||
# (#26093).
|
# (#26093).
|
||||||
raw_prefix = 'u' if six.PY3 else ''
|
raw_prefix = 'u'
|
||||||
|
|
||||||
def join_tokens(tokens, trim=False):
|
def join_tokens(tokens, trim=False):
|
||||||
message = ''.join(tokens)
|
message = ''.join(tokens)
|
||||||
|
@ -13,7 +13,7 @@ from django.conf.locale import LANG_INFO
|
|||||||
from django.core.exceptions import AppRegistryNotReady
|
from django.core.exceptions import AppRegistryNotReady
|
||||||
from django.core.signals import setting_changed
|
from django.core.signals import setting_changed
|
||||||
from django.dispatch import receiver
|
from django.dispatch import receiver
|
||||||
from django.utils import lru_cache, six
|
from django.utils import lru_cache
|
||||||
from django.utils._os import upath
|
from django.utils._os import upath
|
||||||
from django.utils.encoding import force_text
|
from django.utils.encoding import force_text
|
||||||
from django.utils.safestring import SafeData, mark_safe
|
from django.utils.safestring import SafeData, mark_safe
|
||||||
@ -336,11 +336,7 @@ def gettext(message):
|
|||||||
return do_translate(message, 'gettext')
|
return do_translate(message, 'gettext')
|
||||||
|
|
||||||
|
|
||||||
if six.PY3:
|
ugettext = gettext
|
||||||
ugettext = gettext
|
|
||||||
else:
|
|
||||||
def ugettext(message):
|
|
||||||
return do_translate(message, 'ugettext')
|
|
||||||
|
|
||||||
|
|
||||||
def pgettext(context, message):
|
def pgettext(context, message):
|
||||||
@ -384,15 +380,7 @@ def ngettext(singular, plural, number):
|
|||||||
return do_ntranslate(singular, plural, number, 'ngettext')
|
return do_ntranslate(singular, plural, number, 'ngettext')
|
||||||
|
|
||||||
|
|
||||||
if six.PY3:
|
ungettext = ngettext
|
||||||
ungettext = ngettext
|
|
||||||
else:
|
|
||||||
def ungettext(singular, plural, number):
|
|
||||||
"""
|
|
||||||
Returns a unicode strings of the translation of either the singular or
|
|
||||||
plural, based on the number.
|
|
||||||
"""
|
|
||||||
return do_ntranslate(singular, plural, number, 'ungettext')
|
|
||||||
|
|
||||||
|
|
||||||
def npgettext(context, singular, plural, number):
|
def npgettext(context, singular, plural, number):
|
||||||
|
@ -399,11 +399,9 @@ class ExceptionReporter(object):
|
|||||||
if not exceptions:
|
if not exceptions:
|
||||||
return frames
|
return frames
|
||||||
|
|
||||||
# In case there's just one exception (always in Python 2,
|
# In case there's just one exception, take the traceback from self.tb
|
||||||
# sometimes in Python 3), take the traceback from self.tb (Python 2
|
|
||||||
# doesn't have a __traceback__ attribute on Exception)
|
|
||||||
exc_value = exceptions.pop()
|
exc_value = exceptions.pop()
|
||||||
tb = self.tb if six.PY2 or not exceptions else exc_value.__traceback__
|
tb = self.tb if not exceptions else exc_value.__traceback__
|
||||||
|
|
||||||
while tb is not None:
|
while tb is not None:
|
||||||
# Support for __traceback_hide__ which is used by a few libraries
|
# Support for __traceback_hide__ which is used by a few libraries
|
||||||
@ -438,9 +436,7 @@ class ExceptionReporter(object):
|
|||||||
|
|
||||||
# If the traceback for current exception is consumed, try the
|
# If the traceback for current exception is consumed, try the
|
||||||
# other exception.
|
# other exception.
|
||||||
if six.PY2:
|
if not tb.tb_next and exceptions:
|
||||||
tb = tb.tb_next
|
|
||||||
elif not tb.tb_next and exceptions:
|
|
||||||
exc_value = exceptions.pop()
|
exc_value = exceptions.pop()
|
||||||
tb = exc_value.__traceback__
|
tb = exc_value.__traceback__
|
||||||
else:
|
else:
|
||||||
|
@ -3,7 +3,7 @@ doc_files = docs extras AUTHORS INSTALL LICENSE README.rst
|
|||||||
install-script = scripts/rpm-install.sh
|
install-script = scripts/rpm-install.sh
|
||||||
|
|
||||||
[flake8]
|
[flake8]
|
||||||
exclude = build,.git,.tox,./django/utils/lru_cache.py,./django/utils/six.py,./django/conf/app_template/*,./django/dispatch/weakref_backports.py,./tests/.env,./xmlrunner,tests/view_tests/tests/py3_test_debug.py,tests/template_tests/annotated_tag_function.py
|
exclude = build,.git,.tox,./django/utils/lru_cache.py,./django/utils/six.py,./django/conf/app_template/*,./tests/.env,./xmlrunner
|
||||||
ignore = W601
|
ignore = W601
|
||||||
max-line-length = 119
|
max-line-length = 119
|
||||||
|
|
||||||
|
@ -10,7 +10,6 @@ from django.db.models import fields
|
|||||||
from django.test import SimpleTestCase, modify_settings, override_settings
|
from django.test import SimpleTestCase, modify_settings, override_settings
|
||||||
from django.test.utils import captured_stderr
|
from django.test.utils import captured_stderr
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
from django.utils import six
|
|
||||||
|
|
||||||
from .models import Company, Person
|
from .models import Company, Person
|
||||||
from .tests import AdminDocsTestCase, TestDataMixin
|
from .tests import AdminDocsTestCase, TestDataMixin
|
||||||
@ -53,7 +52,6 @@ class AdminDocViewTests(TestDataMixin, AdminDocsTestCase):
|
|||||||
self.assertContains(response, 'Views by namespace test')
|
self.assertContains(response, 'Views by namespace test')
|
||||||
self.assertContains(response, 'Name: <code>test:func</code>.')
|
self.assertContains(response, 'Name: <code>test:func</code>.')
|
||||||
|
|
||||||
@unittest.skipIf(six.PY2, "Python 2 doesn't support __qualname__.")
|
|
||||||
def test_view_index_with_method(self):
|
def test_view_index_with_method(self):
|
||||||
"""
|
"""
|
||||||
Views that are methods are listed correctly.
|
Views that are methods are listed correctly.
|
||||||
@ -89,7 +87,7 @@ class AdminDocViewTests(TestDataMixin, AdminDocsTestCase):
|
|||||||
"""
|
"""
|
||||||
url = reverse('django-admindocs-views-detail', args=['django.contrib.admin.sites.AdminSite.index'])
|
url = reverse('django-admindocs-views-detail', args=['django.contrib.admin.sites.AdminSite.index'])
|
||||||
response = self.client.get(url)
|
response = self.client.get(url)
|
||||||
self.assertEqual(response.status_code, 200 if six.PY3 else 404)
|
self.assertEqual(response.status_code, 200)
|
||||||
|
|
||||||
def test_model_index(self):
|
def test_model_index(self):
|
||||||
response = self.client.get(reverse('django-admindocs-models-index'))
|
response = self.client.get(reverse('django-admindocs-models-index'))
|
||||||
|
@ -27,7 +27,7 @@ from django.test import (
|
|||||||
)
|
)
|
||||||
from django.utils._os import npath, upath
|
from django.utils._os import npath, upath
|
||||||
from django.utils.encoding import force_text
|
from django.utils.encoding import force_text
|
||||||
from django.utils.six import PY2, StringIO
|
from django.utils.six import StringIO
|
||||||
|
|
||||||
custom_templates_dir = os.path.join(os.path.dirname(upath(__file__)), 'custom_templates')
|
custom_templates_dir = os.path.join(os.path.dirname(upath(__file__)), 'custom_templates')
|
||||||
|
|
||||||
@ -626,7 +626,6 @@ class DjangoAdminSettingsDirectory(AdminScriptTestCase):
|
|||||||
self.assertTrue(os.path.exists(app_path))
|
self.assertTrue(os.path.exists(app_path))
|
||||||
self.assertTrue(os.path.exists(os.path.join(app_path, 'api.py')))
|
self.assertTrue(os.path.exists(os.path.join(app_path, 'api.py')))
|
||||||
|
|
||||||
@unittest.skipIf(PY2, "Python 2 doesn't support Unicode package names.")
|
|
||||||
def test_startapp_unicode_name(self):
|
def test_startapp_unicode_name(self):
|
||||||
"directory: startapp creates the correct directory with unicode characters"
|
"directory: startapp creates the correct directory with unicode characters"
|
||||||
args = ['startapp', 'こんにちは']
|
args = ['startapp', 'こんにちは']
|
||||||
@ -1897,18 +1896,11 @@ class StartProject(LiveServerTestCase, AdminScriptTestCase):
|
|||||||
self.addCleanup(shutil.rmtree, testproject_dir, True)
|
self.addCleanup(shutil.rmtree, testproject_dir, True)
|
||||||
|
|
||||||
out, err = self.run_django_admin(args)
|
out, err = self.run_django_admin(args)
|
||||||
if PY2:
|
self.assertOutput(
|
||||||
self.assertOutput(
|
err,
|
||||||
err,
|
"Error: '%s' is not a valid project name. Please make "
|
||||||
"Error: '%s' is not a valid project name. Please make "
|
"sure the name is a valid identifier." % bad_name
|
||||||
"sure the name begins with a letter or underscore." % bad_name
|
)
|
||||||
)
|
|
||||||
else:
|
|
||||||
self.assertOutput(
|
|
||||||
err,
|
|
||||||
"Error: '%s' is not a valid project name. Please make "
|
|
||||||
"sure the name is a valid identifier." % bad_name
|
|
||||||
)
|
|
||||||
self.assertFalse(os.path.exists(testproject_dir))
|
self.assertFalse(os.path.exists(testproject_dir))
|
||||||
|
|
||||||
def test_simple_project_different_directory(self):
|
def test_simple_project_different_directory(self):
|
||||||
|
@ -8,7 +8,6 @@ from django.db.models import (
|
|||||||
)
|
)
|
||||||
from django.db.models.functions import Lower
|
from django.db.models.functions import Lower
|
||||||
from django.test import TestCase, skipUnlessDBFeature
|
from django.test import TestCase, skipUnlessDBFeature
|
||||||
from django.utils import six
|
|
||||||
|
|
||||||
from .models import (
|
from .models import (
|
||||||
Author, Book, Company, DepartmentStore, Employee, Publisher, Store, Ticket,
|
Author, Book, Company, DepartmentStore, Employee, Publisher, Store, Ticket,
|
||||||
@ -24,7 +23,7 @@ def cxOracle_py3_bug(func):
|
|||||||
"""
|
"""
|
||||||
from unittest import expectedFailure
|
from unittest import expectedFailure
|
||||||
from django.db import connection
|
from django.db import connection
|
||||||
return expectedFailure(func) if connection.vendor == 'oracle' and six.PY3 else func
|
return expectedFailure(func) if connection.vendor == 'oracle' else func
|
||||||
|
|
||||||
|
|
||||||
class NonAggregateAnnotationTestCase(TestCase):
|
class NonAggregateAnnotationTestCase(TestCase):
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
import os
|
import os
|
||||||
from unittest import skipUnless
|
|
||||||
|
|
||||||
from django.apps import AppConfig, apps
|
from django.apps import AppConfig, apps
|
||||||
from django.apps.registry import Apps
|
from django.apps.registry import Apps
|
||||||
@ -8,7 +7,6 @@ from django.core.exceptions import AppRegistryNotReady, ImproperlyConfigured
|
|||||||
from django.db import models
|
from django.db import models
|
||||||
from django.test import SimpleTestCase, override_settings
|
from django.test import SimpleTestCase, override_settings
|
||||||
from django.test.utils import extend_sys_path, isolate_apps
|
from django.test.utils import extend_sys_path, isolate_apps
|
||||||
from django.utils import six
|
|
||||||
from django.utils._os import upath
|
from django.utils._os import upath
|
||||||
|
|
||||||
from .default_config_app.apps import CustomConfig
|
from .default_config_app.apps import CustomConfig
|
||||||
@ -371,7 +369,6 @@ class AppConfigTests(SimpleTestCase):
|
|||||||
self.assertEqual(ac.path, 'a')
|
self.assertEqual(ac.path, 'a')
|
||||||
|
|
||||||
|
|
||||||
@skipUnless(six.PY3, "Namespace packages sans __init__.py were added in Python 3.3")
|
|
||||||
class NamespacePackageAppTests(SimpleTestCase):
|
class NamespacePackageAppTests(SimpleTestCase):
|
||||||
# We need nsapp to be top-level so our multiple-paths tests can add another
|
# We need nsapp to be top-level so our multiple-paths tests can add another
|
||||||
# location for it (if its inside a normal package with an __init__.py that
|
# location for it (if its inside a normal package with an __init__.py that
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
import datetime
|
import datetime
|
||||||
import re
|
import re
|
||||||
from unittest import skipIf
|
|
||||||
|
|
||||||
from django import forms
|
from django import forms
|
||||||
from django.contrib.auth.forms import (
|
from django.contrib.auth.forms import (
|
||||||
@ -15,7 +14,7 @@ from django.core import mail
|
|||||||
from django.core.mail import EmailMultiAlternatives
|
from django.core.mail import EmailMultiAlternatives
|
||||||
from django.forms.fields import CharField, Field, IntegerField
|
from django.forms.fields import CharField, Field, IntegerField
|
||||||
from django.test import SimpleTestCase, TestCase, mock, override_settings
|
from django.test import SimpleTestCase, TestCase, mock, override_settings
|
||||||
from django.utils import six, translation
|
from django.utils import translation
|
||||||
from django.utils.encoding import force_text
|
from django.utils.encoding import force_text
|
||||||
from django.utils.text import capfirst
|
from django.utils.text import capfirst
|
||||||
from django.utils.translation import ugettext as _
|
from django.utils.translation import ugettext as _
|
||||||
@ -114,14 +113,10 @@ class UserCreationFormTest(TestDataMixin, TestCase):
|
|||||||
'password2': 'test123',
|
'password2': 'test123',
|
||||||
}
|
}
|
||||||
form = UserCreationForm(data)
|
form = UserCreationForm(data)
|
||||||
if six.PY3:
|
self.assertTrue(form.is_valid())
|
||||||
self.assertTrue(form.is_valid())
|
u = form.save()
|
||||||
u = form.save()
|
self.assertEqual(u.username, '宝')
|
||||||
self.assertEqual(u.username, '宝')
|
|
||||||
else:
|
|
||||||
self.assertFalse(form.is_valid())
|
|
||||||
|
|
||||||
@skipIf(six.PY2, "Python 2 doesn't support unicode usernames by default.")
|
|
||||||
def test_normalize_username(self):
|
def test_normalize_username(self):
|
||||||
# The normalization happens in AbstractBaseUser.clean() and ModelForm
|
# The normalization happens in AbstractBaseUser.clean() and ModelForm
|
||||||
# validation calls Model.clean().
|
# validation calls Model.clean().
|
||||||
@ -137,7 +132,6 @@ class UserCreationFormTest(TestDataMixin, TestCase):
|
|||||||
self.assertNotEqual(user.username, ohm_username)
|
self.assertNotEqual(user.username, ohm_username)
|
||||||
self.assertEqual(user.username, 'testΩ') # U+03A9 GREEK CAPITAL LETTER OMEGA
|
self.assertEqual(user.username, 'testΩ') # U+03A9 GREEK CAPITAL LETTER OMEGA
|
||||||
|
|
||||||
@skipIf(six.PY2, "Python 2 doesn't support unicode usernames by default.")
|
|
||||||
def test_duplicate_normalized_unicode(self):
|
def test_duplicate_normalized_unicode(self):
|
||||||
"""
|
"""
|
||||||
To prevent almost identical usernames, visually identical but differing
|
To prevent almost identical usernames, visually identical but differing
|
||||||
|
@ -32,9 +32,6 @@ def mock_inputs(inputs):
|
|||||||
class mock_getpass:
|
class mock_getpass:
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def getpass(prompt=b'Password: ', stream=None):
|
def getpass(prompt=b'Password: ', stream=None):
|
||||||
if six.PY2:
|
|
||||||
# getpass on Windows only supports prompt as bytestring (#19807)
|
|
||||||
assert isinstance(prompt, six.binary_type)
|
|
||||||
if callable(inputs['password']):
|
if callable(inputs['password']):
|
||||||
return inputs['password']()
|
return inputs['password']()
|
||||||
return inputs['password']
|
return inputs['password']
|
||||||
|
@ -1,11 +1,9 @@
|
|||||||
import unittest
|
|
||||||
from datetime import date, timedelta
|
from datetime import date, timedelta
|
||||||
|
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.contrib.auth.models import User
|
from django.contrib.auth.models import User
|
||||||
from django.contrib.auth.tokens import PasswordResetTokenGenerator
|
from django.contrib.auth.tokens import PasswordResetTokenGenerator
|
||||||
from django.test import TestCase
|
from django.test import TestCase
|
||||||
from django.utils.six import PY3
|
|
||||||
|
|
||||||
|
|
||||||
class TokenGeneratorTest(TestCase):
|
class TokenGeneratorTest(TestCase):
|
||||||
@ -51,18 +49,6 @@ class TokenGeneratorTest(TestCase):
|
|||||||
p2 = Mocked(date.today() + timedelta(settings.PASSWORD_RESET_TIMEOUT_DAYS + 1))
|
p2 = Mocked(date.today() + timedelta(settings.PASSWORD_RESET_TIMEOUT_DAYS + 1))
|
||||||
self.assertFalse(p2.check_token(user, tk1))
|
self.assertFalse(p2.check_token(user, tk1))
|
||||||
|
|
||||||
@unittest.skipIf(PY3, "Unnecessary test with Python 3")
|
|
||||||
def test_date_length(self):
|
|
||||||
"""
|
|
||||||
Overly long dates, which are a potential DoS vector, aren't allowed.
|
|
||||||
"""
|
|
||||||
user = User.objects.create_user('ima1337h4x0r', 'test4@example.com', 'p4ssw0rd')
|
|
||||||
p0 = PasswordResetTokenGenerator()
|
|
||||||
|
|
||||||
# This will put a 14-digit base36 timestamp into the token, which is too large.
|
|
||||||
with self.assertRaises(ValueError):
|
|
||||||
p0._make_token_with_timestamp(user, 175455491841851871349)
|
|
||||||
|
|
||||||
def test_check_token_with_nonexistent_token_and_user(self):
|
def test_check_token_with_nonexistent_token_and_user(self):
|
||||||
user = User.objects.create_user('tokentestuser', 'test2@example.com', 'testpw')
|
user = User.objects.create_user('tokentestuser', 'test2@example.com', 'testpw')
|
||||||
p0 = PasswordResetTokenGenerator()
|
p0 = PasswordResetTokenGenerator()
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
from django.core.exceptions import ImproperlyConfigured
|
from django.core.exceptions import ImproperlyConfigured
|
||||||
from django.db.utils import load_backend
|
from django.db.utils import load_backend
|
||||||
from django.test import SimpleTestCase
|
from django.test import SimpleTestCase
|
||||||
from django.utils import six
|
|
||||||
|
|
||||||
|
|
||||||
class TestLoadBackend(SimpleTestCase):
|
class TestLoadBackend(SimpleTestCase):
|
||||||
@ -10,7 +9,7 @@ class TestLoadBackend(SimpleTestCase):
|
|||||||
"'foo' isn't an available database backend.\n"
|
"'foo' isn't an available database backend.\n"
|
||||||
"Try using 'django.db.backends.XXX', where XXX is one of:\n"
|
"Try using 'django.db.backends.XXX', where XXX is one of:\n"
|
||||||
" 'mysql', 'oracle', 'postgresql', 'sqlite3'\n"
|
" 'mysql', 'oracle', 'postgresql', 'sqlite3'\n"
|
||||||
"Error was: No module named %s"
|
"Error was: No module named 'foo'"
|
||||||
) % "foo.base" if six.PY2 else "'foo'"
|
)
|
||||||
with self.assertRaisesMessage(ImproperlyConfigured, msg):
|
with self.assertRaisesMessage(ImproperlyConfigured, msg):
|
||||||
load_backend('foo')
|
load_backend('foo')
|
||||||
|
@ -13,12 +13,3 @@ class CustomBaseModel(models.base.ModelBase):
|
|||||||
|
|
||||||
class MyModel(six.with_metaclass(CustomBaseModel, models.Model)):
|
class MyModel(six.with_metaclass(CustomBaseModel, models.Model)):
|
||||||
"""Model subclass with a custom base using six.with_metaclass."""
|
"""Model subclass with a custom base using six.with_metaclass."""
|
||||||
|
|
||||||
|
|
||||||
# This is done to ensure that for Python2 only, defining metaclasses
|
|
||||||
# still does not fail to create the model.
|
|
||||||
|
|
||||||
if six.PY2:
|
|
||||||
class MyPython2Model(models.Model):
|
|
||||||
"""Model subclass with a custom base using __metaclass__."""
|
|
||||||
__metaclass__ = CustomBaseModel
|
|
||||||
|
6
tests/cache/tests.py
vendored
6
tests/cache/tests.py
vendored
@ -928,11 +928,7 @@ class BaseCacheTests(object):
|
|||||||
self.assertEqual(cache.get_or_set('mykey', my_callable()), 'value')
|
self.assertEqual(cache.get_or_set('mykey', my_callable()), 'value')
|
||||||
|
|
||||||
def test_get_or_set_version(self):
|
def test_get_or_set_version(self):
|
||||||
msg = (
|
msg = "get_or_set() missing 1 required positional argument: 'default'"
|
||||||
"get_or_set() missing 1 required positional argument: 'default'"
|
|
||||||
if six.PY3
|
|
||||||
else 'get_or_set() takes at least 3 arguments'
|
|
||||||
)
|
|
||||||
cache.get_or_set('brian', 1979, version=2)
|
cache.get_or_set('brian', 1979, version=2)
|
||||||
with self.assertRaisesMessage(TypeError, msg):
|
with self.assertRaisesMessage(TypeError, msg):
|
||||||
cache.get_or_set('brian')
|
cache.get_or_set('brian')
|
||||||
|
@ -3,7 +3,6 @@ import os
|
|||||||
|
|
||||||
from django.db.backends.postgresql.client import DatabaseClient
|
from django.db.backends.postgresql.client import DatabaseClient
|
||||||
from django.test import SimpleTestCase, mock
|
from django.test import SimpleTestCase, mock
|
||||||
from django.utils import six
|
|
||||||
from django.utils.encoding import force_bytes, force_str
|
from django.utils.encoding import force_bytes, force_str
|
||||||
|
|
||||||
|
|
||||||
@ -91,16 +90,12 @@ class PostgreSqlDbshellCommandTestCase(SimpleTestCase):
|
|||||||
encoding = locale.getpreferredencoding()
|
encoding = locale.getpreferredencoding()
|
||||||
username = 'rôle'
|
username = 'rôle'
|
||||||
password = 'sésame'
|
password = 'sésame'
|
||||||
try:
|
username_str = force_str(username, encoding)
|
||||||
username_str = force_str(username, encoding)
|
password_str = force_str(password, encoding)
|
||||||
password_str = force_str(password, encoding)
|
pgpass_bytes = force_bytes(
|
||||||
pgpass_bytes = force_bytes(
|
'somehost:444:dbname:%s:%s' % (username, password),
|
||||||
'somehost:444:dbname:%s:%s' % (username, password),
|
encoding=encoding,
|
||||||
encoding=encoding,
|
)
|
||||||
)
|
|
||||||
except UnicodeEncodeError:
|
|
||||||
if six.PY2:
|
|
||||||
self.skipTest("Your locale can't run this test.")
|
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
self._run_it({
|
self._run_it({
|
||||||
'database': 'dbname',
|
'database': 'dbname',
|
||||||
|
@ -15,7 +15,7 @@ from django.http.multipartparser import MultiPartParser, parse_header
|
|||||||
from django.test import SimpleTestCase, TestCase, client, override_settings
|
from django.test import SimpleTestCase, TestCase, client, override_settings
|
||||||
from django.utils.encoding import force_bytes
|
from django.utils.encoding import force_bytes
|
||||||
from django.utils.http import urlquote
|
from django.utils.http import urlquote
|
||||||
from django.utils.six import PY2, StringIO
|
from django.utils.six import StringIO
|
||||||
|
|
||||||
from . import uploadhandler
|
from . import uploadhandler
|
||||||
from .models import FileModel
|
from .models import FileModel
|
||||||
@ -102,9 +102,7 @@ class FileUploadTests(TestCase):
|
|||||||
self._test_base64_upload("Big data" * 68000) # > 512Kb
|
self._test_base64_upload("Big data" * 68000) # > 512Kb
|
||||||
|
|
||||||
def test_big_base64_newlines_upload(self):
|
def test_big_base64_newlines_upload(self):
|
||||||
self._test_base64_upload(
|
self._test_base64_upload("Big data" * 68000, encode=base64.encodebytes)
|
||||||
# encodestring is a deprecated alias on Python 3
|
|
||||||
"Big data" * 68000, encode=base64.encodestring if PY2 else base64.encodebytes)
|
|
||||||
|
|
||||||
def test_unicode_file_name(self):
|
def test_unicode_file_name(self):
|
||||||
tdir = sys_tempfile.mkdtemp()
|
tdir = sys_tempfile.mkdtemp()
|
||||||
|
@ -181,10 +181,7 @@ class ContentFileTestCase(unittest.TestCase):
|
|||||||
retrieved content is of the same type.
|
retrieved content is of the same type.
|
||||||
"""
|
"""
|
||||||
self.assertIsInstance(ContentFile(b"content").read(), bytes)
|
self.assertIsInstance(ContentFile(b"content").read(), bytes)
|
||||||
if six.PY3:
|
self.assertIsInstance(ContentFile("español").read(), six.text_type)
|
||||||
self.assertIsInstance(ContentFile("español").read(), six.text_type)
|
|
||||||
else:
|
|
||||||
self.assertIsInstance(ContentFile("español").read(), bytes)
|
|
||||||
|
|
||||||
|
|
||||||
class DimensionClosingBug(unittest.TestCase):
|
class DimensionClosingBug(unittest.TestCase):
|
||||||
|
@ -2,10 +2,8 @@
|
|||||||
import json
|
import json
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
import unittest
|
|
||||||
import warnings
|
import warnings
|
||||||
|
|
||||||
import django
|
|
||||||
from django.core import management, serializers
|
from django.core import management, serializers
|
||||||
from django.core.exceptions import ImproperlyConfigured
|
from django.core.exceptions import ImproperlyConfigured
|
||||||
from django.core.serializers.base import DeserializationError
|
from django.core.serializers.base import DeserializationError
|
||||||
@ -15,9 +13,8 @@ from django.test import (
|
|||||||
TestCase, TransactionTestCase, override_settings, skipIfDBFeature,
|
TestCase, TransactionTestCase, override_settings, skipIfDBFeature,
|
||||||
skipUnlessDBFeature,
|
skipUnlessDBFeature,
|
||||||
)
|
)
|
||||||
from django.utils import six
|
|
||||||
from django.utils._os import upath
|
from django.utils._os import upath
|
||||||
from django.utils.six import PY3, StringIO
|
from django.utils.six import StringIO
|
||||||
|
|
||||||
from .models import (
|
from .models import (
|
||||||
Absolute, Animal, Article, Book, Child, Circle1, Circle2, Circle3,
|
Absolute, Animal, Article, Book, Child, Circle1, Circle2, Circle3,
|
||||||
@ -32,16 +29,6 @@ from .models import (
|
|||||||
_cur_dir = os.path.dirname(os.path.abspath(upath(__file__)))
|
_cur_dir = os.path.dirname(os.path.abspath(upath(__file__)))
|
||||||
|
|
||||||
|
|
||||||
def is_ascii(s):
|
|
||||||
return all(ord(c) < 128 for c in s)
|
|
||||||
|
|
||||||
|
|
||||||
skipIfNonASCIIPath = unittest.skipIf(
|
|
||||||
not is_ascii(django.__file__) and six.PY2,
|
|
||||||
'Python 2 crashes when checking non-ASCII exception messages.'
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
class TestFixtures(TestCase):
|
class TestFixtures(TestCase):
|
||||||
|
|
||||||
def animal_pre_save_check(self, signal, sender, instance, **kwargs):
|
def animal_pre_save_check(self, signal, sender, instance, **kwargs):
|
||||||
@ -205,7 +192,6 @@ class TestFixtures(TestCase):
|
|||||||
verbosity=0,
|
verbosity=0,
|
||||||
)
|
)
|
||||||
|
|
||||||
@skipIfNonASCIIPath
|
|
||||||
@override_settings(SERIALIZATION_MODULES={'unkn': 'unexistent.path'})
|
@override_settings(SERIALIZATION_MODULES={'unkn': 'unexistent.path'})
|
||||||
def test_unimportable_serializer(self):
|
def test_unimportable_serializer(self):
|
||||||
"""
|
"""
|
||||||
@ -350,8 +336,8 @@ class TestFixtures(TestCase):
|
|||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
self.pre_save_checks,
|
self.pre_save_checks,
|
||||||
[
|
[
|
||||||
("Count = 42 (<%s 'int'>)" % ('class' if PY3 else 'type'),
|
("Count = 42 (<class 'int'>)",
|
||||||
"Weight = 1.2 (<%s 'float'>)" % ('class' if PY3 else 'type'))
|
"Weight = 1.2 (<class 'float'>)")
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
finally:
|
finally:
|
||||||
@ -531,7 +517,6 @@ class TestFixtures(TestCase):
|
|||||||
with self.assertRaisesMessage(ImproperlyConfigured, "settings.FIXTURE_DIRS contains duplicates."):
|
with self.assertRaisesMessage(ImproperlyConfigured, "settings.FIXTURE_DIRS contains duplicates."):
|
||||||
management.call_command('loaddata', 'absolute.json', verbosity=0)
|
management.call_command('loaddata', 'absolute.json', verbosity=0)
|
||||||
|
|
||||||
@skipIfNonASCIIPath
|
|
||||||
@override_settings(FIXTURE_DIRS=[os.path.join(_cur_dir, 'fixtures')])
|
@override_settings(FIXTURE_DIRS=[os.path.join(_cur_dir, 'fixtures')])
|
||||||
def test_fixture_dirs_with_default_fixture_path(self):
|
def test_fixture_dirs_with_default_fixture_path(self):
|
||||||
"""
|
"""
|
||||||
|
@ -34,7 +34,7 @@ class HandlerTests(SimpleTestCase):
|
|||||||
produces a 404.
|
produces a 404.
|
||||||
"""
|
"""
|
||||||
environ = RequestFactory().get('/').environ
|
environ = RequestFactory().get('/').environ
|
||||||
environ['PATH_INFO'] = b'\xed' if six.PY2 else '\xed'
|
environ['PATH_INFO'] = '\xed'
|
||||||
handler = WSGIHandler()
|
handler = WSGIHandler()
|
||||||
response = handler(environ, lambda *a, **k: None)
|
response = handler(environ, lambda *a, **k: None)
|
||||||
# The path of the request will be encoded to '/%ED'.
|
# The path of the request will be encoded to '/%ED'.
|
||||||
@ -53,25 +53,17 @@ class HandlerTests(SimpleTestCase):
|
|||||||
]
|
]
|
||||||
got = []
|
got = []
|
||||||
for raw_query_string in raw_query_strings:
|
for raw_query_string in raw_query_strings:
|
||||||
if six.PY3:
|
# Simulate http.server.BaseHTTPRequestHandler.parse_request handling of raw request
|
||||||
# Simulate http.server.BaseHTTPRequestHandler.parse_request handling of raw request
|
environ['QUERY_STRING'] = str(raw_query_string, 'iso-8859-1')
|
||||||
environ['QUERY_STRING'] = str(raw_query_string, 'iso-8859-1')
|
|
||||||
else:
|
|
||||||
environ['QUERY_STRING'] = raw_query_string
|
|
||||||
request = WSGIRequest(environ)
|
request = WSGIRequest(environ)
|
||||||
got.append(request.GET['want'])
|
got.append(request.GET['want'])
|
||||||
if six.PY2:
|
# %E9 is converted to the unicode replacement character by parse_qsl
|
||||||
self.assertListEqual(got, ['café', 'café', 'café', 'café'])
|
self.assertListEqual(got, ['café', 'café', 'caf\ufffd', 'café'])
|
||||||
else:
|
|
||||||
# On Python 3, %E9 is converted to the unicode replacement character by parse_qsl
|
|
||||||
self.assertListEqual(got, ['café', 'café', 'caf\ufffd', 'café'])
|
|
||||||
|
|
||||||
def test_non_ascii_cookie(self):
|
def test_non_ascii_cookie(self):
|
||||||
"""Non-ASCII cookies set in JavaScript are properly decoded (#20557)."""
|
"""Non-ASCII cookies set in JavaScript are properly decoded (#20557)."""
|
||||||
environ = RequestFactory().get('/').environ
|
environ = RequestFactory().get('/').environ
|
||||||
raw_cookie = 'want="café"'
|
raw_cookie = 'want="café"'.encode('utf-8').decode('iso-8859-1')
|
||||||
if six.PY3:
|
|
||||||
raw_cookie = raw_cookie.encode('utf-8').decode('iso-8859-1')
|
|
||||||
environ['HTTP_COOKIE'] = raw_cookie
|
environ['HTTP_COOKIE'] = raw_cookie
|
||||||
request = WSGIRequest(environ)
|
request = WSGIRequest(environ)
|
||||||
# If would be nicer if request.COOKIES returned unicode values.
|
# If would be nicer if request.COOKIES returned unicode values.
|
||||||
|
@ -55,8 +55,6 @@ class QueryDictTests(SimpleTestCase):
|
|||||||
def test_immutable_basic_operations(self):
|
def test_immutable_basic_operations(self):
|
||||||
q = QueryDict()
|
q = QueryDict()
|
||||||
self.assertEqual(q.getlist('foo'), [])
|
self.assertEqual(q.getlist('foo'), [])
|
||||||
if six.PY2:
|
|
||||||
self.assertIs(q.has_key('foo'), False)
|
|
||||||
self.assertNotIn('foo', q)
|
self.assertNotIn('foo', q)
|
||||||
self.assertEqual(list(six.iteritems(q)), [])
|
self.assertEqual(list(six.iteritems(q)), [])
|
||||||
self.assertEqual(list(six.iterlists(q)), [])
|
self.assertEqual(list(six.iterlists(q)), [])
|
||||||
@ -85,11 +83,7 @@ class QueryDictTests(SimpleTestCase):
|
|||||||
with self.assertRaises(AttributeError):
|
with self.assertRaises(AttributeError):
|
||||||
q.appendlist('foo', ['bar'])
|
q.appendlist('foo', ['bar'])
|
||||||
|
|
||||||
if six.PY2:
|
|
||||||
self.assertTrue(q.has_key('foo'))
|
|
||||||
self.assertIn('foo', q)
|
self.assertIn('foo', q)
|
||||||
if six.PY2:
|
|
||||||
self.assertFalse(q.has_key('bar'))
|
|
||||||
self.assertNotIn('bar', q)
|
self.assertNotIn('bar', q)
|
||||||
|
|
||||||
self.assertEqual(list(six.iteritems(q)), [('foo', 'bar')])
|
self.assertEqual(list(six.iteritems(q)), [('foo', 'bar')])
|
||||||
@ -150,8 +144,6 @@ class QueryDictTests(SimpleTestCase):
|
|||||||
q.appendlist('foo', 'another')
|
q.appendlist('foo', 'another')
|
||||||
self.assertEqual(q.getlist('foo'), ['bar', 'baz', 'another'])
|
self.assertEqual(q.getlist('foo'), ['bar', 'baz', 'another'])
|
||||||
self.assertEqual(q['foo'], 'another')
|
self.assertEqual(q['foo'], 'another')
|
||||||
if six.PY2:
|
|
||||||
self.assertTrue(q.has_key('foo'))
|
|
||||||
self.assertIn('foo', q)
|
self.assertIn('foo', q)
|
||||||
|
|
||||||
self.assertListEqual(sorted(six.iteritems(q)),
|
self.assertListEqual(sorted(six.iteritems(q)),
|
||||||
@ -199,11 +191,7 @@ class QueryDictTests(SimpleTestCase):
|
|||||||
with self.assertRaises(AttributeError):
|
with self.assertRaises(AttributeError):
|
||||||
q.appendlist('foo', ['bar'])
|
q.appendlist('foo', ['bar'])
|
||||||
|
|
||||||
if six.PY2:
|
|
||||||
self.assertIs(q.has_key('vote'), True)
|
|
||||||
self.assertIn('vote', q)
|
self.assertIn('vote', q)
|
||||||
if six.PY2:
|
|
||||||
self.assertIs(q.has_key('foo'), False)
|
|
||||||
self.assertNotIn('foo', q)
|
self.assertNotIn('foo', q)
|
||||||
self.assertEqual(list(six.iteritems(q)), [('vote', 'no')])
|
self.assertEqual(list(six.iteritems(q)), [('vote', 'no')])
|
||||||
self.assertEqual(list(six.iterlists(q)), [('vote', ['yes', 'no'])])
|
self.assertEqual(list(six.iterlists(q)), [('vote', ['yes', 'no'])])
|
||||||
@ -224,19 +212,6 @@ class QueryDictTests(SimpleTestCase):
|
|||||||
with self.assertRaises(AttributeError):
|
with self.assertRaises(AttributeError):
|
||||||
q.__delitem__('vote')
|
q.__delitem__('vote')
|
||||||
|
|
||||||
if six.PY2:
|
|
||||||
def test_invalid_input_encoding(self):
|
|
||||||
"""
|
|
||||||
QueryDicts must be able to handle invalid input encoding (in this
|
|
||||||
case, bad UTF-8 encoding), falling back to ISO-8859-1 decoding.
|
|
||||||
|
|
||||||
This test doesn't apply under Python 3 because the URL is a string
|
|
||||||
and not a bytestring.
|
|
||||||
"""
|
|
||||||
q = QueryDict(str(b'foo=bar&foo=\xff'))
|
|
||||||
self.assertEqual(q['foo'], '\xff')
|
|
||||||
self.assertEqual(q.getlist('foo'), ['bar', '\xff'])
|
|
||||||
|
|
||||||
def test_pickle(self):
|
def test_pickle(self):
|
||||||
q = QueryDict()
|
q = QueryDict()
|
||||||
q1 = pickle.loads(pickle.dumps(q, 2))
|
q1 = pickle.loads(pickle.dumps(q, 2))
|
||||||
@ -807,15 +782,6 @@ class CookieTests(unittest.TestCase):
|
|||||||
c.load({'name': 'val'})
|
c.load({'name': 'val'})
|
||||||
self.assertEqual(c['name'].value, 'val')
|
self.assertEqual(c['name'].value, 'val')
|
||||||
|
|
||||||
@unittest.skipUnless(six.PY2, "PY3 throws an exception on invalid cookie keys.")
|
|
||||||
def test_bad_cookie(self):
|
|
||||||
"""
|
|
||||||
Regression test for #18403
|
|
||||||
"""
|
|
||||||
r = HttpResponse()
|
|
||||||
r.set_cookie("a:.b/", 1)
|
|
||||||
self.assertEqual(len(r.cookies.bad_cookies), 1)
|
|
||||||
|
|
||||||
def test_pickle(self):
|
def test_pickle(self):
|
||||||
rawdata = 'Customer="WILE_E_COYOTE"; Path=/acme; Version=1'
|
rawdata = 'Customer="WILE_E_COYOTE"; Path=/acme; Version=1'
|
||||||
expected_output = 'Set-Cookie: %s' % rawdata
|
expected_output = 'Set-Cookie: %s' % rawdata
|
||||||
|
@ -12,7 +12,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, mock, override_settings
|
from django.test import SimpleTestCase, mock, override_settings
|
||||||
from django.test.utils import captured_stderr, captured_stdout
|
from django.test.utils import captured_stderr, captured_stdout
|
||||||
from django.utils import six, translation
|
from django.utils import translation
|
||||||
from django.utils.encoding import force_text
|
from django.utils.encoding import force_text
|
||||||
from django.utils.six import StringIO
|
from django.utils.six import StringIO
|
||||||
from django.utils.translation import ugettext
|
from django.utils.translation import ugettext
|
||||||
@ -144,18 +144,11 @@ class CompilationErrorHandling(MessageCompilationTests):
|
|||||||
env = os.environ.copy()
|
env = os.environ.copy()
|
||||||
env.update({str('LANG'): str('C')})
|
env.update({str('LANG'): str('C')})
|
||||||
with mock.patch('django.core.management.utils.Popen', lambda *args, **kwargs: Popen(*args, env=env, **kwargs)):
|
with mock.patch('django.core.management.utils.Popen', lambda *args, **kwargs: Popen(*args, env=env, **kwargs)):
|
||||||
if six.PY2:
|
cmd = MakeMessagesCommand()
|
||||||
# Various assertRaises on PY2 don't support unicode error messages.
|
if cmd.gettext_version < (0, 18, 3):
|
||||||
try:
|
self.skipTest("python-brace-format is a recent gettext addition.")
|
||||||
call_command('compilemessages', locale=['ko'], verbosity=0)
|
with self.assertRaisesMessage(CommandError, "' cannot start a field name"):
|
||||||
except CommandError as err:
|
call_command('compilemessages', locale=['ko'], verbosity=0)
|
||||||
self.assertIn("' cannot start a field name", six.text_type(err))
|
|
||||||
else:
|
|
||||||
cmd = MakeMessagesCommand()
|
|
||||||
if cmd.gettext_version < (0, 18, 3):
|
|
||||||
self.skipTest("python-brace-format is a recent gettext addition.")
|
|
||||||
with self.assertRaisesMessage(CommandError, "' cannot start a field name"):
|
|
||||||
call_command('compilemessages', locale=['ko'], verbosity=0)
|
|
||||||
|
|
||||||
|
|
||||||
class ProjectAndAppTests(MessageCompilationTests):
|
class ProjectAndAppTests(MessageCompilationTests):
|
||||||
|
@ -6,7 +6,6 @@ import pickle
|
|||||||
from contextlib import contextmanager
|
from contextlib import contextmanager
|
||||||
from importlib import import_module
|
from importlib import import_module
|
||||||
from threading import local
|
from threading import local
|
||||||
from unittest import skipUnless
|
|
||||||
|
|
||||||
from django import forms
|
from django import forms
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
@ -23,13 +22,11 @@ from django.utils.formats import (
|
|||||||
)
|
)
|
||||||
from django.utils.numberformat import format as nformat
|
from django.utils.numberformat import format as nformat
|
||||||
from django.utils.safestring import SafeBytes, SafeText
|
from django.utils.safestring import SafeBytes, SafeText
|
||||||
from django.utils.six import PY3
|
|
||||||
from django.utils.translation import (
|
from django.utils.translation import (
|
||||||
LANGUAGE_SESSION_KEY, activate, check_for_language, deactivate,
|
LANGUAGE_SESSION_KEY, activate, check_for_language, deactivate,
|
||||||
get_language, get_language_from_request, get_language_info, gettext,
|
get_language, get_language_from_request, get_language_info, gettext_lazy,
|
||||||
gettext_lazy, ngettext_lazy, npgettext, npgettext_lazy, pgettext,
|
ngettext_lazy, npgettext, npgettext_lazy, pgettext, trans_real, ugettext,
|
||||||
pgettext_lazy, trans_real, ugettext, ugettext_lazy, ungettext,
|
ugettext_lazy, ungettext, ungettext_lazy,
|
||||||
ungettext_lazy,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
from .forms import CompanyForm, I18nForm, SelectDateForm
|
from .forms import CompanyForm, I18nForm, SelectDateForm
|
||||||
@ -141,33 +138,6 @@ class TranslationTests(SimpleTestCase):
|
|||||||
s4 = ugettext_lazy('Some other string')
|
s4 = ugettext_lazy('Some other string')
|
||||||
self.assertNotEqual(s, s4)
|
self.assertNotEqual(s, s4)
|
||||||
|
|
||||||
@skipUnless(six.PY2, "No more bytestring translations on PY3")
|
|
||||||
def test_bytestrings(self):
|
|
||||||
"""gettext() returns a bytestring if input is bytestring."""
|
|
||||||
|
|
||||||
# Using repr() to check translated text and type
|
|
||||||
self.assertEqual(repr(gettext(b"Time")), repr(b"Time"))
|
|
||||||
self.assertEqual(repr(gettext("Time")), repr("Time"))
|
|
||||||
|
|
||||||
with translation.override('de', deactivate=True):
|
|
||||||
self.assertEqual(repr(gettext(b"Time")), repr(b"Zeit"))
|
|
||||||
self.assertEqual(repr(gettext("Time")), repr(b"Zeit"))
|
|
||||||
|
|
||||||
@skipUnless(six.PY2, "No more bytestring translations on PY3")
|
|
||||||
def test_lazy_and_bytestrings(self):
|
|
||||||
# On Python 2, (n)gettext_lazy should not transform a bytestring to unicode
|
|
||||||
self.assertEqual(gettext_lazy(b"test").upper(), b"TEST")
|
|
||||||
self.assertEqual((ngettext_lazy(b"%d test", b"%d tests") % 1).upper(), b"1 TEST")
|
|
||||||
|
|
||||||
# Other versions of lazy functions always return unicode
|
|
||||||
self.assertEqual(ugettext_lazy(b"test").upper(), "TEST")
|
|
||||||
self.assertEqual((ungettext_lazy(b"%d test", b"%d tests") % 1).upper(), "1 TEST")
|
|
||||||
self.assertEqual(pgettext_lazy(b"context", b"test").upper(), "TEST")
|
|
||||||
self.assertEqual(
|
|
||||||
(npgettext_lazy(b"context", b"%d test", b"%d tests") % 1).upper(),
|
|
||||||
"1 TEST"
|
|
||||||
)
|
|
||||||
|
|
||||||
def test_lazy_pickle(self):
|
def test_lazy_pickle(self):
|
||||||
s1 = ugettext_lazy("test")
|
s1 = ugettext_lazy("test")
|
||||||
self.assertEqual(six.text_type(s1), "test")
|
self.assertEqual(six.text_type(s1), "test")
|
||||||
@ -223,20 +193,6 @@ class TranslationTests(SimpleTestCase):
|
|||||||
with self.assertRaisesMessage(KeyError, 'Your dictionary lacks key'):
|
with self.assertRaisesMessage(KeyError, 'Your dictionary lacks key'):
|
||||||
complex_context_deferred % {'name': 'Jim'}
|
complex_context_deferred % {'name': 'Jim'}
|
||||||
|
|
||||||
@skipUnless(six.PY2, "PY3 doesn't have distinct int and long types")
|
|
||||||
def test_ungettext_lazy_long(self):
|
|
||||||
"""
|
|
||||||
Regression test for #22820: int and long should be treated alike in ungettext_lazy.
|
|
||||||
"""
|
|
||||||
result = ungettext_lazy('%(name)s has %(num)d good result', '%(name)s has %(num)d good results', 4)
|
|
||||||
self.assertEqual(result % {'name': 'Joe', 'num': 4}, "Joe has 4 good results")
|
|
||||||
# Now with a long
|
|
||||||
result = ungettext_lazy(
|
|
||||||
'%(name)s has %(num)d good result', '%(name)s has %(num)d good results',
|
|
||||||
long(4) # NOQA: long undefined on PY3
|
|
||||||
)
|
|
||||||
self.assertEqual(result % {'name': 'Joe', 'num': 4}, "Joe has 4 good results")
|
|
||||||
|
|
||||||
def test_ungettext_lazy_bool(self):
|
def test_ungettext_lazy_bool(self):
|
||||||
self.assertTrue(ungettext_lazy('%d good result', '%d good results'))
|
self.assertTrue(ungettext_lazy('%d good result', '%d good results'))
|
||||||
self.assertFalse(ungettext_lazy('', ''))
|
self.assertFalse(ungettext_lazy('', ''))
|
||||||
@ -298,7 +254,7 @@ class FormattingTests(SimpleTestCase):
|
|||||||
self.d = datetime.date(2009, 12, 31)
|
self.d = datetime.date(2009, 12, 31)
|
||||||
self.dt = datetime.datetime(2009, 12, 31, 20, 50)
|
self.dt = datetime.datetime(2009, 12, 31, 20, 50)
|
||||||
self.t = datetime.time(10, 15, 48)
|
self.t = datetime.time(10, 15, 48)
|
||||||
self.long = 10000 if PY3 else long(10000) # NOQA: long undefined on PY3
|
self.long = 10000
|
||||||
self.ctxt = Context({
|
self.ctxt = Context({
|
||||||
'n': self.n,
|
'n': self.n,
|
||||||
't': self.t,
|
't': self.t,
|
||||||
|
@ -5,7 +5,7 @@ from django.core.management import call_command
|
|||||||
from django.db import connection
|
from django.db import connection
|
||||||
from django.test import TestCase, mock, skipUnlessDBFeature
|
from django.test import TestCase, mock, skipUnlessDBFeature
|
||||||
from django.utils.encoding import force_text
|
from django.utils.encoding import force_text
|
||||||
from django.utils.six import PY3, StringIO
|
from django.utils.six import StringIO
|
||||||
|
|
||||||
from .models import ColumnTypes
|
from .models import ColumnTypes
|
||||||
|
|
||||||
@ -196,11 +196,7 @@ class InspectDBTestCase(TestCase):
|
|||||||
self.assertIn("field_field_0 = models.IntegerField(db_column='%s__')" % base_name, output)
|
self.assertIn("field_field_0 = models.IntegerField(db_column='%s__')" % base_name, output)
|
||||||
self.assertIn("field_field_1 = models.IntegerField(db_column='__field')", output)
|
self.assertIn("field_field_1 = models.IntegerField(db_column='__field')", output)
|
||||||
self.assertIn("prc_x = models.IntegerField(db_column='prc(%) x')", output)
|
self.assertIn("prc_x = models.IntegerField(db_column='prc(%) x')", output)
|
||||||
if PY3:
|
self.assertIn("tamaño = models.IntegerField()", output)
|
||||||
# Python 3 allows non-ASCII identifiers
|
|
||||||
self.assertIn("tamaño = models.IntegerField()", output)
|
|
||||||
else:
|
|
||||||
self.assertIn("tama_o = models.IntegerField(db_column='tama\\xf1o')", output)
|
|
||||||
|
|
||||||
def test_table_name_introspection(self):
|
def test_table_name_introspection(self):
|
||||||
"""
|
"""
|
||||||
|
@ -3,7 +3,6 @@ from django.db import models
|
|||||||
from django.db.models.fields.related import ForeignObject
|
from django.db.models.fields.related import ForeignObject
|
||||||
from django.test.testcases import SimpleTestCase, skipIfDBFeature
|
from django.test.testcases import SimpleTestCase, skipIfDBFeature
|
||||||
from django.test.utils import isolate_apps, override_settings
|
from django.test.utils import isolate_apps, override_settings
|
||||||
from django.utils import six
|
|
||||||
|
|
||||||
|
|
||||||
@isolate_apps('invalid_models_tests')
|
@isolate_apps('invalid_models_tests')
|
||||||
@ -655,10 +654,8 @@ class RelativeFieldTests(SimpleTestCase):
|
|||||||
'with', # a Python keyword
|
'with', # a Python keyword
|
||||||
'related_name\n',
|
'related_name\n',
|
||||||
'',
|
'',
|
||||||
|
',', # non-ASCII
|
||||||
]
|
]
|
||||||
# Python 2 crashes on non-ASCII strings.
|
|
||||||
if six.PY3:
|
|
||||||
invalid_related_names.append(',')
|
|
||||||
|
|
||||||
class Parent(models.Model):
|
class Parent(models.Model):
|
||||||
pass
|
pass
|
||||||
@ -695,10 +692,9 @@ class RelativeFieldTests(SimpleTestCase):
|
|||||||
'ends_with_plus+',
|
'ends_with_plus+',
|
||||||
'_+',
|
'_+',
|
||||||
'+',
|
'+',
|
||||||
|
'試',
|
||||||
|
'試驗+',
|
||||||
]
|
]
|
||||||
# Python 2 crashes on non-ASCII strings.
|
|
||||||
if six.PY3:
|
|
||||||
related_names.extend(['試', '試驗+'])
|
|
||||||
|
|
||||||
class Parent(models.Model):
|
class Parent(models.Model):
|
||||||
pass
|
pass
|
||||||
|
@ -8,8 +8,10 @@ import socket
|
|||||||
import sys
|
import sys
|
||||||
import tempfile
|
import tempfile
|
||||||
import threading
|
import threading
|
||||||
|
from email import message_from_binary_file, message_from_bytes
|
||||||
from email.header import Header
|
from email.header import Header
|
||||||
from email.mime.text import MIMEText
|
from email.mime.text import MIMEText
|
||||||
|
from email.utils import parseaddr
|
||||||
from smtplib import SMTP, SMTPAuthenticationError, SMTPException
|
from smtplib import SMTP, SMTPAuthenticationError, SMTPException
|
||||||
from ssl import SSLError
|
from ssl import SSLError
|
||||||
|
|
||||||
@ -24,19 +26,9 @@ from django.test import SimpleTestCase, override_settings
|
|||||||
from django.test.utils import requires_tz_support
|
from django.test.utils import requires_tz_support
|
||||||
from django.utils._os import upath
|
from django.utils._os import upath
|
||||||
from django.utils.encoding import force_bytes, force_text
|
from django.utils.encoding import force_bytes, force_text
|
||||||
from django.utils.six import PY3, StringIO, binary_type
|
from django.utils.six import StringIO, binary_type
|
||||||
from django.utils.translation import ugettext_lazy
|
from django.utils.translation import ugettext_lazy
|
||||||
|
|
||||||
if PY3:
|
|
||||||
from email.utils import parseaddr
|
|
||||||
from email import message_from_bytes, message_from_binary_file
|
|
||||||
else:
|
|
||||||
from email.Utils import parseaddr
|
|
||||||
from email import (
|
|
||||||
message_from_string as message_from_bytes,
|
|
||||||
message_from_file as message_from_binary_file,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
class HeadersCheckMixin(object):
|
class HeadersCheckMixin(object):
|
||||||
|
|
||||||
@ -656,16 +648,10 @@ class MailTests(HeadersCheckMixin, SimpleTestCase):
|
|||||||
sanitize_address(('A name', 'to@example.com'), 'ascii'),
|
sanitize_address(('A name', 'to@example.com'), 'ascii'),
|
||||||
'A name <to@example.com>'
|
'A name <to@example.com>'
|
||||||
)
|
)
|
||||||
if PY3:
|
self.assertEqual(
|
||||||
self.assertEqual(
|
sanitize_address(('A name', 'to@example.com'), 'utf-8'),
|
||||||
sanitize_address(('A name', 'to@example.com'), 'utf-8'),
|
'=?utf-8?q?A_name?= <to@example.com>'
|
||||||
'=?utf-8?q?A_name?= <to@example.com>'
|
)
|
||||||
)
|
|
||||||
else:
|
|
||||||
self.assertEqual(
|
|
||||||
sanitize_address(('A name', 'to@example.com'), 'utf-8'),
|
|
||||||
'A name <to@example.com>'
|
|
||||||
)
|
|
||||||
|
|
||||||
# Unicode characters are are supported in RFC-6532.
|
# Unicode characters are are supported in RFC-6532.
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
@ -1165,18 +1151,8 @@ class FakeSMTPServer(smtpd.SMTPServer, threading.Thread):
|
|||||||
self.active_lock = threading.Lock()
|
self.active_lock = threading.Lock()
|
||||||
self.sink_lock = threading.Lock()
|
self.sink_lock = threading.Lock()
|
||||||
|
|
||||||
if not PY3:
|
|
||||||
def handle_accept(self):
|
|
||||||
# copy of Python 2.7 smtpd.SMTPServer.handle_accept with hardcoded
|
|
||||||
# SMTPChannel replaced by self.channel_class
|
|
||||||
pair = self.accept()
|
|
||||||
if pair is not None:
|
|
||||||
conn, addr = pair
|
|
||||||
self.channel_class(self, conn, addr)
|
|
||||||
|
|
||||||
def process_message(self, peer, mailfrom, rcpttos, data):
|
def process_message(self, peer, mailfrom, rcpttos, data):
|
||||||
if PY3:
|
data = data.encode('utf-8')
|
||||||
data = data.encode('utf-8')
|
|
||||||
m = message_from_bytes(data)
|
m = message_from_bytes(data)
|
||||||
maddr = parseaddr(m.get('from'))[1]
|
maddr = parseaddr(m.get('from'))[1]
|
||||||
|
|
||||||
@ -1448,8 +1424,7 @@ class SMTPBackendTests(BaseEmailBackendTests, SMTPBackendTestsBase):
|
|||||||
|
|
||||||
self.assertTrue(msg)
|
self.assertTrue(msg)
|
||||||
|
|
||||||
if PY3:
|
msg = msg.decode('utf-8')
|
||||||
msg = msg.decode('utf-8')
|
|
||||||
# The message only contains CRLF and not combinations of CRLF, LF, and CR.
|
# The message only contains CRLF and not combinations of CRLF, LF, and CR.
|
||||||
msg = msg.replace('\r\n', '')
|
msg = msg.replace('\r\n', '')
|
||||||
self.assertNotIn('\r', msg)
|
self.assertNotIn('\r', msg)
|
||||||
|
@ -2,7 +2,6 @@ import gzip
|
|||||||
import random
|
import random
|
||||||
import re
|
import re
|
||||||
from io import BytesIO
|
from io import BytesIO
|
||||||
from unittest import skipIf
|
|
||||||
|
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.core import mail
|
from django.core import mail
|
||||||
@ -401,24 +400,6 @@ class BrokenLinkEmailsMiddlewareTest(SimpleTestCase):
|
|||||||
BrokenLinkEmailsMiddleware().process_response(self.req, self.resp)
|
BrokenLinkEmailsMiddleware().process_response(self.req, self.resp)
|
||||||
self.assertEqual(len(mail.outbox), 0)
|
self.assertEqual(len(mail.outbox), 0)
|
||||||
|
|
||||||
@skipIf(six.PY3, "HTTP_REFERER is str type on Python 3")
|
|
||||||
def test_404_error_nonascii_referrer(self):
|
|
||||||
# Such referer strings should not happen, but anyway, if it happens,
|
|
||||||
# let's not crash
|
|
||||||
self.req.META['HTTP_REFERER'] = b'http://testserver/c/\xd0\xbb\xd0\xb8/'
|
|
||||||
BrokenLinkEmailsMiddleware().process_response(self.req, self.resp)
|
|
||||||
self.assertEqual(len(mail.outbox), 1)
|
|
||||||
|
|
||||||
@skipIf(six.PY3, "HTTP_USER_AGENT is str type on Python 3")
|
|
||||||
def test_404_error_nonascii_user_agent(self):
|
|
||||||
# Such user agent strings should not happen, but anyway, if it happens,
|
|
||||||
# let's not crash
|
|
||||||
self.req.META['HTTP_REFERER'] = '/another/url/'
|
|
||||||
self.req.META['HTTP_USER_AGENT'] = b'\xd0\xbb\xd0\xb8\xff\xff'
|
|
||||||
BrokenLinkEmailsMiddleware().process_response(self.req, self.resp)
|
|
||||||
self.assertEqual(len(mail.outbox), 1)
|
|
||||||
self.assertIn('User agent: \u043b\u0438\ufffd\ufffd\n', mail.outbox[0].body)
|
|
||||||
|
|
||||||
def test_custom_request_checker(self):
|
def test_custom_request_checker(self):
|
||||||
class SubclassedMiddleware(BrokenLinkEmailsMiddleware):
|
class SubclassedMiddleware(BrokenLinkEmailsMiddleware):
|
||||||
ignored_user_agent_patterns = (re.compile(r'Spider.*'), re.compile(r'Robot.*'))
|
ignored_user_agent_patterns = (re.compile(r'Spider.*'), re.compile(r'Robot.*'))
|
||||||
|
@ -661,18 +661,10 @@ class MakeMigrationsTests(MigrationTestBase):
|
|||||||
self.assertIn('migrations.CreateModel', content)
|
self.assertIn('migrations.CreateModel', content)
|
||||||
self.assertIn('initial = True', content)
|
self.assertIn('initial = True', content)
|
||||||
|
|
||||||
if six.PY3:
|
self.assertIn('úñí©óðé µóðéø', content) # Meta.verbose_name
|
||||||
self.assertIn('úñí©óðé µóðéø', content) # Meta.verbose_name
|
self.assertIn('úñí©óðé µóðéøß', content) # Meta.verbose_name_plural
|
||||||
self.assertIn('úñí©óðé µóðéøß', content) # Meta.verbose_name_plural
|
self.assertIn('ÚÑÍ¢ÓÐÉ', content) # title.verbose_name
|
||||||
self.assertIn('ÚÑÍ¢ÓÐÉ', content) # title.verbose_name
|
self.assertIn('“Ðjáñgó”', content) # title.default
|
||||||
self.assertIn('“Ðjáñgó”', content) # title.default
|
|
||||||
else:
|
|
||||||
# Meta.verbose_name
|
|
||||||
self.assertIn('\\xfa\\xf1\\xed\\xa9\\xf3\\xf0\\xe9 \\xb5\\xf3\\xf0\\xe9\\xf8', content)
|
|
||||||
# Meta.verbose_name_plural
|
|
||||||
self.assertIn('\\xfa\\xf1\\xed\\xa9\\xf3\\xf0\\xe9 \\xb5\\xf3\\xf0\\xe9\\xf8\\xdf', content)
|
|
||||||
self.assertIn('\\xda\\xd1\\xcd\\xa2\\xd3\\xd0\\xc9', content) # title.verbose_name
|
|
||||||
self.assertIn('\\u201c\\xd0j\\xe1\\xf1g\\xf3\\u201d', content) # title.default
|
|
||||||
|
|
||||||
def test_makemigrations_order(self):
|
def test_makemigrations_order(self):
|
||||||
"""
|
"""
|
||||||
|
@ -1,5 +1,3 @@
|
|||||||
from unittest import skipIf
|
|
||||||
|
|
||||||
from django.db import connection, connections
|
from django.db import connection, connections
|
||||||
from django.db.migrations.exceptions import (
|
from django.db.migrations.exceptions import (
|
||||||
AmbiguityError, InconsistentMigrationHistory, NodeNotFoundError,
|
AmbiguityError, InconsistentMigrationHistory, NodeNotFoundError,
|
||||||
@ -7,7 +5,6 @@ from django.db.migrations.exceptions import (
|
|||||||
from django.db.migrations.loader import MigrationLoader
|
from django.db.migrations.loader import MigrationLoader
|
||||||
from django.db.migrations.recorder import MigrationRecorder
|
from django.db.migrations.recorder import MigrationRecorder
|
||||||
from django.test import TestCase, modify_settings, override_settings
|
from django.test import TestCase, modify_settings, override_settings
|
||||||
from django.utils import six
|
|
||||||
|
|
||||||
|
|
||||||
class RecorderTests(TestCase):
|
class RecorderTests(TestCase):
|
||||||
@ -170,7 +167,6 @@ class LoaderTests(TestCase):
|
|||||||
"App with migrations module file not in unmigrated apps."
|
"App with migrations module file not in unmigrated apps."
|
||||||
)
|
)
|
||||||
|
|
||||||
@skipIf(six.PY2, "PY2 doesn't load empty dirs.")
|
|
||||||
def test_load_empty_dir(self):
|
def test_load_empty_dir(self):
|
||||||
with override_settings(MIGRATION_MODULES={"migrations": "migrations.faulty_migrations.namespace"}):
|
with override_settings(MIGRATION_MODULES={"migrations": "migrations.faulty_migrations.namespace"}):
|
||||||
loader = MigrationLoader(connection)
|
loader = MigrationLoader(connection)
|
||||||
|
@ -47,12 +47,6 @@ 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):
|
||||||
@ -486,15 +480,6 @@ class WriterTests(SimpleTestCase):
|
|||||||
self.assertEqual(string, 'range')
|
self.assertEqual(string, 'range')
|
||||||
self.assertEqual(imports, set())
|
self.assertEqual(imports, set())
|
||||||
|
|
||||||
@unittest.skipUnless(six.PY2, "Only applies on Python 2")
|
|
||||||
def test_serialize_direct_function_reference(self):
|
|
||||||
"""
|
|
||||||
Ticket #22436: You cannot use a function straight from its body
|
|
||||||
(e.g. define the method and use it in the same body)
|
|
||||||
"""
|
|
||||||
with self.assertRaises(ValueError):
|
|
||||||
self.serialize_round_trip(TestModel1.thing)
|
|
||||||
|
|
||||||
def test_serialize_local_function_reference(self):
|
def test_serialize_local_function_reference(self):
|
||||||
"""
|
"""
|
||||||
Neither py2 or py3 can serialize a reference in a local scope.
|
Neither py2 or py3 can serialize a reference in a local scope.
|
||||||
|
@ -1,13 +1,12 @@
|
|||||||
import datetime
|
import datetime
|
||||||
import unittest
|
|
||||||
from decimal import Decimal
|
from decimal import Decimal
|
||||||
|
|
||||||
from django.db.models.fields import (
|
from django.db.models.fields import (
|
||||||
AutoField, BigIntegerField, BinaryField, BooleanField, CharField,
|
AutoField, BinaryField, BooleanField, CharField, DateField, DateTimeField,
|
||||||
DateField, DateTimeField, DecimalField, EmailField, FilePathField,
|
DecimalField, EmailField, FilePathField, FloatField, GenericIPAddressField,
|
||||||
FloatField, GenericIPAddressField, IntegerField, IPAddressField,
|
IntegerField, IPAddressField, NullBooleanField, PositiveIntegerField,
|
||||||
NullBooleanField, PositiveIntegerField, PositiveSmallIntegerField,
|
PositiveSmallIntegerField, SlugField, SmallIntegerField, TextField,
|
||||||
SlugField, SmallIntegerField, TextField, TimeField, URLField,
|
TimeField, URLField,
|
||||||
)
|
)
|
||||||
from django.db.models.fields.files import FileField, ImageField
|
from django.db.models.fields.files import FileField, ImageField
|
||||||
from django.test import SimpleTestCase
|
from django.test import SimpleTestCase
|
||||||
@ -21,11 +20,6 @@ class PromiseTest(SimpleTestCase):
|
|||||||
lazy_func = lazy(lambda: 1, int)
|
lazy_func = lazy(lambda: 1, int)
|
||||||
self.assertIsInstance(AutoField(primary_key=True).get_prep_value(lazy_func()), int)
|
self.assertIsInstance(AutoField(primary_key=True).get_prep_value(lazy_func()), int)
|
||||||
|
|
||||||
@unittest.skipIf(six.PY3, 'Python 3 has no `long` type.')
|
|
||||||
def test_BigIntegerField(self):
|
|
||||||
lazy_func = lazy(lambda: long(9999999999999999999), long) # NOQA: long undefined on PY3
|
|
||||||
self.assertIsInstance(BigIntegerField().get_prep_value(lazy_func()), long) # NOQA
|
|
||||||
|
|
||||||
def test_BinaryField(self):
|
def test_BinaryField(self):
|
||||||
lazy_func = lazy(lambda: b'', bytes)
|
lazy_func = lazy(lambda: b'', bytes)
|
||||||
self.assertIsInstance(BinaryField().get_prep_value(lazy_func()), bytes)
|
self.assertIsInstance(BinaryField().get_prep_value(lazy_func()), bytes)
|
||||||
|
@ -1,18 +1,11 @@
|
|||||||
import os
|
import os
|
||||||
import shutil
|
import shutil
|
||||||
import unittest
|
|
||||||
|
|
||||||
from django import conf
|
from django import conf
|
||||||
from django.test import TestCase
|
from django.test import TestCase
|
||||||
from django.utils import six
|
|
||||||
from django.utils._os import upath
|
from django.utils._os import upath
|
||||||
|
|
||||||
|
|
||||||
@unittest.skipIf(
|
|
||||||
six.PY2,
|
|
||||||
'Python 2 cannot import the project template because '
|
|
||||||
'django/conf/project_template doesn\'t have an __init__.py file.'
|
|
||||||
)
|
|
||||||
class TestStartProjectSettings(TestCase):
|
class TestStartProjectSettings(TestCase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
# Ensure settings.py exists
|
# Ensure settings.py exists
|
||||||
|
@ -11,7 +11,6 @@ from django.db.models.sql.constants import LOUTER
|
|||||||
from django.db.models.sql.where import NothingNode, WhereNode
|
from django.db.models.sql.where import NothingNode, WhereNode
|
||||||
from django.test import TestCase, skipUnlessDBFeature
|
from django.test import TestCase, skipUnlessDBFeature
|
||||||
from django.test.utils import CaptureQueriesContext
|
from django.test.utils import CaptureQueriesContext
|
||||||
from django.utils import six
|
|
||||||
from django.utils.six.moves import range
|
from django.utils.six.moves import range
|
||||||
|
|
||||||
from .models import (
|
from .models import (
|
||||||
@ -406,7 +405,7 @@ class Queries1Tests(TestCase):
|
|||||||
local_recursion_limit = 127
|
local_recursion_limit = 127
|
||||||
msg = 'Maximum recursion depth exceeded: too many subqueries.'
|
msg = 'Maximum recursion depth exceeded: too many subqueries.'
|
||||||
with self.assertRaisesMessage(RuntimeError, msg):
|
with self.assertRaisesMessage(RuntimeError, msg):
|
||||||
for i in six.moves.range(local_recursion_limit * 2):
|
for i in range(local_recursion_limit * 2):
|
||||||
x = Tag.objects.filter(pk__in=x)
|
x = Tag.objects.filter(pk__in=x)
|
||||||
|
|
||||||
def test_reasonable_number_of_subq_aliases(self):
|
def test_reasonable_number_of_subq_aliases(self):
|
||||||
@ -2249,25 +2248,6 @@ class QuerySetSupportsPythonIdioms(TestCase):
|
|||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
|
||||||
@unittest.skipUnless(six.PY2, "Python 2 only -- Python 3 doesn't have longs.")
|
|
||||||
def test_slicing_works_with_longs(self):
|
|
||||||
# NOQA: long undefined on PY3
|
|
||||||
self.assertEqual(self.get_ordered_articles()[long(0)].name, 'Article 1') # NOQA
|
|
||||||
self.assertQuerysetEqual(self.get_ordered_articles()[long(1):long(3)], # NOQA
|
|
||||||
["<Article: Article 2>", "<Article: Article 3>"])
|
|
||||||
self.assertQuerysetEqual(
|
|
||||||
self.get_ordered_articles()[::long(2)], [ # NOQA
|
|
||||||
"<Article: Article 1>",
|
|
||||||
"<Article: Article 3>",
|
|
||||||
"<Article: Article 5>",
|
|
||||||
"<Article: Article 7>"
|
|
||||||
]
|
|
||||||
)
|
|
||||||
|
|
||||||
# And can be mixed with ints.
|
|
||||||
self.assertQuerysetEqual(self.get_ordered_articles()[1:long(3)], # NOQA
|
|
||||||
["<Article: Article 2>", "<Article: Article 3>"])
|
|
||||||
|
|
||||||
def test_slicing_without_step_is_lazy(self):
|
def test_slicing_without_step_is_lazy(self):
|
||||||
with self.assertNumQueries(0):
|
with self.assertNumQueries(0):
|
||||||
self.get_ordered_articles()[0:5]
|
self.get_ordered_articles()[0:5]
|
||||||
@ -2965,8 +2945,6 @@ class QuerySetExceptionTests(TestCase):
|
|||||||
|
|
||||||
def test_invalid_order_by(self):
|
def test_invalid_order_by(self):
|
||||||
msg = "Invalid order_by arguments: ['*']"
|
msg = "Invalid order_by arguments: ['*']"
|
||||||
if six.PY2:
|
|
||||||
msg = msg.replace("[", "[u")
|
|
||||||
with self.assertRaisesMessage(FieldError, msg):
|
with self.assertRaisesMessage(FieldError, msg):
|
||||||
list(Article.objects.order_by('*'))
|
list(Article.objects.order_by('*'))
|
||||||
|
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
import datetime
|
import datetime
|
||||||
|
|
||||||
from django.db import DJANGO_VERSION_PICKLE_KEY, models
|
from django.db import DJANGO_VERSION_PICKLE_KEY, models
|
||||||
from django.utils import six
|
|
||||||
from django.utils.translation import ugettext_lazy as _
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
|
||||||
|
|
||||||
@ -45,9 +44,7 @@ class Happening(models.Model):
|
|||||||
when = models.DateTimeField(blank=True, default=datetime.datetime.now)
|
when = models.DateTimeField(blank=True, default=datetime.datetime.now)
|
||||||
name = models.CharField(blank=True, max_length=100, default="test")
|
name = models.CharField(blank=True, max_length=100, default="test")
|
||||||
number1 = models.IntegerField(blank=True, default=standalone_number)
|
number1 = models.IntegerField(blank=True, default=standalone_number)
|
||||||
if six.PY3:
|
number2 = models.IntegerField(blank=True, default=Numbers.get_static_number)
|
||||||
# default serializable on Python 3 only
|
|
||||||
number2 = models.IntegerField(blank=True, default=Numbers.get_static_number)
|
|
||||||
|
|
||||||
|
|
||||||
class Container(object):
|
class Container(object):
|
||||||
|
@ -1,10 +1,8 @@
|
|||||||
import datetime
|
import datetime
|
||||||
import pickle
|
import pickle
|
||||||
import unittest
|
|
||||||
|
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from django.test import TestCase
|
from django.test import TestCase
|
||||||
from django.utils import six
|
|
||||||
from django.utils.version import get_version
|
from django.utils.version import get_version
|
||||||
|
|
||||||
from .models import Container, Event, Group, Happening, M2MModel
|
from .models import Container, Event, Group, Happening, M2MModel
|
||||||
@ -33,7 +31,6 @@ class PickleabilityTestCase(TestCase):
|
|||||||
def test_standalone_method_as_default(self):
|
def test_standalone_method_as_default(self):
|
||||||
self.assert_pickles(Happening.objects.filter(number1=1))
|
self.assert_pickles(Happening.objects.filter(number1=1))
|
||||||
|
|
||||||
@unittest.skipIf(six.PY2, "Field doesn't exist on Python 2.")
|
|
||||||
def test_staticmethod_as_default(self):
|
def test_staticmethod_as_default(self):
|
||||||
self.assert_pickles(Happening.objects.filter(number2=1))
|
self.assert_pickles(Happening.objects.filter(number2=1))
|
||||||
|
|
||||||
|
@ -12,7 +12,6 @@ from django.http.request import split_domain_port
|
|||||||
from django.test import RequestFactory, SimpleTestCase, override_settings
|
from django.test import RequestFactory, SimpleTestCase, override_settings
|
||||||
from django.test.client import FakePayload
|
from django.test.client import FakePayload
|
||||||
from django.test.utils import freeze_time, str_prefix
|
from django.test.utils import freeze_time, str_prefix
|
||||||
from django.utils import six
|
|
||||||
from django.utils.encoding import force_str
|
from django.utils.encoding import force_str
|
||||||
from django.utils.http import cookie_date, urlencode
|
from django.utils.http import cookie_date, urlencode
|
||||||
from django.utils.six.moves import http_cookies
|
from django.utils.six.moves import http_cookies
|
||||||
@ -168,9 +167,8 @@ class RequestsTests(SimpleTestCase):
|
|||||||
|
|
||||||
def test_wsgirequest_path_info(self):
|
def test_wsgirequest_path_info(self):
|
||||||
def wsgi_str(path_info, encoding='utf-8'):
|
def wsgi_str(path_info, encoding='utf-8'):
|
||||||
path_info = path_info.encode(encoding) # Actual URL sent by the browser (bytestring)
|
path_info = path_info.encode(encoding) # Actual URL sent by the browser (bytestring)
|
||||||
if six.PY3:
|
path_info = path_info.decode('iso-8859-1') # Value in the WSGI environ dict (native string)
|
||||||
path_info = path_info.decode('iso-8859-1') # Value in the WSGI environ dict (native string)
|
|
||||||
return path_info
|
return path_info
|
||||||
# Regression for #19468
|
# Regression for #19468
|
||||||
request = WSGIRequest({'PATH_INFO': wsgi_str("/سلام/"), 'REQUEST_METHOD': 'get', 'wsgi.input': BytesIO(b'')})
|
request = WSGIRequest({'PATH_INFO': wsgi_str("/سلام/"), 'REQUEST_METHOD': 'get', 'wsgi.input': BytesIO(b'')})
|
||||||
@ -583,7 +581,7 @@ class RequestsTests(SimpleTestCase):
|
|||||||
request = WSGIRequest({
|
request = WSGIRequest({
|
||||||
'REQUEST_METHOD': 'GET',
|
'REQUEST_METHOD': 'GET',
|
||||||
'wsgi.input': '',
|
'wsgi.input': '',
|
||||||
'QUERY_STRING': b'name=Hello%20G%C3%BCnter' if six.PY2 else 'name=Hello%20G%C3%BCnter'
|
'QUERY_STRING': 'name=Hello%20G%C3%BCnter',
|
||||||
})
|
})
|
||||||
self.assertEqual(request.GET, {'name': ['Hello Günter']})
|
self.assertEqual(request.GET, {'name': ['Hello Günter']})
|
||||||
request.encoding = 'iso-8859-16'
|
request.encoding = 'iso-8859-16'
|
||||||
|
@ -3,7 +3,6 @@ import datetime
|
|||||||
from django.core import signing
|
from django.core import signing
|
||||||
from django.test import SimpleTestCase
|
from django.test import SimpleTestCase
|
||||||
from django.test.utils import freeze_time
|
from django.test.utils import freeze_time
|
||||||
from django.utils import six
|
|
||||||
from django.utils.encoding import force_str
|
from django.utils.encoding import force_str
|
||||||
|
|
||||||
|
|
||||||
@ -45,8 +44,6 @@ class TestSigner(SimpleTestCase):
|
|||||||
'jkw osanteuh ,rcuh nthu aou oauh ,ud du',
|
'jkw osanteuh ,rcuh nthu aou oauh ,ud du',
|
||||||
'\u2019',
|
'\u2019',
|
||||||
]
|
]
|
||||||
if six.PY2:
|
|
||||||
examples.append(b'a byte string')
|
|
||||||
for example in examples:
|
for example in examples:
|
||||||
signed = signer.sign(example)
|
signed = signer.sign(example)
|
||||||
self.assertIsInstance(signed, str)
|
self.assertIsInstance(signed, str)
|
||||||
@ -76,8 +73,6 @@ class TestSigner(SimpleTestCase):
|
|||||||
'a unicode string \u2019',
|
'a unicode string \u2019',
|
||||||
{'a': 'dictionary'},
|
{'a': 'dictionary'},
|
||||||
]
|
]
|
||||||
if six.PY2:
|
|
||||||
objects.append(b'a byte string')
|
|
||||||
for o in objects:
|
for o in objects:
|
||||||
self.assertNotEqual(o, signing.dumps(o))
|
self.assertNotEqual(o, signing.dumps(o))
|
||||||
self.assertEqual(o, signing.loads(signing.dumps(o)))
|
self.assertEqual(o, signing.loads(signing.dumps(o)))
|
||||||
|
@ -183,8 +183,7 @@ class TestInteractiveMessages(CollectionTestCase):
|
|||||||
@staticmethod
|
@staticmethod
|
||||||
def mock_input(stdout):
|
def mock_input(stdout):
|
||||||
def _input(msg):
|
def _input(msg):
|
||||||
# Python 2 reads bytes from the console output, use bytes for the StringIO
|
stdout.write(msg)
|
||||||
stdout.write(msg.encode('utf-8') if six.PY2 else msg)
|
|
||||||
return 'yes'
|
return 'yes'
|
||||||
return _input
|
return _input
|
||||||
|
|
||||||
|
@ -1,31 +1,16 @@
|
|||||||
"""
|
"""
|
||||||
Adding __str__() or __unicode__() to models
|
Adding __str__() to models
|
||||||
|
|
||||||
Although it's not a strict requirement, each model should have a
|
Although it's not a strict requirement, each model should have a ``_str__()``
|
||||||
``_str__()`` or ``__unicode__()`` method to return a "human-readable"
|
method to return a "human-readable" representation of the object. Do this not
|
||||||
representation of the object. Do this not only for your own sanity when dealing
|
only for your own sanity when dealing with the interactive prompt, but also
|
||||||
with the interactive prompt, but also because objects' representations are used
|
because objects' representations are used throughout Django's
|
||||||
throughout Django's automatically-generated admin.
|
automatically-generated admin.
|
||||||
|
|
||||||
Normally, you should write ``__unicode__()`` method, since this will work for
|
|
||||||
all field types (and Django will automatically provide an appropriate
|
|
||||||
``__str__()`` method). However, you can write a ``__str__()`` method directly,
|
|
||||||
if you prefer. You must be careful to encode the results correctly, though.
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from django.db import models
|
from django.db import models
|
||||||
|
|
||||||
|
|
||||||
class Article(models.Model):
|
|
||||||
headline = models.CharField(max_length=100)
|
|
||||||
pub_date = models.DateTimeField()
|
|
||||||
|
|
||||||
def __str__(self):
|
|
||||||
# Caution: this is only safe if you are certain that headline will be
|
|
||||||
# in ASCII.
|
|
||||||
return self.headline
|
|
||||||
|
|
||||||
|
|
||||||
class InternationalArticle(models.Model):
|
class InternationalArticle(models.Model):
|
||||||
headline = models.CharField(max_length=100)
|
headline = models.CharField(max_length=100)
|
||||||
pub_date = models.DateTimeField()
|
pub_date = models.DateTimeField()
|
||||||
|
@ -1,25 +1,14 @@
|
|||||||
import datetime
|
import datetime
|
||||||
from unittest import skipIf
|
|
||||||
|
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from django.test import TestCase
|
from django.test import TestCase
|
||||||
from django.test.utils import isolate_apps
|
from django.test.utils import isolate_apps
|
||||||
from django.utils import six
|
|
||||||
|
|
||||||
from .models import Article, InternationalArticle
|
from .models import InternationalArticle
|
||||||
|
|
||||||
|
|
||||||
class SimpleTests(TestCase):
|
class SimpleTests(TestCase):
|
||||||
|
|
||||||
@skipIf(six.PY3, "tests a __str__ method returning unicode under Python 2")
|
|
||||||
def test_basic(self):
|
|
||||||
a = Article.objects.create(
|
|
||||||
headline=b'Parrot programs in Python',
|
|
||||||
pub_date=datetime.datetime(2005, 7, 28)
|
|
||||||
)
|
|
||||||
self.assertEqual(str(a), str('Parrot programs in Python'))
|
|
||||||
self.assertEqual(repr(a), str('<Article: Parrot programs in Python>'))
|
|
||||||
|
|
||||||
def test_international(self):
|
def test_international(self):
|
||||||
a = InternationalArticle.objects.create(
|
a = InternationalArticle.objects.create(
|
||||||
headline='Girl wins €12.500 in lottery',
|
headline='Girl wins €12.500 in lottery',
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
from django.template import TemplateSyntaxError
|
from django.template import TemplateSyntaxError
|
||||||
from django.test import SimpleTestCase
|
from django.test import SimpleTestCase
|
||||||
from django.utils import six
|
|
||||||
|
|
||||||
from ..utils import setup
|
from ..utils import setup
|
||||||
|
|
||||||
@ -36,11 +35,10 @@ class WidthRatioTagTests(SimpleTestCase):
|
|||||||
@setup({'widthratio06': '{% widthratio a b 100 %}'})
|
@setup({'widthratio06': '{% widthratio a b 100 %}'})
|
||||||
def test_widthratio06(self):
|
def test_widthratio06(self):
|
||||||
"""
|
"""
|
||||||
62.5 should round to 63 on Python 2 and 62 on Python 3
|
62.5 should round to 62
|
||||||
See http://docs.python.org/py3k/whatsnew/3.0.html
|
|
||||||
"""
|
"""
|
||||||
output = self.engine.render_to_string('widthratio06', {'a': 50, 'b': 80})
|
output = self.engine.render_to_string('widthratio06', {'a': 50, 'b': 80})
|
||||||
self.assertEqual(output, '62' if six.PY3 else '63')
|
self.assertEqual(output, '62')
|
||||||
|
|
||||||
@setup({'widthratio07': '{% widthratio a b 100 %}'})
|
@setup({'widthratio07': '{% widthratio a b 100 %}'})
|
||||||
def test_widthratio07(self):
|
def test_widthratio07(self):
|
||||||
|
@ -1,12 +1,10 @@
|
|||||||
import os
|
import os
|
||||||
from unittest import skipUnless
|
|
||||||
|
|
||||||
from django.template import Context, Engine, TemplateSyntaxError
|
from django.template import Context, Engine, TemplateSyntaxError
|
||||||
from django.template.base import Node
|
from django.template.base import Node
|
||||||
from django.template.library import InvalidTemplateLibrary
|
from django.template.library import InvalidTemplateLibrary
|
||||||
from django.test import SimpleTestCase
|
from django.test import SimpleTestCase
|
||||||
from django.test.utils import extend_sys_path
|
from django.test.utils import extend_sys_path
|
||||||
from django.utils import six
|
|
||||||
|
|
||||||
from .templatetags import custom, inclusion
|
from .templatetags import custom, inclusion
|
||||||
from .utils import ROOT
|
from .utils import ROOT
|
||||||
@ -344,7 +342,6 @@ class TemplateTagLoadingTests(SimpleTestCase):
|
|||||||
})
|
})
|
||||||
engine.from_string(ttext)
|
engine.from_string(ttext)
|
||||||
|
|
||||||
@skipUnless(six.PY3, "Python 3 only -- Python 2 doesn't have annotations.")
|
|
||||||
def test_load_annotated_function(self):
|
def test_load_annotated_function(self):
|
||||||
Engine(libraries={
|
Engine(libraries={
|
||||||
'annotated_tag_function': 'template_tests.annotated_tag_function',
|
'annotated_tag_function': 'template_tests.annotated_tag_function',
|
||||||
|
@ -7,7 +7,6 @@ from contextlib import contextmanager
|
|||||||
from django.template import TemplateDoesNotExist
|
from django.template import TemplateDoesNotExist
|
||||||
from django.template.engine import Engine
|
from django.template.engine import Engine
|
||||||
from django.test import SimpleTestCase, override_settings
|
from django.test import SimpleTestCase, override_settings
|
||||||
from django.utils import six
|
|
||||||
from django.utils.functional import lazystr
|
from django.utils.functional import lazystr
|
||||||
|
|
||||||
from .utils import TEMPLATE_DIR
|
from .utils import TEMPLATE_DIR
|
||||||
@ -64,7 +63,6 @@ class CachedLoaderTests(SimpleTestCase):
|
|||||||
self.assertIsInstance(e, TemplateDoesNotExist)
|
self.assertIsInstance(e, TemplateDoesNotExist)
|
||||||
self.assertEqual(e.args[0], 'debug-template-missing.html')
|
self.assertEqual(e.args[0], 'debug-template-missing.html')
|
||||||
|
|
||||||
@unittest.skipIf(six.PY2, "Python 2 doesn't set extra exception attributes")
|
|
||||||
def test_cached_exception_no_traceback(self):
|
def test_cached_exception_no_traceback(self):
|
||||||
"""
|
"""
|
||||||
When a TemplateDoesNotExist instance is cached, the cached instance
|
When a TemplateDoesNotExist instance is cached, the cached instance
|
||||||
|
@ -2,7 +2,6 @@ from unittest import TestCase
|
|||||||
|
|
||||||
from django.template import Context, Engine
|
from django.template import Context, Engine
|
||||||
from django.template.base import TextNode, VariableNode
|
from django.template.base import TextNode, VariableNode
|
||||||
from django.utils import six
|
|
||||||
|
|
||||||
|
|
||||||
class NodelistTest(TestCase):
|
class NodelistTest(TestCase):
|
||||||
@ -38,13 +37,11 @@ class TextNodeTest(TestCase):
|
|||||||
def test_textnode_repr(self):
|
def test_textnode_repr(self):
|
||||||
engine = Engine()
|
engine = Engine()
|
||||||
for temptext, reprtext in [
|
for temptext, reprtext in [
|
||||||
("Hello, world!", "<TextNode: u'Hello, world!'>"),
|
("Hello, world!", "<TextNode: 'Hello, world!'>"),
|
||||||
("One\ntwo.", "<TextNode: u'One\\ntwo.'>"),
|
("One\ntwo.", "<TextNode: 'One\\ntwo.'>"),
|
||||||
]:
|
]:
|
||||||
template = engine.from_string(temptext)
|
template = engine.from_string(temptext)
|
||||||
texts = template.nodelist.get_nodes_by_type(TextNode)
|
texts = template.nodelist.get_nodes_by_type(TextNode)
|
||||||
if six.PY3:
|
|
||||||
reprtext = reprtext.replace("u'", "'")
|
|
||||||
self.assertEqual(repr(texts[0]), reprtext)
|
self.assertEqual(repr(texts[0]), reprtext)
|
||||||
|
|
||||||
|
|
||||||
|
@ -5,7 +5,6 @@ from django.db import connection
|
|||||||
from django.test import TestCase
|
from django.test import TestCase
|
||||||
from django.test.runner import DiscoverRunner
|
from django.test.runner import DiscoverRunner
|
||||||
from django.utils import six
|
from django.utils import six
|
||||||
from django.utils.encoding import force_text
|
|
||||||
|
|
||||||
from .models import Person
|
from .models import Person
|
||||||
|
|
||||||
@ -43,8 +42,6 @@ class TestDebugSQL(unittest.TestCase):
|
|||||||
).run(suite)
|
).run(suite)
|
||||||
runner.teardown_databases(old_config)
|
runner.teardown_databases(old_config)
|
||||||
|
|
||||||
if six.PY2:
|
|
||||||
stream.buflist = [force_text(x) for x in stream.buflist]
|
|
||||||
return stream.getvalue()
|
return stream.getvalue()
|
||||||
|
|
||||||
def test_output_normal(self):
|
def test_output_normal(self):
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user