mirror of
https://github.com/django/django.git
synced 2025-03-12 10:22:37 +00:00
Refs #27656 -- Updated django.utils docstring verbs according to PEP 257.
This commit is contained in:
parent
98bcc5d81b
commit
9718fa2e8a
@ -24,11 +24,11 @@ def npath(path):
|
|||||||
|
|
||||||
def safe_join(base, *paths):
|
def safe_join(base, *paths):
|
||||||
"""
|
"""
|
||||||
Joins one or more path components to the base path component intelligently.
|
Join one or more path components to the base path component intelligently.
|
||||||
Returns a normalized, absolute version of the final path.
|
Return a normalized, absolute version of the final path.
|
||||||
|
|
||||||
The final path must be located inside of the base path component (otherwise
|
Raise ValueError if the final path isn't located inside of the base path
|
||||||
a ValueError is raised).
|
component.
|
||||||
"""
|
"""
|
||||||
base = force_text(base)
|
base = force_text(base)
|
||||||
paths = [force_text(p) for p in paths]
|
paths = [force_text(p) for p in paths]
|
||||||
@ -52,9 +52,9 @@ def safe_join(base, *paths):
|
|||||||
|
|
||||||
def symlinks_supported():
|
def symlinks_supported():
|
||||||
"""
|
"""
|
||||||
A function to check if creating symlinks are supported in the
|
Return whether or not creating symlinks are supported in the host platform
|
||||||
host platform and/or if they are allowed to be created (e.g.
|
and/or if they are allowed to be created (e.g. on Windows it requires admin
|
||||||
on Windows it requires admin permissions).
|
permissions).
|
||||||
"""
|
"""
|
||||||
with tempfile.TemporaryDirectory() as temp_dir:
|
with tempfile.TemporaryDirectory() as temp_dir:
|
||||||
original_path = os.path.join(temp_dir, 'original')
|
original_path = os.path.join(temp_dir, 'original')
|
||||||
|
@ -119,8 +119,8 @@ class BaseArchive:
|
|||||||
|
|
||||||
def has_leading_dir(self, paths):
|
def has_leading_dir(self, paths):
|
||||||
"""
|
"""
|
||||||
Returns true if all the paths have the same leading path name
|
Return True if all the paths have the same leading path name
|
||||||
(i.e., everything is in one subdirectory in an archive)
|
(i.e., everything is in one subdirectory in an archive).
|
||||||
"""
|
"""
|
||||||
common_prefix = None
|
common_prefix = None
|
||||||
for path in paths:
|
for path in paths:
|
||||||
|
@ -81,8 +81,7 @@ _cached_filenames = []
|
|||||||
|
|
||||||
def gen_filenames(only_new=False):
|
def gen_filenames(only_new=False):
|
||||||
"""
|
"""
|
||||||
Returns a list of filenames referenced in sys.modules and translation
|
Return a list of filenames referenced in sys.modules and translation files.
|
||||||
files.
|
|
||||||
"""
|
"""
|
||||||
# N.B. ``list(...)`` is needed, because this runs in parallel with
|
# N.B. ``list(...)`` is needed, because this runs in parallel with
|
||||||
# application code which might be mutating ``sys.modules``, and this will
|
# application code which might be mutating ``sys.modules``, and this will
|
||||||
@ -152,7 +151,7 @@ def reset_translations():
|
|||||||
|
|
||||||
def inotify_code_changed():
|
def inotify_code_changed():
|
||||||
"""
|
"""
|
||||||
Checks for changed code using inotify. After being called
|
Check for changed code using inotify. After being called
|
||||||
it blocks until a change event has been fired.
|
it blocks until a change event has been fired.
|
||||||
"""
|
"""
|
||||||
class EventHandler(pyinotify.ProcessEvent):
|
class EventHandler(pyinotify.ProcessEvent):
|
||||||
|
@ -40,8 +40,8 @@ logger = logging.getLogger('django.request')
|
|||||||
|
|
||||||
def patch_cache_control(response, **kwargs):
|
def patch_cache_control(response, **kwargs):
|
||||||
"""
|
"""
|
||||||
This function patches the Cache-Control header by adding all
|
Patch the Cache-Control header by adding all keyword arguments to it.
|
||||||
keyword arguments to it. The transformation is as follows:
|
The transformation is as follows:
|
||||||
|
|
||||||
* All keyword parameter names are turned to lowercase, and underscores
|
* All keyword parameter names are turned to lowercase, and underscores
|
||||||
are converted to hyphens.
|
are converted to hyphens.
|
||||||
@ -89,8 +89,8 @@ def patch_cache_control(response, **kwargs):
|
|||||||
|
|
||||||
def get_max_age(response):
|
def get_max_age(response):
|
||||||
"""
|
"""
|
||||||
Returns the max-age from the response Cache-Control header as an integer
|
Return the max-age from the response Cache-Control header as an integer,
|
||||||
(or ``None`` if it wasn't found or wasn't an integer.
|
or None if it wasn't found or wasn't an integer.
|
||||||
"""
|
"""
|
||||||
if not response.has_header('Cache-Control'):
|
if not response.has_header('Cache-Control'):
|
||||||
return
|
return
|
||||||
@ -267,7 +267,7 @@ def patch_response_headers(response, cache_timeout=None):
|
|||||||
|
|
||||||
def add_never_cache_headers(response):
|
def add_never_cache_headers(response):
|
||||||
"""
|
"""
|
||||||
Adds headers to a response to indicate that a page should never be cached.
|
Add headers to a response to indicate that a page should never be cached.
|
||||||
"""
|
"""
|
||||||
patch_response_headers(response, cache_timeout=-1)
|
patch_response_headers(response, cache_timeout=-1)
|
||||||
patch_cache_control(response, no_cache=True, no_store=True, must_revalidate=True)
|
patch_cache_control(response, no_cache=True, no_store=True, must_revalidate=True)
|
||||||
@ -275,7 +275,7 @@ def add_never_cache_headers(response):
|
|||||||
|
|
||||||
def patch_vary_headers(response, newheaders):
|
def patch_vary_headers(response, newheaders):
|
||||||
"""
|
"""
|
||||||
Adds (or updates) the "Vary" header in the given HttpResponse object.
|
Add (or update) the "Vary" header in the given HttpResponse object.
|
||||||
newheaders is a list of header names that should be in "Vary". Existing
|
newheaders is a list of header names that should be in "Vary". Existing
|
||||||
headers in "Vary" aren't removed.
|
headers in "Vary" aren't removed.
|
||||||
"""
|
"""
|
||||||
@ -295,7 +295,7 @@ def patch_vary_headers(response, newheaders):
|
|||||||
|
|
||||||
def has_vary_header(response, header_query):
|
def has_vary_header(response, header_query):
|
||||||
"""
|
"""
|
||||||
Checks to see if the response has a given header name in its Vary header.
|
Check to see if the response has a given header name in its Vary header.
|
||||||
"""
|
"""
|
||||||
if not response.has_header('Vary'):
|
if not response.has_header('Vary'):
|
||||||
return False
|
return False
|
||||||
@ -305,7 +305,7 @@ def has_vary_header(response, header_query):
|
|||||||
|
|
||||||
|
|
||||||
def _i18n_cache_key_suffix(request, cache_key):
|
def _i18n_cache_key_suffix(request, cache_key):
|
||||||
"""If necessary, adds the current locale or time zone to the cache key."""
|
"""If necessary, add the current locale or time zone to the cache key."""
|
||||||
if settings.USE_I18N or settings.USE_L10N:
|
if settings.USE_I18N or settings.USE_L10N:
|
||||||
# first check if LocaleMiddleware or another middleware added
|
# first check if LocaleMiddleware or another middleware added
|
||||||
# LANGUAGE_CODE to request, then fall back to the active language
|
# LANGUAGE_CODE to request, then fall back to the active language
|
||||||
@ -322,7 +322,7 @@ def _i18n_cache_key_suffix(request, cache_key):
|
|||||||
|
|
||||||
|
|
||||||
def _generate_cache_key(request, method, headerlist, key_prefix):
|
def _generate_cache_key(request, method, headerlist, key_prefix):
|
||||||
"""Returns a cache key from the headers given in the header list."""
|
"""Return a cache key from the headers given in the header list."""
|
||||||
ctx = hashlib.md5()
|
ctx = hashlib.md5()
|
||||||
for header in headerlist:
|
for header in headerlist:
|
||||||
value = request.META.get(header)
|
value = request.META.get(header)
|
||||||
@ -335,7 +335,7 @@ def _generate_cache_key(request, method, headerlist, key_prefix):
|
|||||||
|
|
||||||
|
|
||||||
def _generate_cache_header_key(key_prefix, request):
|
def _generate_cache_header_key(key_prefix, request):
|
||||||
"""Returns a cache key for the header cache."""
|
"""Return a cache key for the header cache."""
|
||||||
url = hashlib.md5(force_bytes(iri_to_uri(request.build_absolute_uri())))
|
url = hashlib.md5(force_bytes(iri_to_uri(request.build_absolute_uri())))
|
||||||
cache_key = 'views.decorators.cache.cache_header.%s.%s' % (
|
cache_key = 'views.decorators.cache.cache_header.%s.%s' % (
|
||||||
key_prefix, url.hexdigest())
|
key_prefix, url.hexdigest())
|
||||||
@ -344,13 +344,13 @@ def _generate_cache_header_key(key_prefix, request):
|
|||||||
|
|
||||||
def get_cache_key(request, key_prefix=None, method='GET', cache=None):
|
def get_cache_key(request, key_prefix=None, method='GET', cache=None):
|
||||||
"""
|
"""
|
||||||
Returns a cache key based on the request URL and query. It can be used
|
Return a cache key based on the request URL and query. It can be used
|
||||||
in the request phase because it pulls the list of headers to take into
|
in the request phase because it pulls the list of headers to take into
|
||||||
account from the global URL registry and uses those to build a cache key
|
account from the global URL registry and uses those to build a cache key
|
||||||
to check against.
|
to check against.
|
||||||
|
|
||||||
If there is no headerlist stored, the page needs to be rebuilt, so this
|
If there isn't a headerlist stored, return None, indicating that the page
|
||||||
function returns None.
|
needs to be rebuilt.
|
||||||
"""
|
"""
|
||||||
if key_prefix is None:
|
if key_prefix is None:
|
||||||
key_prefix = settings.CACHE_MIDDLEWARE_KEY_PREFIX
|
key_prefix = settings.CACHE_MIDDLEWARE_KEY_PREFIX
|
||||||
@ -366,8 +366,8 @@ def get_cache_key(request, key_prefix=None, method='GET', cache=None):
|
|||||||
|
|
||||||
def learn_cache_key(request, response, cache_timeout=None, key_prefix=None, cache=None):
|
def learn_cache_key(request, response, cache_timeout=None, key_prefix=None, cache=None):
|
||||||
"""
|
"""
|
||||||
Learns what headers to take into account for some request URL from the
|
Learn what headers to take into account for some request URL from the
|
||||||
response object. It stores those headers in a global URL registry so that
|
response object. Store those headers in a global URL registry so that
|
||||||
later access to that URL will know what headers to take into account
|
later access to that URL will know what headers to take into account
|
||||||
without building the response object itself. The headers are named in the
|
without building the response object itself. The headers are named in the
|
||||||
Vary header of the response, but we want to prevent response generation.
|
Vary header of the response, but we want to prevent response generation.
|
||||||
|
@ -22,7 +22,7 @@ except NotImplementedError:
|
|||||||
|
|
||||||
def salted_hmac(key_salt, value, secret=None):
|
def salted_hmac(key_salt, value, secret=None):
|
||||||
"""
|
"""
|
||||||
Returns the HMAC-SHA1 of 'value', using a key generated from key_salt and a
|
Return the HMAC-SHA1 of 'value', using a key generated from key_salt and a
|
||||||
secret (which defaults to settings.SECRET_KEY).
|
secret (which defaults to settings.SECRET_KEY).
|
||||||
|
|
||||||
A different key_salt should be passed in for every application of HMAC.
|
A different key_salt should be passed in for every application of HMAC.
|
||||||
@ -49,7 +49,7 @@ def get_random_string(length=12,
|
|||||||
allowed_chars='abcdefghijklmnopqrstuvwxyz'
|
allowed_chars='abcdefghijklmnopqrstuvwxyz'
|
||||||
'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'):
|
'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'):
|
||||||
"""
|
"""
|
||||||
Returns a securely generated random string.
|
Return a securely generated random string.
|
||||||
|
|
||||||
The default length of 12 with the a-z, A-Z, 0-9 character set returns
|
The default length of 12 with the a-z, A-Z, 0-9 character set returns
|
||||||
a 71-bit value. log_2((26+26+10)^12) =~ 71 bits
|
a 71-bit value. log_2((26+26+10)^12) =~ 71 bits
|
||||||
|
@ -70,8 +70,8 @@ class MultiValueDict(dict):
|
|||||||
|
|
||||||
def __getitem__(self, key):
|
def __getitem__(self, key):
|
||||||
"""
|
"""
|
||||||
Returns the last data value for this key, or [] if it's an empty list;
|
Return the last data value for this key, or [] if it's an empty list;
|
||||||
raises KeyError if not found.
|
raise KeyError if not found.
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
list_ = super().__getitem__(key)
|
list_ = super().__getitem__(key)
|
||||||
@ -114,8 +114,8 @@ class MultiValueDict(dict):
|
|||||||
|
|
||||||
def get(self, key, default=None):
|
def get(self, key, default=None):
|
||||||
"""
|
"""
|
||||||
Returns the last data value for the passed key. If key doesn't exist
|
Return the last data value for the passed key. If key doesn't exist
|
||||||
or value is an empty list, then default is returned.
|
or value is an empty list, return `default`.
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
val = self[key]
|
val = self[key]
|
||||||
@ -170,19 +170,19 @@ class MultiValueDict(dict):
|
|||||||
return self._getlist(key)
|
return self._getlist(key)
|
||||||
|
|
||||||
def appendlist(self, key, value):
|
def appendlist(self, key, value):
|
||||||
"""Appends an item to the internal list associated with key."""
|
"""Append an item to the internal list associated with key."""
|
||||||
self.setlistdefault(key).append(value)
|
self.setlistdefault(key).append(value)
|
||||||
|
|
||||||
def items(self):
|
def items(self):
|
||||||
"""
|
"""
|
||||||
Yields (key, value) pairs, where value is the last item in the list
|
Yield (key, value) pairs, where value is the last item in the list
|
||||||
associated with the key.
|
associated with the key.
|
||||||
"""
|
"""
|
||||||
for key in self:
|
for key in self:
|
||||||
yield key, self[key]
|
yield key, self[key]
|
||||||
|
|
||||||
def lists(self):
|
def lists(self):
|
||||||
"""Yields (key, list) pairs."""
|
"""Yield (key, list) pairs."""
|
||||||
return iter(super().items())
|
return iter(super().items())
|
||||||
|
|
||||||
def values(self):
|
def values(self):
|
||||||
@ -191,14 +191,11 @@ class MultiValueDict(dict):
|
|||||||
yield self[key]
|
yield self[key]
|
||||||
|
|
||||||
def copy(self):
|
def copy(self):
|
||||||
"""Returns a shallow copy of this object."""
|
"""Return a shallow copy of this object."""
|
||||||
return copy.copy(self)
|
return copy.copy(self)
|
||||||
|
|
||||||
def update(self, *args, **kwargs):
|
def update(self, *args, **kwargs):
|
||||||
"""
|
"""Extend rather than replace existing key lists."""
|
||||||
update() extends rather than replaces existing key lists.
|
|
||||||
Also accepts keyword args.
|
|
||||||
"""
|
|
||||||
if len(args) > 1:
|
if len(args) > 1:
|
||||||
raise TypeError("update expected at most 1 arguments, got %d" % len(args))
|
raise TypeError("update expected at most 1 arguments, got %d" % len(args))
|
||||||
if args:
|
if args:
|
||||||
@ -216,9 +213,7 @@ class MultiValueDict(dict):
|
|||||||
self.setlistdefault(key).append(value)
|
self.setlistdefault(key).append(value)
|
||||||
|
|
||||||
def dict(self):
|
def dict(self):
|
||||||
"""
|
"""Return current object as a dict with singular values."""
|
||||||
Returns current object as a dict with singular values.
|
|
||||||
"""
|
|
||||||
return {key: self[key] for key in self}
|
return {key: self[key] for key in self}
|
||||||
|
|
||||||
|
|
||||||
@ -264,7 +259,7 @@ class ImmutableList(tuple):
|
|||||||
|
|
||||||
class DictWrapper(dict):
|
class DictWrapper(dict):
|
||||||
"""
|
"""
|
||||||
Wraps accesses to a dictionary so that certain values (those starting with
|
Wrap accesses to a dictionary so that certain values (those starting with
|
||||||
the specified prefix) are passed through a function before being returned.
|
the specified prefix) are passed through a function before being returned.
|
||||||
The prefix is removed before looking up the real value.
|
The prefix is removed before looking up the real value.
|
||||||
|
|
||||||
@ -278,7 +273,7 @@ class DictWrapper(dict):
|
|||||||
|
|
||||||
def __getitem__(self, key):
|
def __getitem__(self, key):
|
||||||
"""
|
"""
|
||||||
Retrieves the real value after stripping the prefix string (if
|
Retrieve the real value after stripping the prefix string (if
|
||||||
present). If the prefix is present, pass the value through self.func
|
present). If the prefix is present, pass the value through self.func
|
||||||
before returning, otherwise return the raw value.
|
before returning, otherwise return the raw value.
|
||||||
"""
|
"""
|
||||||
|
@ -77,8 +77,7 @@ class TimeFormat(Formatter):
|
|||||||
"""
|
"""
|
||||||
Timezone name.
|
Timezone name.
|
||||||
|
|
||||||
If timezone information is not available, this method returns
|
If timezone information is not available, return an empty string.
|
||||||
an empty string.
|
|
||||||
"""
|
"""
|
||||||
if not self.timezone:
|
if not self.timezone:
|
||||||
return ""
|
return ""
|
||||||
@ -129,8 +128,7 @@ class TimeFormat(Formatter):
|
|||||||
"""
|
"""
|
||||||
Difference to Greenwich time in hours; e.g. '+0200', '-0430'.
|
Difference to Greenwich time in hours; e.g. '+0200', '-0430'.
|
||||||
|
|
||||||
If timezone information is not available, this method returns
|
If timezone information is not available, return an empty string.
|
||||||
an empty string.
|
|
||||||
"""
|
"""
|
||||||
if not self.timezone:
|
if not self.timezone:
|
||||||
return ""
|
return ""
|
||||||
@ -163,8 +161,7 @@ class TimeFormat(Formatter):
|
|||||||
"""
|
"""
|
||||||
Time zone of this machine; e.g. 'EST' or 'MDT'.
|
Time zone of this machine; e.g. 'EST' or 'MDT'.
|
||||||
|
|
||||||
If timezone information is not available, this method returns
|
If timezone information is not available, return an empty string.
|
||||||
an empty string.
|
|
||||||
"""
|
"""
|
||||||
if not self.timezone:
|
if not self.timezone:
|
||||||
return ""
|
return ""
|
||||||
@ -191,8 +188,7 @@ class TimeFormat(Formatter):
|
|||||||
timezones west of UTC is always negative, and for those east of UTC is
|
timezones west of UTC is always negative, and for those east of UTC is
|
||||||
always positive.
|
always positive.
|
||||||
|
|
||||||
If timezone information is not available, this method returns
|
If timezone information is not available, return an empty string.
|
||||||
an empty string.
|
|
||||||
"""
|
"""
|
||||||
if not self.timezone:
|
if not self.timezone:
|
||||||
return ""
|
return ""
|
||||||
|
@ -52,10 +52,10 @@ iso8601_duration_re = re.compile(
|
|||||||
|
|
||||||
|
|
||||||
def parse_date(value):
|
def parse_date(value):
|
||||||
"""Parses a string and return a datetime.date.
|
"""Parse a string and return a datetime.date.
|
||||||
|
|
||||||
Raises ValueError if the input is well formatted but not a valid date.
|
Raise ValueError if the input is well formatted but not a valid date.
|
||||||
Returns None if the input isn't well formatted.
|
Return None if the input isn't well formatted.
|
||||||
"""
|
"""
|
||||||
match = date_re.match(value)
|
match = date_re.match(value)
|
||||||
if match:
|
if match:
|
||||||
@ -64,12 +64,12 @@ def parse_date(value):
|
|||||||
|
|
||||||
|
|
||||||
def parse_time(value):
|
def parse_time(value):
|
||||||
"""Parses a string and return a datetime.time.
|
"""Parse a string and return a datetime.time.
|
||||||
|
|
||||||
This function doesn't support time zone offsets.
|
This function doesn't support time zone offsets.
|
||||||
|
|
||||||
Raises ValueError if the input is well formatted but not a valid time.
|
Raise ValueError if the input is well formatted but not a valid time.
|
||||||
Returns None if the input isn't well formatted, in particular if it
|
Return None if the input isn't well formatted, in particular if it
|
||||||
contains an offset.
|
contains an offset.
|
||||||
"""
|
"""
|
||||||
match = time_re.match(value)
|
match = time_re.match(value)
|
||||||
@ -82,13 +82,13 @@ def parse_time(value):
|
|||||||
|
|
||||||
|
|
||||||
def parse_datetime(value):
|
def parse_datetime(value):
|
||||||
"""Parses a string and return a datetime.datetime.
|
"""Parse a string and return a datetime.datetime.
|
||||||
|
|
||||||
This function supports time zone offsets. When the input contains one,
|
This function supports time zone offsets. When the input contains one,
|
||||||
the output uses a timezone with a fixed offset from UTC.
|
the output uses a timezone with a fixed offset from UTC.
|
||||||
|
|
||||||
Raises ValueError if the input is well formatted but not a valid datetime.
|
Raise ValueError if the input is well formatted but not a valid datetime.
|
||||||
Returns None if the input isn't well formatted.
|
Return None if the input isn't well formatted.
|
||||||
"""
|
"""
|
||||||
match = datetime_re.match(value)
|
match = datetime_re.match(value)
|
||||||
if match:
|
if match:
|
||||||
@ -110,7 +110,7 @@ def parse_datetime(value):
|
|||||||
|
|
||||||
|
|
||||||
def parse_duration(value):
|
def parse_duration(value):
|
||||||
"""Parses a duration string and returns a datetime.timedelta.
|
"""Parse a duration string and return a datetime.timedelta.
|
||||||
|
|
||||||
The preferred format for durations in Django is '%d %H:%M:%S.%f'.
|
The preferred format for durations in Django is '%d %H:%M:%S.%f'.
|
||||||
|
|
||||||
|
@ -5,10 +5,10 @@ from django.utils.version import get_docs_version
|
|||||||
|
|
||||||
def deconstructible(*args, path=None):
|
def deconstructible(*args, path=None):
|
||||||
"""
|
"""
|
||||||
Class decorator that allow the decorated class to be serialized
|
Class decorator that allows the decorated class to be serialized
|
||||||
by the migrations subsystem.
|
by the migrations subsystem.
|
||||||
|
|
||||||
Accepts an optional kwarg `path` to specify the import path.
|
The `path` kwarg specifies the import path.
|
||||||
"""
|
"""
|
||||||
def decorator(klass):
|
def decorator(klass):
|
||||||
def __new__(cls, *args, **kwargs):
|
def __new__(cls, *args, **kwargs):
|
||||||
@ -19,7 +19,7 @@ def deconstructible(*args, path=None):
|
|||||||
|
|
||||||
def deconstruct(obj):
|
def deconstruct(obj):
|
||||||
"""
|
"""
|
||||||
Returns a 3-tuple of class import path, positional arguments,
|
Return a 3-tuple of class import path, positional arguments,
|
||||||
and keyword arguments.
|
and keyword arguments.
|
||||||
"""
|
"""
|
||||||
# Fallback version
|
# Fallback version
|
||||||
|
@ -14,7 +14,7 @@ class classonlymethod(classmethod):
|
|||||||
|
|
||||||
def method_decorator(decorator, name=''):
|
def method_decorator(decorator, name=''):
|
||||||
"""
|
"""
|
||||||
Converts a function decorator into a method decorator
|
Convert a function decorator into a method decorator
|
||||||
"""
|
"""
|
||||||
# 'obj' can be a class or a function. If 'obj' is a function at the time it
|
# 'obj' can be a class or a function. If 'obj' is a function at the time it
|
||||||
# is passed to _dec, it will eventually be a method of the class it is
|
# is passed to _dec, it will eventually be a method of the class it is
|
||||||
@ -90,7 +90,7 @@ def method_decorator(decorator, name=''):
|
|||||||
|
|
||||||
def decorator_from_middleware_with_args(middleware_class):
|
def decorator_from_middleware_with_args(middleware_class):
|
||||||
"""
|
"""
|
||||||
Like decorator_from_middleware, but returns a function
|
Like decorator_from_middleware, but return a function
|
||||||
that accepts the arguments to be passed to the middleware_class.
|
that accepts the arguments to be passed to the middleware_class.
|
||||||
Use like::
|
Use like::
|
||||||
|
|
||||||
@ -106,7 +106,7 @@ def decorator_from_middleware_with_args(middleware_class):
|
|||||||
|
|
||||||
def decorator_from_middleware(middleware_class):
|
def decorator_from_middleware(middleware_class):
|
||||||
"""
|
"""
|
||||||
Given a middleware class (not an instance), returns a view decorator. This
|
Given a middleware class (not an instance), return a view decorator. This
|
||||||
lets you use middleware functionality on a per-view basis. The middleware
|
lets you use middleware functionality on a per-view basis. The middleware
|
||||||
is created with no params passed.
|
is created with no params passed.
|
||||||
"""
|
"""
|
||||||
|
@ -72,7 +72,7 @@ def force_text(s, encoding='utf-8', strings_only=False, errors='strict'):
|
|||||||
|
|
||||||
def smart_bytes(s, encoding='utf-8', strings_only=False, errors='strict'):
|
def smart_bytes(s, encoding='utf-8', strings_only=False, errors='strict'):
|
||||||
"""
|
"""
|
||||||
Returns a bytestring version of 's', encoded as specified in 'encoding'.
|
Return a bytestring version of 's', encoded as specified in 'encoding'.
|
||||||
|
|
||||||
If strings_only is True, don't convert (some) non-string-like objects.
|
If strings_only is True, don't convert (some) non-string-like objects.
|
||||||
"""
|
"""
|
||||||
@ -171,12 +171,12 @@ _hextobyte.update({
|
|||||||
|
|
||||||
def uri_to_iri(uri):
|
def uri_to_iri(uri):
|
||||||
"""
|
"""
|
||||||
Converts a Uniform Resource Identifier(URI) into an Internationalized
|
Convert a Uniform Resource Identifier(URI) into an Internationalized
|
||||||
Resource Identifier(IRI).
|
Resource Identifier(IRI).
|
||||||
|
|
||||||
This is the algorithm from section 3.2 of RFC 3987, excluding step 4.
|
This is the algorithm from section 3.2 of RFC 3987, excluding step 4.
|
||||||
|
|
||||||
Takes an URI in ASCII bytes (e.g. '/I%20%E2%99%A5%20Django/') and returns
|
Take an URI in ASCII bytes (e.g. '/I%20%E2%99%A5%20Django/') and return
|
||||||
a string containing the encoded result (e.g. '/I%20♥%20Django/').
|
a string containing the encoded result (e.g. '/I%20♥%20Django/').
|
||||||
"""
|
"""
|
||||||
if uri is None:
|
if uri is None:
|
||||||
@ -225,8 +225,8 @@ def escape_uri_path(path):
|
|||||||
def repercent_broken_unicode(path):
|
def repercent_broken_unicode(path):
|
||||||
"""
|
"""
|
||||||
As per section 3.2 of RFC 3987, step three of converting a URI into an IRI,
|
As per section 3.2 of RFC 3987, step three of converting a URI into an IRI,
|
||||||
we need to re-percent-encode any octet produced that is not part of a
|
repercent-encode any octet produced that is not part of a strictly legal
|
||||||
strictly legal UTF-8 octet sequence.
|
UTF-8 octet sequence.
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
path.decode()
|
path.decode()
|
||||||
@ -241,12 +241,9 @@ def filepath_to_uri(path):
|
|||||||
"""Convert a file system path to a URI portion that is suitable for
|
"""Convert a file system path to a URI portion that is suitable for
|
||||||
inclusion in a URL.
|
inclusion in a URL.
|
||||||
|
|
||||||
This method will encode certain chars that would normally be recognized as
|
Encode certain chars that would normally be recognized as special chars
|
||||||
special chars for URIs. Note that this method does not encode the '
|
for URIs. Do not encode the ' character, as it is a valid character
|
||||||
character, as it is a valid character within URIs. See
|
within URIs. See the encodeURIComponent() JavaScript function for details.
|
||||||
encodeURIComponent() JavaScript function for more details.
|
|
||||||
|
|
||||||
Return a string containing the result.
|
|
||||||
"""
|
"""
|
||||||
if path is None:
|
if path is None:
|
||||||
return path
|
return path
|
||||||
@ -257,9 +254,9 @@ def filepath_to_uri(path):
|
|||||||
|
|
||||||
def get_system_encoding():
|
def get_system_encoding():
|
||||||
"""
|
"""
|
||||||
The encoding of the default system locale but falls back to the given
|
The encoding of the default system locale. Fallback to 'ascii' if the
|
||||||
fallback encoding if the encoding is unsupported by python or could
|
#encoding is unsupported by Python or could not be determined. See tickets
|
||||||
not be determined. See tickets #10335 and #5846
|
#10335 and #5846.
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
encoding = locale.getdefaultlocale()[1] or 'ascii'
|
encoding = locale.getdefaultlocale()[1] or 'ascii'
|
||||||
|
@ -68,7 +68,7 @@ def rfc3339_date(date):
|
|||||||
|
|
||||||
def get_tag_uri(url, date):
|
def get_tag_uri(url, date):
|
||||||
"""
|
"""
|
||||||
Creates a TagURI.
|
Create a TagURI.
|
||||||
|
|
||||||
See http://web.archive.org/web/20110514113830/http://diveintomark.org/archives/2004/05/28/howto-atom-id
|
See http://web.archive.org/web/20110514113830/http://diveintomark.org/archives/2004/05/28/howto-atom-id
|
||||||
"""
|
"""
|
||||||
@ -176,14 +176,14 @@ class SyndicationFeed:
|
|||||||
|
|
||||||
def write(self, outfile, encoding):
|
def write(self, outfile, encoding):
|
||||||
"""
|
"""
|
||||||
Outputs the feed in the given encoding to outfile, which is a file-like
|
Output the feed in the given encoding to outfile, which is a file-like
|
||||||
object. Subclasses should override this.
|
object. Subclasses should override this.
|
||||||
"""
|
"""
|
||||||
raise NotImplementedError('subclasses of SyndicationFeed must provide a write() method')
|
raise NotImplementedError('subclasses of SyndicationFeed must provide a write() method')
|
||||||
|
|
||||||
def writeString(self, encoding):
|
def writeString(self, encoding):
|
||||||
"""
|
"""
|
||||||
Returns the feed in the given encoding as a string.
|
Return the feed in the given encoding as a string.
|
||||||
"""
|
"""
|
||||||
s = StringIO()
|
s = StringIO()
|
||||||
self.write(s, encoding)
|
self.write(s, encoding)
|
||||||
@ -191,8 +191,8 @@ class SyndicationFeed:
|
|||||||
|
|
||||||
def latest_post_date(self):
|
def latest_post_date(self):
|
||||||
"""
|
"""
|
||||||
Returns the latest item's pubdate or updateddate. If no items
|
Return the latest item's pubdate or updateddate. If no items
|
||||||
have either of these attributes this returns the current UTC date/time.
|
have either of these attributes this return the current UTC date/time.
|
||||||
"""
|
"""
|
||||||
latest_date = None
|
latest_date = None
|
||||||
date_keys = ('updateddate', 'pubdate')
|
date_keys = ('updateddate', 'pubdate')
|
||||||
@ -209,7 +209,7 @@ class SyndicationFeed:
|
|||||||
|
|
||||||
|
|
||||||
class Enclosure:
|
class Enclosure:
|
||||||
"Represents an RSS enclosure"
|
"""An RSS enclosure"""
|
||||||
def __init__(self, url, length, mime_type):
|
def __init__(self, url, length, mime_type):
|
||||||
"All args are expected to be strings"
|
"All args are expected to be strings"
|
||||||
self.length, self.mime_type = length, mime_type
|
self.length, self.mime_type = length, mime_type
|
||||||
|
@ -59,9 +59,7 @@ def reset_format_cache():
|
|||||||
|
|
||||||
|
|
||||||
def iter_format_modules(lang, format_module_path=None):
|
def iter_format_modules(lang, format_module_path=None):
|
||||||
"""
|
"""Find format modules."""
|
||||||
Does the heavy lifting of finding format modules.
|
|
||||||
"""
|
|
||||||
if not check_for_language(lang):
|
if not check_for_language(lang):
|
||||||
return
|
return
|
||||||
|
|
||||||
@ -88,9 +86,7 @@ def iter_format_modules(lang, format_module_path=None):
|
|||||||
|
|
||||||
|
|
||||||
def get_format_modules(lang=None, reverse=False):
|
def get_format_modules(lang=None, reverse=False):
|
||||||
"""
|
"""Return a list of the format modules found."""
|
||||||
Returns a list of the format modules found
|
|
||||||
"""
|
|
||||||
if lang is None:
|
if lang is None:
|
||||||
lang = get_language()
|
lang = get_language()
|
||||||
if lang not in _format_modules_cache:
|
if lang not in _format_modules_cache:
|
||||||
@ -103,11 +99,11 @@ def get_format_modules(lang=None, reverse=False):
|
|||||||
|
|
||||||
def get_format(format_type, lang=None, use_l10n=None):
|
def get_format(format_type, lang=None, use_l10n=None):
|
||||||
"""
|
"""
|
||||||
For a specific format type, returns the format for the current
|
For a specific format type, return the format for the current
|
||||||
language (locale), defaults to the format in the settings.
|
language (locale). Default to the format in the settings.
|
||||||
format_type is the name of the format, e.g. 'DATE_FORMAT'
|
format_type is the name of the format, e.g. 'DATE_FORMAT'.
|
||||||
|
|
||||||
If use_l10n is provided and is not None, that will force the value to
|
If use_l10n is provided and is not None, it forces the value to
|
||||||
be localized (or not), overriding the value of settings.USE_L10N.
|
be localized (or not), overriding the value of settings.USE_L10N.
|
||||||
"""
|
"""
|
||||||
use_l10n = use_l10n or (use_l10n is None and settings.USE_L10N)
|
use_l10n = use_l10n or (use_l10n is None and settings.USE_L10N)
|
||||||
@ -151,8 +147,8 @@ get_format_lazy = lazy(get_format, str, list, tuple)
|
|||||||
|
|
||||||
def date_format(value, format=None, use_l10n=None):
|
def date_format(value, format=None, use_l10n=None):
|
||||||
"""
|
"""
|
||||||
Formats a datetime.date or datetime.datetime object using a
|
Format a datetime.date or datetime.datetime object using a
|
||||||
localizable format
|
localizable format.
|
||||||
|
|
||||||
If use_l10n is provided and is not None, that will force the value to
|
If use_l10n is provided and is not None, that will force the value to
|
||||||
be localized (or not), overriding the value of settings.USE_L10N.
|
be localized (or not), overriding the value of settings.USE_L10N.
|
||||||
@ -162,9 +158,9 @@ def date_format(value, format=None, use_l10n=None):
|
|||||||
|
|
||||||
def time_format(value, format=None, use_l10n=None):
|
def time_format(value, format=None, use_l10n=None):
|
||||||
"""
|
"""
|
||||||
Formats a datetime.time object using a localizable format
|
Format a datetime.time object using a localizable format.
|
||||||
|
|
||||||
If use_l10n is provided and is not None, that will force the value to
|
If use_l10n is provided and is not None, it forces the value to
|
||||||
be localized (or not), overriding the value of settings.USE_L10N.
|
be localized (or not), overriding the value of settings.USE_L10N.
|
||||||
"""
|
"""
|
||||||
return dateformat.time_format(value, get_format(format or 'TIME_FORMAT', use_l10n=use_l10n))
|
return dateformat.time_format(value, get_format(format or 'TIME_FORMAT', use_l10n=use_l10n))
|
||||||
@ -172,9 +168,9 @@ def time_format(value, format=None, use_l10n=None):
|
|||||||
|
|
||||||
def number_format(value, decimal_pos=None, use_l10n=None, force_grouping=False):
|
def number_format(value, decimal_pos=None, use_l10n=None, force_grouping=False):
|
||||||
"""
|
"""
|
||||||
Formats a numeric value using localization settings
|
Format a numeric value using localization settings.
|
||||||
|
|
||||||
If use_l10n is provided and is not None, that will force the value to
|
If use_l10n is provided and is not None, it forces the value to
|
||||||
be localized (or not), overriding the value of settings.USE_L10N.
|
be localized (or not), overriding the value of settings.USE_L10N.
|
||||||
"""
|
"""
|
||||||
if use_l10n or (use_l10n is None and settings.USE_L10N):
|
if use_l10n or (use_l10n is None and settings.USE_L10N):
|
||||||
@ -193,10 +189,10 @@ def number_format(value, decimal_pos=None, use_l10n=None, force_grouping=False):
|
|||||||
|
|
||||||
def localize(value, use_l10n=None):
|
def localize(value, use_l10n=None):
|
||||||
"""
|
"""
|
||||||
Checks if value is a localizable type (date, number...) and returns it
|
Check if value is a localizable type (date, number...) and return it
|
||||||
formatted as a string using current locale format.
|
formatted as a string using current locale format.
|
||||||
|
|
||||||
If use_l10n is provided and is not None, that will force the value to
|
If use_l10n is provided and is not None, it forces the value to
|
||||||
be localized (or not), overriding the value of settings.USE_L10N.
|
be localized (or not), overriding the value of settings.USE_L10N.
|
||||||
"""
|
"""
|
||||||
if isinstance(value, str): # Handle strings first for performance reasons.
|
if isinstance(value, str): # Handle strings first for performance reasons.
|
||||||
@ -216,7 +212,7 @@ def localize(value, use_l10n=None):
|
|||||||
|
|
||||||
def localize_input(value, default=None):
|
def localize_input(value, default=None):
|
||||||
"""
|
"""
|
||||||
Checks if an input value is a localizable type and returns it
|
Check if an input value is a localizable type and return it
|
||||||
formatted with the appropriate formatting string of the current locale.
|
formatted with the appropriate formatting string of the current locale.
|
||||||
"""
|
"""
|
||||||
if isinstance(value, str): # Handle strings first for performance reasons.
|
if isinstance(value, str): # Handle strings first for performance reasons.
|
||||||
@ -241,7 +237,7 @@ def localize_input(value, default=None):
|
|||||||
|
|
||||||
def sanitize_separators(value):
|
def sanitize_separators(value):
|
||||||
"""
|
"""
|
||||||
Sanitizes a value according to the current decimal and
|
Sanitize a value according to the current decimal and
|
||||||
thousand separator setting. Used with form field input.
|
thousand separator setting. Used with form field input.
|
||||||
"""
|
"""
|
||||||
if settings.USE_L10N and isinstance(value, str):
|
if settings.USE_L10N and isinstance(value, str):
|
||||||
|
@ -34,17 +34,16 @@ class cached_property:
|
|||||||
|
|
||||||
class Promise:
|
class Promise:
|
||||||
"""
|
"""
|
||||||
This is just a base class for the proxy class created in
|
Base class for the proxy class created in the closure of the lazy function.
|
||||||
the closure of the lazy function. It can be used to recognize
|
It's used to recognize promises in code.
|
||||||
promises in code.
|
|
||||||
"""
|
"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
def lazy(func, *resultclasses):
|
def lazy(func, *resultclasses):
|
||||||
"""
|
"""
|
||||||
Turns any callable into a lazy evaluated callable. You need to give result
|
Turn any callable into a lazy evaluated callable. result classes or types
|
||||||
classes or types -- at least one is needed so that the automatic forcing of
|
is required -- at least one is needed so that the automatic forcing of
|
||||||
the lazy evaluation code is triggered. Results are not memoized; the
|
the lazy evaluation code is triggered. Results are not memoized; the
|
||||||
function is evaluated on every access.
|
function is evaluated on every access.
|
||||||
"""
|
"""
|
||||||
@ -383,7 +382,7 @@ class SimpleLazyObject(LazyObject):
|
|||||||
|
|
||||||
def partition(predicate, values):
|
def partition(predicate, values):
|
||||||
"""
|
"""
|
||||||
Splits the values into two sets, based on the return value of the function
|
Split the values into two sets, based on the return value of the function
|
||||||
(True/False). e.g.:
|
(True/False). e.g.:
|
||||||
|
|
||||||
>>> partition(lambda x: x > 3, range(5))
|
>>> partition(lambda x: x > 3, range(5))
|
||||||
|
@ -35,12 +35,12 @@ simple_email_re = re.compile(r'^\S+@\S+\.\S+$')
|
|||||||
@keep_lazy(str, SafeText)
|
@keep_lazy(str, SafeText)
|
||||||
def escape(text):
|
def escape(text):
|
||||||
"""
|
"""
|
||||||
Returns the given text with ampersands, quotes and angle brackets encoded
|
Return the given text with ampersands, quotes and angle brackets encoded
|
||||||
for use in HTML.
|
for use in HTML.
|
||||||
|
|
||||||
This function always escapes its input, even if it's already escaped and
|
Always escape input, even if it's already escaped and marked as such.
|
||||||
marked as such. This may result in double-escaping. If this is a concern,
|
This may result in double-escaping. If this is a concern, use
|
||||||
use conditional_escape() instead.
|
conditional_escape() instead.
|
||||||
"""
|
"""
|
||||||
return mark_safe(
|
return mark_safe(
|
||||||
force_text(text).replace('&', '&').replace('<', '<')
|
force_text(text).replace('&', '&').replace('<', '<')
|
||||||
@ -68,7 +68,7 @@ _js_escapes.update((ord('%c' % z), '\\u%04X' % z) for z in range(32))
|
|||||||
|
|
||||||
@keep_lazy(str, SafeText)
|
@keep_lazy(str, SafeText)
|
||||||
def escapejs(value):
|
def escapejs(value):
|
||||||
"""Hex encodes characters for use in JavaScript strings."""
|
"""Hex encode characters for use in JavaScript strings."""
|
||||||
return mark_safe(force_text(value).translate(_js_escapes))
|
return mark_safe(force_text(value).translate(_js_escapes))
|
||||||
|
|
||||||
|
|
||||||
@ -89,8 +89,8 @@ def conditional_escape(text):
|
|||||||
|
|
||||||
def format_html(format_string, *args, **kwargs):
|
def format_html(format_string, *args, **kwargs):
|
||||||
"""
|
"""
|
||||||
Similar to str.format, but passes all arguments through conditional_escape,
|
Similar to str.format, but pass all arguments through conditional_escape(),
|
||||||
and calls 'mark_safe' on the result. This function should be used instead
|
and call mark_safe() on the result. This function should be used instead
|
||||||
of str.format or % interpolation to build up small HTML fragments.
|
of str.format or % interpolation to build up small HTML fragments.
|
||||||
"""
|
"""
|
||||||
args_safe = map(conditional_escape, args)
|
args_safe = map(conditional_escape, args)
|
||||||
@ -119,7 +119,7 @@ def format_html_join(sep, format_string, args_generator):
|
|||||||
|
|
||||||
@keep_lazy_text
|
@keep_lazy_text
|
||||||
def linebreaks(value, autoescape=False):
|
def linebreaks(value, autoescape=False):
|
||||||
"""Converts newlines into <p> and <br />s."""
|
"""Convert newlines into <p> and <br />s."""
|
||||||
value = normalize_newlines(force_text(value))
|
value = normalize_newlines(force_text(value))
|
||||||
paras = re.split('\n{2,}', value)
|
paras = re.split('\n{2,}', value)
|
||||||
if autoescape:
|
if autoescape:
|
||||||
@ -167,7 +167,7 @@ def _strip_once(value):
|
|||||||
|
|
||||||
@keep_lazy_text
|
@keep_lazy_text
|
||||||
def strip_tags(value):
|
def strip_tags(value):
|
||||||
"""Returns the given HTML with all tags stripped."""
|
"""Return the given HTML with all tags stripped."""
|
||||||
# Note: in typical case this loop executes _strip_once once. Loop condition
|
# Note: in typical case this loop executes _strip_once once. Loop condition
|
||||||
# is redundant, but helps to reduce number of executions of _strip_once.
|
# is redundant, but helps to reduce number of executions of _strip_once.
|
||||||
value = force_text(value)
|
value = force_text(value)
|
||||||
@ -182,12 +182,12 @@ def strip_tags(value):
|
|||||||
|
|
||||||
@keep_lazy_text
|
@keep_lazy_text
|
||||||
def strip_spaces_between_tags(value):
|
def strip_spaces_between_tags(value):
|
||||||
"""Returns the given HTML with spaces between tags removed."""
|
"""Return the given HTML with spaces between tags removed."""
|
||||||
return re.sub(r'>\s+<', '><', force_text(value))
|
return re.sub(r'>\s+<', '><', force_text(value))
|
||||||
|
|
||||||
|
|
||||||
def smart_urlquote(url):
|
def smart_urlquote(url):
|
||||||
"Quotes a URL if it isn't already quoted."
|
"""Quote a URL if it isn't already quoted."""
|
||||||
def unquote_quote(segment):
|
def unquote_quote(segment):
|
||||||
segment = unquote(segment)
|
segment = unquote(segment)
|
||||||
# Tilde is part of RFC3986 Unreserved Characters
|
# Tilde is part of RFC3986 Unreserved Characters
|
||||||
@ -225,20 +225,19 @@ def smart_urlquote(url):
|
|||||||
@keep_lazy_text
|
@keep_lazy_text
|
||||||
def urlize(text, trim_url_limit=None, nofollow=False, autoescape=False):
|
def urlize(text, trim_url_limit=None, nofollow=False, autoescape=False):
|
||||||
"""
|
"""
|
||||||
Converts any URLs in text into clickable links.
|
Convert any URLs in text into clickable links.
|
||||||
|
|
||||||
Works on http://, https://, www. links, and also on links ending in one of
|
Works on http://, https://, www. links, and also on links ending in one of
|
||||||
the original seven gTLDs (.com, .edu, .gov, .int, .mil, .net, and .org).
|
the original seven gTLDs (.com, .edu, .gov, .int, .mil, .net, and .org).
|
||||||
Links can have trailing punctuation (periods, commas, close-parens) and
|
Links can have trailing punctuation (periods, commas, close-parens) and
|
||||||
leading punctuation (opening parens) and it'll still do the right thing.
|
leading punctuation (opening parens) and it'll still do the right thing.
|
||||||
|
|
||||||
If trim_url_limit is not None, the URLs in the link text longer than this
|
If trim_url_limit is not None, truncate the URLs in the link text longer
|
||||||
limit will be truncated to trim_url_limit-3 characters and appended with
|
than this limit to trim_url_limit-3 characters and append an ellipsis.
|
||||||
an ellipsis.
|
|
||||||
|
|
||||||
If nofollow is True, the links will get a rel="nofollow" attribute.
|
If nofollow is True, give the links a rel="nofollow" attribute.
|
||||||
|
|
||||||
If autoescape is True, the link text and URLs will be autoescaped.
|
If autoescape is True, autoescape the link text and URLs.
|
||||||
"""
|
"""
|
||||||
safe_input = isinstance(text, SafeData)
|
safe_input = isinstance(text, SafeData)
|
||||||
|
|
||||||
@ -249,8 +248,8 @@ def urlize(text, trim_url_limit=None, nofollow=False, autoescape=False):
|
|||||||
|
|
||||||
def unescape(text, trail):
|
def unescape(text, trail):
|
||||||
"""
|
"""
|
||||||
If input URL is HTML-escaped, unescape it so as we can safely feed it to
|
If input URL is HTML-escaped, unescape it so that it can be safely fed
|
||||||
smart_urlquote. For example:
|
to smart_urlquote. For example:
|
||||||
http://example.com?x=1&y=<2> => http://example.com?x=1&y=<2>
|
http://example.com?x=1&y=<2> => http://example.com?x=1&y=<2>
|
||||||
"""
|
"""
|
||||||
unescaped = (text + trail).replace(
|
unescaped = (text + trail).replace(
|
||||||
|
@ -98,13 +98,13 @@ def urlencode(query, doseq=False):
|
|||||||
|
|
||||||
def cookie_date(epoch_seconds=None):
|
def cookie_date(epoch_seconds=None):
|
||||||
"""
|
"""
|
||||||
Formats the time to ensure compatibility with Netscape's cookie standard.
|
Format the time to ensure compatibility with Netscape's cookie standard.
|
||||||
|
|
||||||
Accepts a floating point number expressed in seconds since the epoch, in
|
`epoch_seconds` is a floating point number expressed in seconds since the
|
||||||
UTC - such as that outputted by time.time(). If set to None, defaults to
|
epoch, in UTC - such as that outputted by time.time(). If set to None, it
|
||||||
the current time.
|
defaults to the current time.
|
||||||
|
|
||||||
Outputs a string in the format 'Wdy, DD-Mon-YYYY HH:MM:SS GMT'.
|
Output a string in the format 'Wdy, DD-Mon-YYYY HH:MM:SS GMT'.
|
||||||
"""
|
"""
|
||||||
rfcdate = formatdate(epoch_seconds)
|
rfcdate = formatdate(epoch_seconds)
|
||||||
return '%s-%s-%s GMT' % (rfcdate[:7], rfcdate[8:11], rfcdate[12:25])
|
return '%s-%s-%s GMT' % (rfcdate[:7], rfcdate[8:11], rfcdate[12:25])
|
||||||
@ -112,26 +112,26 @@ def cookie_date(epoch_seconds=None):
|
|||||||
|
|
||||||
def http_date(epoch_seconds=None):
|
def http_date(epoch_seconds=None):
|
||||||
"""
|
"""
|
||||||
Formats the time to match the RFC1123 date format as specified by HTTP
|
Format the time to match the RFC1123 date format as specified by HTTP
|
||||||
RFC7231 section 7.1.1.1.
|
RFC7231 section 7.1.1.1.
|
||||||
|
|
||||||
Accepts a floating point number expressed in seconds since the epoch, in
|
`epoch_seconds` is a floating point number expressed in seconds since the
|
||||||
UTC - such as that outputted by time.time(). If set to None, defaults to
|
epoch, in UTC - such as that outputted by time.time(). If set to None, it
|
||||||
the current time.
|
defaults to the current time.
|
||||||
|
|
||||||
Outputs a string in the format 'Wdy, DD Mon YYYY HH:MM:SS GMT'.
|
Output a string in the format 'Wdy, DD Mon YYYY HH:MM:SS GMT'.
|
||||||
"""
|
"""
|
||||||
return formatdate(epoch_seconds, usegmt=True)
|
return formatdate(epoch_seconds, usegmt=True)
|
||||||
|
|
||||||
|
|
||||||
def parse_http_date(date):
|
def parse_http_date(date):
|
||||||
"""
|
"""
|
||||||
Parses a date format as specified by HTTP RFC7231 section 7.1.1.1.
|
Parse a date format as specified by HTTP RFC7231 section 7.1.1.1.
|
||||||
|
|
||||||
The three formats allowed by the RFC are accepted, even if only the first
|
The three formats allowed by the RFC are accepted, even if only the first
|
||||||
one is still in widespread use.
|
one is still in widespread use.
|
||||||
|
|
||||||
Returns an integer expressed in seconds since the epoch, in UTC.
|
Return an integer expressed in seconds since the epoch, in UTC.
|
||||||
"""
|
"""
|
||||||
# emails.Util.parsedate does the job for RFC1123 dates; unfortunately
|
# emails.Util.parsedate does the job for RFC1123 dates; unfortunately
|
||||||
# RFC7231 makes it mandatory to support RFC850 dates too. So we roll
|
# RFC7231 makes it mandatory to support RFC850 dates too. So we roll
|
||||||
@ -162,7 +162,7 @@ def parse_http_date(date):
|
|||||||
|
|
||||||
def parse_http_date_safe(date):
|
def parse_http_date_safe(date):
|
||||||
"""
|
"""
|
||||||
Same as parse_http_date, but returns None if the input is invalid.
|
Same as parse_http_date, but return None if the input is invalid.
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
return parse_http_date(date)
|
return parse_http_date(date)
|
||||||
@ -174,8 +174,8 @@ def parse_http_date_safe(date):
|
|||||||
|
|
||||||
def base36_to_int(s):
|
def base36_to_int(s):
|
||||||
"""
|
"""
|
||||||
Converts a base 36 string to an ``int``. Raises ``ValueError` if the
|
Convert a base 36 string to an int. Raise ValueError if the input won't fit
|
||||||
input won't fit into an int.
|
into an int.
|
||||||
"""
|
"""
|
||||||
# To prevent overconsumption of server resources, reject any
|
# To prevent overconsumption of server resources, reject any
|
||||||
# base36 string that is longer than 13 base36 digits (13 digits
|
# base36 string that is longer than 13 base36 digits (13 digits
|
||||||
@ -186,9 +186,7 @@ def base36_to_int(s):
|
|||||||
|
|
||||||
|
|
||||||
def int_to_base36(i):
|
def int_to_base36(i):
|
||||||
"""
|
"""Convert an integer to a base36 string."""
|
||||||
Converts an integer to a base36 string
|
|
||||||
"""
|
|
||||||
char_set = '0123456789abcdefghijklmnopqrstuvwxyz'
|
char_set = '0123456789abcdefghijklmnopqrstuvwxyz'
|
||||||
if i < 0:
|
if i < 0:
|
||||||
raise ValueError("Negative base36 conversion input.")
|
raise ValueError("Negative base36 conversion input.")
|
||||||
@ -203,15 +201,15 @@ def int_to_base36(i):
|
|||||||
|
|
||||||
def urlsafe_base64_encode(s):
|
def urlsafe_base64_encode(s):
|
||||||
"""
|
"""
|
||||||
Encodes a bytestring in base64 for use in URLs, stripping any trailing
|
Encode a bytestring in base64 for use in URLs. Strip any trailing equal
|
||||||
equal signs.
|
signs.
|
||||||
"""
|
"""
|
||||||
return base64.urlsafe_b64encode(s).rstrip(b'\n=')
|
return base64.urlsafe_b64encode(s).rstrip(b'\n=')
|
||||||
|
|
||||||
|
|
||||||
def urlsafe_base64_decode(s):
|
def urlsafe_base64_decode(s):
|
||||||
"""
|
"""
|
||||||
Decodes a base64 encoded string, adding back any trailing equal signs that
|
Decode a base64 encoded string. Add back any trailing equal signs that
|
||||||
might have been stripped.
|
might have been stripped.
|
||||||
"""
|
"""
|
||||||
s = force_bytes(s)
|
s = force_bytes(s)
|
||||||
@ -270,7 +268,7 @@ def is_safe_url(url, host=None, allowed_hosts=None, require_https=False):
|
|||||||
Return ``True`` if the url is a safe redirection (i.e. it doesn't point to
|
Return ``True`` if the url is a safe redirection (i.e. it doesn't point to
|
||||||
a different host and uses a safe scheme).
|
a different host and uses a safe scheme).
|
||||||
|
|
||||||
Always returns ``False`` on an empty url.
|
Always return ``False`` on an empty url.
|
||||||
|
|
||||||
If ``require_https`` is ``True``, only 'https' will be considered a valid
|
If ``require_https`` is ``True``, only 'https' will be considered a valid
|
||||||
scheme, as opposed to 'http' and 'https' with the default, ``False``.
|
scheme, as opposed to 'http' and 'https' with the default, ``False``.
|
||||||
|
@ -37,13 +37,7 @@ def clean_ipv6_address(ip_str, unpack_ipv4=False,
|
|||||||
|
|
||||||
def is_valid_ipv6_address(ip_str):
|
def is_valid_ipv6_address(ip_str):
|
||||||
"""
|
"""
|
||||||
Ensure we have a valid IPv6 address.
|
Return whether or not the `ip_str` string is a valid IPv6 address.
|
||||||
|
|
||||||
Args:
|
|
||||||
ip_str: A string, the IPv6 address.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
A boolean, True if this is a valid IPv6 address.
|
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
ipaddress.IPv6Address(ip_str)
|
ipaddress.IPv6Address(ip_str)
|
||||||
|
@ -1,12 +1,5 @@
|
|||||||
"""
|
|
||||||
Providing iterator functions that are not in all version of Python we support.
|
|
||||||
Where possible, we try to use the system-native version and only fall back to
|
|
||||||
these implementations if necessary.
|
|
||||||
"""
|
|
||||||
|
|
||||||
|
|
||||||
def is_iterable(x):
|
def is_iterable(x):
|
||||||
"A implementation independent way of checking for iterables"
|
"An implementation independent way of checking for iterables"
|
||||||
try:
|
try:
|
||||||
iter(x)
|
iter(x)
|
||||||
except TypeError:
|
except TypeError:
|
||||||
|
@ -50,7 +50,7 @@ class Lexer:
|
|||||||
"""
|
"""
|
||||||
Lexically analyze `text`.
|
Lexically analyze `text`.
|
||||||
|
|
||||||
Yields pairs (`name`, `tokentext`).
|
Yield pairs (`name`, `tokentext`).
|
||||||
"""
|
"""
|
||||||
end = len(text)
|
end = len(text)
|
||||||
state = self.state
|
state = self.state
|
||||||
|
@ -55,7 +55,7 @@ COMMON_WORDS = (
|
|||||||
|
|
||||||
def sentence():
|
def sentence():
|
||||||
"""
|
"""
|
||||||
Returns a randomly generated sentence of lorem ipsum text.
|
Return a randomly generated sentence of lorem ipsum text.
|
||||||
|
|
||||||
The first word is capitalized, and the sentence ends in either a period or
|
The first word is capitalized, and the sentence ends in either a period or
|
||||||
question mark. Commas are added at random.
|
question mark. Commas are added at random.
|
||||||
@ -70,7 +70,7 @@ def sentence():
|
|||||||
|
|
||||||
def paragraph():
|
def paragraph():
|
||||||
"""
|
"""
|
||||||
Returns a randomly generated paragraph of lorem ipsum text.
|
Return a randomly generated paragraph of lorem ipsum text.
|
||||||
|
|
||||||
The paragraph consists of between 1 and 4 sentences, inclusive.
|
The paragraph consists of between 1 and 4 sentences, inclusive.
|
||||||
"""
|
"""
|
||||||
@ -79,7 +79,7 @@ def paragraph():
|
|||||||
|
|
||||||
def paragraphs(count, common=True):
|
def paragraphs(count, common=True):
|
||||||
"""
|
"""
|
||||||
Returns a list of paragraphs as returned by paragraph().
|
Return a list of paragraphs as returned by paragraph().
|
||||||
|
|
||||||
If `common` is True, then the first paragraph will be the standard
|
If `common` is True, then the first paragraph will be the standard
|
||||||
'lorem ipsum' paragraph. Otherwise, the first paragraph will be random
|
'lorem ipsum' paragraph. Otherwise, the first paragraph will be random
|
||||||
@ -96,7 +96,7 @@ def paragraphs(count, common=True):
|
|||||||
|
|
||||||
def words(count, common=True):
|
def words(count, common=True):
|
||||||
"""
|
"""
|
||||||
Returns a string of `count` lorem ipsum words separated by a single space.
|
Return a string of `count` lorem ipsum words separated by a single space.
|
||||||
|
|
||||||
If `common` is True, then the first 19 words will be the standard
|
If `common` is True, then the first 19 words will be the standard
|
||||||
'lorem ipsum' words. Otherwise, all words will be selected randomly.
|
'lorem ipsum' words. Otherwise, all words will be selected randomly.
|
||||||
|
@ -7,7 +7,7 @@ from django.utils.safestring import mark_safe
|
|||||||
def format(number, decimal_sep, decimal_pos=None, grouping=0, thousand_sep='',
|
def format(number, decimal_sep, decimal_pos=None, grouping=0, thousand_sep='',
|
||||||
force_grouping=False):
|
force_grouping=False):
|
||||||
"""
|
"""
|
||||||
Gets a number (as a number or string), and returns it as a string,
|
Get a number (as a number or string), and return it as a string,
|
||||||
using formats defined as arguments:
|
using formats defined as arguments:
|
||||||
|
|
||||||
* decimal_sep: Decimal separator symbol (for example ".")
|
* decimal_sep: Decimal separator symbol (for example ".")
|
||||||
|
@ -27,28 +27,20 @@ ESCAPE_MAPPINGS = {
|
|||||||
|
|
||||||
|
|
||||||
class Choice(list):
|
class Choice(list):
|
||||||
"""
|
"""Represent multiple possibilities at this point in a pattern string."""
|
||||||
Used to represent multiple possibilities at this point in a pattern string.
|
|
||||||
We use a distinguished type, rather than a list, so that the usage in the
|
|
||||||
code is clear.
|
|
||||||
"""
|
|
||||||
|
|
||||||
|
|
||||||
class Group(list):
|
class Group(list):
|
||||||
"""
|
"""Represent a capturing group in the pattern string."""
|
||||||
Used to represent a capturing group in the pattern string.
|
|
||||||
"""
|
|
||||||
|
|
||||||
|
|
||||||
class NonCapture(list):
|
class NonCapture(list):
|
||||||
"""
|
"""Represent a non-capturing group in the pattern string."""
|
||||||
Used to represent a non-capturing group in the pattern string.
|
|
||||||
"""
|
|
||||||
|
|
||||||
|
|
||||||
def normalize(pattern):
|
def normalize(pattern):
|
||||||
r"""
|
r"""
|
||||||
Given a reg-exp pattern, normalizes it to an iterable of forms that
|
Given a reg-exp pattern, normalize it to an iterable of forms that
|
||||||
suffice for reverse matching. This does the following:
|
suffice for reverse matching. This does the following:
|
||||||
|
|
||||||
(1) For any repeating sections, keeps the minimum number of occurrences
|
(1) For any repeating sections, keeps the minimum number of occurrences
|
||||||
@ -212,7 +204,7 @@ def next_char(input_iter):
|
|||||||
its class (e.g. \w -> "x"). If the escaped character is one that is
|
its class (e.g. \w -> "x"). If the escaped character is one that is
|
||||||
skipped, it is not returned (the next character is returned instead).
|
skipped, it is not returned (the next character is returned instead).
|
||||||
|
|
||||||
Yields the next character, along with a boolean indicating whether it is a
|
Yield the next character, along with a boolean indicating whether it is a
|
||||||
raw (unescaped) character or not.
|
raw (unescaped) character or not.
|
||||||
"""
|
"""
|
||||||
for ch in input_iter:
|
for ch in input_iter:
|
||||||
@ -228,8 +220,8 @@ def next_char(input_iter):
|
|||||||
|
|
||||||
def walk_to_end(ch, input_iter):
|
def walk_to_end(ch, input_iter):
|
||||||
"""
|
"""
|
||||||
The iterator is currently inside a capturing group. We want to walk to the
|
The iterator is currently inside a capturing group. Walk to the close of
|
||||||
close of this group, skipping over any nested groups and handling escaped
|
this group, skipping over any nested groups and handling escaped
|
||||||
parentheses correctly.
|
parentheses correctly.
|
||||||
"""
|
"""
|
||||||
if ch == '(':
|
if ch == '(':
|
||||||
@ -252,7 +244,7 @@ def get_quantifier(ch, input_iter):
|
|||||||
Parse a quantifier from the input, where "ch" is the first character in the
|
Parse a quantifier from the input, where "ch" is the first character in the
|
||||||
quantifier.
|
quantifier.
|
||||||
|
|
||||||
Returns the minimum number of occurrences permitted by the quantifier and
|
Return the minimum number of occurrences permitted by the quantifier and
|
||||||
either None or the next character from the input_iter if the next character
|
either None or the next character from the input_iter if the next character
|
||||||
is not part of the quantifier.
|
is not part of the quantifier.
|
||||||
"""
|
"""
|
||||||
@ -286,7 +278,7 @@ def get_quantifier(ch, input_iter):
|
|||||||
|
|
||||||
def contains(source, inst):
|
def contains(source, inst):
|
||||||
"""
|
"""
|
||||||
Returns True if the "source" contains an instance of "inst". False,
|
Return True if the "source" contains an instance of "inst". False,
|
||||||
otherwise.
|
otherwise.
|
||||||
"""
|
"""
|
||||||
if isinstance(source, inst):
|
if isinstance(source, inst):
|
||||||
@ -300,8 +292,8 @@ def contains(source, inst):
|
|||||||
|
|
||||||
def flatten_result(source):
|
def flatten_result(source):
|
||||||
"""
|
"""
|
||||||
Turns the given source sequence into a list of reg-exp possibilities and
|
Turn the given source sequence into a list of reg-exp possibilities and
|
||||||
their arguments. Returns a list of strings and a list of argument lists.
|
their arguments. Return a list of strings and a list of argument lists.
|
||||||
Each of the two lists will be of the same length.
|
Each of the two lists will be of the same length.
|
||||||
"""
|
"""
|
||||||
if source is None:
|
if source is None:
|
||||||
|
@ -11,7 +11,7 @@ from django.utils.functional import Promise, wraps
|
|||||||
class SafeData:
|
class SafeData:
|
||||||
def __html__(self):
|
def __html__(self):
|
||||||
"""
|
"""
|
||||||
Returns the html representation of a string for interoperability.
|
Return the html representation of a string for interoperability.
|
||||||
|
|
||||||
This allows other template engines to understand Django's SafeData.
|
This allows other template engines to understand Django's SafeData.
|
||||||
"""
|
"""
|
||||||
|
@ -12,12 +12,12 @@ opt_dict = {'bold': '1', 'underscore': '4', 'blink': '5', 'reverse': '7', 'conce
|
|||||||
|
|
||||||
def colorize(text='', opts=(), **kwargs):
|
def colorize(text='', opts=(), **kwargs):
|
||||||
"""
|
"""
|
||||||
Returns your text, enclosed in ANSI graphics codes.
|
Return your text, enclosed in ANSI graphics codes.
|
||||||
|
|
||||||
Depends on the keyword arguments 'fg' and 'bg', and the contents of
|
Depends on the keyword arguments 'fg' and 'bg', and the contents of
|
||||||
the opts tuple/list.
|
the opts tuple/list.
|
||||||
|
|
||||||
Returns the RESET code if no parameters are given.
|
Return the RESET code if no parameters are given.
|
||||||
|
|
||||||
Valid colors:
|
Valid colors:
|
||||||
'black', 'red', 'green', 'yellow', 'blue', 'magenta', 'cyan', 'white'
|
'black', 'red', 'green', 'yellow', 'blue', 'magenta', 'cyan', 'white'
|
||||||
@ -57,7 +57,7 @@ def colorize(text='', opts=(), **kwargs):
|
|||||||
|
|
||||||
def make_style(opts=(), **kwargs):
|
def make_style(opts=(), **kwargs):
|
||||||
"""
|
"""
|
||||||
Returns a function with default parameters for colorize()
|
Return a function with default parameters for colorize()
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
bold_red = make_style(opts=('bold',), fg='red')
|
bold_red = make_style(opts=('bold',), fg='red')
|
||||||
|
@ -32,10 +32,10 @@ def wrap(text, width):
|
|||||||
A word-wrap function that preserves existing line breaks. Expects that
|
A word-wrap function that preserves existing line breaks. Expects that
|
||||||
existing line breaks are posix newlines.
|
existing line breaks are posix newlines.
|
||||||
|
|
||||||
All white space is preserved except added line breaks consume the space on
|
Preserve all white space except added line breaks consume the space on
|
||||||
which they break the line.
|
which they break the line.
|
||||||
|
|
||||||
Long words are not wrapped, so the output text may have lines longer than
|
Don't wrap long words, thus the output text may have lines longer than
|
||||||
``width``.
|
``width``.
|
||||||
"""
|
"""
|
||||||
text = force_text(text)
|
text = force_text(text)
|
||||||
@ -84,12 +84,12 @@ class Truncator(SimpleLazyObject):
|
|||||||
|
|
||||||
def chars(self, num, truncate=None, html=False):
|
def chars(self, num, truncate=None, html=False):
|
||||||
"""
|
"""
|
||||||
Returns the text truncated to be no longer than the specified number
|
Return the text truncated to be no longer than the specified number
|
||||||
of characters.
|
of characters.
|
||||||
|
|
||||||
Takes an optional argument of what should be used to notify that the
|
`truncate` specifies what should be used to notify that the string has
|
||||||
string has been truncated, defaulting to a translatable string of an
|
been truncated, defaulting to a translatable string of an ellipsis
|
||||||
ellipsis (...).
|
(...).
|
||||||
"""
|
"""
|
||||||
self._setup()
|
self._setup()
|
||||||
length = int(num)
|
length = int(num)
|
||||||
@ -107,9 +107,7 @@ class Truncator(SimpleLazyObject):
|
|||||||
return self._text_chars(length, truncate, text, truncate_len)
|
return self._text_chars(length, truncate, text, truncate_len)
|
||||||
|
|
||||||
def _text_chars(self, length, truncate, text, truncate_len):
|
def _text_chars(self, length, truncate, text, truncate_len):
|
||||||
"""
|
"""Truncate a string after a certain number of chars."""
|
||||||
Truncates a string after a certain number of chars.
|
|
||||||
"""
|
|
||||||
s_len = 0
|
s_len = 0
|
||||||
end_index = None
|
end_index = None
|
||||||
for i, char in enumerate(text):
|
for i, char in enumerate(text):
|
||||||
@ -130,9 +128,9 @@ class Truncator(SimpleLazyObject):
|
|||||||
|
|
||||||
def words(self, num, truncate=None, html=False):
|
def words(self, num, truncate=None, html=False):
|
||||||
"""
|
"""
|
||||||
Truncates a string after a certain number of words. Takes an optional
|
Truncate a string after a certain number of words. `truncate` specifies
|
||||||
argument of what should be used to notify that the string has been
|
what should be used to notify that the string has been truncated,
|
||||||
truncated, defaulting to ellipsis (...).
|
defaulting to ellipsis (...).
|
||||||
"""
|
"""
|
||||||
self._setup()
|
self._setup()
|
||||||
length = int(num)
|
length = int(num)
|
||||||
@ -142,9 +140,9 @@ class Truncator(SimpleLazyObject):
|
|||||||
|
|
||||||
def _text_words(self, length, truncate):
|
def _text_words(self, length, truncate):
|
||||||
"""
|
"""
|
||||||
Truncates a string after a certain number of words.
|
Truncate a string after a certain number of words.
|
||||||
|
|
||||||
Newlines in the string will be stripped.
|
Strip newlines in the string.
|
||||||
"""
|
"""
|
||||||
words = self._wrapped.split()
|
words = self._wrapped.split()
|
||||||
if len(words) > length:
|
if len(words) > length:
|
||||||
@ -154,11 +152,11 @@ class Truncator(SimpleLazyObject):
|
|||||||
|
|
||||||
def _truncate_html(self, length, truncate, text, truncate_len, words):
|
def _truncate_html(self, length, truncate, text, truncate_len, words):
|
||||||
"""
|
"""
|
||||||
Truncates HTML to a certain number of chars (not counting tags and
|
Truncate HTML to a certain number of chars (not counting tags and
|
||||||
comments), or, if words is True, then to a certain number of words.
|
comments), or, if words is True, then to a certain number of words.
|
||||||
Closes opened tags if they were correctly closed in the given HTML.
|
Close opened tags if they were correctly closed in the given HTML.
|
||||||
|
|
||||||
Newlines in the HTML are preserved.
|
Preserve newlines in the HTML.
|
||||||
"""
|
"""
|
||||||
if words and length <= 0:
|
if words and length <= 0:
|
||||||
return ''
|
return ''
|
||||||
@ -228,10 +226,10 @@ class Truncator(SimpleLazyObject):
|
|||||||
@keep_lazy_text
|
@keep_lazy_text
|
||||||
def get_valid_filename(s):
|
def get_valid_filename(s):
|
||||||
"""
|
"""
|
||||||
Returns the given string converted to a string that can be used for a clean
|
Return the given string converted to a string that can be used for a clean
|
||||||
filename. Specifically, leading and trailing spaces are removed; other
|
filename. Remove leading and trailing spaces; convert other spaces to
|
||||||
spaces are converted to underscores; and anything that is not an
|
underscores; and remove anything that is not an alphanumeric, dash,
|
||||||
alphanumeric, dash, underscore, or dot, is removed.
|
underscore, or dot.
|
||||||
>>> get_valid_filename("john's portrait in 2004.jpg")
|
>>> get_valid_filename("john's portrait in 2004.jpg")
|
||||||
'johns_portrait_in_2004.jpg'
|
'johns_portrait_in_2004.jpg'
|
||||||
"""
|
"""
|
||||||
@ -265,14 +263,14 @@ def get_text_list(list_, last_word=gettext_lazy('or')):
|
|||||||
|
|
||||||
@keep_lazy_text
|
@keep_lazy_text
|
||||||
def normalize_newlines(text):
|
def normalize_newlines(text):
|
||||||
"""Normalizes CRLF and CR newlines to just LF."""
|
"""Normalize CRLF and CR newlines to just LF."""
|
||||||
text = force_text(text)
|
text = force_text(text)
|
||||||
return re_newlines.sub('\n', text)
|
return re_newlines.sub('\n', text)
|
||||||
|
|
||||||
|
|
||||||
@keep_lazy_text
|
@keep_lazy_text
|
||||||
def phone2numeric(phone):
|
def phone2numeric(phone):
|
||||||
"""Converts a phone number with letters into its numeric equivalent."""
|
"""Convert a phone number with letters into its numeric equivalent."""
|
||||||
char2number = {
|
char2number = {
|
||||||
'a': '2', 'b': '2', 'c': '2', 'd': '3', 'e': '3', 'f': '3', 'g': '4',
|
'a': '2', 'b': '2', 'c': '2', 'd': '3', 'e': '3', 'f': '3', 'g': '4',
|
||||||
'h': '4', 'i': '4', 'j': '5', 'k': '5', 'l': '5', 'm': '6', 'n': '6',
|
'h': '4', 'i': '4', 'j': '5', 'k': '5', 'l': '5', 'm': '6', 'n': '6',
|
||||||
@ -426,8 +424,7 @@ def slugify(value, allow_unicode=False):
|
|||||||
|
|
||||||
def camel_case_to_spaces(value):
|
def camel_case_to_spaces(value):
|
||||||
"""
|
"""
|
||||||
Splits CamelCase and converts to lower case. Also strips leading and
|
Split CamelCase and convert to lower case. Strip surrounding whitespace.
|
||||||
trailing whitespace.
|
|
||||||
"""
|
"""
|
||||||
return re_camel_case.sub(r' \1', value).strip().lower()
|
return re_camel_case.sub(r' \1', value).strip().lower()
|
||||||
|
|
||||||
|
@ -17,9 +17,9 @@ TIMESINCE_CHUNKS = (
|
|||||||
|
|
||||||
def timesince(d, now=None, reversed=False):
|
def timesince(d, now=None, reversed=False):
|
||||||
"""
|
"""
|
||||||
Takes two datetime objects and returns the time between d and now
|
Take two datetime objects and return the time between d and now as a nicely
|
||||||
as a nicely formatted string, e.g. "10 minutes". If d occurs after now,
|
formatted string, e.g. "10 minutes". If d occurs after now, return
|
||||||
then "0 minutes" is returned.
|
"0 minutes".
|
||||||
|
|
||||||
Units used are years, months, weeks, days, hours, and minutes.
|
Units used are years, months, weeks, days, hours, and minutes.
|
||||||
Seconds and microseconds are ignored. Up to two adjacent units will be
|
Seconds and microseconds are ignored. Up to two adjacent units will be
|
||||||
@ -72,7 +72,6 @@ def timesince(d, now=None, reversed=False):
|
|||||||
|
|
||||||
def timeuntil(d, now=None):
|
def timeuntil(d, now=None):
|
||||||
"""
|
"""
|
||||||
Like timesince, but returns a string measuring the time until
|
Like timesince, but return a string measuring the time until the given time.
|
||||||
the given time.
|
|
||||||
"""
|
"""
|
||||||
return timesince(d, now, reversed=True)
|
return timesince(d, now, reversed=True)
|
||||||
|
@ -51,14 +51,12 @@ class FixedOffset(tzinfo):
|
|||||||
return ZERO
|
return ZERO
|
||||||
|
|
||||||
|
|
||||||
|
# UTC time zone as a tzinfo instance.
|
||||||
utc = pytz.utc
|
utc = pytz.utc
|
||||||
"""UTC time zone as a tzinfo instance."""
|
|
||||||
|
|
||||||
|
|
||||||
def get_fixed_timezone(offset):
|
def get_fixed_timezone(offset):
|
||||||
"""
|
"""Return a tzinfo instance with a fixed offset from UTC."""
|
||||||
Returns a tzinfo instance with a fixed offset from UTC.
|
|
||||||
"""
|
|
||||||
if isinstance(offset, timedelta):
|
if isinstance(offset, timedelta):
|
||||||
offset = offset.seconds // 60
|
offset = offset.seconds // 60
|
||||||
sign = '-' if offset < 0 else '+'
|
sign = '-' if offset < 0 else '+'
|
||||||
@ -72,7 +70,7 @@ def get_fixed_timezone(offset):
|
|||||||
@functools.lru_cache()
|
@functools.lru_cache()
|
||||||
def get_default_timezone():
|
def get_default_timezone():
|
||||||
"""
|
"""
|
||||||
Returns the default time zone as a tzinfo instance.
|
Return the default time zone as a tzinfo instance.
|
||||||
|
|
||||||
This is the time zone defined by settings.TIME_ZONE.
|
This is the time zone defined by settings.TIME_ZONE.
|
||||||
"""
|
"""
|
||||||
@ -81,9 +79,7 @@ def get_default_timezone():
|
|||||||
|
|
||||||
# This function exists for consistency with get_current_timezone_name
|
# This function exists for consistency with get_current_timezone_name
|
||||||
def get_default_timezone_name():
|
def get_default_timezone_name():
|
||||||
"""
|
"""Return the name of the default time zone."""
|
||||||
Returns the name of the default time zone.
|
|
||||||
"""
|
|
||||||
return _get_timezone_name(get_default_timezone())
|
return _get_timezone_name(get_default_timezone())
|
||||||
|
|
||||||
|
|
||||||
@ -91,23 +87,17 @@ _active = local()
|
|||||||
|
|
||||||
|
|
||||||
def get_current_timezone():
|
def get_current_timezone():
|
||||||
"""
|
"""Return the currently active time zone as a tzinfo instance."""
|
||||||
Returns the currently active time zone as a tzinfo instance.
|
|
||||||
"""
|
|
||||||
return getattr(_active, "value", get_default_timezone())
|
return getattr(_active, "value", get_default_timezone())
|
||||||
|
|
||||||
|
|
||||||
def get_current_timezone_name():
|
def get_current_timezone_name():
|
||||||
"""
|
"""Return the name of the currently active time zone."""
|
||||||
Returns the name of the currently active time zone.
|
|
||||||
"""
|
|
||||||
return _get_timezone_name(get_current_timezone())
|
return _get_timezone_name(get_current_timezone())
|
||||||
|
|
||||||
|
|
||||||
def _get_timezone_name(timezone):
|
def _get_timezone_name(timezone):
|
||||||
"""
|
"""Return the name of ``timezone``."""
|
||||||
Returns the name of ``timezone``.
|
|
||||||
"""
|
|
||||||
try:
|
try:
|
||||||
# for pytz timezones
|
# for pytz timezones
|
||||||
return timezone.zone
|
return timezone.zone
|
||||||
@ -123,7 +113,7 @@ def _get_timezone_name(timezone):
|
|||||||
|
|
||||||
def activate(timezone):
|
def activate(timezone):
|
||||||
"""
|
"""
|
||||||
Sets the time zone for the current thread.
|
Set the time zone for the current thread.
|
||||||
|
|
||||||
The ``timezone`` argument must be an instance of a tzinfo subclass or a
|
The ``timezone`` argument must be an instance of a tzinfo subclass or a
|
||||||
time zone name.
|
time zone name.
|
||||||
@ -138,7 +128,7 @@ def activate(timezone):
|
|||||||
|
|
||||||
def deactivate():
|
def deactivate():
|
||||||
"""
|
"""
|
||||||
Unsets the time zone for the current thread.
|
Unset the time zone for the current thread.
|
||||||
|
|
||||||
Django will then use the time zone defined by settings.TIME_ZONE.
|
Django will then use the time zone defined by settings.TIME_ZONE.
|
||||||
"""
|
"""
|
||||||
@ -150,8 +140,8 @@ class override(ContextDecorator):
|
|||||||
"""
|
"""
|
||||||
Temporarily set the time zone for the current thread.
|
Temporarily set the time zone for the current thread.
|
||||||
|
|
||||||
This is a context manager that uses ``~django.utils.timezone.activate()``
|
This is a context manager that uses django.utils.timezone.activate()
|
||||||
to set the timezone on entry, and restores the previously active timezone
|
to set the timezone on entry and restores the previously active timezone
|
||||||
on exit.
|
on exit.
|
||||||
|
|
||||||
The ``timezone`` argument must be an instance of a ``tzinfo`` subclass, a
|
The ``timezone`` argument must be an instance of a ``tzinfo`` subclass, a
|
||||||
@ -179,7 +169,7 @@ class override(ContextDecorator):
|
|||||||
|
|
||||||
def template_localtime(value, use_tz=None):
|
def template_localtime(value, use_tz=None):
|
||||||
"""
|
"""
|
||||||
Checks if value is a datetime and converts it to local time if necessary.
|
Check if value is a datetime and converts it to local time if necessary.
|
||||||
|
|
||||||
If use_tz is provided and is not None, that will force the value to
|
If use_tz is provided and is not None, that will force the value to
|
||||||
be converted (or not), overriding the value of settings.USE_TZ.
|
be converted (or not), overriding the value of settings.USE_TZ.
|
||||||
@ -199,7 +189,7 @@ def template_localtime(value, use_tz=None):
|
|||||||
|
|
||||||
def localtime(value=None, timezone=None):
|
def localtime(value=None, timezone=None):
|
||||||
"""
|
"""
|
||||||
Converts an aware datetime.datetime to local time.
|
Convert an aware datetime.datetime to local time.
|
||||||
|
|
||||||
Only aware datetimes are allowed. When value is omitted, it defaults to
|
Only aware datetimes are allowed. When value is omitted, it defaults to
|
||||||
now().
|
now().
|
||||||
@ -236,7 +226,7 @@ def localdate(value=None, timezone=None):
|
|||||||
|
|
||||||
def now():
|
def now():
|
||||||
"""
|
"""
|
||||||
Returns an aware or naive datetime.datetime, depending on settings.USE_TZ.
|
Return an aware or naive datetime.datetime, depending on settings.USE_TZ.
|
||||||
"""
|
"""
|
||||||
if settings.USE_TZ:
|
if settings.USE_TZ:
|
||||||
# timeit shows that datetime.now(tz=utc) is 24% slower
|
# timeit shows that datetime.now(tz=utc) is 24% slower
|
||||||
@ -250,7 +240,7 @@ def now():
|
|||||||
|
|
||||||
def is_aware(value):
|
def is_aware(value):
|
||||||
"""
|
"""
|
||||||
Determines if a given datetime.datetime is aware.
|
Determine if a given datetime.datetime is aware.
|
||||||
|
|
||||||
The concept is defined in Python's docs:
|
The concept is defined in Python's docs:
|
||||||
http://docs.python.org/library/datetime.html#datetime.tzinfo
|
http://docs.python.org/library/datetime.html#datetime.tzinfo
|
||||||
@ -263,7 +253,7 @@ def is_aware(value):
|
|||||||
|
|
||||||
def is_naive(value):
|
def is_naive(value):
|
||||||
"""
|
"""
|
||||||
Determines if a given datetime.datetime is naive.
|
Determine if a given datetime.datetime is naive.
|
||||||
|
|
||||||
The concept is defined in Python's docs:
|
The concept is defined in Python's docs:
|
||||||
http://docs.python.org/library/datetime.html#datetime.tzinfo
|
http://docs.python.org/library/datetime.html#datetime.tzinfo
|
||||||
@ -275,9 +265,7 @@ def is_naive(value):
|
|||||||
|
|
||||||
|
|
||||||
def make_aware(value, timezone=None, is_dst=None):
|
def make_aware(value, timezone=None, is_dst=None):
|
||||||
"""
|
"""Make a naive datetime.datetime in a given time zone aware."""
|
||||||
Makes a naive datetime.datetime in a given time zone aware.
|
|
||||||
"""
|
|
||||||
if timezone is None:
|
if timezone is None:
|
||||||
timezone = get_current_timezone()
|
timezone = get_current_timezone()
|
||||||
if hasattr(timezone, 'localize'):
|
if hasattr(timezone, 'localize'):
|
||||||
@ -293,9 +281,7 @@ def make_aware(value, timezone=None, is_dst=None):
|
|||||||
|
|
||||||
|
|
||||||
def make_naive(value, timezone=None):
|
def make_naive(value, timezone=None):
|
||||||
"""
|
"""Make an aware datetime.datetime naive in a given time zone."""
|
||||||
Makes an aware datetime.datetime naive in a given time zone.
|
|
||||||
"""
|
|
||||||
if timezone is None:
|
if timezone is None:
|
||||||
timezone = get_current_timezone()
|
timezone = get_current_timezone()
|
||||||
# Emulate the behavior of astimezone() on Python < 3.6.
|
# Emulate the behavior of astimezone() on Python < 3.6.
|
||||||
|
@ -59,7 +59,7 @@ def reset_cache(**kwargs):
|
|||||||
|
|
||||||
def to_locale(language, to_lower=False):
|
def to_locale(language, to_lower=False):
|
||||||
"""
|
"""
|
||||||
Turns a language name (en-us) into a locale name (en_US). If 'to_lower' is
|
Turn a language name (en-us) into a locale name (en_US). If 'to_lower' is
|
||||||
True, the last component is lower-cased (en_us).
|
True, the last component is lower-cased (en_us).
|
||||||
"""
|
"""
|
||||||
p = language.find('-')
|
p = language.find('-')
|
||||||
@ -76,7 +76,7 @@ def to_locale(language, to_lower=False):
|
|||||||
|
|
||||||
|
|
||||||
def to_language(locale):
|
def to_language(locale):
|
||||||
"""Turns a locale name (en_US) into a language name (en-us)."""
|
"""Turn a locale name (en_US) into a language name (en-us)."""
|
||||||
p = locale.find('_')
|
p = locale.find('_')
|
||||||
if p >= 0:
|
if p >= 0:
|
||||||
return locale[:p].lower() + '-' + locale[p + 1:].lower()
|
return locale[:p].lower() + '-' + locale[p + 1:].lower()
|
||||||
@ -86,8 +86,7 @@ def to_language(locale):
|
|||||||
|
|
||||||
class DjangoTranslation(gettext_module.GNUTranslations):
|
class DjangoTranslation(gettext_module.GNUTranslations):
|
||||||
"""
|
"""
|
||||||
This class sets up the GNUTranslations context with regard to output
|
Set up the GNUTranslations context with regard to output charset.
|
||||||
charset.
|
|
||||||
|
|
||||||
This translation object will be constructed out of multiple GNUTranslations
|
This translation object will be constructed out of multiple GNUTranslations
|
||||||
objects by merging their catalogs. It will construct an object for the
|
objects by merging their catalogs. It will construct an object for the
|
||||||
@ -138,7 +137,7 @@ class DjangoTranslation(gettext_module.GNUTranslations):
|
|||||||
|
|
||||||
def _new_gnu_trans(self, localedir, use_null_fallback=True):
|
def _new_gnu_trans(self, localedir, use_null_fallback=True):
|
||||||
"""
|
"""
|
||||||
Returns a mergeable gettext.GNUTranslations instance.
|
Return a mergeable gettext.GNUTranslations instance.
|
||||||
|
|
||||||
A convenience wrapper. By default gettext uses 'fallback=False'.
|
A convenience wrapper. By default gettext uses 'fallback=False'.
|
||||||
Using param `use_null_fallback` to avoid confusion with any other
|
Using param `use_null_fallback` to avoid confusion with any other
|
||||||
@ -152,14 +151,14 @@ class DjangoTranslation(gettext_module.GNUTranslations):
|
|||||||
fallback=use_null_fallback)
|
fallback=use_null_fallback)
|
||||||
|
|
||||||
def _init_translation_catalog(self):
|
def _init_translation_catalog(self):
|
||||||
"""Creates a base catalog using global django translations."""
|
"""Create a base catalog using global django translations."""
|
||||||
settingsfile = sys.modules[settings.__module__].__file__
|
settingsfile = sys.modules[settings.__module__].__file__
|
||||||
localedir = os.path.join(os.path.dirname(settingsfile), 'locale')
|
localedir = os.path.join(os.path.dirname(settingsfile), 'locale')
|
||||||
translation = self._new_gnu_trans(localedir)
|
translation = self._new_gnu_trans(localedir)
|
||||||
self.merge(translation)
|
self.merge(translation)
|
||||||
|
|
||||||
def _add_installed_apps_translations(self):
|
def _add_installed_apps_translations(self):
|
||||||
"""Merges translations from each installed app."""
|
"""Merge translations from each installed app."""
|
||||||
try:
|
try:
|
||||||
app_configs = reversed(list(apps.get_app_configs()))
|
app_configs = reversed(list(apps.get_app_configs()))
|
||||||
except AppRegistryNotReady:
|
except AppRegistryNotReady:
|
||||||
@ -174,13 +173,13 @@ class DjangoTranslation(gettext_module.GNUTranslations):
|
|||||||
self.merge(translation)
|
self.merge(translation)
|
||||||
|
|
||||||
def _add_local_translations(self):
|
def _add_local_translations(self):
|
||||||
"""Merges translations defined in LOCALE_PATHS."""
|
"""Merge translations defined in LOCALE_PATHS."""
|
||||||
for localedir in reversed(settings.LOCALE_PATHS):
|
for localedir in reversed(settings.LOCALE_PATHS):
|
||||||
translation = self._new_gnu_trans(localedir)
|
translation = self._new_gnu_trans(localedir)
|
||||||
self.merge(translation)
|
self.merge(translation)
|
||||||
|
|
||||||
def _add_fallback(self, localedirs=None):
|
def _add_fallback(self, localedirs=None):
|
||||||
"""Sets the GNUTranslations() fallback with the default language."""
|
"""Set the GNUTranslations() fallback with the default language."""
|
||||||
# Don't set a fallback for the default language or any English variant
|
# Don't set a fallback for the default language or any English variant
|
||||||
# (as it's empty, so it'll ALWAYS fall back to the default language)
|
# (as it's empty, so it'll ALWAYS fall back to the default language)
|
||||||
if self.__language == settings.LANGUAGE_CODE or self.__language.startswith('en'):
|
if self.__language == settings.LANGUAGE_CODE or self.__language.startswith('en'):
|
||||||
@ -207,17 +206,17 @@ class DjangoTranslation(gettext_module.GNUTranslations):
|
|||||||
self._catalog.update(other._catalog)
|
self._catalog.update(other._catalog)
|
||||||
|
|
||||||
def language(self):
|
def language(self):
|
||||||
"""Returns the translation language."""
|
"""Return the translation language."""
|
||||||
return self.__language
|
return self.__language
|
||||||
|
|
||||||
def to_language(self):
|
def to_language(self):
|
||||||
"""Returns the translation language name."""
|
"""Return the translation language name."""
|
||||||
return self.__to_language
|
return self.__to_language
|
||||||
|
|
||||||
|
|
||||||
def translation(language):
|
def translation(language):
|
||||||
"""
|
"""
|
||||||
Returns a translation object in the default 'django' domain.
|
Return a translation object in the default 'django' domain.
|
||||||
"""
|
"""
|
||||||
global _translations
|
global _translations
|
||||||
if language not in _translations:
|
if language not in _translations:
|
||||||
@ -227,7 +226,7 @@ def translation(language):
|
|||||||
|
|
||||||
def activate(language):
|
def activate(language):
|
||||||
"""
|
"""
|
||||||
Fetches the translation object for a given language and installs it as the
|
Fetch the translation object for a given language and install it as the
|
||||||
current translation object for the current thread.
|
current translation object for the current thread.
|
||||||
"""
|
"""
|
||||||
if not language:
|
if not language:
|
||||||
@ -237,8 +236,8 @@ def activate(language):
|
|||||||
|
|
||||||
def deactivate():
|
def deactivate():
|
||||||
"""
|
"""
|
||||||
Deinstalls the currently active translation object so that further _ calls
|
Uninstall the active translation object so that further _() calls resolve
|
||||||
will resolve against the default translation object, again.
|
to the default translation object.
|
||||||
"""
|
"""
|
||||||
if hasattr(_active, "value"):
|
if hasattr(_active, "value"):
|
||||||
del _active.value
|
del _active.value
|
||||||
@ -246,7 +245,7 @@ def deactivate():
|
|||||||
|
|
||||||
def deactivate_all():
|
def deactivate_all():
|
||||||
"""
|
"""
|
||||||
Makes the active translation object a NullTranslations() instance. This is
|
Make the active translation object a NullTranslations() instance. This is
|
||||||
useful when we want delayed translations to appear as the original string
|
useful when we want delayed translations to appear as the original string
|
||||||
for some reason.
|
for some reason.
|
||||||
"""
|
"""
|
||||||
@ -255,7 +254,7 @@ def deactivate_all():
|
|||||||
|
|
||||||
|
|
||||||
def get_language():
|
def get_language():
|
||||||
"""Returns the currently selected language."""
|
"""Return the currently selected language."""
|
||||||
t = getattr(_active, "value", None)
|
t = getattr(_active, "value", None)
|
||||||
if t is not None:
|
if t is not None:
|
||||||
try:
|
try:
|
||||||
@ -268,7 +267,7 @@ def get_language():
|
|||||||
|
|
||||||
def get_language_bidi():
|
def get_language_bidi():
|
||||||
"""
|
"""
|
||||||
Returns selected language's BiDi layout.
|
Return selected language's BiDi layout.
|
||||||
|
|
||||||
* False = left-to-right layout
|
* False = left-to-right layout
|
||||||
* True = right-to-left layout
|
* True = right-to-left layout
|
||||||
@ -283,7 +282,7 @@ def get_language_bidi():
|
|||||||
|
|
||||||
def catalog():
|
def catalog():
|
||||||
"""
|
"""
|
||||||
Returns the current active catalog for further processing.
|
Return the current active catalog for further processing.
|
||||||
This can be used if you need to modify the catalog or want to access the
|
This can be used if you need to modify the catalog or want to access the
|
||||||
whole message catalog instead of just translating one string.
|
whole message catalog instead of just translating one string.
|
||||||
"""
|
"""
|
||||||
@ -308,7 +307,7 @@ def gettext(message):
|
|||||||
eol_message = message.replace('\r\n', '\n').replace('\r', '\n')
|
eol_message = message.replace('\r\n', '\n').replace('\r', '\n')
|
||||||
|
|
||||||
if len(eol_message) == 0:
|
if len(eol_message) == 0:
|
||||||
# Returns an empty value of the corresponding type if an empty message
|
# Return an empty value of the corresponding type if an empty message
|
||||||
# is given, instead of metadata, which is the default gettext behavior.
|
# is given, instead of metadata, which is the default gettext behavior.
|
||||||
result = type(message)("")
|
result = type(message)("")
|
||||||
else:
|
else:
|
||||||
@ -335,7 +334,7 @@ def pgettext(context, message):
|
|||||||
|
|
||||||
def gettext_noop(message):
|
def gettext_noop(message):
|
||||||
"""
|
"""
|
||||||
Marks strings for translation but doesn't translate them now. This can be
|
Mark strings for translation but don't translate them now. This can be
|
||||||
used to store strings in global variables that should stay in the base
|
used to store strings in global variables that should stay in the base
|
||||||
language (because they might be used externally) and will be translated
|
language (because they might be used externally) and will be translated
|
||||||
later.
|
later.
|
||||||
@ -356,7 +355,7 @@ def do_ntranslate(singular, plural, number, translation_function):
|
|||||||
|
|
||||||
def ngettext(singular, plural, number):
|
def ngettext(singular, plural, number):
|
||||||
"""
|
"""
|
||||||
Returns a string of the translation of either the singular or plural,
|
Return a string of the translation of either the singular or plural,
|
||||||
based on the number.
|
based on the number.
|
||||||
"""
|
"""
|
||||||
return do_ntranslate(singular, plural, number, 'ngettext')
|
return do_ntranslate(singular, plural, number, 'ngettext')
|
||||||
@ -375,7 +374,7 @@ def npgettext(context, singular, plural, number):
|
|||||||
|
|
||||||
def all_locale_paths():
|
def all_locale_paths():
|
||||||
"""
|
"""
|
||||||
Returns a list of paths to user-provides languages files.
|
Return a list of paths to user-provides languages files.
|
||||||
"""
|
"""
|
||||||
globalpath = os.path.join(
|
globalpath = os.path.join(
|
||||||
os.path.dirname(sys.modules[settings.__module__].__file__), 'locale')
|
os.path.dirname(sys.modules[settings.__module__].__file__), 'locale')
|
||||||
@ -385,7 +384,7 @@ def all_locale_paths():
|
|||||||
@functools.lru_cache(maxsize=1000)
|
@functools.lru_cache(maxsize=1000)
|
||||||
def check_for_language(lang_code):
|
def check_for_language(lang_code):
|
||||||
"""
|
"""
|
||||||
Checks whether there is a global language file for the given language
|
Check whether there is a global language file for the given language
|
||||||
code. This is used to decide whether a user-provided language is
|
code. This is used to decide whether a user-provided language is
|
||||||
available.
|
available.
|
||||||
|
|
||||||
@ -413,10 +412,10 @@ def get_languages():
|
|||||||
@functools.lru_cache(maxsize=1000)
|
@functools.lru_cache(maxsize=1000)
|
||||||
def get_supported_language_variant(lang_code, strict=False):
|
def get_supported_language_variant(lang_code, strict=False):
|
||||||
"""
|
"""
|
||||||
Returns the language-code that's listed in supported languages, possibly
|
Return the language-code that's listed in supported languages, possibly
|
||||||
selecting a more generic variant. Raises LookupError if nothing found.
|
selecting a more generic variant. Raise LookupError if nothing is found.
|
||||||
|
|
||||||
If `strict` is False (the default), the function will look for an alternative
|
If `strict` is False (the default), look for an alternative
|
||||||
country-specific variant when the currently checked is not found.
|
country-specific variant when the currently checked is not found.
|
||||||
|
|
||||||
lru_cache should have a maxsize to prevent from memory exhaustion attacks,
|
lru_cache should have a maxsize to prevent from memory exhaustion attacks,
|
||||||
@ -447,7 +446,7 @@ def get_supported_language_variant(lang_code, strict=False):
|
|||||||
|
|
||||||
def get_language_from_path(path, strict=False):
|
def get_language_from_path(path, strict=False):
|
||||||
"""
|
"""
|
||||||
Returns the language-code if there is a valid language-code
|
Return the language-code if there is a valid language-code
|
||||||
found in the `path`.
|
found in the `path`.
|
||||||
|
|
||||||
If `strict` is False (the default), the function will look for an alternative
|
If `strict` is False (the default), the function will look for an alternative
|
||||||
@ -465,7 +464,7 @@ def get_language_from_path(path, strict=False):
|
|||||||
|
|
||||||
def get_language_from_request(request, check_path=False):
|
def get_language_from_request(request, check_path=False):
|
||||||
"""
|
"""
|
||||||
Analyzes the request to find what language the user wants the system to
|
Analyze the request to find what language the user wants the system to
|
||||||
show. Only languages listed in settings.LANGUAGES are taken into account.
|
show. Only languages listed in settings.LANGUAGES are taken into account.
|
||||||
If the user requests a sublanguage where we have a main language, we send
|
If the user requests a sublanguage where we have a main language, we send
|
||||||
out the main language.
|
out the main language.
|
||||||
@ -513,10 +512,10 @@ def get_language_from_request(request, check_path=False):
|
|||||||
|
|
||||||
def parse_accept_lang_header(lang_string):
|
def parse_accept_lang_header(lang_string):
|
||||||
"""
|
"""
|
||||||
Parses the lang_string, which is the body of an HTTP Accept-Language
|
Parse the lang_string, which is the body of an HTTP Accept-Language
|
||||||
header, and returns a list of (lang, q-value), ordered by 'q' values.
|
header, and return a list of (lang, q-value), ordered by 'q' values.
|
||||||
|
|
||||||
Any format errors in lang_string results in an empty list being returned.
|
Return an empty list if there are any format errors in lang_string.
|
||||||
"""
|
"""
|
||||||
result = []
|
result = []
|
||||||
pieces = accept_language_re.split(lang_string.lower())
|
pieces = accept_language_re.split(lang_string.lower())
|
||||||
|
@ -17,25 +17,22 @@ class Node:
|
|||||||
default = 'DEFAULT'
|
default = 'DEFAULT'
|
||||||
|
|
||||||
def __init__(self, children=None, connector=None, negated=False):
|
def __init__(self, children=None, connector=None, negated=False):
|
||||||
"""
|
"""Construct a new Node. If no connector is given, use the default."""
|
||||||
Constructs a new Node. If no connector is given, the default will be
|
|
||||||
used.
|
|
||||||
"""
|
|
||||||
self.children = children[:] if children else []
|
self.children = children[:] if children else []
|
||||||
self.connector = connector or self.default
|
self.connector = connector or self.default
|
||||||
self.negated = negated
|
self.negated = negated
|
||||||
|
|
||||||
# We need this because of django.db.models.query_utils.Q. Q. __init__() is
|
# Required because django.db.models.query_utils.Q. Q. __init__() is
|
||||||
# problematic, but it is a natural Node subclass in all other respects.
|
# problematic, but it is a natural Node subclass in all other respects.
|
||||||
@classmethod
|
@classmethod
|
||||||
def _new_instance(cls, children=None, connector=None, negated=False):
|
def _new_instance(cls, children=None, connector=None, negated=False):
|
||||||
"""
|
"""
|
||||||
This is called to create a new instance of this class when we need new
|
Create a new instance of this class when new Nodes (or subclasses) are
|
||||||
Nodes (or subclasses) in the internal code in this class. Normally, it
|
needed in the internal code in this class. Normally, it just shadows
|
||||||
just shadows __init__(). However, subclasses with an __init__ signature
|
__init__(). However, subclasses with an __init__ signature that aren't
|
||||||
that is not an extension of Node.__init__ might need to implement this
|
an extension of Node.__init__ might need to implement this method to
|
||||||
method to allow a Node to create a new instance of them (if they have
|
allow a Node to create a new instance of them (if they have any extra
|
||||||
any extra setting up to do).
|
setting up to do).
|
||||||
"""
|
"""
|
||||||
obj = Node(children, connector, negated)
|
obj = Node(children, connector, negated)
|
||||||
obj.__class__ = cls
|
obj.__class__ = cls
|
||||||
@ -49,43 +46,34 @@ class Node:
|
|||||||
return "<%s: %s>" % (self.__class__.__name__, self)
|
return "<%s: %s>" % (self.__class__.__name__, self)
|
||||||
|
|
||||||
def __deepcopy__(self, memodict):
|
def __deepcopy__(self, memodict):
|
||||||
"""
|
|
||||||
Utility method used by copy.deepcopy().
|
|
||||||
"""
|
|
||||||
obj = Node(connector=self.connector, negated=self.negated)
|
obj = Node(connector=self.connector, negated=self.negated)
|
||||||
obj.__class__ = self.__class__
|
obj.__class__ = self.__class__
|
||||||
obj.children = copy.deepcopy(self.children, memodict)
|
obj.children = copy.deepcopy(self.children, memodict)
|
||||||
return obj
|
return obj
|
||||||
|
|
||||||
def __len__(self):
|
def __len__(self):
|
||||||
"""
|
"""Return the the number of children this node has."""
|
||||||
The size of a node if the number of children it has.
|
|
||||||
"""
|
|
||||||
return len(self.children)
|
return len(self.children)
|
||||||
|
|
||||||
def __bool__(self):
|
def __bool__(self):
|
||||||
"""
|
"""Return whether or not this node has children."""
|
||||||
For truth value testing.
|
|
||||||
"""
|
|
||||||
return bool(self.children)
|
return bool(self.children)
|
||||||
|
|
||||||
def __contains__(self, other):
|
def __contains__(self, other):
|
||||||
"""
|
"""Return True if 'other' is a direct child of this instance."""
|
||||||
Returns True is 'other' is a direct child of this instance.
|
|
||||||
"""
|
|
||||||
return other in self.children
|
return other in self.children
|
||||||
|
|
||||||
def add(self, data, conn_type, squash=True):
|
def add(self, data, conn_type, squash=True):
|
||||||
"""
|
"""
|
||||||
Combines this tree and the data represented by data using the
|
Combine this tree and the data represented by data using the
|
||||||
connector conn_type. The combine is done by squashing the node other
|
connector conn_type. The combine is done by squashing the node other
|
||||||
away if possible.
|
away if possible.
|
||||||
|
|
||||||
This tree (self) will never be pushed to a child node of the
|
This tree (self) will never be pushed to a child node of the
|
||||||
combined tree, nor will the connector or negated properties change.
|
combined tree, nor will the connector or negated properties change.
|
||||||
|
|
||||||
The function returns a node which can be used in place of data
|
Return a node which can be used in place of data regardless if the
|
||||||
regardless if the node other got squashed or not.
|
node other got squashed or not.
|
||||||
|
|
||||||
If `squash` is False the data is prepared and added as a child to
|
If `squash` is False the data is prepared and added as a child to
|
||||||
this tree without further logic.
|
this tree without further logic.
|
||||||
@ -120,7 +108,5 @@ class Node:
|
|||||||
return data
|
return data
|
||||||
|
|
||||||
def negate(self):
|
def negate(self):
|
||||||
"""
|
"""Negate the sense of the root connector."""
|
||||||
Negate the sense of the root connector.
|
|
||||||
"""
|
|
||||||
self.negated = not self.negated
|
self.negated = not self.negated
|
||||||
|
@ -5,7 +5,7 @@ import subprocess
|
|||||||
|
|
||||||
|
|
||||||
def get_version(version=None):
|
def get_version(version=None):
|
||||||
"Returns a PEP 440-compliant version number from VERSION."
|
"""Return a PEP 440-compliant version number from VERSION."""
|
||||||
version = get_complete_version(version)
|
version = get_complete_version(version)
|
||||||
|
|
||||||
# Now build the two parts of the version number:
|
# Now build the two parts of the version number:
|
||||||
@ -29,15 +29,16 @@ def get_version(version=None):
|
|||||||
|
|
||||||
|
|
||||||
def get_main_version(version=None):
|
def get_main_version(version=None):
|
||||||
"Returns main version (X.Y[.Z]) from VERSION."
|
"""Return main version (X.Y[.Z]) from VERSION."""
|
||||||
version = get_complete_version(version)
|
version = get_complete_version(version)
|
||||||
parts = 2 if version[2] == 0 else 3
|
parts = 2 if version[2] == 0 else 3
|
||||||
return '.'.join(str(x) for x in version[:parts])
|
return '.'.join(str(x) for x in version[:parts])
|
||||||
|
|
||||||
|
|
||||||
def get_complete_version(version=None):
|
def get_complete_version(version=None):
|
||||||
"""Returns a tuple of the django version. If version argument is non-empty,
|
"""
|
||||||
then checks for correctness of the tuple provided.
|
Return a tuple of the django version. If version argument is non-empty,
|
||||||
|
check for correctness of the tuple provided.
|
||||||
"""
|
"""
|
||||||
if version is None:
|
if version is None:
|
||||||
from django import VERSION as version
|
from django import VERSION as version
|
||||||
@ -58,7 +59,7 @@ def get_docs_version(version=None):
|
|||||||
|
|
||||||
@functools.lru_cache()
|
@functools.lru_cache()
|
||||||
def get_git_changeset():
|
def get_git_changeset():
|
||||||
"""Returns a numeric identifier of the latest git changeset.
|
"""Return a numeric identifier of the latest git changeset.
|
||||||
|
|
||||||
The result is the UTC timestamp of the changeset in YYYYMMDDHHMMSS format.
|
The result is the UTC timestamp of the changeset in YYYYMMDDHHMMSS format.
|
||||||
This value isn't guaranteed to be unique, but collisions are very unlikely,
|
This value isn't guaranteed to be unique, but collisions are very unlikely,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user