mirror of
https://github.com/django/django.git
synced 2024-11-22 11:57:34 +01: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.template.engine import Engine
|
||||
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.inspect import (
|
||||
func_accepts_kwargs, func_accepts_var_args, func_has_no_args,
|
||||
@ -132,12 +131,7 @@ class ViewIndexView(BaseAdminDocsView):
|
||||
@staticmethod
|
||||
def _get_full_name(func):
|
||||
mod_name = func.__module__
|
||||
if six.PY3:
|
||||
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)
|
||||
return '%s.%s' % (mod_name, func.__qualname__)
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
views = []
|
||||
|
@ -8,8 +8,6 @@ from django.apps import apps as global_apps
|
||||
from django.contrib.auth import get_permission_codename
|
||||
from django.core import exceptions
|
||||
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):
|
||||
@ -98,12 +96,6 @@ def get_system_username():
|
||||
# if there is no corresponding entry in the /etc/passwd file
|
||||
# (a very restricted chroot environment, for example).
|
||||
return ''
|
||||
if six.PY2:
|
||||
try:
|
||||
result = result.decode(DEFAULT_LOCALE_ENCODING)
|
||||
except UnicodeDecodeError:
|
||||
# UnicodeDecodeError - preventive treatment for non-latin Windows.
|
||||
return ''
|
||||
return result
|
||||
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
import django.contrib.auth.models
|
||||
from django.contrib.auth import validators
|
||||
from django.db import migrations, models
|
||||
from django.utils import six, timezone
|
||||
from django.utils import timezone
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
@ -63,9 +63,7 @@ class Migration(migrations.Migration):
|
||||
('username', models.CharField(
|
||||
help_text='Required. 30 characters or fewer. Letters, digits and @/./+/-/_ only.', unique=True,
|
||||
max_length=30, verbose_name='username',
|
||||
validators=[
|
||||
validators.UnicodeUsernameValidator() if six.PY3 else validators.ASCIIUsernameValidator()
|
||||
],
|
||||
validators=[validators.UnicodeUsernameValidator()],
|
||||
)),
|
||||
('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)),
|
||||
|
@ -1,6 +1,5 @@
|
||||
from django.contrib.auth import validators
|
||||
from django.db import migrations, models
|
||||
from django.utils import six
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
@ -16,7 +15,7 @@ class Migration(migrations.Migration):
|
||||
name='username',
|
||||
field=models.CharField(
|
||||
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.',
|
||||
unique=True, verbose_name='username'
|
||||
),
|
||||
|
@ -1,6 +1,5 @@
|
||||
from django.contrib.auth import validators
|
||||
from django.db import migrations, models
|
||||
from django.utils import six
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
@ -18,7 +17,7 @@ class Migration(migrations.Migration):
|
||||
help_text='Required. 30 characters or fewer. Letters, digits and @/./+/-/_ only.',
|
||||
max_length=30,
|
||||
unique=True,
|
||||
validators=[validators.UnicodeUsernameValidator() if six.PY3 else validators.ASCIIUsernameValidator()],
|
||||
validators=[validators.UnicodeUsernameValidator()],
|
||||
verbose_name='username',
|
||||
),
|
||||
),
|
||||
|
@ -1,6 +1,5 @@
|
||||
from django.contrib.auth import validators
|
||||
from django.db import migrations, models
|
||||
from django.utils import six
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
@ -18,7 +17,7 @@ class Migration(migrations.Migration):
|
||||
help_text='Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only.',
|
||||
max_length=150,
|
||||
unique=True,
|
||||
validators=[validators.UnicodeUsernameValidator() if six.PY3 else validators.ASCIIUsernameValidator()],
|
||||
validators=[validators.UnicodeUsernameValidator()],
|
||||
verbose_name='username',
|
||||
),
|
||||
),
|
||||
|
@ -9,7 +9,7 @@ from django.db.models.manager import EmptyManager
|
||||
from django.utils import six, timezone
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
from .validators import ASCIIUsernameValidator, UnicodeUsernameValidator
|
||||
from .validators import UnicodeUsernameValidator
|
||||
|
||||
|
||||
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_validator = UnicodeUsernameValidator() if six.PY3 else ASCIIUsernameValidator()
|
||||
username_validator = UnicodeUsernameValidator()
|
||||
|
||||
username = models.CharField(
|
||||
_('username'),
|
||||
|
@ -1,7 +1,6 @@
|
||||
import re
|
||||
|
||||
from django.core import validators
|
||||
from django.utils import six
|
||||
from django.utils.deconstruct import deconstructible
|
||||
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, '
|
||||
'numbers, and @/./+/-/_ characters.'
|
||||
)
|
||||
flags = re.ASCII if six.PY3 else 0
|
||||
flags = re.ASCII
|
||||
|
||||
|
||||
@deconstructible
|
||||
@ -23,4 +22,4 @@ class UnicodeUsernameValidator(validators.RegexValidator):
|
||||
'Enter a valid username. This value may contain only letters, '
|
||||
'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:
|
||||
yield ''
|
||||
yield ' def __%s__(self): return self.%s' % (
|
||||
'str' if six.PY3 else 'unicode', name_field)
|
||||
yield ' def __str__(self): return self.%s' % name_field
|
||||
|
@ -1,18 +1,13 @@
|
||||
from psycopg2 import ProgrammingError
|
||||
from psycopg2.extras import register_hstore
|
||||
|
||||
from django.utils import six
|
||||
|
||||
|
||||
def register_hstore_handler(connection, **kwargs):
|
||||
if connection.vendor != 'postgresql':
|
||||
return
|
||||
|
||||
try:
|
||||
if six.PY2:
|
||||
register_hstore(connection.connection, globally=True, unicode=True)
|
||||
else:
|
||||
register_hstore(connection.connection, globally=True)
|
||||
register_hstore(connection.connection, globally=True)
|
||||
except ProgrammingError:
|
||||
# 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.core.cache.backends.base import DEFAULT_TIMEOUT, BaseCache
|
||||
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
|
||||
|
||||
try:
|
||||
@ -112,11 +112,9 @@ class DatabaseCache(BaseDatabaseCache):
|
||||
if num > self._max_entries:
|
||||
self._cull(db, cursor, now)
|
||||
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
|
||||
# string, not bytes. Refs #19274.
|
||||
if six.PY3:
|
||||
b64encoded = b64encoded.decode('latin1')
|
||||
b64encoded = base64.b64encode(pickled).decode('latin1')
|
||||
try:
|
||||
# Note: typecasting for datetimes is needed by some 3rd party
|
||||
# database backends. All core backends work without typecasting,
|
||||
|
@ -1,7 +1,6 @@
|
||||
"""
|
||||
Global Django exception and warning classes.
|
||||
"""
|
||||
from django.utils import six
|
||||
from django.utils.encoding import force_text
|
||||
|
||||
|
||||
@ -115,10 +114,7 @@ class ValidationError(Exception):
|
||||
if isinstance(message, ValidationError):
|
||||
if hasattr(message, 'error_dict'):
|
||||
message = message.error_dict
|
||||
# PY2 has a `message` property which is always there so we can't
|
||||
# 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'):
|
||||
elif not hasattr(message, 'message'):
|
||||
message = message.error_list
|
||||
else:
|
||||
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.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):
|
||||
@ -140,11 +140,7 @@ class ContentFile(File):
|
||||
A File-like object that takes just raw content, rather than an actual file.
|
||||
"""
|
||||
def __init__(self, content, name=None):
|
||||
if six.PY3:
|
||||
stream_class = StringIO if isinstance(content, six.text_type) else BytesIO
|
||||
else:
|
||||
stream_class = BytesIO
|
||||
content = force_bytes(content)
|
||||
stream_class = StringIO if isinstance(content, six.text_type) else BytesIO
|
||||
super(ContentFile, self).__init__(stream_class(content), name=name)
|
||||
self.size = len(content)
|
||||
|
||||
|
@ -8,7 +8,6 @@ from django.conf import settings
|
||||
from django.core import signals
|
||||
from django.core.handlers import base
|
||||
from django.urls import set_script_prefix
|
||||
from django.utils import six
|
||||
from django.utils.encoding import (
|
||||
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.
|
||||
|
||||
key and default should be str objects. Under Python 2 they may also be
|
||||
unicode objects provided they only contain ASCII characters.
|
||||
key and default should be str objects.
|
||||
"""
|
||||
value = environ.get(str(key), str(default))
|
||||
# Under Python 3, non-ASCII values in the WSGI environ are arbitrarily
|
||||
# decoded with ISO-8859-1. This is wrong for Django websites where UTF-8
|
||||
# is the default. Re-encode to recover the original bytestring.
|
||||
return value.encode(ISO_8859_1) if six.PY3 else value
|
||||
# Non-ASCII values in the WSGI environ are arbitrarily decoded with
|
||||
# ISO-8859-1. This is wrong for Django websites where UTF-8 is the default.
|
||||
# Re-encode to recover the original bytestring.
|
||||
return value.encode(ISO_8859_1)
|
||||
|
||||
|
||||
def get_str_from_wsgi(environ, key, default):
|
||||
"""
|
||||
Get a value from the WSGI environ dictionary as str.
|
||||
|
||||
key and default should be str objects. Under Python 2 they may also be
|
||||
unicode objects provided they only contain ASCII characters.
|
||||
key and default should be str objects.
|
||||
"""
|
||||
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
|
||||
|
||||
from django.core.mail.backends.base import BaseEmailBackend
|
||||
from django.utils import six
|
||||
|
||||
|
||||
class EmailBackend(BaseEmailBackend):
|
||||
@ -17,9 +16,8 @@ class EmailBackend(BaseEmailBackend):
|
||||
def write_message(self, message):
|
||||
msg = message.message()
|
||||
msg_data = msg.as_bytes()
|
||||
if six.PY3:
|
||||
charset = msg.get_charset().get_output_charset() if msg.get_charset() else 'utf-8'
|
||||
msg_data = msg_data.decode(charset)
|
||||
charset = msg.get_charset().get_output_charset() if msg.get_charset() else 'utf-8'
|
||||
msg_data = msg_data.decode(charset)
|
||||
self.stream.write('%s\n' % msg_data)
|
||||
self.stream.write('-' * 79)
|
||||
self.stream.write('\n')
|
||||
|
@ -5,7 +5,9 @@ import time
|
||||
from email import (
|
||||
charset as Charset, encoders as Encoders, generator, message_from_string,
|
||||
)
|
||||
from email.errors import InvalidHeaderDefect, NonASCIILocalPartDefect
|
||||
from email.header import Header
|
||||
from email.headerregistry import Address
|
||||
from email.message import Message
|
||||
from email.mime.base import MIMEBase
|
||||
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
|
||||
localpart, domain = split_addr(addr, encoding)
|
||||
|
||||
if six.PY2:
|
||||
# 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
|
||||
# An `email.headerregistry.Address` object is used since
|
||||
# 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:
|
||||
address = Address(nm, username=localpart, domain=domain)
|
||||
return str(address)
|
||||
@ -174,27 +166,21 @@ class MIMEMixin():
|
||||
"""
|
||||
fp = six.StringIO()
|
||||
g = generator.Generator(fp, mangle_from_=False)
|
||||
if six.PY2:
|
||||
g.flatten(self, unixfrom=unixfrom)
|
||||
else:
|
||||
g.flatten(self, unixfrom=unixfrom, linesep=linesep)
|
||||
g.flatten(self, unixfrom=unixfrom, linesep=linesep)
|
||||
return fp.getvalue()
|
||||
|
||||
if six.PY2:
|
||||
as_bytes = as_string
|
||||
else:
|
||||
def as_bytes(self, unixfrom=False, linesep='\n'):
|
||||
"""Return the entire formatted message as bytes.
|
||||
Optional `unixfrom' when True, means include the Unix From_ envelope
|
||||
header.
|
||||
def as_bytes(self, unixfrom=False, linesep='\n'):
|
||||
"""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
|
||||
lines that begin with 'From '. See bug #13433 for details.
|
||||
"""
|
||||
fp = BytesIO()
|
||||
g = generator.BytesGenerator(fp, mangle_from_=False)
|
||||
g.flatten(self, unixfrom=unixfrom, linesep=linesep)
|
||||
return fp.getvalue()
|
||||
This overrides the default as_bytes() implementation to not mangle
|
||||
lines that begin with 'From '. See bug #13433 for details.
|
||||
"""
|
||||
fp = BytesIO()
|
||||
g = generator.BytesGenerator(fp, mangle_from_=False)
|
||||
g.flatten(self, unixfrom=unixfrom, linesep=linesep)
|
||||
return fp.getvalue()
|
||||
|
||||
|
||||
class SafeMIMEMessage(MIMEMixin, MIMEMessage):
|
||||
@ -450,8 +436,6 @@ class EmailMessage(object):
|
||||
try:
|
||||
filename.encode('ascii')
|
||||
except UnicodeEncodeError:
|
||||
if six.PY2:
|
||||
filename = filename.encode('utf-8')
|
||||
filename = ('utf-8', '', filename)
|
||||
attachment.add_header('Content-Disposition', 'attachment',
|
||||
filename=filename)
|
||||
|
@ -20,7 +20,6 @@ from django.utils import lru_cache
|
||||
from django.utils._os import upath
|
||||
from django.utils.encoding import force_text
|
||||
from django.utils.functional import cached_property
|
||||
from django.utils.glob import glob_escape
|
||||
|
||||
try:
|
||||
import bz2
|
||||
@ -238,7 +237,7 @@ class Command(BaseCommand):
|
||||
self.stdout.write("Checking %s for fixtures..." % humanize(fixture_dir))
|
||||
fixture_files_in_dir = []
|
||||
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:
|
||||
# Save the fixture_dir and fixture_name for future error messages.
|
||||
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 (
|
||||
WSGIServer, get_internal_wsgi_application, run,
|
||||
)
|
||||
from django.utils import autoreload, six
|
||||
from django.utils.encoding import force_text, get_system_encoding
|
||||
from django.utils import autoreload
|
||||
from django.utils.encoding import force_text
|
||||
|
||||
|
||||
naiveip_re = re.compile(r"""^(?:
|
||||
@ -125,8 +125,6 @@ class Command(BaseCommand):
|
||||
# requires_migrations_check attribute.
|
||||
self.check_migrations()
|
||||
now = datetime.now().strftime('%B %d, %Y - %X')
|
||||
if six.PY2:
|
||||
now = now.decode(get_system_encoding())
|
||||
self.stdout.write(now)
|
||||
self.stdout.write((
|
||||
"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.utils import handle_extensions
|
||||
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.version import get_docs_version
|
||||
|
||||
@ -218,21 +218,11 @@ class TemplateCommand(BaseCommand):
|
||||
raise CommandError("you must provide %s %s name" % (
|
||||
"an" if app_or_project == "app" else "a", app_or_project))
|
||||
# If it's not a valid directory name.
|
||||
if six.PY2:
|
||||
if not re.search(r'^[_a-zA-Z]\w*$', name):
|
||||
# Provide a smart error message, depending on the error.
|
||||
if not re.search(r'^[_a-zA-Z]', name):
|
||||
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)
|
||||
)
|
||||
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):
|
||||
"""
|
||||
|
@ -219,8 +219,6 @@ class DatabaseWrapper(BaseDatabaseWrapper):
|
||||
'conv': django_conversions,
|
||||
'charset': 'utf8',
|
||||
}
|
||||
if six.PY2:
|
||||
kwargs['use_unicode'] = True
|
||||
settings_dict = self.settings_dict
|
||||
if 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
|
||||
# The DB API definition does not define this attribute.
|
||||
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
|
||||
# `statement` doesn't contain the query parameters. refs #20010.
|
||||
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.backends.base.base import BaseDatabaseWrapper
|
||||
from django.db.utils import DatabaseError as WrappedDatabaseError
|
||||
from django.utils import six
|
||||
from django.utils.encoding import force_str
|
||||
from django.utils.functional import cached_property
|
||||
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 .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(SafeText, psycopg2.extensions.QuotedString)
|
||||
psycopg2.extras.register_uuid()
|
||||
|
@ -19,7 +19,6 @@ from django.utils.dateparse import (
|
||||
parse_date, parse_datetime, parse_duration, parse_time,
|
||||
)
|
||||
from django.utils.encoding import force_text
|
||||
from django.utils.safestring import SafeBytes
|
||||
|
||||
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_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):
|
||||
|
@ -1,6 +1,5 @@
|
||||
from django.db import utils
|
||||
from django.db.backends.base.features import BaseDatabaseFeatures
|
||||
from django.utils import six
|
||||
from django.utils.functional import cached_property
|
||||
|
||||
from .base import Database
|
||||
@ -48,7 +47,6 @@ class DatabaseFeatures(BaseDatabaseFeatures):
|
||||
@cached_property
|
||||
def can_share_in_memory_db(self):
|
||||
return (
|
||||
six.PY3 and
|
||||
Database.__name__ == 'sqlite3.dbapi2' and
|
||||
Database.sqlite_version_info >= (3, 7, 13)
|
||||
)
|
||||
|
@ -4,7 +4,7 @@ import sys
|
||||
|
||||
from django.apps import apps
|
||||
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 .loader import MigrationLoader
|
||||
@ -125,13 +125,7 @@ class InteractiveMigrationQuestioner(MigrationQuestioner):
|
||||
prompt = "[default: {}] >>> ".format(default)
|
||||
else:
|
||||
prompt = ">>> "
|
||||
if six.PY3:
|
||||
# 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)
|
||||
code = input(prompt)
|
||||
if not code and default:
|
||||
code = default
|
||||
if not code:
|
||||
|
@ -53,11 +53,7 @@ class BaseSimpleSerializer(BaseSerializer):
|
||||
|
||||
class ByteTypeSerializer(BaseSerializer):
|
||||
def serialize(self):
|
||||
value_repr = repr(self.value)
|
||||
if six.PY2:
|
||||
# Prepend the `b` prefix since we're importing unicode_literals
|
||||
value_repr = 'b' + value_repr
|
||||
return value_repr, set()
|
||||
return repr(self.value), set()
|
||||
|
||||
|
||||
class DatetimeSerializer(BaseSerializer):
|
||||
@ -276,11 +272,7 @@ class SettingsReferenceSerializer(BaseSerializer):
|
||||
|
||||
class TextTypeSerializer(BaseSerializer):
|
||||
def serialize(self):
|
||||
value_repr = repr(self.value)
|
||||
if six.PY2:
|
||||
# Strip the `u` prefix since we're importing unicode_literals
|
||||
value_repr = value_repr[1:]
|
||||
return value_repr, set()
|
||||
return repr(self.value), set()
|
||||
|
||||
|
||||
class TimedeltaSerializer(BaseSerializer):
|
||||
|
@ -510,9 +510,7 @@ class Model(six.with_metaclass(ModelBase)):
|
||||
return force_str('<%s: %s>' % (self.__class__.__name__, u))
|
||||
|
||||
def __str__(self):
|
||||
if six.PY2 and hasattr(self, '__unicode__'):
|
||||
return force_text(self).encode('utf-8')
|
||||
return str('%s object' % self.__class__.__name__)
|
||||
return '%s object' % self.__class__.__name__
|
||||
|
||||
def __eq__(self, other):
|
||||
if not isinstance(other, Model):
|
||||
|
@ -107,7 +107,6 @@ class RelatedField(Field):
|
||||
return errors
|
||||
|
||||
def _check_related_name_is_valid(self):
|
||||
import re
|
||||
import keyword
|
||||
related_name = self.remote_field.related_name
|
||||
if related_name is None:
|
||||
@ -115,12 +114,8 @@ class RelatedField(Field):
|
||||
is_valid_id = True
|
||||
if keyword.iskeyword(related_name):
|
||||
is_valid_id = False
|
||||
if six.PY3:
|
||||
if not related_name.isidentifier():
|
||||
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 related_name.isidentifier():
|
||||
is_valid_id = False
|
||||
if not (is_valid_id or related_name.endswith('+')):
|
||||
return [
|
||||
checks.Error(
|
||||
|
@ -4,7 +4,6 @@ from importlib import import_module
|
||||
|
||||
from django.db import router
|
||||
from django.db.models.query import QuerySet
|
||||
from django.utils import six
|
||||
|
||||
|
||||
class BaseManager(object):
|
||||
@ -86,9 +85,7 @@ class BaseManager(object):
|
||||
return manager_method
|
||||
|
||||
new_methods = {}
|
||||
# Refs http://bugs.python.org/issue1785.
|
||||
predicate = inspect.isfunction if six.PY3 else inspect.ismethod
|
||||
for name, method in inspect.getmembers(queryset_class, predicate=predicate):
|
||||
for name, method in inspect.getmembers(queryset_class, predicate=inspect.isfunction):
|
||||
# Only copy missing methods.
|
||||
if hasattr(cls, name):
|
||||
continue
|
||||
|
@ -14,7 +14,7 @@ DEFAULT_DB_ALIAS = 'default'
|
||||
DJANGO_VERSION_PICKLE_KEY = '_django_version'
|
||||
|
||||
|
||||
class Error(Exception if six.PY3 else StandardError): # NOQA: StandardError undefined on PY3
|
||||
class Error(Exception):
|
||||
pass
|
||||
|
||||
|
||||
|
@ -2,15 +2,9 @@ import sys
|
||||
import threading
|
||||
import weakref
|
||||
|
||||
from django.utils import six
|
||||
from django.utils.inspect import func_accepts_kwargs
|
||||
from django.utils.six.moves import range
|
||||
|
||||
if six.PY2:
|
||||
from .weakref_backports import WeakMethod
|
||||
else:
|
||||
from weakref import WeakMethod
|
||||
|
||||
|
||||
def _make_id(target):
|
||||
if hasattr(target, '__func__'):
|
||||
@ -107,13 +101,10 @@ class Signal(object):
|
||||
receiver_object = receiver
|
||||
# Check for bound methods
|
||||
if hasattr(receiver, '__self__') and hasattr(receiver, '__func__'):
|
||||
ref = WeakMethod
|
||||
ref = weakref.WeakMethod
|
||||
receiver_object = receiver.__self__
|
||||
if six.PY3:
|
||||
receiver = ref(receiver)
|
||||
weakref.finalize(receiver_object, self._remove_receiver)
|
||||
else:
|
||||
receiver = ref(receiver, self._remove_receiver)
|
||||
receiver = ref(receiver)
|
||||
weakref.finalize(receiver_object, self._remove_receiver)
|
||||
|
||||
with self.lock:
|
||||
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
|
||||
|
||||
from django.utils import six
|
||||
from django.utils.encoding import force_str
|
||||
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+
|
||||
# http://bugs.python.org/issue22775
|
||||
cookie_pickles_properly = (
|
||||
@ -14,7 +9,7 @@ cookie_pickles_properly = (
|
||||
sys.version_info >= (3, 4, 3)
|
||||
)
|
||||
|
||||
if _cookie_allows_colon_in_names and cookie_pickles_properly:
|
||||
if cookie_pickles_properly:
|
||||
SimpleCookie = http_cookies.SimpleCookie
|
||||
else:
|
||||
Morsel = http_cookies.Morsel
|
||||
@ -30,37 +25,12 @@ else:
|
||||
else:
|
||||
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):
|
||||
"""
|
||||
Return a dictionary parsed from a `Cookie:` header string.
|
||||
"""
|
||||
cookiedict = {}
|
||||
if six.PY2:
|
||||
cookie = force_str(cookie)
|
||||
for chunk in cookie.split(str(';')):
|
||||
if str('=') in chunk:
|
||||
key, val = chunk.split(str('='), 1)
|
||||
|
@ -40,8 +40,6 @@ RAW = "raw"
|
||||
FILE = "file"
|
||||
FIELD = "field"
|
||||
|
||||
_BASE64_DECODE_ERROR = TypeError if six.PY2 else binascii.Error
|
||||
|
||||
|
||||
class MultiPartParser(object):
|
||||
"""
|
||||
@ -190,7 +188,7 @@ class MultiPartParser(object):
|
||||
num_bytes_read += len(raw_data)
|
||||
try:
|
||||
data = base64.b64decode(raw_data)
|
||||
except _BASE64_DECODE_ERROR:
|
||||
except binascii.Error:
|
||||
data = raw_data
|
||||
else:
|
||||
data = field_stream.read(size=read_size)
|
||||
@ -684,10 +682,7 @@ def parse_header(line):
|
||||
value = p[i + 1:].strip()
|
||||
if has_encoding:
|
||||
encoding, lang, value = value.split(b"'")
|
||||
if six.PY3:
|
||||
value = unquote(value.decode(), encoding=encoding.decode())
|
||||
else:
|
||||
value = unquote(value).decode(encoding)
|
||||
value = unquote(value.decode(), encoding=encoding.decode())
|
||||
if len(value) >= 2 and value[:1] == value[-1:] == b'"':
|
||||
value = value[1:-1]
|
||||
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.datastructures import ImmutableList, MultiValueDict
|
||||
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.six.moves.urllib.parse import (
|
||||
@ -381,24 +381,15 @@ class QueryDict(MultiValueDict):
|
||||
'fields_limit': settings.DATA_UPLOAD_MAX_NUMBER_FIELDS,
|
||||
'encoding': encoding,
|
||||
}
|
||||
if six.PY3:
|
||||
if isinstance(query_string, bytes):
|
||||
# query_string normally contains URL-encoded data, a subset of ASCII.
|
||||
try:
|
||||
query_string = query_string.decode(encoding)
|
||||
except UnicodeDecodeError:
|
||||
# ... but some user agents are misbehaving :-(
|
||||
query_string = query_string.decode('iso-8859-1')
|
||||
for key, value in limited_parse_qsl(query_string, **parse_qsl_kwargs):
|
||||
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)
|
||||
if isinstance(query_string, bytes):
|
||||
# query_string normally contains URL-encoded data, a subset of ASCII.
|
||||
try:
|
||||
query_string = query_string.decode(encoding)
|
||||
except UnicodeDecodeError:
|
||||
# ... but some user agents are misbehaving :-(
|
||||
query_string = query_string.decode('iso-8859-1')
|
||||
for key, value in limited_parse_qsl(query_string, **parse_qsl_kwargs):
|
||||
self.appendlist(key, value)
|
||||
self._mutable = mutable
|
||||
|
||||
@classmethod
|
||||
|
@ -100,10 +100,7 @@ class HttpResponseBase(six.Iterator):
|
||||
]
|
||||
return b'\r\n'.join(headers)
|
||||
|
||||
if six.PY3:
|
||||
__bytes__ = serialize_headers
|
||||
else:
|
||||
__str__ = serialize_headers
|
||||
__bytes__ = serialize_headers
|
||||
|
||||
@property
|
||||
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)):
|
||||
raise BadHeaderError("Header values can't contain newlines (got %r)" % value)
|
||||
try:
|
||||
if six.PY3:
|
||||
if isinstance(value, str):
|
||||
# Ensure string is valid in given charset
|
||||
value.encode(charset)
|
||||
else:
|
||||
# Convert bytestring using given charset
|
||||
value = value.decode(charset)
|
||||
if isinstance(value, str):
|
||||
# Ensure string is valid in given charset
|
||||
value.encode(charset)
|
||||
else:
|
||||
if isinstance(value, str):
|
||||
# Ensure string is valid in given charset
|
||||
value.decode(charset)
|
||||
else:
|
||||
# Convert unicode string to given charset
|
||||
value = value.encode(charset)
|
||||
# Convert bytestring using given charset
|
||||
value = value.decode(charset)
|
||||
except UnicodeError as e:
|
||||
if mime_encode:
|
||||
# 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."""
|
||||
return self.serialize_headers() + b'\r\n\r\n' + self.content
|
||||
|
||||
if six.PY3:
|
||||
__bytes__ = serialize
|
||||
else:
|
||||
__str__ = serialize
|
||||
__bytes__ = serialize
|
||||
|
||||
@property
|
||||
def content(self):
|
||||
|
@ -322,10 +322,10 @@ class RequestFactory(object):
|
||||
if parsed[3]:
|
||||
path += str(";") + force_str(parsed[3])
|
||||
path = uri_to_iri(path).encode(UTF_8)
|
||||
# Under Python 3, non-ASCII values in the WSGI environ are arbitrarily
|
||||
# decoded with ISO-8859-1. We replicate this behavior here.
|
||||
# Replace the behavior where non-ASCII values in the WSGI environ are
|
||||
# arbitrarily decoded with ISO-8859-1.
|
||||
# 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):
|
||||
"Construct a GET request."
|
||||
@ -406,10 +406,8 @@ class RequestFactory(object):
|
||||
r.update(extra)
|
||||
# If QUERY_STRING is absent or empty, we want to extract it from the URL.
|
||||
if not r.get('QUERY_STRING'):
|
||||
query_string = force_bytes(parsed[4])
|
||||
# WSGI requires latin-1 encoded strings. See get_path_info().
|
||||
if six.PY3:
|
||||
query_string = query_string.decode('iso-8859-1')
|
||||
query_string = force_bytes(parsed[4]).decode('iso-8859-1')
|
||||
r['QUERY_STRING'] = query_string
|
||||
return self.request(**r)
|
||||
|
||||
|
@ -9,7 +9,7 @@ from django.core.signals import setting_changed
|
||||
from django.db import connections, router
|
||||
from django.db.utils import ConnectionRouter
|
||||
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.functional import empty
|
||||
|
||||
@ -139,7 +139,7 @@ def complex_setting_changed(**kwargs):
|
||||
# Considering the current implementation of the signals framework,
|
||||
# this stacklevel shows the line containing the override_settings call.
|
||||
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)
|
||||
|
@ -775,12 +775,6 @@ class SimpleTestCase(unittest.TestCase):
|
||||
standardMsg = '%s == %s' % (safe_repr(xml1, True), safe_repr(xml2, True))
|
||||
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):
|
||||
|
||||
|
@ -6,6 +6,7 @@ import time
|
||||
import warnings
|
||||
from contextlib import contextmanager
|
||||
from functools import wraps
|
||||
from types import SimpleNamespace
|
||||
from unittest import TestCase, skipIf, skipUnless
|
||||
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.translation import deactivate
|
||||
|
||||
if six.PY3:
|
||||
from types import SimpleNamespace
|
||||
else:
|
||||
class SimpleNamespace(object):
|
||||
pass
|
||||
|
||||
try:
|
||||
import jinja2
|
||||
except ImportError:
|
||||
@ -615,7 +610,7 @@ def strip_quotes(want, got):
|
||||
|
||||
|
||||
def str_prefix(s):
|
||||
return s % {'_': '' if six.PY3 else 'u'}
|
||||
return s % {'_': ''}
|
||||
|
||||
|
||||
class CaptureQueriesContext(object):
|
||||
|
@ -209,11 +209,7 @@ class RegexURLPattern(LocaleRegexProvider):
|
||||
callback = callback.func
|
||||
if not hasattr(callback, '__name__'):
|
||||
return callback.__module__ + "." + callback.__class__.__name__
|
||||
elif six.PY3:
|
||||
return callback.__module__ + "." + callback.__qualname__
|
||||
else:
|
||||
# PY2 does not support __qualname__
|
||||
return callback.__module__ + "." + callback.__name__
|
||||
return callback.__module__ + "." + callback.__qualname__
|
||||
|
||||
|
||||
class RegexURLResolver(LocaleRegexProvider):
|
||||
|
@ -1,41 +1,18 @@
|
||||
import os
|
||||
import sys
|
||||
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.utils import six
|
||||
from django.utils.encoding import force_text
|
||||
|
||||
if six.PY2:
|
||||
fs_encoding = sys.getfilesystemencoding() or sys.getdefaultencoding()
|
||||
|
||||
|
||||
# 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)
|
||||
abspathu = abspath
|
||||
|
||||
|
||||
def upath(path):
|
||||
"""
|
||||
Always return a unicode path.
|
||||
"""
|
||||
if six.PY2 and not isinstance(path, six.text_type):
|
||||
return path.decode(fs_encoding)
|
||||
return path
|
||||
|
||||
|
||||
@ -44,8 +21,6 @@ def npath(path):
|
||||
Always return a native path, that is unicode on Python 3 and bytestring on
|
||||
Python 2.
|
||||
"""
|
||||
if six.PY2 and not isinstance(path, bytes):
|
||||
return path.encode(fs_encoding)
|
||||
return path
|
||||
|
||||
|
||||
|
@ -9,7 +9,6 @@ import struct
|
||||
import time
|
||||
|
||||
from django.conf import settings
|
||||
from django.utils import six
|
||||
from django.utils.encoding import force_bytes
|
||||
from django.utils.six.moves import range
|
||||
|
||||
@ -94,7 +93,7 @@ else:
|
||||
if len(val1) != len(val2):
|
||||
return False
|
||||
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):
|
||||
result |= x ^ y
|
||||
else:
|
||||
|
@ -179,7 +179,7 @@ class MultiValueDict(dict):
|
||||
"""Appends an item to the internal list associated with key."""
|
||||
self.setlistdefault(key).append(value)
|
||||
|
||||
def _iteritems(self):
|
||||
def items(self):
|
||||
"""
|
||||
Yields (key, value) pairs, where value is the last item in the list
|
||||
associated with the key.
|
||||
@ -187,33 +187,15 @@ class MultiValueDict(dict):
|
||||
for key in self:
|
||||
yield key, self[key]
|
||||
|
||||
def _iterlists(self):
|
||||
def lists(self):
|
||||
"""Yields (key, list) pairs."""
|
||||
return six.iteritems(super(MultiValueDict, self))
|
||||
|
||||
def _itervalues(self):
|
||||
def values(self):
|
||||
"""Yield the last value on every key list."""
|
||||
for key in self:
|
||||
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):
|
||||
"""Returns a shallow copy of this object."""
|
||||
return copy.copy(self)
|
||||
|
@ -7,8 +7,6 @@ except ImportError:
|
||||
|
||||
from functools import WRAPPER_ASSIGNMENTS, update_wrapper, wraps
|
||||
|
||||
from django.utils import six
|
||||
|
||||
|
||||
class classonlymethod(classmethod):
|
||||
def __get__(self, instance, cls=None):
|
||||
@ -121,13 +119,10 @@ def decorator_from_middleware(middleware_class):
|
||||
def available_attrs(fn):
|
||||
"""
|
||||
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.
|
||||
"""
|
||||
if six.PY3:
|
||||
return WRAPPER_ASSIGNMENTS
|
||||
else:
|
||||
return tuple(a for a in WRAPPER_ASSIGNMENTS if hasattr(fn, a))
|
||||
return WRAPPER_ASSIGNMENTS
|
||||
|
||||
|
||||
def make_middleware_decorator(middleware_class):
|
||||
|
@ -2,13 +2,11 @@ import codecs
|
||||
import datetime
|
||||
import locale
|
||||
from decimal import Decimal
|
||||
from urllib.parse import unquote_to_bytes
|
||||
|
||||
from django.utils import six
|
||||
from django.utils.functional import Promise
|
||||
from django.utils.six.moves.urllib.parse import quote, unquote
|
||||
|
||||
if six.PY3:
|
||||
from urllib.parse import unquote_to_bytes
|
||||
from django.utils.six.moves.urllib.parse import quote
|
||||
|
||||
|
||||
class DjangoUnicodeDecodeError(UnicodeDecodeError):
|
||||
@ -66,15 +64,10 @@ def force_text(s, encoding='utf-8', strings_only=False, errors='strict'):
|
||||
return s
|
||||
try:
|
||||
if not issubclass(type(s), six.string_types):
|
||||
if six.PY3:
|
||||
if isinstance(s, bytes):
|
||||
s = six.text_type(s, encoding, errors)
|
||||
else:
|
||||
s = six.text_type(s)
|
||||
elif hasattr(s, '__unicode__'):
|
||||
s = six.text_type(s)
|
||||
if isinstance(s, bytes):
|
||||
s = six.text_type(s, encoding, errors)
|
||||
else:
|
||||
s = six.text_type(bytes(s), encoding, errors)
|
||||
s = six.text_type(s)
|
||||
else:
|
||||
# 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
|
||||
@ -127,10 +120,7 @@ def force_bytes(s, encoding='utf-8', strings_only=False, errors='strict'):
|
||||
return six.text_type(s).encode(encoding, errors)
|
||||
if not isinstance(s, six.string_types):
|
||||
try:
|
||||
if six.PY3:
|
||||
return six.text_type(s).encode(encoding)
|
||||
else:
|
||||
return bytes(s)
|
||||
return six.text_type(s).encode(encoding)
|
||||
except UnicodeEncodeError:
|
||||
if isinstance(s, Exception):
|
||||
# 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)
|
||||
|
||||
|
||||
if six.PY3:
|
||||
smart_str = smart_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 = smart_text
|
||||
force_str = force_text
|
||||
|
||||
smart_str.__doc__ = """
|
||||
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:
|
||||
return 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')
|
||||
|
||||
|
||||
|
@ -23,7 +23,7 @@ http://web.archive.org/web/20110718035220/http://diveintomark.org/archives/2004/
|
||||
"""
|
||||
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.six import StringIO
|
||||
from django.utils.six.moves.urllib.parse import urlparse
|
||||
@ -42,8 +42,6 @@ def rfc2822_date(date):
|
||||
dow = days[date.weekday()]
|
||||
month = months[date.month - 1]
|
||||
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()
|
||||
# Historically, this function assumes that naive datetimes are in UTC.
|
||||
if offset is None:
|
||||
@ -58,8 +56,6 @@ def rfc3339_date(date):
|
||||
# Support datetime objects older than 1900
|
||||
date = datetime_safe.new_datetime(date)
|
||||
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()
|
||||
# Historically, this function assumes that naive datetimes are in UTC.
|
||||
if offset is None:
|
||||
|
@ -92,16 +92,9 @@ def lazy(func, *resultclasses):
|
||||
assert not (cls._delegate_bytes and cls._delegate_text), (
|
||||
"Cannot call lazy() with both bytes and text return types.")
|
||||
if cls._delegate_text:
|
||||
if six.PY3:
|
||||
cls.__str__ = cls.__text_cast
|
||||
else:
|
||||
cls.__unicode__ = cls.__text_cast
|
||||
cls.__str__ = cls.__bytes_cast_encoded
|
||||
cls.__str__ = cls.__text_cast
|
||||
elif cls._delegate_bytes:
|
||||
if six.PY3:
|
||||
cls.__bytes__ = cls.__bytes_cast
|
||||
else:
|
||||
cls.__str__ = cls.__bytes_cast
|
||||
cls.__bytes__ = cls.__bytes_cast
|
||||
|
||||
@classmethod
|
||||
def __promise__(cls, method_name):
|
||||
@ -154,9 +147,7 @@ def lazy(func, *resultclasses):
|
||||
return hash(self.__cast())
|
||||
|
||||
def __mod__(self, rhs):
|
||||
if self._delegate_bytes and six.PY2:
|
||||
return bytes(self) % rhs
|
||||
elif self._delegate_text:
|
||||
if self._delegate_text:
|
||||
return six.text_type(self) % rhs
|
||||
return self.__cast() % rhs
|
||||
|
||||
@ -316,14 +307,9 @@ class LazyObject(object):
|
||||
return result
|
||||
return copy.deepcopy(self._wrapped, memo)
|
||||
|
||||
if six.PY3:
|
||||
__bytes__ = new_method_proxy(bytes)
|
||||
__str__ = new_method_proxy(str)
|
||||
__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)
|
||||
__bytes__ = new_method_proxy(bytes)
|
||||
__str__ = new_method_proxy(str)
|
||||
__bool__ = new_method_proxy(bool)
|
||||
|
||||
# Introspection support
|
||||
__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 "
|
||||
"__html__()." % klass.__name__
|
||||
)
|
||||
if six.PY2:
|
||||
if '__unicode__' not in klass.__dict__:
|
||||
raise ValueError(
|
||||
"can't apply @html_safe to %s because it doesn't "
|
||||
"define __unicode__()." % klass.__name__
|
||||
)
|
||||
klass_unicode = klass.__unicode__
|
||||
klass.__unicode__ = lambda self: mark_safe(klass_unicode(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)
|
||||
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
|
||||
|
@ -1,4 +1,3 @@
|
||||
from django.utils import six
|
||||
from django.utils.six.moves import html_parser as _html_parser
|
||||
|
||||
try:
|
||||
@ -8,15 +7,13 @@ except AttributeError:
|
||||
class HTMLParseError(Exception):
|
||||
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
|
||||
it at call time because Python 2.7 does not have the keyword
|
||||
argument.
|
||||
"""
|
||||
def __init__(self, convert_charrefs=False, **kwargs):
|
||||
_html_parser.HTMLParser.__init__(self, convert_charrefs=convert_charrefs, **kwargs)
|
||||
else:
|
||||
HTMLParser = _html_parser.HTMLParser
|
||||
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
|
||||
it at call time because Python 2.7 does not have the keyword
|
||||
argument.
|
||||
"""
|
||||
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)
|
||||
if len(s) > 13:
|
||||
raise ValueError("Base36 input too large")
|
||||
value = 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
|
||||
return int(s, 36)
|
||||
|
||||
|
||||
def int_to_base36(i):
|
||||
@ -204,11 +199,6 @@ def int_to_base36(i):
|
||||
char_set = '0123456789abcdefghijklmnopqrstuvwxyz'
|
||||
if i < 0:
|
||||
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:
|
||||
return char_set[i]
|
||||
b36 = ''
|
||||
@ -296,11 +286,6 @@ def is_safe_url(url, host=None, allowed_hosts=None, require_https=False):
|
||||
url = url.strip()
|
||||
if not url:
|
||||
return False
|
||||
if six.PY2:
|
||||
try:
|
||||
url = force_text(url)
|
||||
except UnicodeDecodeError:
|
||||
return False
|
||||
if allowed_hosts is None:
|
||||
allowed_hosts = set()
|
||||
if host:
|
||||
@ -388,13 +373,9 @@ def limited_parse_qsl(qs, keep_blank_values=False, encoding='utf-8',
|
||||
else:
|
||||
continue
|
||||
if len(nv[1]) or keep_blank_values:
|
||||
if six.PY3:
|
||||
name = nv[0].replace('+', ' ')
|
||||
name = unquote(name, encoding=encoding, errors=errors)
|
||||
value = nv[1].replace('+', ' ')
|
||||
value = unquote(value, encoding=encoding, errors=errors)
|
||||
else:
|
||||
name = unquote(nv[0].replace(b'+', b' '))
|
||||
value = unquote(nv[1].replace(b'+', b' '))
|
||||
name = nv[0].replace('+', ' ')
|
||||
name = unquote(name, encoding=encoding, errors=errors)
|
||||
value = nv[1].replace('+', ' ')
|
||||
value = unquote(value, encoding=encoding, errors=errors)
|
||||
r.append((name, value))
|
||||
return r
|
||||
|
@ -1,12 +1,7 @@
|
||||
import inspect
|
||||
|
||||
from django.utils import six
|
||||
|
||||
|
||||
def getargspec(func):
|
||||
if six.PY2:
|
||||
return inspect.getargspec(func)
|
||||
|
||||
sig = inspect.signature(func)
|
||||
args = [
|
||||
p.name for p in sig.parameters.values()
|
||||
@ -30,10 +25,6 @@ def getargspec(func):
|
||||
|
||||
|
||||
def get_func_args(func):
|
||||
if six.PY2:
|
||||
argspec = inspect.getargspec(func)
|
||||
return argspec.args[1:] # ignore 'self'
|
||||
|
||||
sig = inspect.signature(func)
|
||||
return [
|
||||
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
|
||||
*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)
|
||||
args = []
|
||||
for arg_name, param in sig.parameters.items():
|
||||
@ -80,20 +57,6 @@ def get_func_full_args(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(
|
||||
p for p in inspect.signature(func).parameters.values()
|
||||
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.
|
||||
"""
|
||||
if six.PY2:
|
||||
return inspect.getargspec(func)[1] is not None
|
||||
|
||||
return any(
|
||||
p for p in inspect.signature(func).parameters.values()
|
||||
if p.kind == p.VAR_POSITIONAL
|
||||
@ -114,7 +74,7 @@ def func_accepts_var_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()
|
||||
if p.kind == p.POSITIONAL_OR_KEYWORD
|
||||
]
|
||||
@ -122,8 +82,4 @@ def func_has_no_args(func):
|
||||
|
||||
|
||||
def func_supports_parameter(func, parameter):
|
||||
if six.PY3:
|
||||
return parameter in inspect.signature(func).parameters
|
||||
else:
|
||||
args, varargs, varkw, defaults = inspect.getargspec(func)
|
||||
return parameter in args
|
||||
return parameter in inspect.signature(func).parameters
|
||||
|
@ -2,6 +2,7 @@ import copy
|
||||
import os
|
||||
import sys
|
||||
from importlib import import_module
|
||||
from importlib.util import find_spec as importlib_find
|
||||
|
||||
from django.utils import six
|
||||
|
||||
@ -63,88 +64,17 @@ def autodiscover_modules(*args, **kwargs):
|
||||
raise
|
||||
|
||||
|
||||
if six.PY3:
|
||||
from importlib.util import find_spec as importlib_find
|
||||
def module_has_submodule(package, module_name):
|
||||
"""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):
|
||||
"""See if 'module' is in 'package'."""
|
||||
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
|
||||
full_module_name = package_name + '.' + module_name
|
||||
return importlib_find(full_module_name, package_path) is not None
|
||||
|
||||
|
||||
def module_dir(module):
|
||||
|
@ -83,12 +83,7 @@ class SafeText(six.text_type, SafeData):
|
||||
encode = curry(_proxy_method, method=six.text_type.encode)
|
||||
|
||||
|
||||
if six.PY3:
|
||||
SafeString = SafeText
|
||||
else:
|
||||
SafeString = SafeBytes
|
||||
# backwards compatibility for Python 2
|
||||
SafeUnicode = SafeText
|
||||
SafeString = SafeText
|
||||
|
||||
|
||||
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.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
|
||||
def capfirst(x):
|
||||
|
@ -5,7 +5,6 @@ from django.template.base import (
|
||||
TOKEN_BLOCK, TOKEN_COMMENT, TOKEN_TEXT, TOKEN_VAR, TRANSLATOR_COMMENT_MARK,
|
||||
Lexer,
|
||||
)
|
||||
from django.utils import six
|
||||
from django.utils.encoding import force_text
|
||||
from django.utils.six import StringIO
|
||||
|
||||
@ -57,7 +56,7 @@ def templatize(src, origin=None, charset='utf-8'):
|
||||
comment_lineno_cache = None
|
||||
# Adding the u prefix allows gettext to recognize the Unicode string
|
||||
# (#26093).
|
||||
raw_prefix = 'u' if six.PY3 else ''
|
||||
raw_prefix = 'u'
|
||||
|
||||
def join_tokens(tokens, trim=False):
|
||||
message = ''.join(tokens)
|
||||
|
@ -13,7 +13,7 @@ from django.conf.locale import LANG_INFO
|
||||
from django.core.exceptions import AppRegistryNotReady
|
||||
from django.core.signals import setting_changed
|
||||
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.encoding import force_text
|
||||
from django.utils.safestring import SafeData, mark_safe
|
||||
@ -336,11 +336,7 @@ def gettext(message):
|
||||
return do_translate(message, 'gettext')
|
||||
|
||||
|
||||
if six.PY3:
|
||||
ugettext = gettext
|
||||
else:
|
||||
def ugettext(message):
|
||||
return do_translate(message, 'ugettext')
|
||||
ugettext = gettext
|
||||
|
||||
|
||||
def pgettext(context, message):
|
||||
@ -384,15 +380,7 @@ def ngettext(singular, plural, number):
|
||||
return do_ntranslate(singular, plural, number, 'ngettext')
|
||||
|
||||
|
||||
if six.PY3:
|
||||
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')
|
||||
ungettext = ngettext
|
||||
|
||||
|
||||
def npgettext(context, singular, plural, number):
|
||||
|
@ -399,11 +399,9 @@ class ExceptionReporter(object):
|
||||
if not exceptions:
|
||||
return frames
|
||||
|
||||
# In case there's just one exception (always in Python 2,
|
||||
# sometimes in Python 3), take the traceback from self.tb (Python 2
|
||||
# doesn't have a __traceback__ attribute on Exception)
|
||||
# In case there's just one exception, take the traceback from self.tb
|
||||
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:
|
||||
# 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
|
||||
# other exception.
|
||||
if six.PY2:
|
||||
tb = tb.tb_next
|
||||
elif not tb.tb_next and exceptions:
|
||||
if not tb.tb_next and exceptions:
|
||||
exc_value = exceptions.pop()
|
||||
tb = exc_value.__traceback__
|
||||
else:
|
||||
|
@ -3,7 +3,7 @@ doc_files = docs extras AUTHORS INSTALL LICENSE README.rst
|
||||
install-script = scripts/rpm-install.sh
|
||||
|
||||
[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
|
||||
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.utils import captured_stderr
|
||||
from django.urls import reverse
|
||||
from django.utils import six
|
||||
|
||||
from .models import Company, Person
|
||||
from .tests import AdminDocsTestCase, TestDataMixin
|
||||
@ -53,7 +52,6 @@ class AdminDocViewTests(TestDataMixin, AdminDocsTestCase):
|
||||
self.assertContains(response, 'Views by namespace test')
|
||||
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):
|
||||
"""
|
||||
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'])
|
||||
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):
|
||||
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.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')
|
||||
|
||||
@ -626,7 +626,6 @@ class DjangoAdminSettingsDirectory(AdminScriptTestCase):
|
||||
self.assertTrue(os.path.exists(app_path))
|
||||
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):
|
||||
"directory: startapp creates the correct directory with unicode characters"
|
||||
args = ['startapp', 'こんにちは']
|
||||
@ -1897,18 +1896,11 @@ class StartProject(LiveServerTestCase, AdminScriptTestCase):
|
||||
self.addCleanup(shutil.rmtree, testproject_dir, True)
|
||||
|
||||
out, err = self.run_django_admin(args)
|
||||
if PY2:
|
||||
self.assertOutput(
|
||||
err,
|
||||
"Error: '%s' is not a valid project name. Please make "
|
||||
"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.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))
|
||||
|
||||
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.test import TestCase, skipUnlessDBFeature
|
||||
from django.utils import six
|
||||
|
||||
from .models import (
|
||||
Author, Book, Company, DepartmentStore, Employee, Publisher, Store, Ticket,
|
||||
@ -24,7 +23,7 @@ def cxOracle_py3_bug(func):
|
||||
"""
|
||||
from unittest import expectedFailure
|
||||
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):
|
||||
|
@ -1,5 +1,4 @@
|
||||
import os
|
||||
from unittest import skipUnless
|
||||
|
||||
from django.apps import AppConfig, 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.test import SimpleTestCase, override_settings
|
||||
from django.test.utils import extend_sys_path, isolate_apps
|
||||
from django.utils import six
|
||||
from django.utils._os import upath
|
||||
|
||||
from .default_config_app.apps import CustomConfig
|
||||
@ -371,7 +369,6 @@ class AppConfigTests(SimpleTestCase):
|
||||
self.assertEqual(ac.path, 'a')
|
||||
|
||||
|
||||
@skipUnless(six.PY3, "Namespace packages sans __init__.py were added in Python 3.3")
|
||||
class NamespacePackageAppTests(SimpleTestCase):
|
||||
# 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
|
||||
|
@ -1,6 +1,5 @@
|
||||
import datetime
|
||||
import re
|
||||
from unittest import skipIf
|
||||
|
||||
from django import forms
|
||||
from django.contrib.auth.forms import (
|
||||
@ -15,7 +14,7 @@ from django.core import mail
|
||||
from django.core.mail import EmailMultiAlternatives
|
||||
from django.forms.fields import CharField, Field, IntegerField
|
||||
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.text import capfirst
|
||||
from django.utils.translation import ugettext as _
|
||||
@ -114,14 +113,10 @@ class UserCreationFormTest(TestDataMixin, TestCase):
|
||||
'password2': 'test123',
|
||||
}
|
||||
form = UserCreationForm(data)
|
||||
if six.PY3:
|
||||
self.assertTrue(form.is_valid())
|
||||
u = form.save()
|
||||
self.assertEqual(u.username, '宝')
|
||||
else:
|
||||
self.assertFalse(form.is_valid())
|
||||
self.assertTrue(form.is_valid())
|
||||
u = form.save()
|
||||
self.assertEqual(u.username, '宝')
|
||||
|
||||
@skipIf(six.PY2, "Python 2 doesn't support unicode usernames by default.")
|
||||
def test_normalize_username(self):
|
||||
# The normalization happens in AbstractBaseUser.clean() and ModelForm
|
||||
# validation calls Model.clean().
|
||||
@ -137,7 +132,6 @@ class UserCreationFormTest(TestDataMixin, TestCase):
|
||||
self.assertNotEqual(user.username, ohm_username)
|
||||
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):
|
||||
"""
|
||||
To prevent almost identical usernames, visually identical but differing
|
||||
|
@ -32,9 +32,6 @@ def mock_inputs(inputs):
|
||||
class mock_getpass:
|
||||
@staticmethod
|
||||
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']):
|
||||
return inputs['password']()
|
||||
return inputs['password']
|
||||
|
@ -1,11 +1,9 @@
|
||||
import unittest
|
||||
from datetime import date, timedelta
|
||||
|
||||
from django.conf import settings
|
||||
from django.contrib.auth.models import User
|
||||
from django.contrib.auth.tokens import PasswordResetTokenGenerator
|
||||
from django.test import TestCase
|
||||
from django.utils.six import PY3
|
||||
|
||||
|
||||
class TokenGeneratorTest(TestCase):
|
||||
@ -51,18 +49,6 @@ class TokenGeneratorTest(TestCase):
|
||||
p2 = Mocked(date.today() + timedelta(settings.PASSWORD_RESET_TIMEOUT_DAYS + 1))
|
||||
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):
|
||||
user = User.objects.create_user('tokentestuser', 'test2@example.com', 'testpw')
|
||||
p0 = PasswordResetTokenGenerator()
|
||||
|
@ -1,7 +1,6 @@
|
||||
from django.core.exceptions import ImproperlyConfigured
|
||||
from django.db.utils import load_backend
|
||||
from django.test import SimpleTestCase
|
||||
from django.utils import six
|
||||
|
||||
|
||||
class TestLoadBackend(SimpleTestCase):
|
||||
@ -10,7 +9,7 @@ class TestLoadBackend(SimpleTestCase):
|
||||
"'foo' isn't an available database backend.\n"
|
||||
"Try using 'django.db.backends.XXX', where XXX is one of:\n"
|
||||
" 'mysql', 'oracle', 'postgresql', 'sqlite3'\n"
|
||||
"Error was: No module named %s"
|
||||
) % "foo.base" if six.PY2 else "'foo'"
|
||||
"Error was: No module named 'foo'"
|
||||
)
|
||||
with self.assertRaisesMessage(ImproperlyConfigured, msg):
|
||||
load_backend('foo')
|
||||
|
@ -13,12 +13,3 @@ class CustomBaseModel(models.base.ModelBase):
|
||||
|
||||
class MyModel(six.with_metaclass(CustomBaseModel, models.Model)):
|
||||
"""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')
|
||||
|
||||
def test_get_or_set_version(self):
|
||||
msg = (
|
||||
"get_or_set() missing 1 required positional argument: 'default'"
|
||||
if six.PY3
|
||||
else 'get_or_set() takes at least 3 arguments'
|
||||
)
|
||||
msg = "get_or_set() missing 1 required positional argument: 'default'"
|
||||
cache.get_or_set('brian', 1979, version=2)
|
||||
with self.assertRaisesMessage(TypeError, msg):
|
||||
cache.get_or_set('brian')
|
||||
|
@ -3,7 +3,6 @@ import os
|
||||
|
||||
from django.db.backends.postgresql.client import DatabaseClient
|
||||
from django.test import SimpleTestCase, mock
|
||||
from django.utils import six
|
||||
from django.utils.encoding import force_bytes, force_str
|
||||
|
||||
|
||||
@ -91,16 +90,12 @@ class PostgreSqlDbshellCommandTestCase(SimpleTestCase):
|
||||
encoding = locale.getpreferredencoding()
|
||||
username = 'rôle'
|
||||
password = 'sésame'
|
||||
try:
|
||||
username_str = force_str(username, encoding)
|
||||
password_str = force_str(password, encoding)
|
||||
pgpass_bytes = force_bytes(
|
||||
'somehost:444:dbname:%s:%s' % (username, password),
|
||||
encoding=encoding,
|
||||
)
|
||||
except UnicodeEncodeError:
|
||||
if six.PY2:
|
||||
self.skipTest("Your locale can't run this test.")
|
||||
username_str = force_str(username, encoding)
|
||||
password_str = force_str(password, encoding)
|
||||
pgpass_bytes = force_bytes(
|
||||
'somehost:444:dbname:%s:%s' % (username, password),
|
||||
encoding=encoding,
|
||||
)
|
||||
self.assertEqual(
|
||||
self._run_it({
|
||||
'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.utils.encoding import force_bytes
|
||||
from django.utils.http import urlquote
|
||||
from django.utils.six import PY2, StringIO
|
||||
from django.utils.six import StringIO
|
||||
|
||||
from . import uploadhandler
|
||||
from .models import FileModel
|
||||
@ -102,9 +102,7 @@ class FileUploadTests(TestCase):
|
||||
self._test_base64_upload("Big data" * 68000) # > 512Kb
|
||||
|
||||
def test_big_base64_newlines_upload(self):
|
||||
self._test_base64_upload(
|
||||
# encodestring is a deprecated alias on Python 3
|
||||
"Big data" * 68000, encode=base64.encodestring if PY2 else base64.encodebytes)
|
||||
self._test_base64_upload("Big data" * 68000, encode=base64.encodebytes)
|
||||
|
||||
def test_unicode_file_name(self):
|
||||
tdir = sys_tempfile.mkdtemp()
|
||||
|
@ -181,10 +181,7 @@ class ContentFileTestCase(unittest.TestCase):
|
||||
retrieved content is of the same type.
|
||||
"""
|
||||
self.assertIsInstance(ContentFile(b"content").read(), bytes)
|
||||
if six.PY3:
|
||||
self.assertIsInstance(ContentFile("español").read(), six.text_type)
|
||||
else:
|
||||
self.assertIsInstance(ContentFile("español").read(), bytes)
|
||||
self.assertIsInstance(ContentFile("español").read(), six.text_type)
|
||||
|
||||
|
||||
class DimensionClosingBug(unittest.TestCase):
|
||||
|
@ -2,10 +2,8 @@
|
||||
import json
|
||||
import os
|
||||
import re
|
||||
import unittest
|
||||
import warnings
|
||||
|
||||
import django
|
||||
from django.core import management, serializers
|
||||
from django.core.exceptions import ImproperlyConfigured
|
||||
from django.core.serializers.base import DeserializationError
|
||||
@ -15,9 +13,8 @@ from django.test import (
|
||||
TestCase, TransactionTestCase, override_settings, skipIfDBFeature,
|
||||
skipUnlessDBFeature,
|
||||
)
|
||||
from django.utils import six
|
||||
from django.utils._os import upath
|
||||
from django.utils.six import PY3, StringIO
|
||||
from django.utils.six import StringIO
|
||||
|
||||
from .models import (
|
||||
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__)))
|
||||
|
||||
|
||||
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):
|
||||
|
||||
def animal_pre_save_check(self, signal, sender, instance, **kwargs):
|
||||
@ -205,7 +192,6 @@ class TestFixtures(TestCase):
|
||||
verbosity=0,
|
||||
)
|
||||
|
||||
@skipIfNonASCIIPath
|
||||
@override_settings(SERIALIZATION_MODULES={'unkn': 'unexistent.path'})
|
||||
def test_unimportable_serializer(self):
|
||||
"""
|
||||
@ -350,8 +336,8 @@ class TestFixtures(TestCase):
|
||||
self.assertEqual(
|
||||
self.pre_save_checks,
|
||||
[
|
||||
("Count = 42 (<%s 'int'>)" % ('class' if PY3 else 'type'),
|
||||
"Weight = 1.2 (<%s 'float'>)" % ('class' if PY3 else 'type'))
|
||||
("Count = 42 (<class 'int'>)",
|
||||
"Weight = 1.2 (<class 'float'>)")
|
||||
]
|
||||
)
|
||||
finally:
|
||||
@ -531,7 +517,6 @@ class TestFixtures(TestCase):
|
||||
with self.assertRaisesMessage(ImproperlyConfigured, "settings.FIXTURE_DIRS contains duplicates."):
|
||||
management.call_command('loaddata', 'absolute.json', verbosity=0)
|
||||
|
||||
@skipIfNonASCIIPath
|
||||
@override_settings(FIXTURE_DIRS=[os.path.join(_cur_dir, 'fixtures')])
|
||||
def test_fixture_dirs_with_default_fixture_path(self):
|
||||
"""
|
||||
|
@ -34,7 +34,7 @@ class HandlerTests(SimpleTestCase):
|
||||
produces a 404.
|
||||
"""
|
||||
environ = RequestFactory().get('/').environ
|
||||
environ['PATH_INFO'] = b'\xed' if six.PY2 else '\xed'
|
||||
environ['PATH_INFO'] = '\xed'
|
||||
handler = WSGIHandler()
|
||||
response = handler(environ, lambda *a, **k: None)
|
||||
# The path of the request will be encoded to '/%ED'.
|
||||
@ -53,25 +53,17 @@ class HandlerTests(SimpleTestCase):
|
||||
]
|
||||
got = []
|
||||
for raw_query_string in raw_query_strings:
|
||||
if six.PY3:
|
||||
# Simulate http.server.BaseHTTPRequestHandler.parse_request handling of raw request
|
||||
environ['QUERY_STRING'] = str(raw_query_string, 'iso-8859-1')
|
||||
else:
|
||||
environ['QUERY_STRING'] = raw_query_string
|
||||
# Simulate http.server.BaseHTTPRequestHandler.parse_request handling of raw request
|
||||
environ['QUERY_STRING'] = str(raw_query_string, 'iso-8859-1')
|
||||
request = WSGIRequest(environ)
|
||||
got.append(request.GET['want'])
|
||||
if six.PY2:
|
||||
self.assertListEqual(got, ['café', 'café', 'café', 'café'])
|
||||
else:
|
||||
# On Python 3, %E9 is converted to the unicode replacement character by parse_qsl
|
||||
self.assertListEqual(got, ['café', 'café', 'caf\ufffd', 'café'])
|
||||
# %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):
|
||||
"""Non-ASCII cookies set in JavaScript are properly decoded (#20557)."""
|
||||
environ = RequestFactory().get('/').environ
|
||||
raw_cookie = 'want="café"'
|
||||
if six.PY3:
|
||||
raw_cookie = raw_cookie.encode('utf-8').decode('iso-8859-1')
|
||||
raw_cookie = 'want="café"'.encode('utf-8').decode('iso-8859-1')
|
||||
environ['HTTP_COOKIE'] = raw_cookie
|
||||
request = WSGIRequest(environ)
|
||||
# If would be nicer if request.COOKIES returned unicode values.
|
||||
|
@ -55,8 +55,6 @@ class QueryDictTests(SimpleTestCase):
|
||||
def test_immutable_basic_operations(self):
|
||||
q = QueryDict()
|
||||
self.assertEqual(q.getlist('foo'), [])
|
||||
if six.PY2:
|
||||
self.assertIs(q.has_key('foo'), False)
|
||||
self.assertNotIn('foo', q)
|
||||
self.assertEqual(list(six.iteritems(q)), [])
|
||||
self.assertEqual(list(six.iterlists(q)), [])
|
||||
@ -85,11 +83,7 @@ class QueryDictTests(SimpleTestCase):
|
||||
with self.assertRaises(AttributeError):
|
||||
q.appendlist('foo', ['bar'])
|
||||
|
||||
if six.PY2:
|
||||
self.assertTrue(q.has_key('foo'))
|
||||
self.assertIn('foo', q)
|
||||
if six.PY2:
|
||||
self.assertFalse(q.has_key('bar'))
|
||||
self.assertNotIn('bar', q)
|
||||
|
||||
self.assertEqual(list(six.iteritems(q)), [('foo', 'bar')])
|
||||
@ -150,8 +144,6 @@ class QueryDictTests(SimpleTestCase):
|
||||
q.appendlist('foo', 'another')
|
||||
self.assertEqual(q.getlist('foo'), ['bar', 'baz', 'another'])
|
||||
self.assertEqual(q['foo'], 'another')
|
||||
if six.PY2:
|
||||
self.assertTrue(q.has_key('foo'))
|
||||
self.assertIn('foo', q)
|
||||
|
||||
self.assertListEqual(sorted(six.iteritems(q)),
|
||||
@ -199,11 +191,7 @@ class QueryDictTests(SimpleTestCase):
|
||||
with self.assertRaises(AttributeError):
|
||||
q.appendlist('foo', ['bar'])
|
||||
|
||||
if six.PY2:
|
||||
self.assertIs(q.has_key('vote'), True)
|
||||
self.assertIn('vote', q)
|
||||
if six.PY2:
|
||||
self.assertIs(q.has_key('foo'), False)
|
||||
self.assertNotIn('foo', q)
|
||||
self.assertEqual(list(six.iteritems(q)), [('vote', 'no')])
|
||||
self.assertEqual(list(six.iterlists(q)), [('vote', ['yes', 'no'])])
|
||||
@ -224,19 +212,6 @@ class QueryDictTests(SimpleTestCase):
|
||||
with self.assertRaises(AttributeError):
|
||||
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):
|
||||
q = QueryDict()
|
||||
q1 = pickle.loads(pickle.dumps(q, 2))
|
||||
@ -807,15 +782,6 @@ class CookieTests(unittest.TestCase):
|
||||
c.load({'name': '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):
|
||||
rawdata = 'Customer="WILE_E_COYOTE"; Path=/acme; Version=1'
|
||||
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.test import SimpleTestCase, mock, override_settings
|
||||
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.six import StringIO
|
||||
from django.utils.translation import ugettext
|
||||
@ -144,18 +144,11 @@ class CompilationErrorHandling(MessageCompilationTests):
|
||||
env = os.environ.copy()
|
||||
env.update({str('LANG'): str('C')})
|
||||
with mock.patch('django.core.management.utils.Popen', lambda *args, **kwargs: Popen(*args, env=env, **kwargs)):
|
||||
if six.PY2:
|
||||
# Various assertRaises on PY2 don't support unicode error messages.
|
||||
try:
|
||||
call_command('compilemessages', locale=['ko'], verbosity=0)
|
||||
except CommandError as err:
|
||||
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)
|
||||
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):
|
||||
|
@ -6,7 +6,6 @@ import pickle
|
||||
from contextlib import contextmanager
|
||||
from importlib import import_module
|
||||
from threading import local
|
||||
from unittest import skipUnless
|
||||
|
||||
from django import forms
|
||||
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.safestring import SafeBytes, SafeText
|
||||
from django.utils.six import PY3
|
||||
from django.utils.translation import (
|
||||
LANGUAGE_SESSION_KEY, activate, check_for_language, deactivate,
|
||||
get_language, get_language_from_request, get_language_info, gettext,
|
||||
gettext_lazy, ngettext_lazy, npgettext, npgettext_lazy, pgettext,
|
||||
pgettext_lazy, trans_real, ugettext, ugettext_lazy, ungettext,
|
||||
ungettext_lazy,
|
||||
get_language, get_language_from_request, get_language_info, gettext_lazy,
|
||||
ngettext_lazy, npgettext, npgettext_lazy, pgettext, trans_real, ugettext,
|
||||
ugettext_lazy, ungettext, ungettext_lazy,
|
||||
)
|
||||
|
||||
from .forms import CompanyForm, I18nForm, SelectDateForm
|
||||
@ -141,33 +138,6 @@ class TranslationTests(SimpleTestCase):
|
||||
s4 = ugettext_lazy('Some other string')
|
||||
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):
|
||||
s1 = ugettext_lazy("test")
|
||||
self.assertEqual(six.text_type(s1), "test")
|
||||
@ -223,20 +193,6 @@ class TranslationTests(SimpleTestCase):
|
||||
with self.assertRaisesMessage(KeyError, 'Your dictionary lacks key'):
|
||||
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):
|
||||
self.assertTrue(ungettext_lazy('%d good result', '%d good results'))
|
||||
self.assertFalse(ungettext_lazy('', ''))
|
||||
@ -298,7 +254,7 @@ class FormattingTests(SimpleTestCase):
|
||||
self.d = datetime.date(2009, 12, 31)
|
||||
self.dt = datetime.datetime(2009, 12, 31, 20, 50)
|
||||
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({
|
||||
'n': self.n,
|
||||
't': self.t,
|
||||
|
@ -5,7 +5,7 @@ from django.core.management import call_command
|
||||
from django.db import connection
|
||||
from django.test import TestCase, mock, skipUnlessDBFeature
|
||||
from django.utils.encoding import force_text
|
||||
from django.utils.six import PY3, StringIO
|
||||
from django.utils.six import StringIO
|
||||
|
||||
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_1 = models.IntegerField(db_column='__field')", output)
|
||||
self.assertIn("prc_x = models.IntegerField(db_column='prc(%) x')", output)
|
||||
if PY3:
|
||||
# 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)
|
||||
self.assertIn("tamaño = models.IntegerField()", output)
|
||||
|
||||
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.test.testcases import SimpleTestCase, skipIfDBFeature
|
||||
from django.test.utils import isolate_apps, override_settings
|
||||
from django.utils import six
|
||||
|
||||
|
||||
@isolate_apps('invalid_models_tests')
|
||||
@ -655,10 +654,8 @@ class RelativeFieldTests(SimpleTestCase):
|
||||
'with', # a Python keyword
|
||||
'related_name\n',
|
||||
'',
|
||||
',', # non-ASCII
|
||||
]
|
||||
# Python 2 crashes on non-ASCII strings.
|
||||
if six.PY3:
|
||||
invalid_related_names.append(',')
|
||||
|
||||
class Parent(models.Model):
|
||||
pass
|
||||
@ -695,10 +692,9 @@ class RelativeFieldTests(SimpleTestCase):
|
||||
'ends_with_plus+',
|
||||
'_+',
|
||||
'+',
|
||||
'試',
|
||||
'試驗+',
|
||||
]
|
||||
# Python 2 crashes on non-ASCII strings.
|
||||
if six.PY3:
|
||||
related_names.extend(['試', '試驗+'])
|
||||
|
||||
class Parent(models.Model):
|
||||
pass
|
||||
|
@ -8,8 +8,10 @@ import socket
|
||||
import sys
|
||||
import tempfile
|
||||
import threading
|
||||
from email import message_from_binary_file, message_from_bytes
|
||||
from email.header import Header
|
||||
from email.mime.text import MIMEText
|
||||
from email.utils import parseaddr
|
||||
from smtplib import SMTP, SMTPAuthenticationError, SMTPException
|
||||
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.utils._os import upath
|
||||
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
|
||||
|
||||
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):
|
||||
|
||||
@ -656,16 +648,10 @@ class MailTests(HeadersCheckMixin, SimpleTestCase):
|
||||
sanitize_address(('A name', 'to@example.com'), 'ascii'),
|
||||
'A name <to@example.com>'
|
||||
)
|
||||
if PY3:
|
||||
self.assertEqual(
|
||||
sanitize_address(('A name', 'to@example.com'), 'utf-8'),
|
||||
'=?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>'
|
||||
)
|
||||
self.assertEqual(
|
||||
sanitize_address(('A name', 'to@example.com'), 'utf-8'),
|
||||
'=?utf-8?q?A_name?= <to@example.com>'
|
||||
)
|
||||
|
||||
# Unicode characters are are supported in RFC-6532.
|
||||
self.assertEqual(
|
||||
@ -1165,18 +1151,8 @@ class FakeSMTPServer(smtpd.SMTPServer, threading.Thread):
|
||||
self.active_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):
|
||||
if PY3:
|
||||
data = data.encode('utf-8')
|
||||
data = data.encode('utf-8')
|
||||
m = message_from_bytes(data)
|
||||
maddr = parseaddr(m.get('from'))[1]
|
||||
|
||||
@ -1448,8 +1424,7 @@ class SMTPBackendTests(BaseEmailBackendTests, SMTPBackendTestsBase):
|
||||
|
||||
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.
|
||||
msg = msg.replace('\r\n', '')
|
||||
self.assertNotIn('\r', msg)
|
||||
|
@ -2,7 +2,6 @@ import gzip
|
||||
import random
|
||||
import re
|
||||
from io import BytesIO
|
||||
from unittest import skipIf
|
||||
|
||||
from django.conf import settings
|
||||
from django.core import mail
|
||||
@ -401,24 +400,6 @@ class BrokenLinkEmailsMiddlewareTest(SimpleTestCase):
|
||||
BrokenLinkEmailsMiddleware().process_response(self.req, self.resp)
|
||||
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):
|
||||
class SubclassedMiddleware(BrokenLinkEmailsMiddleware):
|
||||
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('initial = True', content)
|
||||
|
||||
if six.PY3:
|
||||
self.assertIn('úñí©óðé µóðéø', content) # Meta.verbose_name
|
||||
self.assertIn('úñí©óðé µóðéøß', content) # Meta.verbose_name_plural
|
||||
self.assertIn('ÚÑÍ¢ÓÐÉ', content) # title.verbose_name
|
||||
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
|
||||
self.assertIn('úñí©óðé µóðéø', content) # Meta.verbose_name
|
||||
self.assertIn('úñí©óðé µóðéøß', content) # Meta.verbose_name_plural
|
||||
self.assertIn('ÚÑÍ¢ÓÐÉ', content) # title.verbose_name
|
||||
self.assertIn('“Ðjáñgó”', content) # title.default
|
||||
|
||||
def test_makemigrations_order(self):
|
||||
"""
|
||||
|
@ -1,5 +1,3 @@
|
||||
from unittest import skipIf
|
||||
|
||||
from django.db import connection, connections
|
||||
from django.db.migrations.exceptions import (
|
||||
AmbiguityError, InconsistentMigrationHistory, NodeNotFoundError,
|
||||
@ -7,7 +5,6 @@ from django.db.migrations.exceptions import (
|
||||
from django.db.migrations.loader import MigrationLoader
|
||||
from django.db.migrations.recorder import MigrationRecorder
|
||||
from django.test import TestCase, modify_settings, override_settings
|
||||
from django.utils import six
|
||||
|
||||
|
||||
class RecorderTests(TestCase):
|
||||
@ -170,7 +167,6 @@ class LoaderTests(TestCase):
|
||||
"App with migrations module file not in unmigrated apps."
|
||||
)
|
||||
|
||||
@skipIf(six.PY2, "PY2 doesn't load empty dirs.")
|
||||
def test_load_empty_dir(self):
|
||||
with override_settings(MIGRATION_MODULES={"migrations": "migrations.faulty_migrations.namespace"}):
|
||||
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):
|
||||
|
||||
def test_empty_signature(self):
|
||||
@ -486,15 +480,6 @@ class WriterTests(SimpleTestCase):
|
||||
self.assertEqual(string, 'range')
|
||||
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):
|
||||
"""
|
||||
Neither py2 or py3 can serialize a reference in a local scope.
|
||||
|
@ -1,13 +1,12 @@
|
||||
import datetime
|
||||
import unittest
|
||||
from decimal import Decimal
|
||||
|
||||
from django.db.models.fields import (
|
||||
AutoField, BigIntegerField, BinaryField, BooleanField, CharField,
|
||||
DateField, DateTimeField, DecimalField, EmailField, FilePathField,
|
||||
FloatField, GenericIPAddressField, IntegerField, IPAddressField,
|
||||
NullBooleanField, PositiveIntegerField, PositiveSmallIntegerField,
|
||||
SlugField, SmallIntegerField, TextField, TimeField, URLField,
|
||||
AutoField, BinaryField, BooleanField, CharField, DateField, DateTimeField,
|
||||
DecimalField, EmailField, FilePathField, FloatField, GenericIPAddressField,
|
||||
IntegerField, IPAddressField, NullBooleanField, PositiveIntegerField,
|
||||
PositiveSmallIntegerField, SlugField, SmallIntegerField, TextField,
|
||||
TimeField, URLField,
|
||||
)
|
||||
from django.db.models.fields.files import FileField, ImageField
|
||||
from django.test import SimpleTestCase
|
||||
@ -21,11 +20,6 @@ class PromiseTest(SimpleTestCase):
|
||||
lazy_func = lazy(lambda: 1, 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):
|
||||
lazy_func = lazy(lambda: b'', bytes)
|
||||
self.assertIsInstance(BinaryField().get_prep_value(lazy_func()), bytes)
|
||||
|
@ -1,18 +1,11 @@
|
||||
import os
|
||||
import shutil
|
||||
import unittest
|
||||
|
||||
from django import conf
|
||||
from django.test import TestCase
|
||||
from django.utils import six
|
||||
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):
|
||||
def setUp(self):
|
||||
# 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.test import TestCase, skipUnlessDBFeature
|
||||
from django.test.utils import CaptureQueriesContext
|
||||
from django.utils import six
|
||||
from django.utils.six.moves import range
|
||||
|
||||
from .models import (
|
||||
@ -406,7 +405,7 @@ class Queries1Tests(TestCase):
|
||||
local_recursion_limit = 127
|
||||
msg = 'Maximum recursion depth exceeded: too many subqueries.'
|
||||
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)
|
||||
|
||||
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):
|
||||
with self.assertNumQueries(0):
|
||||
self.get_ordered_articles()[0:5]
|
||||
@ -2965,8 +2945,6 @@ class QuerySetExceptionTests(TestCase):
|
||||
|
||||
def test_invalid_order_by(self):
|
||||
msg = "Invalid order_by arguments: ['*']"
|
||||
if six.PY2:
|
||||
msg = msg.replace("[", "[u")
|
||||
with self.assertRaisesMessage(FieldError, msg):
|
||||
list(Article.objects.order_by('*'))
|
||||
|
||||
|
@ -1,7 +1,6 @@
|
||||
import datetime
|
||||
|
||||
from django.db import DJANGO_VERSION_PICKLE_KEY, models
|
||||
from django.utils import six
|
||||
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)
|
||||
name = models.CharField(blank=True, max_length=100, default="test")
|
||||
number1 = models.IntegerField(blank=True, default=standalone_number)
|
||||
if six.PY3:
|
||||
# default serializable on Python 3 only
|
||||
number2 = models.IntegerField(blank=True, default=Numbers.get_static_number)
|
||||
number2 = models.IntegerField(blank=True, default=Numbers.get_static_number)
|
||||
|
||||
|
||||
class Container(object):
|
||||
|
@ -1,10 +1,8 @@
|
||||
import datetime
|
||||
import pickle
|
||||
import unittest
|
||||
|
||||
from django.db import models
|
||||
from django.test import TestCase
|
||||
from django.utils import six
|
||||
from django.utils.version import get_version
|
||||
|
||||
from .models import Container, Event, Group, Happening, M2MModel
|
||||
@ -33,7 +31,6 @@ class PickleabilityTestCase(TestCase):
|
||||
def test_standalone_method_as_default(self):
|
||||
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):
|
||||
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.client import FakePayload
|
||||
from django.test.utils import freeze_time, str_prefix
|
||||
from django.utils import six
|
||||
from django.utils.encoding import force_str
|
||||
from django.utils.http import cookie_date, urlencode
|
||||
from django.utils.six.moves import http_cookies
|
||||
@ -168,9 +167,8 @@ class RequestsTests(SimpleTestCase):
|
||||
|
||||
def test_wsgirequest_path_info(self):
|
||||
def wsgi_str(path_info, encoding='utf-8'):
|
||||
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.encode(encoding) # Actual URL sent by the browser (bytestring)
|
||||
path_info = path_info.decode('iso-8859-1') # Value in the WSGI environ dict (native string)
|
||||
return path_info
|
||||
# Regression for #19468
|
||||
request = WSGIRequest({'PATH_INFO': wsgi_str("/سلام/"), 'REQUEST_METHOD': 'get', 'wsgi.input': BytesIO(b'')})
|
||||
@ -583,7 +581,7 @@ class RequestsTests(SimpleTestCase):
|
||||
request = WSGIRequest({
|
||||
'REQUEST_METHOD': 'GET',
|
||||
'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']})
|
||||
request.encoding = 'iso-8859-16'
|
||||
|
@ -3,7 +3,6 @@ import datetime
|
||||
from django.core import signing
|
||||
from django.test import SimpleTestCase
|
||||
from django.test.utils import freeze_time
|
||||
from django.utils import six
|
||||
from django.utils.encoding import force_str
|
||||
|
||||
|
||||
@ -45,8 +44,6 @@ class TestSigner(SimpleTestCase):
|
||||
'jkw osanteuh ,rcuh nthu aou oauh ,ud du',
|
||||
'\u2019',
|
||||
]
|
||||
if six.PY2:
|
||||
examples.append(b'a byte string')
|
||||
for example in examples:
|
||||
signed = signer.sign(example)
|
||||
self.assertIsInstance(signed, str)
|
||||
@ -76,8 +73,6 @@ class TestSigner(SimpleTestCase):
|
||||
'a unicode string \u2019',
|
||||
{'a': 'dictionary'},
|
||||
]
|
||||
if six.PY2:
|
||||
objects.append(b'a byte string')
|
||||
for o in objects:
|
||||
self.assertNotEqual(o, signing.dumps(o))
|
||||
self.assertEqual(o, signing.loads(signing.dumps(o)))
|
||||
|
@ -183,8 +183,7 @@ class TestInteractiveMessages(CollectionTestCase):
|
||||
@staticmethod
|
||||
def mock_input(stdout):
|
||||
def _input(msg):
|
||||
# Python 2 reads bytes from the console output, use bytes for the StringIO
|
||||
stdout.write(msg.encode('utf-8') if six.PY2 else msg)
|
||||
stdout.write(msg)
|
||||
return 'yes'
|
||||
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
|
||||
``_str__()`` or ``__unicode__()`` method to return a "human-readable"
|
||||
representation of the object. Do this not only for your own sanity when dealing
|
||||
with the interactive prompt, but also because objects' representations are used
|
||||
throughout Django's 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.
|
||||
Although it's not a strict requirement, each model should have a ``_str__()``
|
||||
method to return a "human-readable" representation of the object. Do this not
|
||||
only for your own sanity when dealing with the interactive prompt, but also
|
||||
because objects' representations are used throughout Django's
|
||||
automatically-generated admin.
|
||||
"""
|
||||
|
||||
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):
|
||||
headline = models.CharField(max_length=100)
|
||||
pub_date = models.DateTimeField()
|
||||
|
@ -1,25 +1,14 @@
|
||||
import datetime
|
||||
from unittest import skipIf
|
||||
|
||||
from django.db import models
|
||||
from django.test import TestCase
|
||||
from django.test.utils import isolate_apps
|
||||
from django.utils import six
|
||||
|
||||
from .models import Article, InternationalArticle
|
||||
from .models import InternationalArticle
|
||||
|
||||
|
||||
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):
|
||||
a = InternationalArticle.objects.create(
|
||||
headline='Girl wins €12.500 in lottery',
|
||||
|
@ -1,6 +1,5 @@
|
||||
from django.template import TemplateSyntaxError
|
||||
from django.test import SimpleTestCase
|
||||
from django.utils import six
|
||||
|
||||
from ..utils import setup
|
||||
|
||||
@ -36,11 +35,10 @@ class WidthRatioTagTests(SimpleTestCase):
|
||||
@setup({'widthratio06': '{% widthratio a b 100 %}'})
|
||||
def test_widthratio06(self):
|
||||
"""
|
||||
62.5 should round to 63 on Python 2 and 62 on Python 3
|
||||
See http://docs.python.org/py3k/whatsnew/3.0.html
|
||||
62.5 should round to 62
|
||||
"""
|
||||
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 %}'})
|
||||
def test_widthratio07(self):
|
||||
|
@ -1,12 +1,10 @@
|
||||
import os
|
||||
from unittest import skipUnless
|
||||
|
||||
from django.template import Context, Engine, TemplateSyntaxError
|
||||
from django.template.base import Node
|
||||
from django.template.library import InvalidTemplateLibrary
|
||||
from django.test import SimpleTestCase
|
||||
from django.test.utils import extend_sys_path
|
||||
from django.utils import six
|
||||
|
||||
from .templatetags import custom, inclusion
|
||||
from .utils import ROOT
|
||||
@ -344,7 +342,6 @@ class TemplateTagLoadingTests(SimpleTestCase):
|
||||
})
|
||||
engine.from_string(ttext)
|
||||
|
||||
@skipUnless(six.PY3, "Python 3 only -- Python 2 doesn't have annotations.")
|
||||
def test_load_annotated_function(self):
|
||||
Engine(libraries={
|
||||
'annotated_tag_function': 'template_tests.annotated_tag_function',
|
||||
|
@ -7,7 +7,6 @@ from contextlib import contextmanager
|
||||
from django.template import TemplateDoesNotExist
|
||||
from django.template.engine import Engine
|
||||
from django.test import SimpleTestCase, override_settings
|
||||
from django.utils import six
|
||||
from django.utils.functional import lazystr
|
||||
|
||||
from .utils import TEMPLATE_DIR
|
||||
@ -64,7 +63,6 @@ class CachedLoaderTests(SimpleTestCase):
|
||||
self.assertIsInstance(e, TemplateDoesNotExist)
|
||||
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):
|
||||
"""
|
||||
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.base import TextNode, VariableNode
|
||||
from django.utils import six
|
||||
|
||||
|
||||
class NodelistTest(TestCase):
|
||||
@ -38,13 +37,11 @@ class TextNodeTest(TestCase):
|
||||
def test_textnode_repr(self):
|
||||
engine = Engine()
|
||||
for temptext, reprtext in [
|
||||
("Hello, world!", "<TextNode: u'Hello, world!'>"),
|
||||
("One\ntwo.", "<TextNode: u'One\\ntwo.'>"),
|
||||
("Hello, world!", "<TextNode: 'Hello, world!'>"),
|
||||
("One\ntwo.", "<TextNode: 'One\\ntwo.'>"),
|
||||
]:
|
||||
template = engine.from_string(temptext)
|
||||
texts = template.nodelist.get_nodes_by_type(TextNode)
|
||||
if six.PY3:
|
||||
reprtext = reprtext.replace("u'", "'")
|
||||
self.assertEqual(repr(texts[0]), reprtext)
|
||||
|
||||
|
||||
|
@ -5,7 +5,6 @@ from django.db import connection
|
||||
from django.test import TestCase
|
||||
from django.test.runner import DiscoverRunner
|
||||
from django.utils import six
|
||||
from django.utils.encoding import force_text
|
||||
|
||||
from .models import Person
|
||||
|
||||
@ -43,8 +42,6 @@ class TestDebugSQL(unittest.TestCase):
|
||||
).run(suite)
|
||||
runner.teardown_databases(old_config)
|
||||
|
||||
if six.PY2:
|
||||
stream.buflist = [force_text(x) for x in stream.buflist]
|
||||
return stream.getvalue()
|
||||
|
||||
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