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