1
0
mirror of https://github.com/django/django.git synced 2024-12-22 09:05:43 +00:00

Refs #23919 -- Removed six.PY2/PY3 usage

Thanks Tim Graham for the review.
This commit is contained in:
Claude Paroz 2016-12-01 11:38:01 +01:00
parent e63d98b7be
commit c716fe8782
111 changed files with 305 additions and 1296 deletions

View File

@ -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 = []

View File

@ -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

View File

@ -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)),

View File

@ -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'
),

View File

@ -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',
),
),

View File

@ -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',
),
),

View File

@ -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'),

View File

@ -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

View File

@ -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

View File

@ -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.
#

View File

@ -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,

View File

@ -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

View File

@ -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)

View File

@ -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')

View File

@ -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')

View File

@ -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)

View File

@ -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))

View File

@ -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"

View File

@ -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):
"""

View File

@ -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']

View File

@ -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)

View File

@ -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()

View File

@ -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):

View File

@ -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)
)

View File

@ -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:

View File

@ -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):

View File

@ -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):

View File

@ -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(

View File

@ -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

View File

@ -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

View File

@ -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()

View File

@ -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__

View File

@ -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)

View File

@ -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'"')

View File

@ -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

View File

@ -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):

View File

@ -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)

View File

@ -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)

View File

@ -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):

View File

@ -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):

View File

@ -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):

View File

@ -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

View File

@ -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:

View File

@ -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)

View File

@ -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):

View File

@ -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')

View File

@ -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:

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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):

View File

@ -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):

View File

@ -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):

View File

@ -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)

View File

@ -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):

View File

@ -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:

View File

@ -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

View File

@ -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'))

View File

@ -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):

View File

@ -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):

View File

@ -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

View File

@ -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

View File

@ -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']

View File

@ -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()

View File

@ -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')

View File

@ -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

View File

@ -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')

View File

@ -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',

View File

@ -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()

View File

@ -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):

View File

@ -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):
"""

View File

@ -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.

View File

@ -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

View File

@ -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):

View File

@ -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,

View File

@ -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):
"""

View File

@ -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

View File

@ -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)

View File

@ -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.*'))

View File

@ -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):
"""

View File

@ -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)

View File

@ -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.

View File

@ -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)

View File

@ -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

View File

@ -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('*'))

View File

@ -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):

View File

@ -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))

View File

@ -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'

View File

@ -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)))

View File

@ -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

View File

@ -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()

View File

@ -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',

View File

@ -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):

View File

@ -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',

View File

@ -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

View File

@ -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)

View File

@ -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