Correct flake8 E302 violations
This commit is contained in:
parent
3bc0d46a84
commit
e2ae8b048e
|
@ -144,6 +144,8 @@ if sys.platform.startswith('java'):
|
|||
# Option constants.
|
||||
|
||||
OPTIONFLAGS_BY_NAME = {}
|
||||
|
||||
|
||||
def register_optionflag(name):
|
||||
# Create a new flag unless `name` is already known.
|
||||
return OPTIONFLAGS_BY_NAME.setdefault(name, 1 << len(OPTIONFLAGS_BY_NAME))
|
||||
|
@ -194,6 +196,7 @@ ELLIPSIS_MARKER = '...'
|
|||
## 1. Utility Functions
|
||||
######################################################################
|
||||
|
||||
|
||||
def _extract_future_flags(globs):
|
||||
"""
|
||||
Return the compiler-flags associated with the future features that
|
||||
|
@ -206,6 +209,7 @@ def _extract_future_flags(globs):
|
|||
flags |= feature.compiler_flag
|
||||
return flags
|
||||
|
||||
|
||||
def _normalize_module(module, depth=2):
|
||||
"""
|
||||
Return the module specified by `module`. In particular:
|
||||
|
@ -225,6 +229,7 @@ def _normalize_module(module, depth=2):
|
|||
else:
|
||||
raise TypeError("Expected a module, string, or None")
|
||||
|
||||
|
||||
def _load_testfile(filename, package, module_relative):
|
||||
if module_relative:
|
||||
package = _normalize_module(package, 3)
|
||||
|
@ -238,6 +243,7 @@ def _load_testfile(filename, package, module_relative):
|
|||
with open(filename) as fp:
|
||||
return fp.read(), filename
|
||||
|
||||
|
||||
def _indent(s, indent=4):
|
||||
"""
|
||||
Add the given number of space characters to the beginning every
|
||||
|
@ -246,6 +252,7 @@ def _indent(s, indent=4):
|
|||
# This regexp matches the start of non-blank lines:
|
||||
return re.sub('(?m)^(?!$)', indent*' ', s)
|
||||
|
||||
|
||||
def _exception_traceback(exc_info):
|
||||
"""
|
||||
Return a string containing a traceback message for the given
|
||||
|
@ -257,6 +264,7 @@ def _exception_traceback(exc_info):
|
|||
traceback.print_exception(exc_type, exc_val, exc_tb, file=excout)
|
||||
return excout.getvalue()
|
||||
|
||||
|
||||
# Override some StringIO methods.
|
||||
class _SpoofOut(StringIO):
|
||||
def getvalue(self):
|
||||
|
@ -277,6 +285,7 @@ class _SpoofOut(StringIO):
|
|||
if hasattr(self, "softspace"):
|
||||
del self.softspace
|
||||
|
||||
|
||||
# Worst-case linear-time ellipsis matching.
|
||||
def _ellipsis_match(want, got):
|
||||
"""
|
||||
|
@ -327,6 +336,7 @@ def _ellipsis_match(want, got):
|
|||
|
||||
return True
|
||||
|
||||
|
||||
def _comment_line(line):
|
||||
"Return a commented form of the given line"
|
||||
line = line.rstrip()
|
||||
|
@ -335,6 +345,7 @@ def _comment_line(line):
|
|||
else:
|
||||
return '#'
|
||||
|
||||
|
||||
class _OutputRedirectingPdb(pdb.Pdb):
|
||||
"""
|
||||
A specialized version of the python debugger that redirects stdout
|
||||
|
@ -368,6 +379,7 @@ class _OutputRedirectingPdb(pdb.Pdb):
|
|||
finally:
|
||||
sys.stdout = save_stdout
|
||||
|
||||
|
||||
# [XX] Normalize with respect to os.path.pardir?
|
||||
def _module_relative_path(module, path):
|
||||
if not inspect.ismodule(module):
|
||||
|
@ -405,6 +417,7 @@ def _module_relative_path(module, path):
|
|||
## a string (such as an object's docstring). The DocTest class also
|
||||
## includes information about where the string was extracted from.
|
||||
|
||||
|
||||
class Example:
|
||||
"""
|
||||
A single doctest example, consisting of source code and expected
|
||||
|
@ -458,6 +471,7 @@ class Example:
|
|||
self.options = options
|
||||
self.exc_msg = exc_msg
|
||||
|
||||
|
||||
class DocTest:
|
||||
"""
|
||||
A collection of doctest examples that should be run in a single
|
||||
|
@ -506,10 +520,10 @@ class DocTest:
|
|||
return ('<DocTest %s from %s:%s (%s)>' %
|
||||
(self.name, self.filename, self.lineno, examples))
|
||||
|
||||
|
||||
# This lets us sort tests by name:
|
||||
def _cmpkey(self):
|
||||
return (self.name, self.filename, self.lineno, id(self))
|
||||
|
||||
def __cmp__(self, other):
|
||||
if not isinstance(other, DocTest):
|
||||
return -1
|
||||
|
@ -1054,6 +1068,7 @@ class DocTestFinder:
|
|||
## 5. DocTest Runner
|
||||
######################################################################
|
||||
|
||||
|
||||
class DocTestRunner:
|
||||
"""
|
||||
A class used to run DocTest test cases, and accumulate statistics.
|
||||
|
@ -1408,6 +1423,7 @@ class DocTestRunner:
|
|||
__LINECACHE_FILENAME_RE = re.compile(r'<doctest '
|
||||
r'(?P<name>[\w\.]+)'
|
||||
r'\[(?P<examplenum>\d+)\]>$')
|
||||
|
||||
def __patched_linecache_getlines(self, filename, module_globals=None):
|
||||
m = self.__LINECACHE_FILENAME_RE.match(filename)
|
||||
if m and m.group('name') == self.test.name:
|
||||
|
@ -1541,6 +1557,7 @@ class DocTestRunner:
|
|||
t = t + t2
|
||||
d[name] = f, t
|
||||
|
||||
|
||||
class OutputChecker:
|
||||
"""
|
||||
A class used to check the whether the actual output from a doctest
|
||||
|
@ -1674,6 +1691,7 @@ class OutputChecker:
|
|||
else:
|
||||
return 'Expected nothing\nGot nothing\n'
|
||||
|
||||
|
||||
class DocTestFailure(Exception):
|
||||
"""A DocTest example has failed in debugging mode.
|
||||
|
||||
|
@ -1693,6 +1711,7 @@ class DocTestFailure(Exception):
|
|||
def __str__(self):
|
||||
return str(self.test)
|
||||
|
||||
|
||||
class UnexpectedException(Exception):
|
||||
"""A DocTest example has encountered an unexpected exception
|
||||
|
||||
|
@ -1712,6 +1731,7 @@ class UnexpectedException(Exception):
|
|||
def __str__(self):
|
||||
return str(self.test)
|
||||
|
||||
|
||||
class DebugRunner(DocTestRunner):
|
||||
r"""Run doc tests but raise an exception as soon as there is a failure.
|
||||
|
||||
|
@ -1824,6 +1844,7 @@ class DebugRunner(DocTestRunner):
|
|||
# class, updated by testmod.
|
||||
master = None
|
||||
|
||||
|
||||
def testmod(m=None, name=None, globs=None, verbose=None,
|
||||
report=True, optionflags=0, extraglobs=None,
|
||||
raise_on_error=False, exclude_empty=False):
|
||||
|
@ -1928,6 +1949,7 @@ def testmod(m=None, name=None, globs=None, verbose=None,
|
|||
|
||||
return runner.failures, runner.tries
|
||||
|
||||
|
||||
def testfile(filename, module_relative=True, name=None, package=None,
|
||||
globs=None, verbose=None, report=True, optionflags=0,
|
||||
extraglobs=None, raise_on_error=False, parser=DocTestParser(),
|
||||
|
@ -2051,6 +2073,7 @@ def testfile(filename, module_relative=True, name=None, package=None,
|
|||
|
||||
return runner.failures, runner.tries
|
||||
|
||||
|
||||
def run_docstring_examples(f, globs, verbose=False, name="NoName",
|
||||
compileflags=None, optionflags=0):
|
||||
"""
|
||||
|
@ -2080,6 +2103,7 @@ def run_docstring_examples(f, globs, verbose=False, name="NoName",
|
|||
# This is provided only for backwards compatibility. It's not
|
||||
# actually used in any way.
|
||||
|
||||
|
||||
class Tester:
|
||||
def __init__(self, mod=None, globs=None, verbose=None, optionflags=0):
|
||||
|
||||
|
@ -2145,6 +2169,7 @@ class Tester:
|
|||
|
||||
_unittest_reportflags = 0
|
||||
|
||||
|
||||
def set_unittest_reportflags(flags):
|
||||
"""Sets the unittest option flags.
|
||||
|
||||
|
@ -2328,6 +2353,7 @@ class DocTestCase(unittest.TestCase):
|
|||
def shortDescription(self):
|
||||
return "Doctest: " + self._dt_test.name
|
||||
|
||||
|
||||
def DocTestSuite(module=None, globs=None, extraglobs=None, test_finder=None,
|
||||
test_class=DocTestCase, **options):
|
||||
"""
|
||||
|
@ -2391,6 +2417,7 @@ def DocTestSuite(module=None, globs=None, extraglobs=None, test_finder=None,
|
|||
|
||||
return suite
|
||||
|
||||
|
||||
class DocFileCase(DocTestCase):
|
||||
|
||||
def id(self):
|
||||
|
@ -2405,6 +2432,7 @@ class DocFileCase(DocTestCase):
|
|||
% (self._dt_test.name, self._dt_test.filename, err)
|
||||
)
|
||||
|
||||
|
||||
def DocFileTest(path, module_relative=True, package=None,
|
||||
globs=None, parser=DocTestParser(),
|
||||
encoding=None, **options):
|
||||
|
@ -2434,6 +2462,7 @@ def DocFileTest(path, module_relative=True, package=None,
|
|||
test = parser.get_doctest(doc, globs, name, path, 0)
|
||||
return DocFileCase(test, **options)
|
||||
|
||||
|
||||
def DocFileSuite(*paths, **kw):
|
||||
"""A unittest suite for one or more doctest files.
|
||||
|
||||
|
@ -2507,6 +2536,7 @@ def DocFileSuite(*paths, **kw):
|
|||
## 9. Debugging Support
|
||||
######################################################################
|
||||
|
||||
|
||||
def script_from_examples(s):
|
||||
r"""Extract script from text with examples.
|
||||
|
||||
|
@ -2587,6 +2617,7 @@ def script_from_examples(s):
|
|||
# Combine the output, and return it.
|
||||
return '\n'.join(output)
|
||||
|
||||
|
||||
def testsource(module, name):
|
||||
"""Extract the test sources from a doctest docstring as a script.
|
||||
|
||||
|
@ -2603,11 +2634,13 @@ def testsource(module, name):
|
|||
testsrc = script_from_examples(test.docstring)
|
||||
return testsrc
|
||||
|
||||
|
||||
def debug_src(src, pm=False, globs=None):
|
||||
"""Debug a single doctest docstring, in argument `src`'"""
|
||||
testsrc = script_from_examples(src)
|
||||
debug_script(testsrc, pm, globs)
|
||||
|
||||
|
||||
def debug_script(src, pm=False, globs=None):
|
||||
"Debug a test script. `src` is the script, as a string."
|
||||
import pdb
|
||||
|
@ -2639,6 +2672,7 @@ def debug_script(src, pm=False, globs=None):
|
|||
finally:
|
||||
os.remove(srcfilename)
|
||||
|
||||
|
||||
def debug(module, name, pm=False):
|
||||
"""Debug a single doctest docstring.
|
||||
|
||||
|
@ -2653,6 +2687,8 @@ def debug(module, name, pm=False):
|
|||
######################################################################
|
||||
## 10. Example Usage
|
||||
######################################################################
|
||||
|
||||
|
||||
class _TestClass:
|
||||
"""
|
||||
A pointless class, for sanity-checking of docstring testing.
|
||||
|
@ -2747,6 +2783,7 @@ __test__ = {"_TestClass": _TestClass,
|
|||
""",
|
||||
}
|
||||
|
||||
|
||||
def _test():
|
||||
r = unittest.TextTestRunner()
|
||||
r.run(DocTestSuite())
|
||||
|
|
|
@ -61,9 +61,11 @@ real_enter_transaction_management = transaction.enter_transaction_management
|
|||
real_leave_transaction_management = transaction.leave_transaction_management
|
||||
real_abort = transaction.abort
|
||||
|
||||
|
||||
def nop(*args, **kwargs):
|
||||
return
|
||||
|
||||
|
||||
def disable_transaction_methods():
|
||||
transaction.commit = nop
|
||||
transaction.rollback = nop
|
||||
|
@ -71,6 +73,7 @@ def disable_transaction_methods():
|
|||
transaction.leave_transaction_management = nop
|
||||
transaction.abort = nop
|
||||
|
||||
|
||||
def restore_transaction_methods():
|
||||
transaction.commit = real_commit
|
||||
transaction.rollback = real_rollback
|
||||
|
|
|
@ -53,6 +53,7 @@ def npath(path):
|
|||
return path.encode(fs_encoding)
|
||||
return path
|
||||
|
||||
|
||||
def safe_join(base, *paths):
|
||||
"""
|
||||
Joins one or more path components to the base path component intelligently.
|
||||
|
|
|
@ -119,6 +119,7 @@ def gen_filenames():
|
|||
if os.path.exists(filename):
|
||||
yield filename
|
||||
|
||||
|
||||
def inotify_code_changed():
|
||||
"""
|
||||
Checks for changed code using inotify. After being called
|
||||
|
@ -149,6 +150,7 @@ def inotify_code_changed():
|
|||
# If we are here the code must have changed.
|
||||
return True
|
||||
|
||||
|
||||
def kqueue_code_changed():
|
||||
"""
|
||||
Checks for changed code using kqueue. After being called
|
||||
|
@ -193,6 +195,7 @@ def kqueue_code_changed():
|
|||
|
||||
return True
|
||||
|
||||
|
||||
def code_changed():
|
||||
global _mtimes, _win
|
||||
for filename in gen_filenames():
|
||||
|
@ -212,6 +215,7 @@ def code_changed():
|
|||
return True
|
||||
return False
|
||||
|
||||
|
||||
def check_errors(fn):
|
||||
def wrapper(*args, **kwargs):
|
||||
try:
|
||||
|
@ -233,6 +237,7 @@ def check_errors(fn):
|
|||
|
||||
return wrapper
|
||||
|
||||
|
||||
def ensure_echo_on():
|
||||
if termios:
|
||||
fd = sys.stdin
|
||||
|
@ -248,6 +253,7 @@ def ensure_echo_on():
|
|||
if old_handler is not None:
|
||||
signal.signal(signal.SIGTTOU, old_handler)
|
||||
|
||||
|
||||
def reloader_thread():
|
||||
ensure_echo_on()
|
||||
if USE_INOTIFY:
|
||||
|
@ -273,6 +279,7 @@ def restart_with_reloader():
|
|||
if exit_code != 3:
|
||||
return exit_code
|
||||
|
||||
|
||||
def python_reloader(main_func, args, kwargs):
|
||||
if os.environ.get("RUN_MAIN") == "true":
|
||||
thread.start_new_thread(main_func, args, kwargs)
|
||||
|
@ -290,6 +297,7 @@ def python_reloader(main_func, args, kwargs):
|
|||
except KeyboardInterrupt:
|
||||
pass
|
||||
|
||||
|
||||
def jython_reloader(main_func, args, kwargs):
|
||||
from _systemrestart import SystemRestart
|
||||
thread.start_new_thread(main_func, args)
|
||||
|
|
|
@ -31,6 +31,7 @@ from django.utils.translation import get_language
|
|||
|
||||
cc_delim_re = re.compile(r'\s*,\s*')
|
||||
|
||||
|
||||
def patch_cache_control(response, **kwargs):
|
||||
"""
|
||||
This function patches the Cache-Control header by adding all
|
||||
|
@ -79,6 +80,7 @@ def patch_cache_control(response, **kwargs):
|
|||
cc = ', '.join(dictvalue(el) for el in cc.items())
|
||||
response['Cache-Control'] = cc
|
||||
|
||||
|
||||
def get_max_age(response):
|
||||
"""
|
||||
Returns the max-age from the response Cache-Control header as an integer
|
||||
|
@ -94,11 +96,13 @@ def get_max_age(response):
|
|||
except (ValueError, TypeError):
|
||||
pass
|
||||
|
||||
|
||||
def _set_response_etag(response):
|
||||
if not response.streaming:
|
||||
response['ETag'] = '"%s"' % hashlib.md5(response.content).hexdigest()
|
||||
return response
|
||||
|
||||
|
||||
def patch_response_headers(response, cache_timeout=None):
|
||||
"""
|
||||
Adds some useful headers to the given HttpResponse object:
|
||||
|
@ -124,12 +128,14 @@ def patch_response_headers(response, cache_timeout=None):
|
|||
response['Expires'] = http_date(time.time() + cache_timeout)
|
||||
patch_cache_control(response, max_age=cache_timeout)
|
||||
|
||||
|
||||
def add_never_cache_headers(response):
|
||||
"""
|
||||
Adds headers to a response to indicate that a page should never be cached.
|
||||
"""
|
||||
patch_response_headers(response, cache_timeout=-1)
|
||||
|
||||
|
||||
def patch_vary_headers(response, newheaders):
|
||||
"""
|
||||
Adds (or updates) the "Vary" header in the given HttpResponse object.
|
||||
|
@ -149,6 +155,7 @@ def patch_vary_headers(response, newheaders):
|
|||
if newheader.lower() not in existing_headers]
|
||||
response['Vary'] = ', '.join(vary_headers + additional_headers)
|
||||
|
||||
|
||||
def has_vary_header(response, header_query):
|
||||
"""
|
||||
Checks to see if the response has a given header name in its Vary header.
|
||||
|
@ -159,6 +166,7 @@ def has_vary_header(response, header_query):
|
|||
existing_headers = set(header.lower() for header in vary_headers)
|
||||
return header_query.lower() in existing_headers
|
||||
|
||||
|
||||
def _i18n_cache_key_suffix(request, cache_key):
|
||||
"""If necessary, adds the current locale or time zone to the cache key."""
|
||||
if settings.USE_I18N or settings.USE_L10N:
|
||||
|
@ -175,6 +183,7 @@ def _i18n_cache_key_suffix(request, cache_key):
|
|||
cache_key += '.%s' % tz_name.encode('ascii', 'ignore').decode('ascii').replace(' ', '_')
|
||||
return cache_key
|
||||
|
||||
|
||||
def _generate_cache_key(request, method, headerlist, key_prefix):
|
||||
"""Returns a cache key from the headers given in the header list."""
|
||||
ctx = hashlib.md5()
|
||||
|
@ -187,6 +196,7 @@ def _generate_cache_key(request, method, headerlist, key_prefix):
|
|||
key_prefix, method, path.hexdigest(), ctx.hexdigest())
|
||||
return _i18n_cache_key_suffix(request, cache_key)
|
||||
|
||||
|
||||
def _generate_cache_header_key(key_prefix, request):
|
||||
"""Returns a cache key for the header cache."""
|
||||
path = hashlib.md5(force_bytes(iri_to_uri(request.get_full_path())))
|
||||
|
@ -194,6 +204,7 @@ def _generate_cache_header_key(key_prefix, request):
|
|||
key_prefix, path.hexdigest())
|
||||
return _i18n_cache_key_suffix(request, cache_key)
|
||||
|
||||
|
||||
def get_cache_key(request, key_prefix=None, method='GET', cache=None):
|
||||
"""
|
||||
Returns a cache key based on the request path and query. It can be used
|
||||
|
@ -215,6 +226,7 @@ def get_cache_key(request, key_prefix=None, method='GET', cache=None):
|
|||
else:
|
||||
return 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 path from the
|
||||
|
|
|
@ -3,6 +3,7 @@ import warnings
|
|||
from collections import OrderedDict
|
||||
from django.utils import six
|
||||
|
||||
|
||||
class MergeDict(object):
|
||||
"""
|
||||
A simple class for creating new "virtual" dictionaries that actually look
|
||||
|
@ -117,6 +118,7 @@ class MergeDict(object):
|
|||
dictreprs = ', '.join(repr(d) for d in self.dicts)
|
||||
return '%s(%s)' % (self.__class__.__name__, dictreprs)
|
||||
|
||||
|
||||
class SortedDict(dict):
|
||||
"""
|
||||
A dictionary that keeps its keys in the order in which they're inserted.
|
||||
|
@ -239,6 +241,7 @@ class SortedDict(dict):
|
|||
super(SortedDict, self).clear()
|
||||
self.keyOrder = []
|
||||
|
||||
|
||||
class OrderedSet(object):
|
||||
"""
|
||||
A set which keeps the ordering of the inserted items.
|
||||
|
@ -269,9 +272,11 @@ class OrderedSet(object):
|
|||
def __nonzero__(self):
|
||||
return bool(self.dict)
|
||||
|
||||
|
||||
class MultiValueDictKeyError(KeyError):
|
||||
pass
|
||||
|
||||
|
||||
class MultiValueDict(dict):
|
||||
"""
|
||||
A subclass of dictionary customized to handle multiple values for the
|
||||
|
@ -504,6 +509,7 @@ class ImmutableList(tuple):
|
|||
sort = complain
|
||||
reverse = complain
|
||||
|
||||
|
||||
class DictWrapper(dict):
|
||||
"""
|
||||
Wraps accesses to a dictionary so that certain values (those starting with
|
||||
|
|
|
@ -26,6 +26,7 @@ from django.utils.timezone import get_default_timezone, is_aware, is_naive
|
|||
re_formatchars = re.compile(r'(?<!\\)([aAbBcdDeEfFgGhHiIjlLmMnNoOPrsStTUuwWyYzZ])')
|
||||
re_escaped = re.compile(r'\\(.)')
|
||||
|
||||
|
||||
class Formatter(object):
|
||||
def format(self, formatstr):
|
||||
pieces = []
|
||||
|
@ -36,6 +37,7 @@ class Formatter(object):
|
|||
pieces.append(re_escaped.sub(r'\1', piece))
|
||||
return ''.join(pieces)
|
||||
|
||||
|
||||
class TimeFormat(Formatter):
|
||||
|
||||
def __init__(self, obj):
|
||||
|
|
|
@ -39,6 +39,7 @@ def parse_date(value):
|
|||
kw = dict((k, int(v)) for k, v in six.iteritems(match.groupdict()))
|
||||
return datetime.date(**kw)
|
||||
|
||||
|
||||
def parse_time(value):
|
||||
"""Parses a string and return a datetime.time.
|
||||
|
||||
|
@ -56,6 +57,7 @@ def parse_time(value):
|
|||
kw = dict((k, int(v)) for k, v in six.iteritems(kw) if v is not None)
|
||||
return datetime.time(**kw)
|
||||
|
||||
|
||||
def parse_datetime(value):
|
||||
"""Parses a string and return a datetime.datetime.
|
||||
|
||||
|
|
|
@ -30,10 +30,12 @@ class datetime(real_datetime):
|
|||
def date(self):
|
||||
return date(self.year, self.month, self.day)
|
||||
|
||||
|
||||
def new_date(d):
|
||||
"Generate a safe date from a datetime.date object."
|
||||
return date(d.year, d.month, d.day)
|
||||
|
||||
|
||||
def new_datetime(d):
|
||||
"""
|
||||
Generate a safe datetime from a datetime.date or datetime.datetime object.
|
||||
|
@ -47,6 +49,7 @@ def new_datetime(d):
|
|||
# Allowed if there's an even number of "%"s because they are escaped.
|
||||
_illegal_formatting = re.compile(r"((^|[^%])(%%)*%[sy])")
|
||||
|
||||
|
||||
def _findall(text, substr):
|
||||
# Also finds overlaps
|
||||
sites = []
|
||||
|
@ -59,6 +62,7 @@ def _findall(text, substr):
|
|||
i = j + 1
|
||||
return sites
|
||||
|
||||
|
||||
def strftime(dt, fmt):
|
||||
if dt.year >= 1900:
|
||||
return super(type(dt), dt).strftime(fmt)
|
||||
|
|
|
@ -32,6 +32,7 @@ from django.utils import six
|
|||
|
||||
IDENTIFIER = re.compile('^[a-z_][a-z0-9_]*$', re.I)
|
||||
|
||||
|
||||
def valid_ident(s):
|
||||
m = IDENTIFIER.match(s)
|
||||
if not m:
|
||||
|
@ -65,6 +66,7 @@ except ImportError:
|
|||
# Each wrapper should have a configurator attribute holding the actual
|
||||
# configurator to use for conversion.
|
||||
|
||||
|
||||
class ConvertingDict(dict):
|
||||
"""A converting dictionary wrapper."""
|
||||
|
||||
|
@ -102,6 +104,7 @@ class ConvertingDict(dict):
|
|||
result.key = key
|
||||
return result
|
||||
|
||||
|
||||
class ConvertingList(list):
|
||||
"""A converting list wrapper."""
|
||||
def __getitem__(self, key):
|
||||
|
@ -125,6 +128,7 @@ class ConvertingList(list):
|
|||
result.parent = self
|
||||
return result
|
||||
|
||||
|
||||
class ConvertingTuple(tuple):
|
||||
"""A converting tuple wrapper."""
|
||||
def __getitem__(self, key):
|
||||
|
@ -137,6 +141,7 @@ class ConvertingTuple(tuple):
|
|||
result.key = key
|
||||
return result
|
||||
|
||||
|
||||
class BaseConfigurator(object):
|
||||
"""
|
||||
The configurator base class which defines some useful defaults.
|
||||
|
@ -270,6 +275,7 @@ class BaseConfigurator(object):
|
|||
value = tuple(value)
|
||||
return value
|
||||
|
||||
|
||||
class DictConfigurator(BaseConfigurator):
|
||||
"""
|
||||
Configure logging using a dictionary-like object to describe the
|
||||
|
@ -555,6 +561,7 @@ class DictConfigurator(BaseConfigurator):
|
|||
|
||||
dictConfigClass = DictConfigurator
|
||||
|
||||
|
||||
def dictConfig(config):
|
||||
"""Configure logging using a dictionary."""
|
||||
dictConfigClass(config).configure()
|
||||
|
|
|
@ -38,6 +38,7 @@ def python_2_unicode_compatible(klass):
|
|||
klass.__str__ = lambda self: self.__unicode__().encode('utf-8')
|
||||
return klass
|
||||
|
||||
|
||||
def smart_text(s, encoding='utf-8', strings_only=False, errors='strict'):
|
||||
"""
|
||||
Returns a text object representing 's' -- unicode on Python 2 and str on
|
||||
|
@ -50,6 +51,7 @@ def smart_text(s, encoding='utf-8', strings_only=False, errors='strict'):
|
|||
return s
|
||||
return force_text(s, encoding, strings_only, errors)
|
||||
|
||||
|
||||
def is_protected_type(obj):
|
||||
"""Determine if the object instance is of a protected type.
|
||||
|
||||
|
@ -59,6 +61,7 @@ def is_protected_type(obj):
|
|||
return isinstance(obj, six.integer_types + (type(None), float, Decimal,
|
||||
datetime.datetime, datetime.date, datetime.time))
|
||||
|
||||
|
||||
def force_text(s, encoding='utf-8', strings_only=False, errors='strict'):
|
||||
"""
|
||||
Similar to smart_text, except that lazy instances are resolved to
|
||||
|
@ -100,6 +103,7 @@ def force_text(s, encoding='utf-8', strings_only=False, errors='strict'):
|
|||
errors) for arg in s])
|
||||
return s
|
||||
|
||||
|
||||
def smart_bytes(s, encoding='utf-8', strings_only=False, errors='strict'):
|
||||
"""
|
||||
Returns a bytestring version of 's', encoded as specified in 'encoding'.
|
||||
|
@ -168,6 +172,7 @@ force_str.__doc__ = """
|
|||
Apply force_text in Python 3 and force_bytes in Python 2.
|
||||
"""
|
||||
|
||||
|
||||
def iri_to_uri(iri):
|
||||
"""
|
||||
Convert an Internationalized Resource Identifier (IRI) portion to a URI
|
||||
|
@ -195,6 +200,7 @@ def iri_to_uri(iri):
|
|||
return iri
|
||||
return quote(force_bytes(iri), safe=b"/#%[]=:;$&()+,!?*@'~")
|
||||
|
||||
|
||||
def filepath_to_uri(path):
|
||||
"""Convert a file system path to a URI portion that is suitable for
|
||||
inclusion in a URL.
|
||||
|
@ -214,6 +220,7 @@ def filepath_to_uri(path):
|
|||
# some flexibility for hardcoding separators.
|
||||
return quote(force_bytes(path).replace(b"\\", b"/"), safe=b"/~!*()'")
|
||||
|
||||
|
||||
def get_system_encoding():
|
||||
"""
|
||||
The encoding of the default system locale but falls back to the given
|
||||
|
|
|
@ -54,6 +54,7 @@ def rfc2822_date(date):
|
|||
else:
|
||||
return time_str + '-0000'
|
||||
|
||||
|
||||
def rfc3339_date(date):
|
||||
# Support datetime objects older than 1900
|
||||
date = datetime_safe.new_datetime(date)
|
||||
|
@ -68,6 +69,7 @@ def rfc3339_date(date):
|
|||
else:
|
||||
return time_str + 'Z'
|
||||
|
||||
|
||||
def get_tag_uri(url, date):
|
||||
"""
|
||||
Creates a TagURI.
|
||||
|
@ -80,6 +82,7 @@ def get_tag_uri(url, date):
|
|||
d = ',%s' % datetime_safe.new_datetime(date).strftime('%Y-%m-%d')
|
||||
return 'tag:%s%s:%s/%s' % (bits.hostname, d, bits.path, bits.fragment)
|
||||
|
||||
|
||||
class SyndicationFeed(object):
|
||||
"Base class for all syndication feeds. Subclasses should provide write()"
|
||||
def __init__(self, title, link, description, language=None, author_email=None,
|
||||
|
@ -205,6 +208,7 @@ class SyndicationFeed(object):
|
|||
|
||||
return latest_date or datetime.datetime.now()
|
||||
|
||||
|
||||
class Enclosure(object):
|
||||
"Represents an RSS enclosure"
|
||||
def __init__(self, url, length, mime_type):
|
||||
|
@ -212,6 +216,7 @@ class Enclosure(object):
|
|||
self.length, self.mime_type = length, mime_type
|
||||
self.url = iri_to_uri(url)
|
||||
|
||||
|
||||
class RssFeed(SyndicationFeed):
|
||||
mime_type = 'application/rss+xml; charset=utf-8'
|
||||
|
||||
|
@ -255,6 +260,7 @@ class RssFeed(SyndicationFeed):
|
|||
def endChannelElement(self, handler):
|
||||
handler.endElement("channel")
|
||||
|
||||
|
||||
class RssUserland091Feed(RssFeed):
|
||||
_version = "0.91"
|
||||
|
||||
|
@ -264,6 +270,7 @@ class RssUserland091Feed(RssFeed):
|
|||
if item['description'] is not None:
|
||||
handler.addQuickElement("description", item['description'])
|
||||
|
||||
|
||||
class Rss201rev2Feed(RssFeed):
|
||||
# Spec: http://blogs.law.harvard.edu/tech/rss
|
||||
_version = "2.0"
|
||||
|
@ -306,6 +313,7 @@ class Rss201rev2Feed(RssFeed):
|
|||
for cat in item['categories']:
|
||||
handler.addQuickElement("category", cat)
|
||||
|
||||
|
||||
class Atom1Feed(SyndicationFeed):
|
||||
# Spec: http://atompub.org/2005/07/11/draft-ietf-atompub-format-10.html
|
||||
mime_type = 'application/atom+xml; charset=utf-8'
|
||||
|
|
|
@ -30,6 +30,7 @@ ISO_INPUT_FORMATS = {
|
|||
),
|
||||
}
|
||||
|
||||
|
||||
def reset_format_cache():
|
||||
"""Clear any cached formats.
|
||||
|
||||
|
@ -40,6 +41,7 @@ def reset_format_cache():
|
|||
_format_cache = {}
|
||||
_format_modules_cache = {}
|
||||
|
||||
|
||||
def iter_format_modules(lang, format_module_path=None):
|
||||
"""
|
||||
Does the heavy lifting of finding format modules.
|
||||
|
@ -60,6 +62,7 @@ def iter_format_modules(lang, format_module_path=None):
|
|||
except ImportError:
|
||||
pass
|
||||
|
||||
|
||||
def get_format_modules(lang=None, reverse=False):
|
||||
"""
|
||||
Returns a list of the format modules found
|
||||
|
@ -71,6 +74,7 @@ def get_format_modules(lang=None, reverse=False):
|
|||
return list(reversed(modules))
|
||||
return modules
|
||||
|
||||
|
||||
def get_format(format_type, lang=None, use_l10n=None):
|
||||
"""
|
||||
For a specific format type, returns the format for the current
|
||||
|
@ -110,6 +114,7 @@ def get_format(format_type, lang=None, use_l10n=None):
|
|||
|
||||
get_format_lazy = lazy(get_format, six.text_type, list, tuple)
|
||||
|
||||
|
||||
def date_format(value, format=None, use_l10n=None):
|
||||
"""
|
||||
Formats a datetime.date or datetime.datetime object using a
|
||||
|
@ -120,6 +125,7 @@ def date_format(value, format=None, use_l10n=None):
|
|||
"""
|
||||
return dateformat.format(value, get_format(format or 'DATE_FORMAT', use_l10n=use_l10n))
|
||||
|
||||
|
||||
def time_format(value, format=None, use_l10n=None):
|
||||
"""
|
||||
Formats a datetime.time object using a localizable format
|
||||
|
@ -129,6 +135,7 @@ def time_format(value, format=None, use_l10n=None):
|
|||
"""
|
||||
return dateformat.time_format(value, get_format(format or 'TIME_FORMAT', use_l10n=use_l10n))
|
||||
|
||||
|
||||
def number_format(value, decimal_pos=None, use_l10n=None, force_grouping=False):
|
||||
"""
|
||||
Formats a numeric value using localization settings
|
||||
|
@ -149,6 +156,7 @@ def number_format(value, decimal_pos=None, use_l10n=None, force_grouping=False):
|
|||
force_grouping=force_grouping
|
||||
)
|
||||
|
||||
|
||||
def localize(value, use_l10n=None):
|
||||
"""
|
||||
Checks if value is a localizable type (date, number...) and returns it
|
||||
|
@ -170,6 +178,7 @@ def localize(value, use_l10n=None):
|
|||
else:
|
||||
return value
|
||||
|
||||
|
||||
def localize_input(value, default=None):
|
||||
"""
|
||||
Checks if an input value is a localizable type and returns it
|
||||
|
@ -190,6 +199,7 @@ def localize_input(value, default=None):
|
|||
return value.strftime(format)
|
||||
return value
|
||||
|
||||
|
||||
def sanitize_separators(value):
|
||||
"""
|
||||
Sanitizes a value according to the current decimal and
|
||||
|
|
|
@ -72,6 +72,7 @@ def conditional_escape(text):
|
|||
else:
|
||||
return escape(text)
|
||||
|
||||
|
||||
def format_html(format_string, *args, **kwargs):
|
||||
"""
|
||||
Similar to str.format, but passes all arguments through conditional_escape,
|
||||
|
@ -83,6 +84,7 @@ def format_html(format_string, *args, **kwargs):
|
|||
six.iteritems(kwargs))
|
||||
return mark_safe(format_string.format(*args_safe, **kwargs_safe))
|
||||
|
||||
|
||||
def format_html_join(sep, format_string, args_generator):
|
||||
"""
|
||||
A wrapper of format_html, for the common case of a group of arguments that
|
||||
|
@ -133,6 +135,7 @@ class MLStripper(HTMLParser):
|
|||
def get_data(self):
|
||||
return ''.join(self.fed)
|
||||
|
||||
|
||||
def strip_tags(value):
|
||||
"""Returns the given HTML with all tags stripped."""
|
||||
s = MLStripper()
|
||||
|
@ -145,6 +148,7 @@ def strip_tags(value):
|
|||
return s.get_data()
|
||||
strip_tags = allow_lazy(strip_tags)
|
||||
|
||||
|
||||
def remove_tags(html, tags):
|
||||
"""Returns the given HTML with given tags removed."""
|
||||
tags = [re.escape(tag) for tag in tags.split()]
|
||||
|
@ -156,21 +160,25 @@ def remove_tags(html, tags):
|
|||
return html
|
||||
remove_tags = allow_lazy(remove_tags, six.text_type)
|
||||
|
||||
|
||||
def strip_spaces_between_tags(value):
|
||||
"""Returns the given HTML with spaces between tags removed."""
|
||||
return re.sub(r'>\s+<', '><', force_text(value))
|
||||
strip_spaces_between_tags = allow_lazy(strip_spaces_between_tags, six.text_type)
|
||||
|
||||
|
||||
def strip_entities(value):
|
||||
"""Returns the given HTML with all entities (&something;) stripped."""
|
||||
return re.sub(r'&(?:\w+|#\d+);', '', force_text(value))
|
||||
strip_entities = allow_lazy(strip_entities, six.text_type)
|
||||
|
||||
|
||||
def fix_ampersands(value):
|
||||
"""Returns the given HTML with all unencoded ampersands encoded correctly."""
|
||||
return unencoded_ampersands_re.sub('&', force_text(value))
|
||||
fix_ampersands = allow_lazy(fix_ampersands, six.text_type)
|
||||
|
||||
|
||||
def smart_urlquote(url):
|
||||
"Quotes a URL if it isn't already quoted."
|
||||
# Handle IDN before quoting.
|
||||
|
@ -192,6 +200,7 @@ def smart_urlquote(url):
|
|||
|
||||
return force_text(url)
|
||||
|
||||
|
||||
def urlize(text, trim_url_limit=None, nofollow=False, autoescape=False):
|
||||
"""
|
||||
Converts any URLs in text into clickable links.
|
||||
|
@ -269,6 +278,7 @@ def urlize(text, trim_url_limit=None, nofollow=False, autoescape=False):
|
|||
return ''.join(words)
|
||||
urlize = allow_lazy(urlize, six.text_type)
|
||||
|
||||
|
||||
def clean_html(text):
|
||||
"""
|
||||
Clean the given HTML. Specifically, do the following:
|
||||
|
@ -304,6 +314,7 @@ def clean_html(text):
|
|||
return text
|
||||
clean_html = allow_lazy(clean_html, six.text_type)
|
||||
|
||||
|
||||
def avoid_wrapping(value):
|
||||
"""
|
||||
Avoid text wrapping in the middle of a phrase by adding non-breaking
|
||||
|
|
|
@ -30,6 +30,7 @@ RFC1123_DATE = re.compile(r'^\w{3}, %s %s %s %s GMT$' % (__D, __M, __Y, __T))
|
|||
RFC850_DATE = re.compile(r'^\w{6,9}, %s-%s-%s %s GMT$' % (__D, __M, __Y2, __T))
|
||||
ASCTIME_DATE = re.compile(r'^\w{3} %s %s %s %s$' % (__M, __D2, __T, __Y))
|
||||
|
||||
|
||||
def urlquote(url, safe='/'):
|
||||
"""
|
||||
A version of Python's urllib.quote() function that can operate on unicode
|
||||
|
@ -40,6 +41,7 @@ def urlquote(url, safe='/'):
|
|||
return force_text(quote(force_str(url), force_str(safe)))
|
||||
urlquote = allow_lazy(urlquote, six.text_type)
|
||||
|
||||
|
||||
def urlquote_plus(url, safe=''):
|
||||
"""
|
||||
A version of Python's urllib.quote_plus() function that can operate on
|
||||
|
@ -50,6 +52,7 @@ def urlquote_plus(url, safe=''):
|
|||
return force_text(quote_plus(force_str(url), force_str(safe)))
|
||||
urlquote_plus = allow_lazy(urlquote_plus, six.text_type)
|
||||
|
||||
|
||||
def urlunquote(quoted_url):
|
||||
"""
|
||||
A wrapper for Python's urllib.unquote() function that can operate on
|
||||
|
@ -58,6 +61,7 @@ def urlunquote(quoted_url):
|
|||
return force_text(unquote(force_str(quoted_url)))
|
||||
urlunquote = allow_lazy(urlunquote, six.text_type)
|
||||
|
||||
|
||||
def urlunquote_plus(quoted_url):
|
||||
"""
|
||||
A wrapper for Python's urllib.unquote_plus() function that can operate on
|
||||
|
@ -66,6 +70,7 @@ def urlunquote_plus(quoted_url):
|
|||
return force_text(unquote_plus(force_str(quoted_url)))
|
||||
urlunquote_plus = allow_lazy(urlunquote_plus, six.text_type)
|
||||
|
||||
|
||||
def urlencode(query, doseq=0):
|
||||
"""
|
||||
A version of Python's urllib.urlencode() function that can operate on
|
||||
|
@ -82,6 +87,7 @@ def urlencode(query, doseq=0):
|
|||
for k, v in query],
|
||||
doseq)
|
||||
|
||||
|
||||
def cookie_date(epoch_seconds=None):
|
||||
"""
|
||||
Formats the time to ensure compatibility with Netscape's cookie standard.
|
||||
|
@ -95,6 +101,7 @@ def cookie_date(epoch_seconds=None):
|
|||
rfcdate = formatdate(epoch_seconds)
|
||||
return '%s-%s-%s GMT' % (rfcdate[:7], rfcdate[8:11], rfcdate[12:25])
|
||||
|
||||
|
||||
def http_date(epoch_seconds=None):
|
||||
"""
|
||||
Formats the time to match the RFC1123 date format as specified by HTTP
|
||||
|
@ -108,6 +115,7 @@ def http_date(epoch_seconds=None):
|
|||
"""
|
||||
return formatdate(epoch_seconds, usegmt=True)
|
||||
|
||||
|
||||
def parse_http_date(date):
|
||||
"""
|
||||
Parses a date format as specified by HTTP RFC2616 section 3.3.1.
|
||||
|
@ -143,6 +151,7 @@ def parse_http_date(date):
|
|||
except Exception:
|
||||
six.reraise(ValueError, ValueError("%r is not a valid date" % date), sys.exc_info()[2])
|
||||
|
||||
|
||||
def parse_http_date_safe(date):
|
||||
"""
|
||||
Same as parse_http_date, but returns None if the input is invalid.
|
||||
|
@ -152,6 +161,7 @@ def parse_http_date_safe(date):
|
|||
except Exception:
|
||||
pass
|
||||
|
||||
|
||||
# Base 36 functions: useful for generating compact URLs
|
||||
|
||||
def base36_to_int(s):
|
||||
|
@ -171,6 +181,7 @@ def base36_to_int(s):
|
|||
raise ValueError("Base36 input too large")
|
||||
return value
|
||||
|
||||
|
||||
def int_to_base36(i):
|
||||
"""
|
||||
Converts an integer to a base36 string
|
||||
|
@ -199,6 +210,7 @@ def int_to_base36(i):
|
|||
factor -= 1
|
||||
return ''.join(base36)
|
||||
|
||||
|
||||
def urlsafe_base64_encode(s):
|
||||
"""
|
||||
Encodes a bytestring in base64 for use in URLs, stripping any trailing
|
||||
|
@ -206,6 +218,7 @@ def urlsafe_base64_encode(s):
|
|||
"""
|
||||
return base64.urlsafe_b64encode(s).rstrip(b'\n=')
|
||||
|
||||
|
||||
def urlsafe_base64_decode(s):
|
||||
"""
|
||||
Decodes a base64 encoded string, adding back any trailing equal signs that
|
||||
|
@ -217,6 +230,7 @@ def urlsafe_base64_decode(s):
|
|||
except (LookupError, BinasciiError) as e:
|
||||
raise ValueError(e)
|
||||
|
||||
|
||||
def parse_etags(etag_str):
|
||||
"""
|
||||
Parses a string with one or several etags passed in If-None-Match and
|
||||
|
@ -230,12 +244,14 @@ def parse_etags(etag_str):
|
|||
etags = [e.encode('ascii').decode('unicode_escape') for e in etags]
|
||||
return etags
|
||||
|
||||
|
||||
def quote_etag(etag):
|
||||
"""
|
||||
Wraps a string in double quotes escaping contents as necessary.
|
||||
"""
|
||||
return '"%s"' % etag.replace('\\', '\\\\').replace('"', '\\"')
|
||||
|
||||
|
||||
def same_origin(url1, url2):
|
||||
"""
|
||||
Checks if two URLs are 'same-origin'
|
||||
|
@ -246,6 +262,7 @@ def same_origin(url1, url2):
|
|||
except ValueError:
|
||||
return False
|
||||
|
||||
|
||||
def is_safe_url(url, host=None):
|
||||
"""
|
||||
Return ``True`` if the url is a safe redirection (i.e. it doesn't point to
|
||||
|
|
|
@ -202,6 +202,7 @@ def normalize(pattern):
|
|||
|
||||
return list(zip(*flatten_result(result)))
|
||||
|
||||
|
||||
def next_char(input_iter):
|
||||
"""
|
||||
An iterator that yields the next character from "pattern_iter", respecting
|
||||
|
@ -222,6 +223,7 @@ def next_char(input_iter):
|
|||
continue
|
||||
yield representative, True
|
||||
|
||||
|
||||
def walk_to_end(ch, input_iter):
|
||||
"""
|
||||
The iterator is currently inside a capturing group. We want to walk to the
|
||||
|
@ -242,6 +244,7 @@ def walk_to_end(ch, input_iter):
|
|||
return
|
||||
nesting -= 1
|
||||
|
||||
|
||||
def get_quantifier(ch, input_iter):
|
||||
"""
|
||||
Parse a quantifier from the input, where "ch" is the first character in the
|
||||
|
@ -278,6 +281,7 @@ def get_quantifier(ch, input_iter):
|
|||
ch = None
|
||||
return int(values[0]), ch
|
||||
|
||||
|
||||
def contains(source, inst):
|
||||
"""
|
||||
Returns True if the "source" contains an instance of "inst". False,
|
||||
|
@ -291,6 +295,7 @@ def contains(source, inst):
|
|||
return True
|
||||
return False
|
||||
|
||||
|
||||
def flatten_result(source):
|
||||
"""
|
||||
Turns the given source sequence into a list of reg-exp possibilities and
|
||||
|
|
|
@ -32,6 +32,7 @@ else:
|
|||
# backwards compatibility for Python 2
|
||||
EscapeUnicode = EscapeText
|
||||
|
||||
|
||||
class SafeData(object):
|
||||
def __html__(self):
|
||||
"""
|
||||
|
@ -41,6 +42,7 @@ class SafeData(object):
|
|||
"""
|
||||
return self
|
||||
|
||||
|
||||
class SafeBytes(bytes, SafeData):
|
||||
"""
|
||||
A bytes subclass that has been specifically marked as "safe" (requires no
|
||||
|
@ -75,6 +77,7 @@ class SafeBytes(bytes, SafeData):
|
|||
|
||||
decode = curry(_proxy_method, method=bytes.decode)
|
||||
|
||||
|
||||
class SafeText(six.text_type, SafeData):
|
||||
"""
|
||||
A unicode (Python 2) / str (Python 3) subclass that has been specifically
|
||||
|
@ -114,6 +117,7 @@ else:
|
|||
# backwards compatibility for Python 2
|
||||
SafeUnicode = SafeText
|
||||
|
||||
|
||||
def mark_safe(s):
|
||||
"""
|
||||
Explicitly mark a string as safe for (HTML) output purposes. The returned
|
||||
|
@ -129,6 +133,7 @@ def mark_safe(s):
|
|||
return SafeText(s)
|
||||
return SafeString(str(s))
|
||||
|
||||
|
||||
def mark_for_escaping(s):
|
||||
"""
|
||||
Explicitly mark a string as requiring HTML escaping upon output. Has no
|
||||
|
|
|
@ -428,14 +428,17 @@ def iterkeys(d, **kw):
|
|||
"""Return an iterator over the keys of a dictionary."""
|
||||
return iter(getattr(d, _iterkeys)(**kw))
|
||||
|
||||
|
||||
def itervalues(d, **kw):
|
||||
"""Return an iterator over the values of a dictionary."""
|
||||
return iter(getattr(d, _itervalues)(**kw))
|
||||
|
||||
|
||||
def iteritems(d, **kw):
|
||||
"""Return an iterator over the (key, value) pairs of a dictionary."""
|
||||
return iter(getattr(d, _iteritems)(**kw))
|
||||
|
||||
|
||||
def iterlists(d, **kw):
|
||||
"""Return an iterator over the (key, [values]) pairs of a dictionary."""
|
||||
return iter(getattr(d, _iterlists)(**kw))
|
||||
|
@ -565,6 +568,7 @@ def with_metaclass(meta, *bases):
|
|||
"""Create a base class with a metaclass."""
|
||||
return meta("NewBase", bases, {})
|
||||
|
||||
|
||||
def add_metaclass(metaclass):
|
||||
"""Class decorator for creating a class with a metaclass."""
|
||||
def wrapper(cls):
|
||||
|
|
|
@ -209,6 +209,7 @@ class Truncator(SimpleLazyObject):
|
|||
# Return string
|
||||
return out
|
||||
|
||||
|
||||
def get_valid_filename(s):
|
||||
"""
|
||||
Returns the given string converted to a string that can be used for a clean
|
||||
|
@ -222,6 +223,7 @@ def get_valid_filename(s):
|
|||
return re.sub(r'(?u)[^-\w.]', '', s)
|
||||
get_valid_filename = allow_lazy(get_valid_filename, six.text_type)
|
||||
|
||||
|
||||
def get_text_list(list_, last_word=ugettext_lazy('or')):
|
||||
"""
|
||||
>>> get_text_list(['a', 'b', 'c', 'd'])
|
||||
|
@ -245,10 +247,12 @@ def get_text_list(list_, last_word=ugettext_lazy('or')):
|
|||
force_text(last_word), force_text(list_[-1]))
|
||||
get_text_list = allow_lazy(get_text_list, six.text_type)
|
||||
|
||||
|
||||
def normalize_newlines(text):
|
||||
return force_text(re.sub(r'\r\n|\r|\n', '\n', text))
|
||||
normalize_newlines = allow_lazy(normalize_newlines, six.text_type)
|
||||
|
||||
|
||||
def recapitalize(text):
|
||||
"Recapitalizes text, placing caps after end-of-sentence punctuation."
|
||||
text = force_text(text).lower()
|
||||
|
@ -257,6 +261,7 @@ def recapitalize(text):
|
|||
return text
|
||||
recapitalize = allow_lazy(recapitalize)
|
||||
|
||||
|
||||
def phone2numeric(phone):
|
||||
"Converts a phone number with letters into its numeric equivalent."
|
||||
char2number = {'a': '2', 'b': '2', 'c': '2', 'd': '3', 'e': '3', 'f': '3',
|
||||
|
@ -267,6 +272,7 @@ def phone2numeric(phone):
|
|||
return ''.join(char2number.get(c, c) for c in phone.lower())
|
||||
phone2numeric = allow_lazy(phone2numeric)
|
||||
|
||||
|
||||
# From http://www.xhaus.com/alan/python/httpcomp.html#gzip
|
||||
# Used with permission.
|
||||
def compress_string(s):
|
||||
|
@ -276,6 +282,7 @@ def compress_string(s):
|
|||
zfile.close()
|
||||
return zbuf.getvalue()
|
||||
|
||||
|
||||
class StreamingBuffer(object):
|
||||
def __init__(self):
|
||||
self.vals = []
|
||||
|
@ -294,6 +301,7 @@ class StreamingBuffer(object):
|
|||
def close(self):
|
||||
return
|
||||
|
||||
|
||||
# Like compress_string, but for iterators of strings.
|
||||
def compress_sequence(sequence):
|
||||
buf = StreamingBuffer()
|
||||
|
@ -309,6 +317,7 @@ def compress_sequence(sequence):
|
|||
|
||||
ustring_re = re.compile("([\u0080-\uffff])")
|
||||
|
||||
|
||||
def javascript_quote(s, quote_double_quotes=False):
|
||||
|
||||
def fix(match):
|
||||
|
@ -340,6 +349,7 @@ smart_split_re = re.compile(r"""
|
|||
) | \S+)
|
||||
""", re.VERBOSE)
|
||||
|
||||
|
||||
def smart_split(text):
|
||||
r"""
|
||||
Generator that splits a string by spaces, leaving quoted phrases together.
|
||||
|
@ -359,6 +369,7 @@ def smart_split(text):
|
|||
for bit in smart_split_re.finditer(text):
|
||||
yield bit.group(0)
|
||||
|
||||
|
||||
def _replace_entity(match):
|
||||
text = match.group(1)
|
||||
if text[0] == '#':
|
||||
|
@ -379,10 +390,12 @@ def _replace_entity(match):
|
|||
|
||||
_entity_re = re.compile(r"&(#?[xX]?(?:[0-9a-fA-F]+|\w{1,8}));")
|
||||
|
||||
|
||||
def unescape_entities(text):
|
||||
return _entity_re.sub(_replace_entity, text)
|
||||
unescape_entities = allow_lazy(unescape_entities, six.text_type)
|
||||
|
||||
|
||||
def unescape_string_literal(s):
|
||||
r"""
|
||||
Convert quoted string literals to unquoted strings with escaped quotes and
|
||||
|
@ -403,6 +416,7 @@ def unescape_string_literal(s):
|
|||
return s[1:-1].replace(r'\%s' % quote, quote).replace(r'\\', '\\')
|
||||
unescape_string_literal = allow_lazy(unescape_string_literal)
|
||||
|
||||
|
||||
def slugify(value):
|
||||
"""
|
||||
Converts to lowercase, removes non-word characters (alphanumerics and
|
||||
|
|
|
@ -6,6 +6,7 @@ from django.utils.html import avoid_wrapping
|
|||
from django.utils.timezone import is_aware, utc
|
||||
from django.utils.translation import ugettext, ungettext_lazy
|
||||
|
||||
|
||||
def timesince(d, now=None, reversed=False):
|
||||
"""
|
||||
Takes two datetime objects and returns the time between d and now
|
||||
|
@ -56,6 +57,7 @@ def timesince(d, now=None, reversed=False):
|
|||
result += ugettext(', ') + avoid_wrapping(name2 % count2)
|
||||
return result
|
||||
|
||||
|
||||
def timeuntil(d, now=None):
|
||||
"""
|
||||
Like timesince, but returns a string measuring the time until
|
||||
|
|
|
@ -29,6 +29,7 @@ __all__ = [
|
|||
|
||||
ZERO = timedelta(0)
|
||||
|
||||
|
||||
class UTC(tzinfo):
|
||||
"""
|
||||
UTC implementation taken from Python's docs.
|
||||
|
@ -48,6 +49,7 @@ class UTC(tzinfo):
|
|||
def dst(self, dt):
|
||||
return ZERO
|
||||
|
||||
|
||||
class FixedOffset(tzinfo):
|
||||
"""
|
||||
Fixed offset in minutes east from UTC. Taken from Python's docs.
|
||||
|
@ -72,6 +74,7 @@ class FixedOffset(tzinfo):
|
|||
def dst(self, dt):
|
||||
return ZERO
|
||||
|
||||
|
||||
class ReferenceLocalTimezone(tzinfo):
|
||||
"""
|
||||
Local time. Taken from Python's docs.
|
||||
|
@ -118,6 +121,7 @@ class ReferenceLocalTimezone(tzinfo):
|
|||
tt = _time.localtime(stamp)
|
||||
return tt.tm_isdst > 0
|
||||
|
||||
|
||||
class LocalTimezone(ReferenceLocalTimezone):
|
||||
"""
|
||||
Slightly improved local time implementation focusing on correctness.
|
||||
|
@ -143,6 +147,7 @@ class LocalTimezone(ReferenceLocalTimezone):
|
|||
utc = pytz.utc if pytz else UTC()
|
||||
"""UTC time zone as a tzinfo instance."""
|
||||
|
||||
|
||||
def get_fixed_timezone(offset):
|
||||
"""
|
||||
Returns a tzinfo instance with a fixed offset from UTC.
|
||||
|
@ -158,6 +163,7 @@ def get_fixed_timezone(offset):
|
|||
# wrap the expression in a function and cache the result.
|
||||
_localtime = None
|
||||
|
||||
|
||||
def get_default_timezone():
|
||||
"""
|
||||
Returns the default time zone as a tzinfo instance.
|
||||
|
@ -173,6 +179,7 @@ def get_default_timezone():
|
|||
_localtime = LocalTimezone()
|
||||
return _localtime
|
||||
|
||||
|
||||
# This function exists for consistency with get_current_timezone_name
|
||||
def get_default_timezone_name():
|
||||
"""
|
||||
|
@ -182,18 +189,21 @@ def get_default_timezone_name():
|
|||
|
||||
_active = local()
|
||||
|
||||
|
||||
def get_current_timezone():
|
||||
"""
|
||||
Returns the currently active time zone as a tzinfo instance.
|
||||
"""
|
||||
return getattr(_active, "value", get_default_timezone())
|
||||
|
||||
|
||||
def get_current_timezone_name():
|
||||
"""
|
||||
Returns the name of the currently active time zone.
|
||||
"""
|
||||
return _get_timezone_name(get_current_timezone())
|
||||
|
||||
|
||||
def _get_timezone_name(timezone):
|
||||
"""
|
||||
Returns the name of ``timezone``.
|
||||
|
@ -210,6 +220,7 @@ def _get_timezone_name(timezone):
|
|||
# These functions don't change os.environ['TZ'] and call time.tzset()
|
||||
# because it isn't thread safe.
|
||||
|
||||
|
||||
def activate(timezone):
|
||||
"""
|
||||
Sets the time zone for the current thread.
|
||||
|
@ -224,6 +235,7 @@ def activate(timezone):
|
|||
else:
|
||||
raise ValueError("Invalid timezone: %r" % timezone)
|
||||
|
||||
|
||||
def deactivate():
|
||||
"""
|
||||
Unsets the time zone for the current thread.
|
||||
|
@ -233,6 +245,7 @@ def deactivate():
|
|||
if hasattr(_active, "value"):
|
||||
del _active.value
|
||||
|
||||
|
||||
class override(object):
|
||||
"""
|
||||
Temporarily set the time zone for the current thread.
|
||||
|
@ -297,6 +310,7 @@ def localtime(value, timezone=None):
|
|||
value = timezone.normalize(value)
|
||||
return value
|
||||
|
||||
|
||||
def now():
|
||||
"""
|
||||
Returns an aware or naive datetime.datetime, depending on settings.USE_TZ.
|
||||
|
@ -307,6 +321,7 @@ def now():
|
|||
else:
|
||||
return datetime.now()
|
||||
|
||||
|
||||
# By design, these four functions don't perform any checks on their arguments.
|
||||
# The caller should ensure that they don't receive an invalid value like None.
|
||||
|
||||
|
@ -319,6 +334,7 @@ def is_aware(value):
|
|||
"""
|
||||
return value.tzinfo is not None and value.tzinfo.utcoffset(value) is not None
|
||||
|
||||
|
||||
def is_naive(value):
|
||||
"""
|
||||
Determines if a given datetime.datetime is naive.
|
||||
|
@ -328,6 +344,7 @@ def is_naive(value):
|
|||
"""
|
||||
return value.tzinfo is None or value.tzinfo.utcoffset(value) is None
|
||||
|
||||
|
||||
def make_aware(value, timezone):
|
||||
"""
|
||||
Makes a naive datetime.datetime in a given time zone aware.
|
||||
|
@ -339,6 +356,7 @@ def make_aware(value, timezone):
|
|||
# may be wrong around DST changes
|
||||
return value.replace(tzinfo=timezone)
|
||||
|
||||
|
||||
def make_naive(value, timezone):
|
||||
"""
|
||||
Makes an aware datetime.datetime naive in a given time zone.
|
||||
|
|
|
@ -61,26 +61,33 @@ _trans = Trans()
|
|||
# The Trans class is no more needed, so remove it from the namespace.
|
||||
del Trans
|
||||
|
||||
|
||||
def gettext_noop(message):
|
||||
return _trans.gettext_noop(message)
|
||||
|
||||
ugettext_noop = gettext_noop
|
||||
|
||||
|
||||
def gettext(message):
|
||||
return _trans.gettext(message)
|
||||
|
||||
|
||||
def ngettext(singular, plural, number):
|
||||
return _trans.ngettext(singular, plural, number)
|
||||
|
||||
|
||||
def ugettext(message):
|
||||
return _trans.ugettext(message)
|
||||
|
||||
|
||||
def ungettext(singular, plural, number):
|
||||
return _trans.ungettext(singular, plural, number)
|
||||
|
||||
|
||||
def pgettext(context, message):
|
||||
return _trans.pgettext(context, message)
|
||||
|
||||
|
||||
def npgettext(context, singular, plural, number):
|
||||
return _trans.npgettext(context, singular, plural, number)
|
||||
|
||||
|
@ -88,6 +95,7 @@ gettext_lazy = lazy(gettext, str)
|
|||
ugettext_lazy = lazy(ugettext, six.text_type)
|
||||
pgettext_lazy = lazy(pgettext, six.text_type)
|
||||
|
||||
|
||||
def lazy_number(func, resultclass, number=None, **kwargs):
|
||||
if isinstance(number, int):
|
||||
kwargs['number'] = number
|
||||
|
@ -117,21 +125,27 @@ def lazy_number(func, resultclass, number=None, **kwargs):
|
|||
proxy = lazy(lambda **kwargs: NumberAwareString(), NumberAwareString)(**kwargs)
|
||||
return proxy
|
||||
|
||||
|
||||
def ngettext_lazy(singular, plural, number=None):
|
||||
return lazy_number(ngettext, str, singular=singular, plural=plural, number=number)
|
||||
|
||||
|
||||
def ungettext_lazy(singular, plural, number=None):
|
||||
return lazy_number(ungettext, six.text_type, singular=singular, plural=plural, number=number)
|
||||
|
||||
|
||||
def npgettext_lazy(context, singular, plural, number=None):
|
||||
return lazy_number(npgettext, six.text_type, context=context, singular=singular, plural=plural, number=number)
|
||||
|
||||
|
||||
def activate(language):
|
||||
return _trans.activate(language)
|
||||
|
||||
|
||||
def deactivate():
|
||||
return _trans.deactivate()
|
||||
|
||||
|
||||
class override(object):
|
||||
def __init__(self, language, deactivate=False):
|
||||
self.language = language
|
||||
|
@ -150,30 +164,39 @@ class override(object):
|
|||
else:
|
||||
activate(self.old_language)
|
||||
|
||||
|
||||
def get_language():
|
||||
return _trans.get_language()
|
||||
|
||||
|
||||
def get_language_bidi():
|
||||
return _trans.get_language_bidi()
|
||||
|
||||
|
||||
def check_for_language(lang_code):
|
||||
return _trans.check_for_language(lang_code)
|
||||
|
||||
|
||||
def to_locale(language):
|
||||
return _trans.to_locale(language)
|
||||
|
||||
|
||||
def get_language_from_request(request, check_path=False):
|
||||
return _trans.get_language_from_request(request, check_path)
|
||||
|
||||
|
||||
def get_language_from_path(path, supported=None):
|
||||
return _trans.get_language_from_path(path, supported=supported)
|
||||
|
||||
|
||||
def templatize(src, origin=None):
|
||||
return _trans.templatize(src, origin)
|
||||
|
||||
|
||||
def deactivate_all():
|
||||
return _trans.deactivate_all()
|
||||
|
||||
|
||||
def _string_concat(*strings):
|
||||
"""
|
||||
Lazy variant of string concatenation, needed for translations that are
|
||||
|
@ -182,6 +205,7 @@ def _string_concat(*strings):
|
|||
return ''.join(force_text(s) for s in strings)
|
||||
string_concat = lazy(_string_concat, six.text_type)
|
||||
|
||||
|
||||
def get_language_info(lang_code):
|
||||
from django.conf.locale import LANG_INFO
|
||||
try:
|
||||
|
|
|
@ -6,18 +6,22 @@ from django.conf import settings
|
|||
from django.utils.encoding import force_text
|
||||
from django.utils.safestring import mark_safe, SafeData
|
||||
|
||||
|
||||
def ngettext(singular, plural, number):
|
||||
if number == 1:
|
||||
return singular
|
||||
return plural
|
||||
ngettext_lazy = ngettext
|
||||
|
||||
|
||||
def ungettext(singular, plural, number):
|
||||
return force_text(ngettext(singular, plural, number))
|
||||
|
||||
|
||||
def pgettext(context, message):
|
||||
return ugettext(message)
|
||||
|
||||
|
||||
def npgettext(context, singular, plural, number):
|
||||
return ungettext(singular, plural, number)
|
||||
|
||||
|
@ -38,17 +42,20 @@ TECHNICAL_ID_MAP = {
|
|||
"MONTH_DAY_FORMAT": settings.MONTH_DAY_FORMAT,
|
||||
}
|
||||
|
||||
|
||||
def gettext(message):
|
||||
result = TECHNICAL_ID_MAP.get(message, message)
|
||||
if isinstance(message, SafeData):
|
||||
return mark_safe(result)
|
||||
return result
|
||||
|
||||
|
||||
def ugettext(message):
|
||||
return force_text(gettext(message))
|
||||
|
||||
gettext_noop = gettext_lazy = _ = gettext
|
||||
|
||||
|
||||
def to_locale(language):
|
||||
p = language.find('-')
|
||||
if p >= 0:
|
||||
|
@ -56,8 +63,10 @@ def to_locale(language):
|
|||
else:
|
||||
return language.lower()
|
||||
|
||||
|
||||
def get_language_from_request(request, check_path=False):
|
||||
return settings.LANGUAGE_CODE
|
||||
|
||||
|
||||
def get_language_from_path(request, supported=None):
|
||||
return None
|
||||
|
|
|
@ -64,6 +64,7 @@ def to_locale(language, to_lower=False):
|
|||
else:
|
||||
return language.lower()
|
||||
|
||||
|
||||
def to_language(locale):
|
||||
"""Turns a locale name (en_US) into a language name (en-us)."""
|
||||
p = locale.find('_')
|
||||
|
@ -72,6 +73,7 @@ def to_language(locale):
|
|||
else:
|
||||
return locale.lower()
|
||||
|
||||
|
||||
class DjangoTranslation(gettext_module.GNUTranslations):
|
||||
"""
|
||||
This class sets up the GNUTranslations context with regard to output
|
||||
|
@ -98,6 +100,7 @@ class DjangoTranslation(gettext_module.GNUTranslations):
|
|||
def __repr__(self):
|
||||
return "<DjangoTranslation lang:%s>" % self.__language
|
||||
|
||||
|
||||
def translation(language):
|
||||
"""
|
||||
Returns a translation object.
|
||||
|
@ -179,6 +182,7 @@ def translation(language):
|
|||
|
||||
return current_translation
|
||||
|
||||
|
||||
def activate(language):
|
||||
"""
|
||||
Fetches the translation object for a given tuple of application name and
|
||||
|
@ -187,6 +191,7 @@ def activate(language):
|
|||
"""
|
||||
_active.value = translation(language)
|
||||
|
||||
|
||||
def deactivate():
|
||||
"""
|
||||
Deinstalls the currently active translation object so that further _ calls
|
||||
|
@ -195,6 +200,7 @@ def deactivate():
|
|||
if hasattr(_active, "value"):
|
||||
del _active.value
|
||||
|
||||
|
||||
def deactivate_all():
|
||||
"""
|
||||
Makes the active translation object a NullTranslations() instance. This is
|
||||
|
@ -203,6 +209,7 @@ def deactivate_all():
|
|||
"""
|
||||
_active.value = gettext_module.NullTranslations()
|
||||
|
||||
|
||||
def get_language():
|
||||
"""Returns the currently selected language."""
|
||||
t = getattr(_active, "value", None)
|
||||
|
@ -215,6 +222,7 @@ def get_language():
|
|||
from django.conf import settings
|
||||
return settings.LANGUAGE_CODE
|
||||
|
||||
|
||||
def get_language_bidi():
|
||||
"""
|
||||
Returns selected language's BiDi layout.
|
||||
|
@ -227,6 +235,7 @@ def get_language_bidi():
|
|||
base_lang = get_language().split('-')[0]
|
||||
return base_lang in settings.LANGUAGES_BIDI
|
||||
|
||||
|
||||
def catalog():
|
||||
"""
|
||||
Returns the current active catalog for further processing.
|
||||
|
@ -243,6 +252,7 @@ def catalog():
|
|||
_default = translation(settings.LANGUAGE_CODE)
|
||||
return _default
|
||||
|
||||
|
||||
def do_translate(message, translation_function):
|
||||
"""
|
||||
Translates 'message' using the given 'translation_function' name -- which
|
||||
|
@ -266,6 +276,7 @@ def do_translate(message, translation_function):
|
|||
return mark_safe(result)
|
||||
return result
|
||||
|
||||
|
||||
def gettext(message):
|
||||
"""
|
||||
Returns a string of the translation of the message.
|
||||
|
@ -280,6 +291,7 @@ else:
|
|||
def ugettext(message):
|
||||
return do_translate(message, 'ugettext')
|
||||
|
||||
|
||||
def pgettext(context, message):
|
||||
msg_with_ctxt = "%s%s%s" % (context, CONTEXT_SEPARATOR, message)
|
||||
result = ugettext(msg_with_ctxt)
|
||||
|
@ -288,6 +300,7 @@ def pgettext(context, message):
|
|||
result = message
|
||||
return result
|
||||
|
||||
|
||||
def gettext_noop(message):
|
||||
"""
|
||||
Marks strings for translation but doesn't translate them now. This can be
|
||||
|
@ -297,6 +310,7 @@ def gettext_noop(message):
|
|||
"""
|
||||
return message
|
||||
|
||||
|
||||
def do_ntranslate(singular, plural, number, translation_function):
|
||||
global _default
|
||||
|
||||
|
@ -308,6 +322,7 @@ def do_ntranslate(singular, plural, number, translation_function):
|
|||
_default = translation(settings.LANGUAGE_CODE)
|
||||
return getattr(_default, translation_function)(singular, plural, number)
|
||||
|
||||
|
||||
def ngettext(singular, plural, number):
|
||||
"""
|
||||
Returns a string of the translation of either the singular or plural,
|
||||
|
@ -327,6 +342,7 @@ else:
|
|||
"""
|
||||
return do_ntranslate(singular, plural, number, 'ungettext')
|
||||
|
||||
|
||||
def npgettext(context, singular, plural, number):
|
||||
msgs_with_ctxt = ("%s%s%s" % (context, CONTEXT_SEPARATOR, singular),
|
||||
"%s%s%s" % (context, CONTEXT_SEPARATOR, plural),
|
||||
|
@ -337,6 +353,7 @@ def npgettext(context, singular, plural, number):
|
|||
result = ungettext(singular, plural, number)
|
||||
return result
|
||||
|
||||
|
||||
def all_locale_paths():
|
||||
"""
|
||||
Returns a list of paths to user-provides languages files.
|
||||
|
@ -346,6 +363,7 @@ def all_locale_paths():
|
|||
os.path.dirname(upath(sys.modules[settings.__module__].__file__)), 'locale')
|
||||
return [globalpath] + list(settings.LOCALE_PATHS)
|
||||
|
||||
|
||||
def check_for_language(lang_code):
|
||||
"""
|
||||
Checks whether there is a global language file for the given language
|
||||
|
@ -359,6 +377,7 @@ def check_for_language(lang_code):
|
|||
return False
|
||||
check_for_language = memoize(check_for_language, _checked_languages, 1)
|
||||
|
||||
|
||||
def get_supported_language_variant(lang_code, supported=None, strict=False):
|
||||
"""
|
||||
Returns the language-code that's listed in supported languages, possibly
|
||||
|
@ -386,6 +405,7 @@ def get_supported_language_variant(lang_code, supported=None, strict=False):
|
|||
return supported_code
|
||||
raise LookupError(lang_code)
|
||||
|
||||
|
||||
def get_language_from_path(path, supported=None, strict=False):
|
||||
"""
|
||||
Returns the language-code if there is a valid language-code
|
||||
|
@ -406,6 +426,7 @@ def get_language_from_path(path, supported=None, strict=False):
|
|||
except LookupError:
|
||||
return None
|
||||
|
||||
|
||||
def get_language_from_request(request, check_path=False):
|
||||
"""
|
||||
Analyzes the request to find what language the user wants the system to
|
||||
|
@ -470,6 +491,8 @@ def get_language_from_request(request, check_path=False):
|
|||
return settings.LANGUAGE_CODE
|
||||
|
||||
dot_re = re.compile(r'\S')
|
||||
|
||||
|
||||
def blankout(src, char):
|
||||
"""
|
||||
Changes every non-whitespace character to the given char.
|
||||
|
@ -653,6 +676,7 @@ def templatize(src, origin=None):
|
|||
out.write(blankout(t.contents, 'X'))
|
||||
return force_str(out.getvalue())
|
||||
|
||||
|
||||
def parse_accept_lang_header(lang_string):
|
||||
"""
|
||||
Parses the lang_string, which is the body of an HTTP Accept-Language
|
||||
|
|
|
@ -21,6 +21,7 @@ HIDDEN_SETTINGS = re.compile('API|TOKEN|KEY|SECRET|PASS|PROFANITIES_LIST|SIGNATU
|
|||
|
||||
CLEANSED_SUBSTITUTE = '********************'
|
||||
|
||||
|
||||
def linebreak_iter(template_source):
|
||||
yield 0
|
||||
p = template_source.find('\n')
|
||||
|
@ -29,6 +30,7 @@ def linebreak_iter(template_source):
|
|||
p = template_source.find('\n', p+1)
|
||||
yield len(template_source) + 1
|
||||
|
||||
|
||||
def cleanse_setting(key, value):
|
||||
"""Cleanse an individual setting key/value of sensitive content.
|
||||
|
||||
|
@ -52,6 +54,7 @@ def cleanse_setting(key, value):
|
|||
|
||||
return cleansed
|
||||
|
||||
|
||||
def get_safe_settings():
|
||||
"Returns a dictionary of the settings module, with sensitive settings blurred out."
|
||||
settings_dict = {}
|
||||
|
@ -60,6 +63,7 @@ def get_safe_settings():
|
|||
settings_dict[k] = cleanse_setting(k, getattr(settings, k))
|
||||
return settings_dict
|
||||
|
||||
|
||||
def technical_500_response(request, exc_type, exc_value, tb):
|
||||
"""
|
||||
Create a technical server error response. The last three arguments are
|
||||
|
@ -76,6 +80,7 @@ def technical_500_response(request, exc_type, exc_value, tb):
|
|||
# Cache for the default exception reporter filter instance.
|
||||
default_exception_reporter_filter = None
|
||||
|
||||
|
||||
def get_exception_reporter_filter(request):
|
||||
global default_exception_reporter_filter
|
||||
if default_exception_reporter_filter is None:
|
||||
|
@ -87,6 +92,7 @@ def get_exception_reporter_filter(request):
|
|||
else:
|
||||
return default_exception_reporter_filter
|
||||
|
||||
|
||||
class ExceptionReporterFilter(object):
|
||||
"""
|
||||
Base for all exception reporter filter classes. All overridable hooks
|
||||
|
@ -108,6 +114,7 @@ class ExceptionReporterFilter(object):
|
|||
def get_traceback_frame_variables(self, request, tb_frame):
|
||||
return list(six.iteritems(tb_frame.f_locals))
|
||||
|
||||
|
||||
class SafeExceptionReporterFilter(ExceptionReporterFilter):
|
||||
"""
|
||||
Use annotations made by the sensitive_post_parameters and
|
||||
|
@ -221,6 +228,7 @@ class SafeExceptionReporterFilter(ExceptionReporterFilter):
|
|||
|
||||
return cleansed.items()
|
||||
|
||||
|
||||
class ExceptionReporter(object):
|
||||
"""
|
||||
A class to organize and coordinate reporting on exceptions.
|
||||
|
@ -491,6 +499,7 @@ def technical_404_response(request, exception):
|
|||
})
|
||||
return HttpResponseNotFound(t.render(c), content_type='text/html')
|
||||
|
||||
|
||||
def default_urlconf(request):
|
||||
"Create an empty URLconf 404 error response."
|
||||
t = Template(DEFAULT_URLCONF_TEMPLATE, name='Default URLconf template')
|
||||
|
|
|
@ -51,6 +51,7 @@ require_POST.__doc__ = "Decorator to require that a view only accept the POST me
|
|||
require_safe = require_http_methods(["GET", "HEAD"])
|
||||
require_safe.__doc__ = "Decorator to require that a view only accept safe methods: GET and HEAD."
|
||||
|
||||
|
||||
def condition(etag_func=None, last_modified_func=None):
|
||||
"""
|
||||
Decorator to support conditional retrieval (or change) for a view
|
||||
|
@ -157,9 +158,11 @@ def condition(etag_func=None, last_modified_func=None):
|
|||
return inner
|
||||
return decorator
|
||||
|
||||
|
||||
# Shortcut decorators for common cases based on ETag or Last-Modified only
|
||||
def etag(etag_func):
|
||||
return condition(etag_func=etag_func)
|
||||
|
||||
|
||||
def last_modified(last_modified_func):
|
||||
return condition(last_modified_func=last_modified_func)
|
||||
|
|
|
@ -2,6 +2,7 @@ from functools import wraps
|
|||
from django.utils.cache import patch_vary_headers
|
||||
from django.utils.decorators import available_attrs
|
||||
|
||||
|
||||
def vary_on_headers(*headers):
|
||||
"""
|
||||
A view decorator that adds the specified headers to the Vary header of the
|
||||
|
@ -22,6 +23,7 @@ def vary_on_headers(*headers):
|
|||
return inner_func
|
||||
return decorator
|
||||
|
||||
|
||||
def vary_on_cookie(func):
|
||||
"""
|
||||
A view decorator that adds "Cookie" to the Vary header of a response. This
|
||||
|
|
|
@ -13,6 +13,7 @@ from django.views.generic.base import View
|
|||
from django.views.generic.detail import BaseDetailView, SingleObjectTemplateResponseMixin
|
||||
from django.views.generic.list import MultipleObjectMixin, MultipleObjectTemplateResponseMixin
|
||||
|
||||
|
||||
class YearMixin(object):
|
||||
"""
|
||||
Mixin for views manipulating year-based data.
|
||||
|
|
|
@ -13,6 +13,7 @@ from django.utils._os import upath
|
|||
from django.utils.http import is_safe_url
|
||||
from django.utils import six
|
||||
|
||||
|
||||
def set_language(request):
|
||||
"""
|
||||
Redirect to a given url while setting the chosen language in the
|
||||
|
|
|
@ -17,6 +17,7 @@ from django.utils.http import http_date, parse_http_date
|
|||
from django.utils.six.moves.urllib.parse import unquote
|
||||
from django.utils.translation import ugettext as _, ugettext_noop
|
||||
|
||||
|
||||
def serve(request, path, document_root=None, show_indexes=False):
|
||||
"""
|
||||
Serve static files below a given point in the directory structure.
|
||||
|
@ -95,6 +96,7 @@ DEFAULT_DIRECTORY_INDEX_TEMPLATE = """
|
|||
"""
|
||||
template_translatable = ugettext_noop("Index of %(directory)s")
|
||||
|
||||
|
||||
def directory_index(path, fullpath):
|
||||
try:
|
||||
t = loader.select_template(['static/directory_index.html',
|
||||
|
@ -113,6 +115,7 @@ def directory_index(path, fullpath):
|
|||
})
|
||||
return HttpResponse(t.render(c))
|
||||
|
||||
|
||||
def was_modified_since(header=None, mtime=0, size=0):
|
||||
"""
|
||||
Was something modified since the user last downloaded it?
|
||||
|
|
Loading…
Reference in New Issue