diff options
author | coderick14 | 2017-05-17 15:40:18 +0530 |
---|---|---|
committer | coderick14 | 2017-05-17 15:41:00 +0530 |
commit | a1e0a5502f04da68b6a9ca8508dda3f9d7e1d055 (patch) | |
tree | 20181e6b1936f50ad48d8e35720d64a37566f558 /lib/python2.7/site-packages/django/test | |
parent | 6f4a84c1e58ff4d54aab94cbee26e995328b05b8 (diff) | |
download | SBHS-2018-Rpi-a1e0a5502f04da68b6a9ca8508dda3f9d7e1d055.tar.gz SBHS-2018-Rpi-a1e0a5502f04da68b6a9ca8508dda3f9d7e1d055.tar.bz2 SBHS-2018-Rpi-a1e0a5502f04da68b6a9ca8508dda3f9d7e1d055.zip |
Upgrade to Django 1.11
- Database integration yet to be tested
Diffstat (limited to 'lib/python2.7/site-packages/django/test')
-rw-r--r-- | lib/python2.7/site-packages/django/test/__init__.py | 10 | ||||
-rw-r--r-- | lib/python2.7/site-packages/django/test/_doctest.py | 2755 | ||||
-rw-r--r-- | lib/python2.7/site-packages/django/test/client.py | 623 | ||||
-rw-r--r-- | lib/python2.7/site-packages/django/test/html.py | 238 | ||||
-rw-r--r-- | lib/python2.7/site-packages/django/test/runner.py | 291 | ||||
-rw-r--r-- | lib/python2.7/site-packages/django/test/signals.py | 81 | ||||
-rw-r--r-- | lib/python2.7/site-packages/django/test/simple.py | 253 | ||||
-rw-r--r-- | lib/python2.7/site-packages/django/test/testcases.py | 1208 | ||||
-rw-r--r-- | lib/python2.7/site-packages/django/test/utils.py | 469 |
9 files changed, 0 insertions, 5928 deletions
diff --git a/lib/python2.7/site-packages/django/test/__init__.py b/lib/python2.7/site-packages/django/test/__init__.py deleted file mode 100644 index 7a49875..0000000 --- a/lib/python2.7/site-packages/django/test/__init__.py +++ /dev/null @@ -1,10 +0,0 @@ -""" -Django Unit Test and Doctest framework. -""" - -from django.test.client import Client, RequestFactory -from django.test.testcases import (TestCase, TransactionTestCase, - SimpleTestCase, LiveServerTestCase, skipIfDBFeature, - skipUnlessDBFeature -) -from django.test.utils import Approximate diff --git a/lib/python2.7/site-packages/django/test/_doctest.py b/lib/python2.7/site-packages/django/test/_doctest.py deleted file mode 100644 index 5381cff..0000000 --- a/lib/python2.7/site-packages/django/test/_doctest.py +++ /dev/null @@ -1,2755 +0,0 @@ -# This is a slightly modified version of the doctest.py that shipped with Python 2.5 -# It incorporates changes that have been submitted to the Python ticket tracker -# as ticket #1521051. These changes allow for a DoctestRunner and Doctest base -# class to be specified when constructing a DoctestSuite. - -# Module doctest. -# Released to the public domain 16-Jan-2001, by Tim Peters (tim@python.org). -# Major enhancements and refactoring by: -# Jim Fulton -# Edward Loper - -# Provided as-is; use at your own risk; no warranty; no promises; enjoy! - -r"""Module doctest -- a framework for running examples in docstrings. - -In simplest use, end each module M to be tested with: - -def _test(): - import doctest - doctest.testmod() - -if __name__ == "__main__": - _test() - -Then running the module as a script will cause the examples in the -docstrings to get executed and verified: - -python M.py - -This won't display anything unless an example fails, in which case the -failing example(s) and the cause(s) of the failure(s) are printed to stdout -(why not stderr? because stderr is a lame hack <0.2 wink>), and the final -line of output is "Test failed.". - -Run it with the -v switch instead: - -python M.py -v - -and a detailed report of all examples tried is printed to stdout, along -with assorted summaries at the end. - -You can force verbose mode by passing "verbose=True" to testmod, or prohibit -it by passing "verbose=False". In either of those cases, sys.argv is not -examined by testmod. - -There are a variety of other ways to run doctests, including integration -with the unittest framework, and support for running non-Python text -files containing doctests. There are also many ways to override parts -of doctest's default behaviors. See the Library Reference Manual for -details. -""" -import warnings - -warnings.warn( - "The django.test._doctest module is deprecated; " - "use the doctest module from the Python standard library instead.", - PendingDeprecationWarning) - - -__docformat__ = 'reStructuredText en' - -__all__ = [ - # 0, Option Flags - 'register_optionflag', - 'DONT_ACCEPT_TRUE_FOR_1', - 'DONT_ACCEPT_BLANKLINE', - 'NORMALIZE_WHITESPACE', - 'ELLIPSIS', - 'SKIP', - 'IGNORE_EXCEPTION_DETAIL', - 'COMPARISON_FLAGS', - 'REPORT_UDIFF', - 'REPORT_CDIFF', - 'REPORT_NDIFF', - 'REPORT_ONLY_FIRST_FAILURE', - 'REPORTING_FLAGS', - # 1. Utility Functions - # 2. Example & DocTest - 'Example', - 'DocTest', - # 3. Doctest Parser - 'DocTestParser', - # 4. Doctest Finder - 'DocTestFinder', - # 5. Doctest Runner - 'DocTestRunner', - 'OutputChecker', - 'DocTestFailure', - 'UnexpectedException', - 'DebugRunner', - # 6. Test Functions - 'testmod', - 'testfile', - 'run_docstring_examples', - # 7. Tester - 'Tester', - # 8. Unittest Support - 'DocTestSuite', - 'DocFileSuite', - 'set_unittest_reportflags', - # 9. Debugging Support - 'script_from_examples', - 'testsource', - 'debug_src', - 'debug', -] - -import __future__ - -import sys, traceback, inspect, linecache, os, re -import unittest, difflib, pdb, tempfile -import warnings - -from django.utils import six -from django.utils.six.moves import StringIO, xrange - -if sys.platform.startswith('java'): - # On Jython, isclass() reports some modules as classes. Patch it. - def patch_isclass(isclass): - def patched_isclass(obj): - return isclass(obj) and hasattr(obj, '__module__') - return patched_isclass - inspect.isclass = patch_isclass(inspect.isclass) - -# There are 4 basic classes: -# - Example: a <source, want> pair, plus an intra-docstring line number. -# - DocTest: a collection of examples, parsed from a docstring, plus -# info about where the docstring came from (name, filename, lineno). -# - DocTestFinder: extracts DocTests from a given object's docstring and -# its contained objects' docstrings. -# - DocTestRunner: runs DocTest cases, and accumulates statistics. -# -# So the basic picture is: -# -# list of: -# +------+ +---------+ +-------+ -# |object| --DocTestFinder-> | DocTest | --DocTestRunner-> |results| -# +------+ +---------+ +-------+ -# | Example | -# | ... | -# | Example | -# +---------+ - -# Option constants. - -OPTIONFLAGS_BY_NAME = {} -def register_optionflag(name): - # Create a new flag unless `name` is already known. - return OPTIONFLAGS_BY_NAME.setdefault(name, 1 << len(OPTIONFLAGS_BY_NAME)) - -DONT_ACCEPT_TRUE_FOR_1 = register_optionflag('DONT_ACCEPT_TRUE_FOR_1') -DONT_ACCEPT_BLANKLINE = register_optionflag('DONT_ACCEPT_BLANKLINE') -NORMALIZE_WHITESPACE = register_optionflag('NORMALIZE_WHITESPACE') -ELLIPSIS = register_optionflag('ELLIPSIS') -SKIP = register_optionflag('SKIP') -IGNORE_EXCEPTION_DETAIL = register_optionflag('IGNORE_EXCEPTION_DETAIL') - -COMPARISON_FLAGS = (DONT_ACCEPT_TRUE_FOR_1 | - DONT_ACCEPT_BLANKLINE | - NORMALIZE_WHITESPACE | - ELLIPSIS | - SKIP | - IGNORE_EXCEPTION_DETAIL) - -REPORT_UDIFF = register_optionflag('REPORT_UDIFF') -REPORT_CDIFF = register_optionflag('REPORT_CDIFF') -REPORT_NDIFF = register_optionflag('REPORT_NDIFF') -REPORT_ONLY_FIRST_FAILURE = register_optionflag('REPORT_ONLY_FIRST_FAILURE') - -REPORTING_FLAGS = (REPORT_UDIFF | - REPORT_CDIFF | - REPORT_NDIFF | - REPORT_ONLY_FIRST_FAILURE) - -# Special string markers for use in `want` strings: -BLANKLINE_MARKER = '<BLANKLINE>' -ELLIPSIS_MARKER = '...' - -###################################################################### -## Table of Contents -###################################################################### -# 1. Utility Functions -# 2. Example & DocTest -- store test cases -# 3. DocTest Parser -- extracts examples from strings -# 4. DocTest Finder -- extracts test cases from objects -# 5. DocTest Runner -- runs test cases -# 6. Test Functions -- convenient wrappers for testing -# 7. Tester Class -- for backwards compatibility -# 8. Unittest Support -# 9. Debugging Support -# 10. Example Usage - -###################################################################### -## 1. Utility Functions -###################################################################### - -def _extract_future_flags(globs): - """ - Return the compiler-flags associated with the future features that - have been imported into the given namespace (globs). - """ - flags = 0 - for fname in __future__.all_feature_names: - feature = globs.get(fname, None) - if feature is getattr(__future__, fname): - flags |= feature.compiler_flag - return flags - -def _normalize_module(module, depth=2): - """ - Return the module specified by `module`. In particular: - - If `module` is a module, then return module. - - If `module` is a string, then import and return the - module with that name. - - If `module` is None, then return the calling module. - The calling module is assumed to be the module of - the stack frame at the given depth in the call stack. - """ - if inspect.ismodule(module): - return module - elif isinstance(module, six.string_types): - return __import__(module, globals(), locals(), ["*"]) - elif module is None: - return sys.modules[sys._getframe(depth).f_globals['__name__']] - else: - raise TypeError("Expected a module, string, or None") - -def _load_testfile(filename, package, module_relative): - if module_relative: - package = _normalize_module(package, 3) - filename = _module_relative_path(package, filename) - if hasattr(package, '__loader__'): - if hasattr(package.__loader__, 'get_data'): - file_contents = package.__loader__.get_data(filename) - # get_data() opens files as 'rb', so one must do the equivalent - # conversion as universal newlines would do. - return file_contents.replace(os.linesep, '\n'), filename - with open(filename) as fp: - return fp.read(), filename - -def _indent(s, indent=4): - """ - Add the given number of space characters to the beginning every - non-blank line in `s`, and return the result. - """ - # This regexp matches the start of non-blank lines: - return re.sub('(?m)^(?!$)', indent*' ', s) - -def _exception_traceback(exc_info): - """ - Return a string containing a traceback message for the given - exc_info tuple (as returned by sys.exc_info()). - """ - # Get a traceback message. - excout = StringIO() - exc_type, exc_val, exc_tb = exc_info - traceback.print_exception(exc_type, exc_val, exc_tb, file=excout) - return excout.getvalue() - -# Override some StringIO methods. -class _SpoofOut(StringIO): - def getvalue(self): - result = StringIO.getvalue(self) - # If anything at all was written, make sure there's a trailing - # newline. There's no way for the expected output to indicate - # that a trailing newline is missing. - if result and not result.endswith("\n"): - result += "\n" - # Prevent softspace from screwing up the next test case, in - # case they used print with a trailing comma in an example. - if hasattr(self, "softspace"): - del self.softspace - return result - - def truncate(self, size=None): - StringIO.truncate(self, size) - if hasattr(self, "softspace"): - del self.softspace - -# Worst-case linear-time ellipsis matching. -def _ellipsis_match(want, got): - """ - Essentially the only subtle case: - >>> _ellipsis_match('aa...aa', 'aaa') - False - """ - if ELLIPSIS_MARKER not in want: - return want == got - - # Find "the real" strings. - ws = want.split(ELLIPSIS_MARKER) - assert len(ws) >= 2 - - # Deal with exact matches possibly needed at one or both ends. - startpos, endpos = 0, len(got) - w = ws[0] - if w: # starts with exact match - if got.startswith(w): - startpos = len(w) - del ws[0] - else: - return False - w = ws[-1] - if w: # ends with exact match - if got.endswith(w): - endpos -= len(w) - del ws[-1] - else: - return False - - if startpos > endpos: - # Exact end matches required more characters than we have, as in - # _ellipsis_match('aa...aa', 'aaa') - return False - - # For the rest, we only need to find the leftmost non-overlapping - # match for each piece. If there's no overall match that way alone, - # there's no overall match period. - for w in ws: - # w may be '' at times, if there are consecutive ellipses, or - # due to an ellipsis at the start or end of `want`. That's OK. - # Search for an empty string succeeds, and doesn't change startpos. - startpos = got.find(w, startpos, endpos) - if startpos < 0: - return False - startpos += len(w) - - return True - -def _comment_line(line): - "Return a commented form of the given line" - line = line.rstrip() - if line: - return '# '+line - else: - return '#' - -class _OutputRedirectingPdb(pdb.Pdb): - """ - A specialized version of the python debugger that redirects stdout - to a given stream when interacting with the user. Stdout is *not* - redirected when traced code is executed. - """ - def __init__(self, out): - self.__out = out - self.__debugger_used = False - pdb.Pdb.__init__(self, stdout=out) - - def set_trace(self, frame=None): - self.__debugger_used = True - if frame is None: - frame = sys._getframe().f_back - pdb.Pdb.set_trace(self, frame) - - def set_continue(self): - # Calling set_continue unconditionally would break unit test - # coverage reporting, as Bdb.set_continue calls sys.settrace(None). - if self.__debugger_used: - pdb.Pdb.set_continue(self) - - def trace_dispatch(self, *args): - # Redirect stdout to the given stream. - save_stdout = sys.stdout - sys.stdout = self.__out - # Call Pdb's trace dispatch method. - try: - return pdb.Pdb.trace_dispatch(self, *args) - finally: - sys.stdout = save_stdout - -# [XX] Normalize with respect to os.path.pardir? -def _module_relative_path(module, path): - if not inspect.ismodule(module): - raise TypeError('Expected a module: %r' % module) - if path.startswith('/'): - raise ValueError('Module-relative files may not have absolute paths') - - # Find the base directory for the path. - if hasattr(module, '__file__'): - # A normal module/package - basedir = os.path.split(module.__file__)[0] - elif module.__name__ == '__main__': - # An interactive session. - if len(sys.argv)>0 and sys.argv[0] != '': - basedir = os.path.split(sys.argv[0])[0] - else: - basedir = os.curdir - else: - # A module w/o __file__ (this includes builtins) - raise ValueError("Can't resolve paths relative to the module " + - module + " (it has no __file__)") - - # Combine the base directory and the path. - return os.path.join(basedir, *(path.split('/'))) - -###################################################################### -## 2. Example & DocTest -###################################################################### -## - An "example" is a <source, want> pair, where "source" is a -## fragment of source code, and "want" is the expected output for -## "source." The Example class also includes information about -## where the example was extracted from. -## -## - A "doctest" is a collection of examples, typically extracted from -## a string (such as an object's docstring). The DocTest class also -## includes information about where the string was extracted from. - -class Example: - """ - A single doctest example, consisting of source code and expected - output. `Example` defines the following attributes: - - - source: A single Python statement, always ending with a newline. - The constructor adds a newline if needed. - - - want: The expected output from running the source code (either - from stdout, or a traceback in case of exception). `want` ends - with a newline unless it's empty, in which case it's an empty - string. The constructor adds a newline if needed. - - - exc_msg: The exception message generated by the example, if - the example is expected to generate an exception; or `None` if - it is not expected to generate an exception. This exception - message is compared against the return value of - `traceback.format_exception_only()`. `exc_msg` ends with a - newline unless it's `None`. The constructor adds a newline - if needed. - - - lineno: The line number within the DocTest string containing - this Example where the Example begins. This line number is - zero-based, with respect to the beginning of the DocTest. - - - indent: The example's indentation in the DocTest string. - I.e., the number of space characters that preceed the - example's first prompt. - - - options: A dictionary mapping from option flags to True or - False, which is used to override default options for this - example. Any option flags not contained in this dictionary - are left at their default value (as specified by the - DocTestRunner's optionflags). By default, no options are set. - """ - def __init__(self, source, want, exc_msg=None, lineno=0, indent=0, - options=None): - # Normalize inputs. - if not source.endswith('\n'): - source += '\n' - if want and not want.endswith('\n'): - want += '\n' - if exc_msg is not None and not exc_msg.endswith('\n'): - exc_msg += '\n' - # Store properties. - self.source = source - self.want = want - self.lineno = lineno - self.indent = indent - if options is None: options = {} - self.options = options - self.exc_msg = exc_msg - -class DocTest: - """ - A collection of doctest examples that should be run in a single - namespace. Each `DocTest` defines the following attributes: - - - examples: the list of examples. - - - globs: The namespace (aka globals) that the examples should - be run in. - - - name: A name identifying the DocTest (typically, the name of - the object whose docstring this DocTest was extracted from). - - - filename: The name of the file that this DocTest was extracted - from, or `None` if the filename is unknown. - - - lineno: The line number within filename where this DocTest - begins, or `None` if the line number is unavailable. This - line number is zero-based, with respect to the beginning of - the file. - - - docstring: The string that the examples were extracted from, - or `None` if the string is unavailable. - """ - def __init__(self, examples, globs, name, filename, lineno, docstring): - """ - Create a new DocTest containing the given examples. The - DocTest's globals are initialized with a copy of `globs`. - """ - assert not isinstance(examples, six.string_types), \ - "DocTest no longer accepts str; use DocTestParser instead" - self.examples = examples - self.docstring = docstring - self.globs = globs.copy() - self.name = name - self.filename = filename - self.lineno = lineno - - def __repr__(self): - if len(self.examples) == 0: - examples = 'no examples' - elif len(self.examples) == 1: - examples = '1 example' - else: - examples = '%d examples' % len(self.examples) - return ('<DocTest %s from %s:%s (%s)>' % - (self.name, self.filename, self.lineno, examples)) - - - # This lets us sort tests by name: - def _cmpkey(self): - return (self.name, self.filename, self.lineno, id(self)) - def __cmp__(self, other): - if not isinstance(other, DocTest): - return -1 - return cmp(self._cmpkey(), other._cmpkey()) - - def __lt__(self, other): - return self._cmpkey() < other._cmpkey() - - def __le__(self, other): - return self._cmpkey() <= other._cmpkey() - - def __gt__(self, other): - return self._cmpkey() > other._cmpkey() - - def __ge__(self, other): - return self._cmpkey() >= other._cmpkey() - - def __eq__(self, other): - return self._cmpkey() == other._cmpkey() - - def __ne__(self, other): - return self._cmpkey() != other._cmpkey() - - -###################################################################### -## 3. DocTestParser -###################################################################### - -class DocTestParser: - """ - A class used to parse strings containing doctest examples. - """ - # This regular expression is used to find doctest examples in a - # string. It defines three groups: `source` is the source code - # (including leading indentation and prompts); `indent` is the - # indentation of the first (PS1) line of the source code; and - # `want` is the expected output (including leading indentation). - _EXAMPLE_RE = re.compile(r''' - # Source consists of a PS1 line followed by zero or more PS2 lines. - (?P<source> - (?:^(?P<indent> [ ]*) >>> .*) # PS1 line - (?:\n [ ]* \.\.\. .*)*) # PS2 lines - \n? - # Want consists of any non-blank lines that do not start with PS1. - (?P<want> (?:(?![ ]*$) # Not a blank line - (?![ ]*>>>) # Not a line starting with PS1 - .*$\n? # But any other line - )*) - ''', re.MULTILINE | re.VERBOSE) - - # A regular expression for handling `want` strings that contain - # expected exceptions. It divides `want` into three pieces: - # - the traceback header line (`hdr`) - # - the traceback stack (`stack`) - # - the exception message (`msg`), as generated by - # traceback.format_exception_only() - # `msg` may have multiple lines. We assume/require that the - # exception message is the first non-indented line starting with a word - # character following the traceback header line. - _EXCEPTION_RE = re.compile(r""" - # Grab the traceback header. Different versions of Python have - # said different things on the first traceback line. - ^(?P<hdr> Traceback\ \( - (?: most\ recent\ call\ last - | innermost\ last - ) \) : - ) - \s* $ # toss trailing whitespace on the header. - (?P<stack> .*?) # don't blink: absorb stuff until... - ^ (?P<msg> \w+ .*) # a line *starts* with alphanum. - """, re.VERBOSE | re.MULTILINE | re.DOTALL) - - # A callable returning a true value if its argument is a blank line - # or contains a single comment. - _IS_BLANK_OR_COMMENT = re.compile(r'^[ ]*(#.*)?$').match - - def parse(self, string, name='<string>'): - """ - Divide the given string into examples and intervening text, - and return them as a list of alternating Examples and strings. - Line numbers for the Examples are 0-based. The optional - argument `name` is a name identifying this string, and is only - used for error messages. - """ - string = string.expandtabs() - # If all lines begin with the same indentation, then strip it. - min_indent = self._min_indent(string) - if min_indent > 0: - string = '\n'.join([l[min_indent:] for l in string.split('\n')]) - - output = [] - charno, lineno = 0, 0 - # Find all doctest examples in the string: - for m in self._EXAMPLE_RE.finditer(string): - # Add the pre-example text to `output`. - output.append(string[charno:m.start()]) - # Update lineno (lines before this example) - lineno += string.count('\n', charno, m.start()) - # Extract info from the regexp match. - (source, options, want, exc_msg) = \ - self._parse_example(m, name, lineno) - # Create an Example, and add it to the list. - if not self._IS_BLANK_OR_COMMENT(source): - output.append( Example(source, want, exc_msg, - lineno=lineno, - indent=min_indent+len(m.group('indent')), - options=options) ) - # Update lineno (lines inside this example) - lineno += string.count('\n', m.start(), m.end()) - # Update charno. - charno = m.end() - # Add any remaining post-example text to `output`. - output.append(string[charno:]) - return output - - def get_doctest(self, string, globs, name, filename, lineno): - """ - Extract all doctest examples from the given string, and - collect them into a `DocTest` object. - - `globs`, `name`, `filename`, and `lineno` are attributes for - the new `DocTest` object. See the documentation for `DocTest` - for more information. - """ - return DocTest(self.get_examples(string, name), globs, - name, filename, lineno, string) - - def get_examples(self, string, name='<string>'): - """ - Extract all doctest examples from the given string, and return - them as a list of `Example` objects. Line numbers are - 0-based, because it's most common in doctests that nothing - interesting appears on the same line as opening triple-quote, - and so the first interesting line is called \"line 1\" then. - - The optional argument `name` is a name identifying this - string, and is only used for error messages. - """ - return [x for x in self.parse(string, name) - if isinstance(x, Example)] - - def _parse_example(self, m, name, lineno): - """ - Given a regular expression match from `_EXAMPLE_RE` (`m`), - return a pair `(source, want)`, where `source` is the matched - example's source code (with prompts and indentation stripped); - and `want` is the example's expected output (with indentation - stripped). - - `name` is the string's name, and `lineno` is the line number - where the example starts; both are used for error messages. - """ - # Get the example's indentation level. - indent = len(m.group('indent')) - - # Divide source into lines; check that they're properly - # indented; and then strip their indentation & prompts. - source_lines = m.group('source').split('\n') - self._check_prompt_blank(source_lines, indent, name, lineno) - self._check_prefix(source_lines[1:], ' '*indent + '.', name, lineno) - source = '\n'.join([sl[indent+4:] for sl in source_lines]) - - # Divide want into lines; check that it's properly indented; and - # then strip the indentation. Spaces before the last newline should - # be preserved, so plain rstrip() isn't good enough. - want = m.group('want') - want_lines = want.split('\n') - if len(want_lines) > 1 and re.match(r' *$', want_lines[-1]): - del want_lines[-1] # forget final newline & spaces after it - self._check_prefix(want_lines, ' '*indent, name, - lineno + len(source_lines)) - want = '\n'.join([wl[indent:] for wl in want_lines]) - - # If `want` contains a traceback message, then extract it. - m = self._EXCEPTION_RE.match(want) - if m: - exc_msg = m.group('msg') - else: - exc_msg = None - - # Extract options from the source. - options = self._find_options(source, name, lineno) - - return source, options, want, exc_msg - - # This regular expression looks for option directives in the - # source code of an example. Option directives are comments - # starting with "doctest:". Warning: this may give false - # positives for string-literals that contain the string - # "#doctest:". Eliminating these false positives would require - # actually parsing the string; but we limit them by ignoring any - # line containing "#doctest:" that is *followed* by a quote mark. - _OPTION_DIRECTIVE_RE = re.compile(r'#\s*doctest:\s*([^\n\'"]*)$', - re.MULTILINE) - - def _find_options(self, source, name, lineno): - """ - Return a dictionary containing option overrides extracted from - option directives in the given source string. - - `name` is the string's name, and `lineno` is the line number - where the example starts; both are used for error messages. - """ - options = {} - # (note: with the current regexp, this will match at most once:) - for m in self._OPTION_DIRECTIVE_RE.finditer(source): - option_strings = m.group(1).replace(',', ' ').split() - for option in option_strings: - if (option[0] not in '+-' or - option[1:] not in OPTIONFLAGS_BY_NAME): - raise ValueError('line %r of the doctest for %s ' - 'has an invalid option: %r' % - (lineno+1, name, option)) - flag = OPTIONFLAGS_BY_NAME[option[1:]] - options[flag] = (option[0] == '+') - if options and self._IS_BLANK_OR_COMMENT(source): - raise ValueError('line %r of the doctest for %s has an option ' - 'directive on a line with no example: %r' % - (lineno, name, source)) - return options - - # This regular expression finds the indentation of every non-blank - # line in a string. - _INDENT_RE = re.compile('^([ ]*)(?=\S)', re.MULTILINE) - - def _min_indent(self, s): - "Return the minimum indentation of any non-blank line in `s`" - indents = [len(indent) for indent in self._INDENT_RE.findall(s)] - if len(indents) > 0: - return min(indents) - else: - return 0 - - def _check_prompt_blank(self, lines, indent, name, lineno): - """ - Given the lines of a source string (including prompts and - leading indentation), check to make sure that every prompt is - followed by a space character. If any line is not followed by - a space character, then raise ValueError. - """ - for i, line in enumerate(lines): - if len(line) >= indent+4 and line[indent+3] != ' ': - raise ValueError('line %r of the docstring for %s ' - 'lacks blank after %s: %r' % - (lineno+i+1, name, - line[indent:indent+3], line)) - - def _check_prefix(self, lines, prefix, name, lineno): - """ - Check that every line in the given list starts with the given - prefix; if any line does not, then raise a ValueError. - """ - for i, line in enumerate(lines): - if line and not line.startswith(prefix): - raise ValueError('line %r of the docstring for %s has ' - 'inconsistent leading whitespace: %r' % - (lineno+i+1, name, line)) - - -###################################################################### -## 4. DocTest Finder -###################################################################### - -class DocTestFinder: - """ - A class used to extract the DocTests that are relevant to a given - object, from its docstring and the docstrings of its contained - objects. Doctests can currently be extracted from the following - object types: modules, functions, classes, methods, staticmethods, - classmethods, and properties. - """ - - def __init__(self, verbose=False, parser=DocTestParser(), - recurse=True, exclude_empty=True): - """ - Create a new doctest finder. - - The optional argument `parser` specifies a class or - function that should be used to create new DocTest objects (or - objects that implement the same interface as DocTest). The - signature for this factory function should match the signature - of the DocTest constructor. - - If the optional argument `recurse` is false, then `find` will - only examine the given object, and not any contained objects. - - If the optional argument `exclude_empty` is false, then `find` - will include tests for objects with empty docstrings. - """ - self._parser = parser - self._verbose = verbose - self._recurse = recurse - self._exclude_empty = exclude_empty - - def find(self, obj, name=None, module=None, globs=None, extraglobs=None): - """ - Return a list of the DocTests that are defined by the given - object's docstring, or by any of its contained objects' - docstrings. - - The optional parameter `module` is the module that contains - the given object. If the module is not specified or is None, then - the test finder will attempt to automatically determine the - correct module. The object's module is used: - - - As a default namespace, if `globs` is not specified. - - To prevent the DocTestFinder from extracting DocTests - from objects that are imported from other modules. - - To find the name of the file containing the object. - - To help find the line number of the object within its - file. - - Contained objects whose module does not match `module` are ignored. - - If `module` is False, no attempt to find the module will be made. - This is obscure, of use mostly in tests: if `module` is False, or - is None but cannot be found automatically, then all objects are - considered to belong to the (non-existent) module, so all contained - objects will (recursively) be searched for doctests. - - The globals for each DocTest is formed by combining `globs` - and `extraglobs` (bindings in `extraglobs` override bindings - in `globs`). A new copy of the globals dictionary is created - for each DocTest. If `globs` is not specified, then it - defaults to the module's `__dict__`, if specified, or {} - otherwise. If `extraglobs` is not specified, then it defaults - to {}. - - """ - # If name was not specified, then extract it from the object. - if name is None: - name = getattr(obj, '__name__', None) - if name is None: - raise ValueError("DocTestFinder.find: name must be given " - "when obj.__name__ doesn't exist: %r" % - (type(obj),)) - - # Find the module that contains the given object (if obj is - # a module, then module=obj.). Note: this may fail, in which - # case module will be None. - if module is False: - module = None - elif module is None: - module = inspect.getmodule(obj) - - # Read the module's source code. This is used by - # DocTestFinder._find_lineno to find the line number for a - # given object's docstring. - try: - file = inspect.getsourcefile(obj) or inspect.getfile(obj) - source_lines = linecache.getlines(file) - if not source_lines: - source_lines = None - except TypeError: - source_lines = None - - # Initialize globals, and merge in extraglobs. - if globs is None: - if module is None: - globs = {} - else: - globs = module.__dict__.copy() - else: - globs = globs.copy() - if extraglobs is not None: - globs.update(extraglobs) - - # Recursively explore `obj`, extracting DocTests. - tests = [] - self._find(tests, obj, name, module, source_lines, globs, {}) - return tests - - def _from_module(self, module, object): - """ - Return true if the given object is defined in the given - module. - """ - if module is None: - return True - elif inspect.isfunction(object): - return module.__dict__ is six.get_function_globals(object) - elif inspect.isclass(object): - return module.__name__ == object.__module__ - elif inspect.getmodule(object) is not None: - return module is inspect.getmodule(object) - elif hasattr(object, '__module__'): - return module.__name__ == object.__module__ - elif isinstance(object, property): - return True # [XX] no way not be sure. - else: - raise ValueError("object must be a class or function") - - def _find(self, tests, obj, name, module, source_lines, globs, seen): - """ - Find tests for the given object and any contained objects, and - add them to `tests`. - """ - if self._verbose: - print('Finding tests in %s' % name) - - # If we've already processed this object, then ignore it. - if id(obj) in seen: - return - seen[id(obj)] = 1 - - # Find a test for this object, and add it to the list of tests. - test = self._get_test(obj, name, module, globs, source_lines) - if test is not None: - tests.append(test) - - # Look for tests in a module's contained objects. - if inspect.ismodule(obj) and self._recurse: - for valname, val in obj.__dict__.items(): - valname = '%s.%s' % (name, valname) - # Recurse to functions & classes. - if ((inspect.isfunction(val) or inspect.isclass(val)) and - self._from_module(module, val)): - self._find(tests, val, valname, module, source_lines, - globs, seen) - - # Look for tests in a module's __test__ dictionary. - if inspect.ismodule(obj) and self._recurse: - for valname, val in getattr(obj, '__test__', {}).items(): - if not isinstance(valname, six.string_types): - raise ValueError("DocTestFinder.find: __test__ keys " - "must be strings: %r" % - (type(valname),)) - if not (inspect.isfunction(val) or inspect.isclass(val) or - inspect.ismethod(val) or inspect.ismodule(val) or - isinstance(val, six.string_types)): - raise ValueError("DocTestFinder.find: __test__ values " - "must be strings, functions, methods, " - "classes, or modules: %r" % - (type(val),)) - valname = '%s.__test__.%s' % (name, valname) - self._find(tests, val, valname, module, source_lines, - globs, seen) - - # Look for tests in a class's contained objects. - if inspect.isclass(obj) and self._recurse: - for valname, val in obj.__dict__.items(): - # Special handling for staticmethod/classmethod. - if isinstance(val, staticmethod): - val = getattr(obj, valname) - if isinstance(val, classmethod): - val = getattr(obj, valname).__func__ - - # Recurse to methods, properties, and nested classes. - if ((inspect.isfunction(val) or inspect.isclass(val) or - isinstance(val, property)) and - self._from_module(module, val)): - valname = '%s.%s' % (name, valname) - self._find(tests, val, valname, module, source_lines, - globs, seen) - - def _get_test(self, obj, name, module, globs, source_lines): - """ - Return a DocTest for the given object, if it defines a docstring; - otherwise, return None. - """ - # Extract the object's docstring. If it doesn't have one, - # then return None (no test for this object). - if isinstance(obj, six.string_types): - docstring = obj - else: - try: - if obj.__doc__ is None: - docstring = '' - else: - docstring = obj.__doc__ - if not isinstance(docstring, six.string_types): - docstring = str(docstring) - except (TypeError, AttributeError): - docstring = '' - - # Find the docstring's location in the file. - lineno = self._find_lineno(obj, source_lines) - - # Don't bother if the docstring is empty. - if self._exclude_empty and not docstring: - return None - - # Return a DocTest for this object. - if module is None: - filename = None - else: - filename = getattr(module, '__file__', module.__name__) - if filename[-4:] in (".pyc", ".pyo"): - filename = filename[:-1] - return self._parser.get_doctest(docstring, globs, name, - filename, lineno) - - def _find_lineno(self, obj, source_lines): - """ - Return a line number of the given object's docstring. Note: - this method assumes that the object has a docstring. - """ - lineno = None - - # Find the line number for modules. - if inspect.ismodule(obj): - lineno = 0 - - # Find the line number for classes. - # Note: this could be fooled if a class is defined multiple - # times in a single file. - if inspect.isclass(obj): - if source_lines is None: - return None - pat = re.compile(r'^\s*class\s*%s\b' % - getattr(obj, '__name__', '-')) - for i, line in enumerate(source_lines): - if pat.match(line): - lineno = i - break - - # Find the line number for functions & methods. - if inspect.ismethod(obj): obj = obj.__func__ - if inspect.isfunction(obj): obj = six.get_function_code(obj) - if inspect.istraceback(obj): obj = obj.tb_frame - if inspect.isframe(obj): obj = obj.f_code - if inspect.iscode(obj): - lineno = getattr(obj, 'co_firstlineno', None)-1 - - # Find the line number where the docstring starts. Assume - # that it's the first line that begins with a quote mark. - # Note: this could be fooled by a multiline function - # signature, where a continuation line begins with a quote - # mark. - if lineno is not None: - if source_lines is None: - return lineno+1 - pat = re.compile('(^|.*:)\s*\w*("|\')') - for lineno in range(lineno, len(source_lines)): - if pat.match(source_lines[lineno]): - return lineno - - # We couldn't find the line number. - return None - -###################################################################### -## 5. DocTest Runner -###################################################################### - -class DocTestRunner: - """ - A class used to run DocTest test cases, and accumulate statistics. - The `run` method is used to process a single DocTest case. It - returns a tuple `(f, t)`, where `t` is the number of test cases - tried, and `f` is the number of test cases that failed. - - >>> tests = DocTestFinder().find(_TestClass) - >>> runner = DocTestRunner(verbose=False) - >>> for test in tests: - ... print(runner.run(test)) - (0, 2) - (0, 1) - (0, 2) - (0, 2) - - The `summarize` method prints a summary of all the test cases that - have been run by the runner, and returns an aggregated `(f, t)` - tuple: - - >>> runner.summarize(verbose=1) - 4 items passed all tests: - 2 tests in _TestClass - 2 tests in _TestClass.__init__ - 2 tests in _TestClass.get - 1 tests in _TestClass.square - 7 tests in 4 items. - 7 passed and 0 failed. - Test passed. - (0, 7) - - The aggregated number of tried examples and failed examples is - also available via the `tries` and `failures` attributes: - - >>> runner.tries - 7 - >>> runner.failures - 0 - - The comparison between expected outputs and actual outputs is done - by an `OutputChecker`. This comparison may be customized with a - number of option flags; see the documentation for `testmod` for - more information. If the option flags are insufficient, then the - comparison may also be customized by passing a subclass of - `OutputChecker` to the constructor. - - The test runner's display output can be controlled in two ways. - First, an output function (`out) can be passed to - `TestRunner.run`; this function will be called with strings that - should be displayed. It defaults to `sys.stdout.write`. If - capturing the output is not sufficient, then the display output - can be also customized by subclassing DocTestRunner, and - overriding the methods `report_start`, `report_success`, - `report_unexpected_exception`, and `report_failure`. - """ - # This divider string is used to separate failure messages, and to - # separate sections of the summary. - DIVIDER = "*" * 70 - - def __init__(self, checker=None, verbose=None, optionflags=0): - """ - Create a new test runner. - - Optional keyword arg `checker` is the `OutputChecker` that - should be used to compare the expected outputs and actual - outputs of doctest examples. - - Optional keyword arg 'verbose' prints lots of stuff if true, - only failures if false; by default, it's true iff '-v' is in - sys.argv. - - Optional argument `optionflags` can be used to control how the - test runner compares expected output to actual output, and how - it displays failures. See the documentation for `testmod` for - more information. - """ - self._checker = checker or OutputChecker() - if verbose is None: - verbose = '-v' in sys.argv - self._verbose = verbose - self.optionflags = optionflags - self.original_optionflags = optionflags - - # Keep track of the examples we've run. - self.tries = 0 - self.failures = 0 - self._name2ft = {} - - # Create a fake output target for capturing doctest output. - self._fakeout = _SpoofOut() - - #///////////////////////////////////////////////////////////////// - # Reporting methods - #///////////////////////////////////////////////////////////////// - - def report_start(self, out, test, example): - """ - Report that the test runner is about to process the given - example. (Only displays a message if verbose=True) - """ - if self._verbose: - if example.want: - out('Trying:\n' + _indent(example.source) + - 'Expecting:\n' + _indent(example.want)) - else: - out('Trying:\n' + _indent(example.source) + - 'Expecting nothing\n') - - def report_success(self, out, test, example, got): - """ - Report that the given example ran successfully. (Only - displays a message if verbose=True) - """ - if self._verbose: - out("ok\n") - - def report_failure(self, out, test, example, got): - """ - Report that the given example failed. - """ - out(self._failure_header(test, example) + - self._checker.output_difference(example, got, self.optionflags)) - - def report_unexpected_exception(self, out, test, example, exc_info): - """ - Report that the given example raised an unexpected exception. - """ - out(self._failure_header(test, example) + - 'Exception raised:\n' + _indent(_exception_traceback(exc_info))) - - def _failure_header(self, test, example): - out = [self.DIVIDER] - if test.filename: - if test.lineno is not None and example.lineno is not None: - lineno = test.lineno + example.lineno + 1 - else: - lineno = '?' - out.append('File "%s", line %s, in %s' % - (test.filename, lineno, test.name)) - else: - out.append('Line %s, in %s' % (example.lineno+1, test.name)) - out.append('Failed example:') - source = example.source - out.append(_indent(source)) - return '\n'.join(out) - - #///////////////////////////////////////////////////////////////// - # DocTest Running - #///////////////////////////////////////////////////////////////// - - def __run(self, test, compileflags, out): - """ - Run the examples in `test`. Write the outcome of each example - with one of the `DocTestRunner.report_*` methods, using the - writer function `out`. `compileflags` is the set of compiler - flags that should be used to execute examples. Return a tuple - `(f, t)`, where `t` is the number of examples tried, and `f` - is the number of examples that failed. The examples are run - in the namespace `test.globs`. - """ - # Keep track of the number of failures and tries. - failures = tries = 0 - - # Save the option flags (since option directives can be used - # to modify them). - original_optionflags = self.optionflags - - SUCCESS, FAILURE, BOOM = range(3) # `outcome` state - - check = self._checker.check_output - - # Process each example. - for examplenum, example in enumerate(test.examples): - - # If REPORT_ONLY_FIRST_FAILURE is set, then suppress - # reporting after the first failure. - quiet = (self.optionflags & REPORT_ONLY_FIRST_FAILURE and - failures > 0) - - # Merge in the example's options. - self.optionflags = original_optionflags - if example.options: - for (optionflag, val) in example.options.items(): - if val: - self.optionflags |= optionflag - else: - self.optionflags &= ~optionflag - - # If 'SKIP' is set, then skip this example. - if self.optionflags & SKIP: - continue - - # Record that we started this example. - tries += 1 - if not quiet: - self.report_start(out, test, example) - - # Use a special filename for compile(), so we can retrieve - # the source code during interactive debugging (see - # __patched_linecache_getlines). - filename = '<doctest %s[%d]>' % (test.name, examplenum) - - # Doctest and Py3 issue: - # If the current example that we wish to run is going to fail - # because it expects a leading u"", then use an alternate displayhook - original_displayhook = sys.displayhook - - if six.PY3: - # only set alternate displayhook if Python 3.x or after - lines = [] - def py3_displayhook(value): - if value is None: - # None should not be considered at all - return original_displayhook(value) - - # Collect the repr output in one variable - s = repr(value) - # Strip b"" and u"" prefixes from the repr and expected output - # TODO: better way of stripping the prefixes? - expected = example.want - expected = expected.strip() # be wary of newlines - s = s.replace("u", "") - s = s.replace("b", "") - expected = expected.replace("u", "") - expected = expected.replace("b", "") - # single quote vs. double quote should not matter - # default all quote marks to double quote - s = s.replace("'", '"') - expected = expected.replace("'", '"') - - # In case of multi-line expected result - lines.append(s) - - # let them match - if s == expected: # be wary of false positives here - # they should be the same, print expected value - sys.stdout.write("%s\n" % example.want.strip()) - - # multi-line expected output, doctest uses loop - elif len(expected.split("\n")) == len(lines): - if "\n".join(lines) == expected: - sys.stdout.write("%s\n" % example.want.strip()) - else: - sys.stdout.write("%s\n" % repr(value)) - elif len(expected.split("\n")) != len(lines): - # we are not done looping yet, do not print anything! - pass - - else: - sys.stdout.write("%s\n" % repr(value)) - - sys.displayhook = py3_displayhook - - # Run the example in the given context (globs), and record - # any exception that gets raised. (But don't intercept - # keyboard interrupts.) - try: - # Don't blink! This is where the user's code gets run. - six.exec_(compile(example.source, filename, "single", - compileflags, 1), test.globs) - self.debugger.set_continue() # ==== Example Finished ==== - exception = None - except KeyboardInterrupt: - raise - except: - exception = sys.exc_info() - self.debugger.set_continue() # ==== Example Finished ==== - finally: - # restore the original displayhook - sys.displayhook = original_displayhook - - got = self._fakeout.getvalue() # the actual output - self._fakeout.truncate(0) - # Python 3.1 requires seek after truncate - self._fakeout.seek(0) - outcome = FAILURE # guilty until proved innocent or insane - - # If the example executed without raising any exceptions, - # verify its output. - if exception is None: - if check(example.want, got, self.optionflags): - outcome = SUCCESS - - # The example raised an exception: check if it was expected. - else: - exc_msg = traceback.format_exception_only(*exception[:2])[-1] - if six.PY3: - # module name will be in group(1) and the expected - # exception message will be in group(2) - m = re.match(r'(.*)\.(\w+:.+\s)', exc_msg) - # make sure there's a match - if m != None: - f_name = m.group(1) - # check to see if m.group(1) contains the module name - if f_name == exception[0].__module__: - # strip the module name from exc_msg - exc_msg = m.group(2) - - if not quiet: - got += _exception_traceback(exception) - - # If `example.exc_msg` is None, then we weren't expecting - # an exception. - if example.exc_msg is None: - outcome = BOOM - - # We expected an exception: see whether it matches. - elif check(example.exc_msg, exc_msg, self.optionflags): - outcome = SUCCESS - - # Another chance if they didn't care about the detail. - elif self.optionflags & IGNORE_EXCEPTION_DETAIL: - m1 = re.match(r'[^:]*:', example.exc_msg) - m2 = re.match(r'[^:]*:', exc_msg) - if m1 and m2 and check(m1.group(0), m2.group(0), - self.optionflags): - outcome = SUCCESS - - # Report the outcome. - if outcome is SUCCESS: - if not quiet: - self.report_success(out, test, example, got) - elif outcome is FAILURE: - if not quiet: - self.report_failure(out, test, example, got) - failures += 1 - elif outcome is BOOM: - if not quiet: - self.report_unexpected_exception(out, test, example, - exception) - failures += 1 - else: - assert False, ("unknown outcome", outcome) - - # Restore the option flags (in case they were modified) - self.optionflags = original_optionflags - - # Record and return the number of failures and tries. - self.__record_outcome(test, failures, tries) - return failures, tries - - def __record_outcome(self, test, f, t): - """ - Record the fact that the given DocTest (`test`) generated `f` - failures out of `t` tried examples. - """ - f2, t2 = self._name2ft.get(test.name, (0,0)) - self._name2ft[test.name] = (f+f2, t+t2) - self.failures += f - self.tries += t - - __LINECACHE_FILENAME_RE = re.compile(r'<doctest ' - r'(?P<name>[\w\.]+)' - r'\[(?P<examplenum>\d+)\]>$') - def __patched_linecache_getlines(self, filename, module_globals=None): - m = self.__LINECACHE_FILENAME_RE.match(filename) - if m and m.group('name') == self.test.name: - example = self.test.examples[int(m.group('examplenum'))] - return example.source.splitlines(True) - else: - return self.save_linecache_getlines(filename, module_globals) - - def run(self, test, compileflags=None, out=None, clear_globs=True): - """ - Run the examples in `test`, and display the results using the - writer function `out`. - - The examples are run in the namespace `test.globs`. If - `clear_globs` is true (the default), then this namespace will - be cleared after the test runs, to help with garbage - collection. If you would like to examine the namespace after - the test completes, then use `clear_globs=False`. - - `compileflags` gives the set of flags that should be used by - the Python compiler when running the examples. If not - specified, then it will default to the set of future-import - flags that apply to `globs`. - - The output of each example is checked using - `DocTestRunner.check_output`, and the results are formatted by - the `DocTestRunner.report_*` methods. - """ - self.test = test - - if compileflags is None: - compileflags = _extract_future_flags(test.globs) - - save_stdout = sys.stdout - if out is None: - out = save_stdout.write - sys.stdout = self._fakeout - - # Patch pdb.set_trace to restore sys.stdout during interactive - # debugging (so it's not still redirected to self._fakeout). - # Note that the interactive output will go to *our* - # save_stdout, even if that's not the real sys.stdout; this - # allows us to write test cases for the set_trace behavior. - save_set_trace = pdb.set_trace - self.debugger = _OutputRedirectingPdb(save_stdout) - self.debugger.reset() - pdb.set_trace = self.debugger.set_trace - - # Patch linecache.getlines, so we can see the example's source - # when we're inside the debugger. - self.save_linecache_getlines = linecache.getlines - linecache.getlines = self.__patched_linecache_getlines - - try: - return self.__run(test, compileflags, out) - finally: - sys.stdout = save_stdout - pdb.set_trace = save_set_trace - linecache.getlines = self.save_linecache_getlines - if clear_globs: - test.globs.clear() - - #///////////////////////////////////////////////////////////////// - # Summarization - #///////////////////////////////////////////////////////////////// - def summarize(self, verbose=None): - """ - Print a summary of all the test cases that have been run by - this DocTestRunner, and return a tuple `(f, t)`, where `f` is - the total number of failed examples, and `t` is the total - number of tried examples. - - The optional `verbose` argument controls how detailed the - summary is. If the verbosity is not specified, then the - DocTestRunner's verbosity is used. - """ - if verbose is None: - verbose = self._verbose - notests = [] - passed = [] - failed = [] - totalt = totalf = 0 - for x in self._name2ft.items(): - name, (f, t) = x - assert f <= t - totalt += t - totalf += f - if t == 0: - notests.append(name) - elif f == 0: - passed.append( (name, t) ) - else: - failed.append(x) - if verbose: - if notests: - print("%d items had no tests:" % len(notests)) - notests.sort() - for thing in notests: - print(" %s" % thing) - if passed: - print("%d items passed all tests:" % len(passed)) - passed.sort() - for thing, count in passed: - print(" %3d tests in %s" % (count, thing)) - if failed: - print(self.DIVIDER) - print("%d items had failures:" % len(failed)) - failed.sort() - for thing, (f, t) in failed: - print(" %3d of %3d in %s" % (f, t, thing)) - if verbose: - print("%d tests in % d items" % (len(self._name2ft), totalt)) - print("%d passed and %d failed." % (totalt - totalf, totalf)) - if totalf: - print("***Test Failed*** %d failures." % totalf) - elif verbose: - print("Test passed.") - return totalf, totalt - - #///////////////////////////////////////////////////////////////// - # Backward compatibility cruft to maintain doctest.master. - #///////////////////////////////////////////////////////////////// - def merge(self, other): - d = self._name2ft - for name, (f, t) in other._name2ft.items(): - if name in d: - print("*** DocTestRunner.merge: '" + name + "' in both" \ - " testers; summing outcomes.") - f2, t2 = d[name] - f = f + f2 - t = t + t2 - d[name] = f, t - -class OutputChecker: - """ - A class used to check the whether the actual output from a doctest - example matches the expected output. `OutputChecker` defines two - methods: `check_output`, which compares a given pair of outputs, - and returns true if they match; and `output_difference`, which - returns a string describing the differences between two outputs. - """ - def check_output(self, want, got, optionflags): - """ - Return True iff the actual output from an example (`got`) - matches the expected output (`want`). These strings are - always considered to match if they are identical; but - depending on what option flags the test runner is using, - several non-exact match types are also possible. See the - documentation for `TestRunner` for more information about - option flags. - """ - # Handle the common case first, for efficiency: - # if they're string-identical, always return true. - if got == want: - return True - - # The values True and False replaced 1 and 0 as the return - # value for boolean comparisons in Python 2.3. - if not (optionflags & DONT_ACCEPT_TRUE_FOR_1): - if (got,want) == ("True\n", "1\n"): - return True - if (got,want) == ("False\n", "0\n"): - return True - - # <BLANKLINE> can be used as a special sequence to signify a - # blank line, unless the DONT_ACCEPT_BLANKLINE flag is used. - if not (optionflags & DONT_ACCEPT_BLANKLINE): - # Replace <BLANKLINE> in want with a blank line. - want = re.sub('(?m)^%s\s*?$' % re.escape(BLANKLINE_MARKER), - '', want) - # If a line in got contains only spaces, then remove the - # spaces. - got = re.sub('(?m)^\s*?$', '', got) - if got == want: - return True - - # This flag causes doctest to ignore any differences in the - # contents of whitespace strings. Note that this can be used - # in conjunction with the ELLIPSIS flag. - if optionflags & NORMALIZE_WHITESPACE: - got = ' '.join(got.split()) - want = ' '.join(want.split()) - if got == want: - return True - - # The ELLIPSIS flag says to let the sequence "..." in `want` - # match any substring in `got`. - if optionflags & ELLIPSIS: - if _ellipsis_match(want, got): - return True - - # We didn't find any match; return false. - return False - - # Should we do a fancy diff? - def _do_a_fancy_diff(self, want, got, optionflags): - # Not unless they asked for a fancy diff. - if not optionflags & (REPORT_UDIFF | - REPORT_CDIFF | - REPORT_NDIFF): - return False - - # If expected output uses ellipsis, a meaningful fancy diff is - # too hard ... or maybe not. In two real-life failures Tim saw, - # a diff was a major help anyway, so this is commented out. - # [todo] _ellipsis_match() knows which pieces do and don't match, - # and could be the basis for a kick-ass diff in this case. - ##if optionflags & ELLIPSIS and ELLIPSIS_MARKER in want: - ## return False - - # ndiff does intraline difference marking, so can be useful even - # for 1-line differences. - if optionflags & REPORT_NDIFF: - return True - - # The other diff types need at least a few lines to be helpful. - return want.count('\n') > 2 and got.count('\n') > 2 - - def output_difference(self, example, got, optionflags): - """ - Return a string describing the differences between the - expected output for a given example (`example`) and the actual - output (`got`). `optionflags` is the set of option flags used - to compare `want` and `got`. - """ - want = example.want - # If <BLANKLINE>s are being used, then replace blank lines - # with <BLANKLINE> in the actual output string. - if not (optionflags & DONT_ACCEPT_BLANKLINE): - got = re.sub('(?m)^[ ]*(?=\n)', BLANKLINE_MARKER, got) - - # Check if we should use diff. - if self._do_a_fancy_diff(want, got, optionflags): - # Split want & got into lines. - want_lines = want.splitlines(True) # True == keep line ends - got_lines = got.splitlines(True) - # Use difflib to find their differences. - if optionflags & REPORT_UDIFF: - diff = difflib.unified_diff(want_lines, got_lines, n=2) - diff = list(diff)[2:] # strip the diff header - kind = 'unified diff with -expected +actual' - elif optionflags & REPORT_CDIFF: - diff = difflib.context_diff(want_lines, got_lines, n=2) - diff = list(diff)[2:] # strip the diff header - kind = 'context diff with expected followed by actual' - elif optionflags & REPORT_NDIFF: - engine = difflib.Differ(charjunk=difflib.IS_CHARACTER_JUNK) - diff = list(engine.compare(want_lines, got_lines)) - kind = 'ndiff with -expected +actual' - else: - assert 0, 'Bad diff option' - # Remove trailing whitespace on diff output. - diff = [line.rstrip() + '\n' for line in diff] - return 'Differences (%s):\n' % kind + _indent(''.join(diff)) - - # If we're not using diff, then simply list the expected - # output followed by the actual output. - if want and got: - return 'Expected:\n%sGot:\n%s' % (_indent(want), _indent(got)) - elif want: - return 'Expected:\n%sGot nothing\n' % _indent(want) - elif got: - return 'Expected nothing\nGot:\n%s' % _indent(got) - else: - return 'Expected nothing\nGot nothing\n' - -class DocTestFailure(Exception): - """A DocTest example has failed in debugging mode. - - The exception instance has variables: - - - test: the DocTest object being run - - - example: the Example object that failed - - - got: the actual output - """ - def __init__(self, test, example, got): - self.test = test - self.example = example - self.got = got - - def __str__(self): - return str(self.test) - -class UnexpectedException(Exception): - """A DocTest example has encountered an unexpected exception - - The exception instance has variables: - - - test: the DocTest object being run - - - example: the Example object that failed - - - exc_info: the exception info - """ - def __init__(self, test, example, exc_info): - self.test = test - self.example = example - self.exc_info = exc_info - - def __str__(self): - return str(self.test) - -class DebugRunner(DocTestRunner): - r"""Run doc tests but raise an exception as soon as there is a failure. - - If an unexpected exception occurs, an UnexpectedException is raised. - It contains the test, the example, and the original exception: - - >>> runner = DebugRunner(verbose=False) - >>> test = DocTestParser().get_doctest('>>> raise KeyError\n42', - ... {}, 'foo', 'foo.py', 0) - >>> try: - ... runner.run(test) - ... except UnexpectedException as e: - ... failure = e - - >>> failure.test is test - True - - >>> failure.example.want - '42\n' - - >>> exc_info = failure.exc_info - >>> raise exc_info[0], exc_info[1], exc_info[2] - Traceback (most recent call last): - ... - KeyError - - We wrap the original exception to give the calling application - access to the test and example information. - - If the output doesn't match, then a DocTestFailure is raised: - - >>> test = DocTestParser().get_doctest(''' - ... >>> x = 1 - ... >>> x - ... 2 - ... ''', {}, 'foo', 'foo.py', 0) - - >>> try: - ... runner.run(test) - ... except DocTestFailure as e: - ... failure = e - - DocTestFailure objects provide access to the test: - - >>> failure.test is test - True - - As well as to the example: - - >>> failure.example.want - '2\n' - - and the actual output: - - >>> failure.got - '1\n' - - If a failure or error occurs, the globals are left intact: - - >>> del test.globs['__builtins__'] - >>> test.globs - {'x': 1} - - >>> test = DocTestParser().get_doctest(''' - ... >>> x = 2 - ... >>> raise KeyError - ... ''', {}, 'foo', 'foo.py', 0) - - >>> runner.run(test) - Traceback (most recent call last): - ... - UnexpectedException: <DocTest foo from foo.py:0 (2 examples)> - - >>> del test.globs['__builtins__'] - >>> test.globs - {'x': 2} - - But the globals are cleared if there is no error: - - >>> test = DocTestParser().get_doctest(''' - ... >>> x = 2 - ... ''', {}, 'foo', 'foo.py', 0) - - >>> runner.run(test) - (0, 1) - - >>> test.globs - {} - - """ - - def run(self, test, compileflags=None, out=None, clear_globs=True): - r = DocTestRunner.run(self, test, compileflags, out, False) - if clear_globs: - test.globs.clear() - return r - - def report_unexpected_exception(self, out, test, example, exc_info): - raise UnexpectedException(test, example, exc_info) - - def report_failure(self, out, test, example, got): - raise DocTestFailure(test, example, got) - -###################################################################### -## 6. Test Functions -###################################################################### -# These should be backwards compatible. - -# For backward compatibility, a global instance of a DocTestRunner -# class, updated by testmod. -master = None - -def testmod(m=None, name=None, globs=None, verbose=None, - report=True, optionflags=0, extraglobs=None, - raise_on_error=False, exclude_empty=False): - """m=None, name=None, globs=None, verbose=None, report=True, - optionflags=0, extraglobs=None, raise_on_error=False, - exclude_empty=False - - Test examples in docstrings in functions and classes reachable - from module m (or the current module if m is not supplied), starting - with m.__doc__. - - Also test examples reachable from dict m.__test__ if it exists and is - not None. m.__test__ maps names to functions, classes and strings; - function and class docstrings are tested even if the name is private; - strings are tested directly, as if they were docstrings. - - Return (#failures, #tests). - - See doctest.__doc__ for an overview. - - Optional keyword arg "name" gives the name of the module; by default - use m.__name__. - - Optional keyword arg "globs" gives a dict to be used as the globals - when executing examples; by default, use m.__dict__. A copy of this - dict is actually used for each docstring, so that each docstring's - examples start with a clean slate. - - Optional keyword arg "extraglobs" gives a dictionary that should be - merged into the globals that are used to execute examples. By - default, no extra globals are used. This is new in 2.4. - - Optional keyword arg "verbose" prints lots of stuff if true, prints - only failures if false; by default, it's true iff "-v" is in sys.argv. - - Optional keyword arg "report" prints a summary at the end when true, - else prints nothing at the end. In verbose mode, the summary is - detailed, else very brief (in fact, empty if all tests passed). - - Optional keyword arg "optionflags" or's together module constants, - and defaults to 0. This is new in 2.3. Possible values (see the - docs for details): - - DONT_ACCEPT_TRUE_FOR_1 - DONT_ACCEPT_BLANKLINE - NORMALIZE_WHITESPACE - ELLIPSIS - SKIP - IGNORE_EXCEPTION_DETAIL - REPORT_UDIFF - REPORT_CDIFF - REPORT_NDIFF - REPORT_ONLY_FIRST_FAILURE - - Optional keyword arg "raise_on_error" raises an exception on the - first unexpected exception or failure. This allows failures to be - post-mortem debugged. - - Advanced tomfoolery: testmod runs methods of a local instance of - class doctest.Tester, then merges the results into (or creates) - global Tester instance doctest.master. Methods of doctest.master - can be called directly too, if you want to do something unusual. - Passing report=0 to testmod is especially useful then, to delay - displaying a summary. Invoke doctest.master.summarize(verbose) - when you're done fiddling. - """ - global master - - # If no module was given, then use __main__. - if m is None: - # DWA - m will still be None if this wasn't invoked from the command - # line, in which case the following TypeError is about as good an error - # as we should expect - m = sys.modules.get('__main__') - - # Check that we were actually given a module. - if not inspect.ismodule(m): - raise TypeError("testmod: module required; %r" % (m,)) - - # If no name was given, then use the module's name. - if name is None: - name = m.__name__ - - # Find, parse, and run all tests in the given module. - finder = DocTestFinder(exclude_empty=exclude_empty) - - if raise_on_error: - runner = DebugRunner(verbose=verbose, optionflags=optionflags) - else: - runner = DocTestRunner(verbose=verbose, optionflags=optionflags) - - for test in finder.find(m, name, globs=globs, extraglobs=extraglobs): - runner.run(test) - - if report: - runner.summarize() - - if master is None: - master = runner - else: - master.merge(runner) - - return runner.failures, runner.tries - -def testfile(filename, module_relative=True, name=None, package=None, - globs=None, verbose=None, report=True, optionflags=0, - extraglobs=None, raise_on_error=False, parser=DocTestParser(), - encoding=None): - """ - Test examples in the given file. Return (#failures, #tests). - - Optional keyword arg "module_relative" specifies how filenames - should be interpreted: - - - If "module_relative" is True (the default), then "filename" - specifies a module-relative path. By default, this path is - relative to the calling module's directory; but if the - "package" argument is specified, then it is relative to that - package. To ensure os-independence, "filename" should use - "/" characters to separate path segments, and should not - be an absolute path (i.e., it may not begin with "/"). - - - If "module_relative" is False, then "filename" specifies an - os-specific path. The path may be absolute or relative (to - the current working directory). - - Optional keyword arg "name" gives the name of the test; by default - use the file's basename. - - Optional keyword argument "package" is a Python package or the - name of a Python package whose directory should be used as the - base directory for a module relative filename. If no package is - specified, then the calling module's directory is used as the base - directory for module relative filenames. It is an error to - specify "package" if "module_relative" is False. - - Optional keyword arg "globs" gives a dict to be used as the globals - when executing examples; by default, use {}. A copy of this dict - is actually used for each docstring, so that each docstring's - examples start with a clean slate. - - Optional keyword arg "extraglobs" gives a dictionary that should be - merged into the globals that are used to execute examples. By - default, no extra globals are used. - - Optional keyword arg "verbose" prints lots of stuff if true, prints - only failures if false; by default, it's true iff "-v" is in sys.argv. - - Optional keyword arg "report" prints a summary at the end when true, - else prints nothing at the end. In verbose mode, the summary is - detailed, else very brief (in fact, empty if all tests passed). - - Optional keyword arg "optionflags" or's together module constants, - and defaults to 0. Possible values (see the docs for details): - - DONT_ACCEPT_TRUE_FOR_1 - DONT_ACCEPT_BLANKLINE - NORMALIZE_WHITESPACE - ELLIPSIS - SKIP - IGNORE_EXCEPTION_DETAIL - REPORT_UDIFF - REPORT_CDIFF - REPORT_NDIFF - REPORT_ONLY_FIRST_FAILURE - - Optional keyword arg "raise_on_error" raises an exception on the - first unexpected exception or failure. This allows failures to be - post-mortem debugged. - - Optional keyword arg "parser" specifies a DocTestParser (or - subclass) that should be used to extract tests from the files. - - Optional keyword arg "encoding" specifies an encoding that should - be used to convert the file to unicode. - - Advanced tomfoolery: testmod runs methods of a local instance of - class doctest.Tester, then merges the results into (or creates) - global Tester instance doctest.master. Methods of doctest.master - can be called directly too, if you want to do something unusual. - Passing report=0 to testmod is especially useful then, to delay - displaying a summary. Invoke doctest.master.summarize(verbose) - when you're done fiddling. - """ - global master - - if package and not module_relative: - raise ValueError("Package may only be specified for module-" - "relative paths.") - - # Relativize the path - text, filename = _load_testfile(filename, package, module_relative) - - # If no name was given, then use the file's name. - if name is None: - name = os.path.basename(filename) - - # Assemble the globals. - if globs is None: - globs = {} - else: - globs = globs.copy() - if extraglobs is not None: - globs.update(extraglobs) - - if raise_on_error: - runner = DebugRunner(verbose=verbose, optionflags=optionflags) - else: - runner = DocTestRunner(verbose=verbose, optionflags=optionflags) - - if encoding is not None: - text = text.decode(encoding) - - # Read the file, convert it to a test, and run it. - test = parser.get_doctest(text, globs, name, filename, 0) - runner.run(test) - - if report: - runner.summarize() - - if master is None: - master = runner - else: - master.merge(runner) - - return runner.failures, runner.tries - -def run_docstring_examples(f, globs, verbose=False, name="NoName", - compileflags=None, optionflags=0): - """ - Test examples in the given object's docstring (`f`), using `globs` - as globals. Optional argument `name` is used in failure messages. - If the optional argument `verbose` is true, then generate output - even if there are no failures. - - `compileflags` gives the set of flags that should be used by the - Python compiler when running the examples. If not specified, then - it will default to the set of future-import flags that apply to - `globs`. - - Optional keyword arg `optionflags` specifies options for the - testing and output. See the documentation for `testmod` for more - information. - """ - # Find, parse, and run all tests in the given module. - finder = DocTestFinder(verbose=verbose, recurse=False) - runner = DocTestRunner(verbose=verbose, optionflags=optionflags) - for test in finder.find(f, name, globs=globs): - runner.run(test, compileflags=compileflags) - -###################################################################### -## 7. Tester -###################################################################### -# This is provided only for backwards compatibility. It's not -# actually used in any way. - -class Tester: - def __init__(self, mod=None, globs=None, verbose=None, optionflags=0): - - warnings.warn("class Tester is deprecated; " - "use class doctest.DocTestRunner instead", - DeprecationWarning, stacklevel=2) - if mod is None and globs is None: - raise TypeError("Tester.__init__: must specify mod or globs") - if mod is not None and not inspect.ismodule(mod): - raise TypeError("Tester.__init__: mod must be a module; %r" % - (mod,)) - if globs is None: - globs = mod.__dict__ - self.globs = globs - - self.verbose = verbose - self.optionflags = optionflags - self.testfinder = DocTestFinder() - self.testrunner = DocTestRunner(verbose=verbose, - optionflags=optionflags) - - def runstring(self, s, name): - test = DocTestParser().get_doctest(s, self.globs, name, None, None) - if self.verbose: - print("Running string %s" % name) - (f,t) = self.testrunner.run(test) - if self.verbose: - print("%s of %s examples failed in string %s" % (f, t, name)) - return (f,t) - - def rundoc(self, object, name=None, module=None): - f = t = 0 - tests = self.testfinder.find(object, name, module=module, - globs=self.globs) - for test in tests: - (f2, t2) = self.testrunner.run(test) - (f,t) = (f+f2, t+t2) - return (f,t) - - def rundict(self, d, name, module=None): - import new - m = new.module(name) - m.__dict__.update(d) - if module is None: - module = False - return self.rundoc(m, name, module) - - def run__test__(self, d, name): - import new - m = new.module(name) - m.__test__ = d - return self.rundoc(m, name) - - def summarize(self, verbose=None): - return self.testrunner.summarize(verbose) - - def merge(self, other): - self.testrunner.merge(other.testrunner) - -###################################################################### -## 8. Unittest Support -###################################################################### - -_unittest_reportflags = 0 - -def set_unittest_reportflags(flags): - """Sets the unittest option flags. - - The old flag is returned so that a runner could restore the old - value if it wished to: - - >>> old = _unittest_reportflags - >>> set_unittest_reportflags(REPORT_NDIFF | - ... REPORT_ONLY_FIRST_FAILURE) == old - True - - >>> import doctest - >>> doctest._unittest_reportflags == (REPORT_NDIFF | - ... REPORT_ONLY_FIRST_FAILURE) - True - - Only reporting flags can be set: - - >>> set_unittest_reportflags(ELLIPSIS) - Traceback (most recent call last): - ... - ValueError: ('Only reporting flags allowed', 8) - - >>> set_unittest_reportflags(old) == (REPORT_NDIFF | - ... REPORT_ONLY_FIRST_FAILURE) - True - """ - global _unittest_reportflags - - if (flags & REPORTING_FLAGS) != flags: - raise ValueError("Only reporting flags allowed", flags) - old = _unittest_reportflags - _unittest_reportflags = flags - return old - - -class DocTestCase(unittest.TestCase): - - def __init__(self, test, optionflags=0, setUp=None, tearDown=None, - checker=None, runner=DocTestRunner): - - unittest.TestCase.__init__(self) - self._dt_optionflags = optionflags - self._dt_checker = checker - self._dt_test = test - self._dt_setUp = setUp - self._dt_tearDown = tearDown - self._dt_runner = runner - - def setUp(self): - test = self._dt_test - - if self._dt_setUp is not None: - self._dt_setUp(test) - - def tearDown(self): - test = self._dt_test - - if self._dt_tearDown is not None: - self._dt_tearDown(test) - - test.globs.clear() - - def runTest(self): - test = self._dt_test - old = sys.stdout - new = StringIO() - optionflags = self._dt_optionflags - - if not (optionflags & REPORTING_FLAGS): - # The option flags don't include any reporting flags, - # so add the default reporting flags - optionflags |= _unittest_reportflags - - runner = self._dt_runner(optionflags=optionflags, - checker=self._dt_checker, verbose=False) - - try: - runner.DIVIDER = "-"*70 - failures, tries = runner.run( - test, out=new.write, clear_globs=False) - finally: - sys.stdout = old - - if failures: - raise self.failureException(self.format_failure(new.getvalue())) - - def format_failure(self, err): - test = self._dt_test - if test.lineno is None: - lineno = 'unknown line number' - else: - lineno = '%s' % test.lineno - lname = '.'.join(test.name.split('.')[-1:]) - return ('Failed doctest test for %s\n' - ' File "%s", line %s, in %s\n\n%s' - % (test.name, test.filename, lineno, lname, err) - ) - - def debug(self): - r"""Run the test case without results and without catching exceptions - - The unit test framework includes a debug method on test cases - and test suites to support post-mortem debugging. The test code - is run in such a way that errors are not caught. This way a - caller can catch the errors and initiate post-mortem debugging. - - The DocTestCase provides a debug method that raises - UnexpectedException errors if there is an unexepcted - exception: - - >>> test = DocTestParser().get_doctest('>>> raise KeyError\n42', - ... {}, 'foo', 'foo.py', 0) - >>> case = DocTestCase(test) - >>> try: - ... case.debug() - ... except UnexpectedException as e: - ... failure = e - - The UnexpectedException contains the test, the example, and - the original exception: - - >>> failure.test is test - True - - >>> failure.example.want - '42\n' - - >>> exc_info = failure.exc_info - >>> raise exc_info[0], exc_info[1], exc_info[2] - Traceback (most recent call last): - ... - KeyError - - If the output doesn't match, then a DocTestFailure is raised: - - >>> test = DocTestParser().get_doctest(''' - ... >>> x = 1 - ... >>> x - ... 2 - ... ''', {}, 'foo', 'foo.py', 0) - >>> case = DocTestCase(test) - - >>> try: - ... case.debug() - ... except DocTestFailure as e: - ... failure = e - - DocTestFailure objects provide access to the test: - - >>> failure.test is test - True - - As well as to the example: - - >>> failure.example.want - '2\n' - - and the actual output: - - >>> failure.got - '1\n' - - """ - - self.setUp() - runner = DebugRunner(optionflags=self._dt_optionflags, - checker=self._dt_checker, verbose=False) - runner.run(self._dt_test) - self.tearDown() - - def id(self): - return self._dt_test.name - - def __repr__(self): - name = self._dt_test.name.split('.') - return "%s (%s)" % (name[-1], '.'.join(name[:-1])) - - __str__ = __repr__ - - def shortDescription(self): - return "Doctest: " + self._dt_test.name - -def DocTestSuite(module=None, globs=None, extraglobs=None, test_finder=None, - test_class=DocTestCase, **options): - """ - Convert doctest tests for a module to a unittest test suite. - - This converts each documentation string in a module that - contains doctest tests to a unittest test case. If any of the - tests in a doc string fail, then the test case fails. An exception - is raised showing the name of the file containing the test and a - (sometimes approximate) line number. - - The `module` argument provides the module to be tested. The argument - can be either a module or a module name. - - If no argument is given, the calling module is used. - - A number of options may be provided as keyword arguments: - - setUp - A set-up function. This is called before running the - tests in each file. The setUp function will be passed a DocTest - object. The setUp function can access the test globals as the - globs attribute of the test passed. - - tearDown - A tear-down function. This is called after running the - tests in each file. The tearDown function will be passed a DocTest - object. The tearDown function can access the test globals as the - globs attribute of the test passed. - - globs - A dictionary containing initial global variables for the tests. - - optionflags - A set of doctest option flags expressed as an integer. - """ - - if test_finder is None: - test_finder = DocTestFinder() - - module = _normalize_module(module) - tests = test_finder.find(module, globs=globs, extraglobs=extraglobs) - if globs is None: - globs = module.__dict__ - if not tests: - # Why do we want to do this? Because it reveals a bug that might - # otherwise be hidden. - raise ValueError(module, "has no tests") - - tests.sort() - suite = unittest.TestSuite() - for test in tests: - if len(test.examples) == 0: - continue - if not test.filename: - filename = module.__file__ - if filename[-4:] in (".pyc", ".pyo"): - filename = filename[:-1] - test.filename = filename - suite.addTest(test_class(test, **options)) - - return suite - -class DocFileCase(DocTestCase): - - def id(self): - return '_'.join(self._dt_test.name.split('.')) - - def __repr__(self): - return self._dt_test.filename - __str__ = __repr__ - - def format_failure(self, err): - return ('Failed doctest test for %s\n File "%s", line 0\n\n%s' - % (self._dt_test.name, self._dt_test.filename, err) - ) - -def DocFileTest(path, module_relative=True, package=None, - globs=None, parser=DocTestParser(), - encoding=None, **options): - if globs is None: - globs = {} - else: - globs = globs.copy() - - if package and not module_relative: - raise ValueError("Package may only be specified for module-" - "relative paths.") - - # Relativize the path. - doc, path = _load_testfile(path, package, module_relative) - - if "__file__" not in globs: - globs["__file__"] = path - - # Find the file and read it. - name = os.path.basename(path) - - # If an encoding is specified, use it to convert the file to unicode - if encoding is not None: - doc = doc.decode(encoding) - - # Convert it to a test, and wrap it in a DocFileCase. - test = parser.get_doctest(doc, globs, name, path, 0) - return DocFileCase(test, **options) - -def DocFileSuite(*paths, **kw): - """A unittest suite for one or more doctest files. - - The path to each doctest file is given as a string; the - interpretation of that string depends on the keyword argument - "module_relative". - - A number of options may be provided as keyword arguments: - - module_relative - If "module_relative" is True, then the given file paths are - interpreted as os-independent module-relative paths. By - default, these paths are relative to the calling module's - directory; but if the "package" argument is specified, then - they are relative to that package. To ensure os-independence, - "filename" should use "/" characters to separate path - segments, and may not be an absolute path (i.e., it may not - begin with "/"). - - If "module_relative" is False, then the given file paths are - interpreted as os-specific paths. These paths may be absolute - or relative (to the current working directory). - - package - A Python package or the name of a Python package whose directory - should be used as the base directory for module relative paths. - If "package" is not specified, then the calling module's - directory is used as the base directory for module relative - filenames. It is an error to specify "package" if - "module_relative" is False. - - setUp - A set-up function. This is called before running the - tests in each file. The setUp function will be passed a DocTest - object. The setUp function can access the test globals as the - globs attribute of the test passed. - - tearDown - A tear-down function. This is called after running the - tests in each file. The tearDown function will be passed a DocTest - object. The tearDown function can access the test globals as the - globs attribute of the test passed. - - globs - A dictionary containing initial global variables for the tests. - - optionflags - A set of doctest option flags expressed as an integer. - - parser - A DocTestParser (or subclass) that should be used to extract - tests from the files. - - encoding - An encoding that will be used to convert the files to unicode. - """ - suite = unittest.TestSuite() - - # We do this here so that _normalize_module is called at the right - # level. If it were called in DocFileTest, then this function - # would be the caller and we might guess the package incorrectly. - if kw.get('module_relative', True): - kw['package'] = _normalize_module(kw.get('package')) - - for path in paths: - suite.addTest(DocFileTest(path, **kw)) - - return suite - -###################################################################### -## 9. Debugging Support -###################################################################### - -def script_from_examples(s): - r"""Extract script from text with examples. - - Converts text with examples to a Python script. Example input is - converted to regular code. Example output and all other words - are converted to comments: - - >>> text = ''' - ... Here are examples of simple math. - ... - ... Python has super accurate integer addition - ... - ... >>> 2 + 2 - ... 5 - ... - ... And very friendly error messages: - ... - ... >>> 1/0 - ... To Infinity - ... And - ... Beyond - ... - ... You can use logic if you want: - ... - ... >>> if 0: - ... ... blah - ... ... blah - ... ... - ... - ... Ho hum - ... ''' - - >>> print(script_from_examples(text)) - # Here are examples of simple math. - # - # Python has super accurate integer addition - # - 2 + 2 - # Expected: - ## 5 - # - # And very friendly error messages: - # - 1/0 - # Expected: - ## To Infinity - ## And - ## Beyond - # - # You can use logic if you want: - # - if 0: - blah - blah - # - # Ho hum - """ - output = [] - for piece in DocTestParser().parse(s): - if isinstance(piece, Example): - # Add the example's source code (strip trailing NL) - output.append(piece.source[:-1]) - # Add the expected output: - want = piece.want - if want: - output.append('# Expected:') - output += ['## '+l for l in want.split('\n')[:-1]] - else: - # Add non-example text. - output += [_comment_line(l) - for l in piece.split('\n')[:-1]] - - # Trim junk on both ends. - while output and output[-1] == '#': - output.pop() - while output and output[0] == '#': - output.pop(0) - # Combine the output, and return it. - return '\n'.join(output) - -def testsource(module, name): - """Extract the test sources from a doctest docstring as a script. - - Provide the module (or dotted name of the module) containing the - test to be debugged and the name (within the module) of the object - with the doc string with tests to be debugged. - """ - module = _normalize_module(module) - tests = DocTestFinder().find(module) - test = [t for t in tests if t.name == name] - if not test: - raise ValueError(name, "not found in tests") - test = test[0] - testsrc = script_from_examples(test.docstring) - return testsrc - -def debug_src(src, pm=False, globs=None): - """Debug a single doctest docstring, in argument `src`'""" - testsrc = script_from_examples(src) - debug_script(testsrc, pm, globs) - -def debug_script(src, pm=False, globs=None): - "Debug a test script. `src` is the script, as a string." - import pdb - - # Note that tempfile.NameTemporaryFile() cannot be used. As the - # docs say, a file so created cannot be opened by name a second time - # on modern Windows boxes, and execfile() needs to open it. - srcfilename = tempfile.mktemp(".py", "doctestdebug") - with open(srcfilename, 'w') as fp: - fp.write(src) - - try: - if globs: - globs = globs.copy() - else: - globs = {} - - if pm: - try: - execfile(srcfilename, globs, globs) - except: - print(sys.exc_info()[1]) - pdb.post_mortem(sys.exc_info()[2]) - else: - # Note that %r is vital here. '%s' instead can, e.g., cause - # backslashes to get treated as metacharacters on Windows. - pdb.run("execfile(%r)" % srcfilename, globs, globs) - - finally: - os.remove(srcfilename) - -def debug(module, name, pm=False): - """Debug a single doctest docstring. - - Provide the module (or dotted name of the module) containing the - test to be debugged and the name (within the module) of the object - with the docstring with tests to be debugged. - """ - module = _normalize_module(module) - testsrc = testsource(module, name) - debug_script(testsrc, pm, module.__dict__) - -###################################################################### -## 10. Example Usage -###################################################################### -class _TestClass: - """ - A pointless class, for sanity-checking of docstring testing. - - Methods: - square() - get() - - >>> _TestClass(13).get() + _TestClass(-12).get() - 1 - >>> hex(_TestClass(13).square().get()) - '0xa9' - """ - - def __init__(self, val): - """val -> _TestClass object with associated value val. - - >>> t = _TestClass(123) - >>> print(t.get()) - 123 - """ - - self.val = val - - def square(self): - """square() -> square TestClass's associated value - - >>> _TestClass(13).square().get() - 169 - """ - - self.val = self.val ** 2 - return self - - def get(self): - """get() -> return TestClass's associated value. - - >>> x = _TestClass(-42) - >>> print(x.get()) - -42 - """ - - return self.val - -__test__ = {"_TestClass": _TestClass, - "string": r""" - Example of a string object, searched as-is. - >>> x = 1; y = 2 - >>> x + y, x * y - (3, 2) - """, - - "bool-int equivalence": r""" - In 2.2, boolean expressions displayed - 0 or 1. By default, we still accept - them. This can be disabled by passing - DONT_ACCEPT_TRUE_FOR_1 to the new - optionflags argument. - >>> 4 == 4 - 1 - >>> 4 == 4 - True - >>> 4 > 4 - 0 - >>> 4 > 4 - False - """, - - "blank lines": r""" - Blank lines can be marked with <BLANKLINE>: - >>> print('foo\n\nbar\n') - foo - <BLANKLINE> - bar - <BLANKLINE> - """, - - "ellipsis": r""" - If the ellipsis flag is used, then '...' can be used to - elide substrings in the desired output: - >>> print(range(1000)) #doctest: +ELLIPSIS - [0, 1, 2, ..., 999] - """, - - "whitespace normalization": r""" - If the whitespace normalization flag is used, then - differences in whitespace are ignored. - >>> print(list(xrange(30))) #doctest: +NORMALIZE_WHITESPACE - [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, - 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, - 27, 28, 29] - """, - } - -def _test(): - r = unittest.TextTestRunner() - r.run(DocTestSuite()) - -if __name__ == "__main__": - _test() diff --git a/lib/python2.7/site-packages/django/test/client.py b/lib/python2.7/site-packages/django/test/client.py deleted file mode 100644 index 6ea8119..0000000 --- a/lib/python2.7/site-packages/django/test/client.py +++ /dev/null @@ -1,623 +0,0 @@ -from __future__ import unicode_literals - -import sys -import os -import re -import mimetypes -from copy import copy -from io import BytesIO - -from django.conf import settings -from django.contrib.auth import authenticate, login, logout, get_user_model -from django.core.handlers.base import BaseHandler -from django.core.handlers.wsgi import WSGIRequest -from django.core.signals import (request_started, request_finished, - got_request_exception) -from django.db import close_old_connections -from django.http import SimpleCookie, HttpRequest, QueryDict -from django.template import TemplateDoesNotExist -from django.test import signals -from django.utils.functional import curry -from django.utils.encoding import force_bytes, force_str -from django.utils.http import urlencode -from django.utils.importlib import import_module -from django.utils.itercompat import is_iterable -from django.utils import six -from django.utils.six.moves.urllib.parse import unquote, urlparse, urlsplit -from django.test.utils import ContextList - -__all__ = ('Client', 'RequestFactory', 'encode_file', 'encode_multipart') - - -BOUNDARY = 'BoUnDaRyStRiNg' -MULTIPART_CONTENT = 'multipart/form-data; boundary=%s' % BOUNDARY -CONTENT_TYPE_RE = re.compile('.*; charset=([\w\d-]+);?') - -class FakePayload(object): - """ - A wrapper around BytesIO that restricts what can be read since data from - the network can't be seeked and cannot be read outside of its content - length. This makes sure that views can't do anything under the test client - that wouldn't work in Real Life. - """ - def __init__(self, content=None): - self.__content = BytesIO() - self.__len = 0 - self.read_started = False - if content is not None: - self.write(content) - - def __len__(self): - return self.__len - - def read(self, num_bytes=None): - if not self.read_started: - self.__content.seek(0) - self.read_started = True - if num_bytes is None: - num_bytes = self.__len or 0 - assert self.__len >= num_bytes, "Cannot read more than the available bytes from the HTTP incoming data." - content = self.__content.read(num_bytes) - self.__len -= num_bytes - return content - - def write(self, content): - if self.read_started: - raise ValueError("Unable to write a payload after he's been read") - content = force_bytes(content) - self.__content.write(content) - self.__len += len(content) - - -def closing_iterator_wrapper(iterable, close): - try: - for item in iterable: - yield item - finally: - request_finished.disconnect(close_old_connections) - close() # will fire request_finished - request_finished.connect(close_old_connections) - - -class ClientHandler(BaseHandler): - """ - A HTTP Handler that can be used for testing purposes. - Uses the WSGI interface to compose requests, but returns - the raw HttpResponse object - """ - def __init__(self, enforce_csrf_checks=True, *args, **kwargs): - self.enforce_csrf_checks = enforce_csrf_checks - super(ClientHandler, self).__init__(*args, **kwargs) - - def __call__(self, environ): - from django.conf import settings - - # Set up middleware if needed. We couldn't do this earlier, because - # settings weren't available. - if self._request_middleware is None: - self.load_middleware() - - request_started.disconnect(close_old_connections) - request_started.send(sender=self.__class__) - request_started.connect(close_old_connections) - request = WSGIRequest(environ) - # sneaky little hack so that we can easily get round - # CsrfViewMiddleware. This makes life easier, and is probably - # required for backwards compatibility with external tests against - # admin views. - request._dont_enforce_csrf_checks = not self.enforce_csrf_checks - response = self.get_response(request) - # We're emulating a WSGI server; we must call the close method - # on completion. - if response.streaming: - response.streaming_content = closing_iterator_wrapper( - response.streaming_content, response.close) - else: - request_finished.disconnect(close_old_connections) - response.close() # will fire request_finished - request_finished.connect(close_old_connections) - - return response - -def store_rendered_templates(store, signal, sender, template, context, **kwargs): - """ - Stores templates and contexts that are rendered. - - The context is copied so that it is an accurate representation at the time - of rendering. - """ - store.setdefault('templates', []).append(template) - store.setdefault('context', ContextList()).append(copy(context)) - -def encode_multipart(boundary, data): - """ - Encodes multipart POST data from a dictionary of form values. - - The key will be used as the form data name; the value will be transmitted - as content. If the value is a file, the contents of the file will be sent - as an application/octet-stream; otherwise, str(value) will be sent. - """ - lines = [] - to_bytes = lambda s: force_bytes(s, settings.DEFAULT_CHARSET) - - # Not by any means perfect, but good enough for our purposes. - is_file = lambda thing: hasattr(thing, "read") and callable(thing.read) - - # Each bit of the multipart form data could be either a form value or a - # file, or a *list* of form values and/or files. Remember that HTTP field - # names can be duplicated! - for (key, value) in data.items(): - if is_file(value): - lines.extend(encode_file(boundary, key, value)) - elif not isinstance(value, six.string_types) and is_iterable(value): - for item in value: - if is_file(item): - lines.extend(encode_file(boundary, key, item)) - else: - lines.extend([to_bytes(val) for val in [ - '--%s' % boundary, - 'Content-Disposition: form-data; name="%s"' % key, - '', - item - ]]) - else: - lines.extend([to_bytes(val) for val in [ - '--%s' % boundary, - 'Content-Disposition: form-data; name="%s"' % key, - '', - value - ]]) - - lines.extend([ - to_bytes('--%s--' % boundary), - b'', - ]) - return b'\r\n'.join(lines) - -def encode_file(boundary, key, file): - to_bytes = lambda s: force_bytes(s, settings.DEFAULT_CHARSET) - content_type = mimetypes.guess_type(file.name)[0] - if content_type is None: - content_type = 'application/octet-stream' - return [ - to_bytes('--%s' % boundary), - to_bytes('Content-Disposition: form-data; name="%s"; filename="%s"' \ - % (key, os.path.basename(file.name))), - to_bytes('Content-Type: %s' % content_type), - b'', - file.read() - ] - - -class RequestFactory(object): - """ - Class that lets you create mock Request objects for use in testing. - - Usage: - - rf = RequestFactory() - get_request = rf.get('/hello/') - post_request = rf.post('/submit/', {'foo': 'bar'}) - - Once you have a request object you can pass it to any view function, - just as if that view had been hooked up using a URLconf. - """ - def __init__(self, **defaults): - self.defaults = defaults - self.cookies = SimpleCookie() - self.errors = BytesIO() - - def _base_environ(self, **request): - """ - The base environment for a request. - """ - # This is a minimal valid WSGI environ dictionary, plus: - # - HTTP_COOKIE: for cookie support, - # - REMOTE_ADDR: often useful, see #8551. - # See http://www.python.org/dev/peps/pep-3333/#environ-variables - environ = { - 'HTTP_COOKIE': self.cookies.output(header='', sep='; '), - 'PATH_INFO': str('/'), - 'REMOTE_ADDR': str('127.0.0.1'), - 'REQUEST_METHOD': str('GET'), - 'SCRIPT_NAME': str(''), - 'SERVER_NAME': str('testserver'), - 'SERVER_PORT': str('80'), - 'SERVER_PROTOCOL': str('HTTP/1.1'), - 'wsgi.version': (1, 0), - 'wsgi.url_scheme': str('http'), - 'wsgi.input': FakePayload(b''), - 'wsgi.errors': self.errors, - 'wsgi.multiprocess': True, - 'wsgi.multithread': False, - 'wsgi.run_once': False, - } - environ.update(self.defaults) - environ.update(request) - return environ - - def request(self, **request): - "Construct a generic request object." - return WSGIRequest(self._base_environ(**request)) - - def _encode_data(self, data, content_type, ): - if content_type is MULTIPART_CONTENT: - return encode_multipart(BOUNDARY, data) - else: - # Encode the content so that the byte representation is correct. - match = CONTENT_TYPE_RE.match(content_type) - if match: - charset = match.group(1) - else: - charset = settings.DEFAULT_CHARSET - return force_bytes(data, encoding=charset) - - def _get_path(self, parsed): - path = force_str(parsed[2]) - # If there are parameters, add them - if parsed[3]: - path += str(";") + force_str(parsed[3]) - path = unquote(path) - # WSGI requires latin-1 encoded strings. See get_path_info(). - if six.PY3: - path = path.encode('utf-8').decode('iso-8859-1') - return path - - def get(self, path, data={}, **extra): - "Construct a GET request." - - parsed = urlparse(path) - query_string = urlencode(data, doseq=True) or force_str(parsed[4]) - if six.PY3: - query_string = query_string.encode('utf-8').decode('iso-8859-1') - - r = { - 'PATH_INFO': self._get_path(parsed), - 'QUERY_STRING': query_string, - 'REQUEST_METHOD': str('GET'), - } - r.update(extra) - return self.request(**r) - - def post(self, path, data={}, content_type=MULTIPART_CONTENT, - **extra): - "Construct a POST request." - - post_data = self._encode_data(data, content_type) - - parsed = urlparse(path) - query_string = force_str(parsed[4]) - if six.PY3: - query_string = query_string.encode('utf-8').decode('iso-8859-1') - - r = { - 'CONTENT_LENGTH': len(post_data), - 'CONTENT_TYPE': content_type, - 'PATH_INFO': self._get_path(parsed), - 'QUERY_STRING': query_string, - 'REQUEST_METHOD': str('POST'), - 'wsgi.input': FakePayload(post_data), - } - r.update(extra) - return self.request(**r) - - def head(self, path, data={}, **extra): - "Construct a HEAD request." - - parsed = urlparse(path) - query_string = urlencode(data, doseq=True) or force_str(parsed[4]) - if six.PY3: - query_string = query_string.encode('utf-8').decode('iso-8859-1') - - r = { - 'PATH_INFO': self._get_path(parsed), - 'QUERY_STRING': query_string, - 'REQUEST_METHOD': str('HEAD'), - } - r.update(extra) - return self.request(**r) - - def options(self, path, data='', content_type='application/octet-stream', - **extra): - "Construct an OPTIONS request." - return self.generic('OPTIONS', path, data, content_type, **extra) - - def put(self, path, data='', content_type='application/octet-stream', - **extra): - "Construct a PUT request." - return self.generic('PUT', path, data, content_type, **extra) - - def patch(self, path, data='', content_type='application/octet-stream', - **extra): - "Construct a PATCH request." - return self.generic('PATCH', path, data, content_type, **extra) - - def delete(self, path, data='', content_type='application/octet-stream', - **extra): - "Construct a DELETE request." - return self.generic('DELETE', path, data, content_type, **extra) - - def generic(self, method, path, - data='', content_type='application/octet-stream', **extra): - parsed = urlparse(path) - data = force_bytes(data, settings.DEFAULT_CHARSET) - r = { - 'PATH_INFO': self._get_path(parsed), - 'REQUEST_METHOD': str(method), - } - if data: - r.update({ - 'CONTENT_LENGTH': len(data), - 'CONTENT_TYPE': str(content_type), - 'wsgi.input': FakePayload(data), - }) - r.update(extra) - # If QUERY_STRING is absent or empty, we want to extract it from the URL. - if not r.get('QUERY_STRING'): - query_string = force_bytes(parsed[4]) - # WSGI requires latin-1 encoded strings. See get_path_info(). - if six.PY3: - query_string = query_string.decode('iso-8859-1') - r['QUERY_STRING'] = query_string - return self.request(**r) - - -class Client(RequestFactory): - """ - A class that can act as a client for testing purposes. - - It allows the user to compose GET and POST requests, and - obtain the response that the server gave to those requests. - The server Response objects are annotated with the details - of the contexts and templates that were rendered during the - process of serving the request. - - Client objects are stateful - they will retain cookie (and - thus session) details for the lifetime of the Client instance. - - This is not intended as a replacement for Twill/Selenium or - the like - it is here to allow testing against the - contexts and templates produced by a view, rather than the - HTML rendered to the end-user. - """ - def __init__(self, enforce_csrf_checks=False, **defaults): - super(Client, self).__init__(**defaults) - self.handler = ClientHandler(enforce_csrf_checks) - self.exc_info = None - - def store_exc_info(self, **kwargs): - """ - Stores exceptions when they are generated by a view. - """ - self.exc_info = sys.exc_info() - - def _session(self): - """ - Obtains the current session variables. - """ - if 'django.contrib.sessions' in settings.INSTALLED_APPS: - engine = import_module(settings.SESSION_ENGINE) - cookie = self.cookies.get(settings.SESSION_COOKIE_NAME, None) - if cookie: - return engine.SessionStore(cookie.value) - return {} - session = property(_session) - - - def request(self, **request): - """ - The master request method. Composes the environment dictionary - and passes to the handler, returning the result of the handler. - Assumes defaults for the query environment, which can be overridden - using the arguments to the request. - """ - environ = self._base_environ(**request) - - # Curry a data dictionary into an instance of the template renderer - # callback function. - data = {} - on_template_render = curry(store_rendered_templates, data) - signals.template_rendered.connect(on_template_render, dispatch_uid="template-render") - # Capture exceptions created by the handler. - got_request_exception.connect(self.store_exc_info, dispatch_uid="request-exception") - try: - - try: - response = self.handler(environ) - except TemplateDoesNotExist as e: - # If the view raises an exception, Django will attempt to show - # the 500.html template. If that template is not available, - # we should ignore the error in favor of re-raising the - # underlying exception that caused the 500 error. Any other - # template found to be missing during view error handling - # should be reported as-is. - if e.args != ('500.html',): - raise - - # Look for a signalled exception, clear the current context - # exception data, then re-raise the signalled exception. - # Also make sure that the signalled exception is cleared from - # the local cache! - if self.exc_info: - exc_info = self.exc_info - self.exc_info = None - six.reraise(*exc_info) - - # Save the client and request that stimulated the response. - response.client = self - response.request = request - - # Add any rendered template detail to the response. - response.templates = data.get("templates", []) - response.context = data.get("context") - - # Flatten a single context. Not really necessary anymore thanks to - # the __getattr__ flattening in ContextList, but has some edge-case - # backwards-compatibility implications. - if response.context and len(response.context) == 1: - response.context = response.context[0] - - # Update persistent cookie data. - if response.cookies: - self.cookies.update(response.cookies) - - return response - finally: - signals.template_rendered.disconnect(dispatch_uid="template-render") - got_request_exception.disconnect(dispatch_uid="request-exception") - - def get(self, path, data={}, follow=False, **extra): - """ - Requests a response from the server using GET. - """ - response = super(Client, self).get(path, data=data, **extra) - if follow: - response = self._handle_redirects(response, **extra) - return response - - def post(self, path, data={}, content_type=MULTIPART_CONTENT, - follow=False, **extra): - """ - Requests a response from the server using POST. - """ - response = super(Client, self).post(path, data=data, content_type=content_type, **extra) - if follow: - response = self._handle_redirects(response, **extra) - return response - - def head(self, path, data={}, follow=False, **extra): - """ - Request a response from the server using HEAD. - """ - response = super(Client, self).head(path, data=data, **extra) - if follow: - response = self._handle_redirects(response, **extra) - return response - - def options(self, path, data='', content_type='application/octet-stream', - follow=False, **extra): - """ - Request a response from the server using OPTIONS. - """ - response = super(Client, self).options(path, - data=data, content_type=content_type, **extra) - if follow: - response = self._handle_redirects(response, **extra) - return response - - def put(self, path, data='', content_type='application/octet-stream', - follow=False, **extra): - """ - Send a resource to the server using PUT. - """ - response = super(Client, self).put(path, - data=data, content_type=content_type, **extra) - if follow: - response = self._handle_redirects(response, **extra) - return response - - def patch(self, path, data='', content_type='application/octet-stream', - follow=False, **extra): - """ - Send a resource to the server using PATCH. - """ - response = super(Client, self).patch( - path, data=data, content_type=content_type, **extra) - if follow: - response = self._handle_redirects(response, **extra) - return response - - def delete(self, path, data='', content_type='application/octet-stream', - follow=False, **extra): - """ - Send a DELETE request to the server. - """ - response = super(Client, self).delete(path, - data=data, content_type=content_type, **extra) - if follow: - response = self._handle_redirects(response, **extra) - return response - - def login(self, **credentials): - """ - Sets the Factory to appear as if it has successfully logged into a site. - - Returns True if login is possible; False if the provided credentials - are incorrect, or the user is inactive, or if the sessions framework is - not available. - """ - user = authenticate(**credentials) - if user and user.is_active \ - and 'django.contrib.sessions' in settings.INSTALLED_APPS: - engine = import_module(settings.SESSION_ENGINE) - - # Create a fake request to store login details. - request = HttpRequest() - if self.session: - request.session = self.session - else: - request.session = engine.SessionStore() - login(request, user) - - # Save the session values. - request.session.save() - - # Set the cookie to represent the session. - session_cookie = settings.SESSION_COOKIE_NAME - self.cookies[session_cookie] = request.session.session_key - cookie_data = { - 'max-age': None, - 'path': '/', - 'domain': settings.SESSION_COOKIE_DOMAIN, - 'secure': settings.SESSION_COOKIE_SECURE or None, - 'expires': None, - } - self.cookies[session_cookie].update(cookie_data) - - return True - else: - return False - - def logout(self): - """ - Removes the authenticated user's cookies and session object. - - Causes the authenticated user to be logged out. - """ - request = HttpRequest() - engine = import_module(settings.SESSION_ENGINE) - UserModel = get_user_model() - if self.session: - request.session = self.session - uid = self.session.get("_auth_user_id") - if uid: - request.user = UserModel._default_manager.get(pk=uid) - else: - request.session = engine.SessionStore() - logout(request) - self.cookies = SimpleCookie() - - def _handle_redirects(self, response, **extra): - "Follows any redirects by requesting responses from the server using GET." - - response.redirect_chain = [] - while response.status_code in (301, 302, 303, 307): - url = response.url - redirect_chain = response.redirect_chain - redirect_chain.append((url, response.status_code)) - - url = urlsplit(url) - if url.scheme: - extra['wsgi.url_scheme'] = url.scheme - if url.hostname: - extra['SERVER_NAME'] = url.hostname - if url.port: - extra['SERVER_PORT'] = str(url.port) - - response = self.get(url.path, QueryDict(url.query), follow=False, **extra) - response.redirect_chain = redirect_chain - - # Prevent loops - if response.redirect_chain[-1] in response.redirect_chain[0:-1]: - break - return response diff --git a/lib/python2.7/site-packages/django/test/html.py b/lib/python2.7/site-packages/django/test/html.py deleted file mode 100644 index 0d30bd2..0000000 --- a/lib/python2.7/site-packages/django/test/html.py +++ /dev/null @@ -1,238 +0,0 @@ -""" -Comparing two html documents. -""" - -from __future__ import unicode_literals - -import re -from django.utils.encoding import force_text -from django.utils.html_parser import HTMLParser, HTMLParseError -from django.utils import six -from django.utils.encoding import python_2_unicode_compatible - - -WHITESPACE = re.compile('\s+') - - -def normalize_whitespace(string): - return WHITESPACE.sub(' ', string) - - -@python_2_unicode_compatible -class Element(object): - def __init__(self, name, attributes): - self.name = name - self.attributes = sorted(attributes) - self.children = [] - - def append(self, element): - if isinstance(element, six.string_types): - element = force_text(element) - element = normalize_whitespace(element) - if self.children: - if isinstance(self.children[-1], six.string_types): - self.children[-1] += element - self.children[-1] = normalize_whitespace(self.children[-1]) - return - elif self.children: - # removing last children if it is only whitespace - # this can result in incorrect dom representations since - # whitespace between inline tags like <span> is significant - if isinstance(self.children[-1], six.string_types): - if self.children[-1].isspace(): - self.children.pop() - if element: - self.children.append(element) - - def finalize(self): - def rstrip_last_element(children): - if children: - if isinstance(children[-1], six.string_types): - children[-1] = children[-1].rstrip() - if not children[-1]: - children.pop() - children = rstrip_last_element(children) - return children - - rstrip_last_element(self.children) - for i, child in enumerate(self.children): - if isinstance(child, six.string_types): - self.children[i] = child.strip() - elif hasattr(child, 'finalize'): - child.finalize() - - def __eq__(self, element): - if not hasattr(element, 'name'): - return False - if hasattr(element, 'name') and self.name != element.name: - return False - if len(self.attributes) != len(element.attributes): - return False - if self.attributes != element.attributes: - # attributes without a value is same as attribute with value that - # equals the attributes name: - # <input checked> == <input checked="checked"> - for i in range(len(self.attributes)): - attr, value = self.attributes[i] - other_attr, other_value = element.attributes[i] - if value is None: - value = attr - if other_value is None: - other_value = other_attr - if attr != other_attr or value != other_value: - return False - if self.children != element.children: - return False - return True - - def __hash__(self): - return hash((self.name,) + tuple(a for a in self.attributes)) - - def __ne__(self, element): - return not self.__eq__(element) - - def _count(self, element, count=True): - if not isinstance(element, six.string_types): - if self == element: - return 1 - i = 0 - for child in self.children: - # child is text content and element is also text content, then - # make a simple "text" in "text" - if isinstance(child, six.string_types): - if isinstance(element, six.string_types): - if count: - i += child.count(element) - elif element in child: - return 1 - else: - i += child._count(element, count=count) - if not count and i: - return i - return i - - def __contains__(self, element): - return self._count(element, count=False) > 0 - - def count(self, element): - return self._count(element, count=True) - - def __getitem__(self, key): - return self.children[key] - - def __str__(self): - output = '<%s' % self.name - for key, value in self.attributes: - if value: - output += ' %s="%s"' % (key, value) - else: - output += ' %s' % key - if self.children: - output += '>\n' - output += ''.join(six.text_type(c) for c in self.children) - output += '\n</%s>' % self.name - else: - output += ' />' - return output - - def __repr__(self): - return six.text_type(self) - - -@python_2_unicode_compatible -class RootElement(Element): - def __init__(self): - super(RootElement, self).__init__(None, ()) - - def __str__(self): - return ''.join(six.text_type(c) for c in self.children) - - -class Parser(HTMLParser): - SELF_CLOSING_TAGS = ('br' , 'hr', 'input', 'img', 'meta', 'spacer', - 'link', 'frame', 'base', 'col') - - def __init__(self): - HTMLParser.__init__(self) - self.root = RootElement() - self.open_tags = [] - self.element_positions = {} - - def error(self, msg): - raise HTMLParseError(msg, self.getpos()) - - def format_position(self, position=None, element=None): - if not position and element: - position = self.element_positions[element] - if position is None: - position = self.getpos() - if hasattr(position, 'lineno'): - position = position.lineno, position.offset - return 'Line %d, Column %d' % position - - @property - def current(self): - if self.open_tags: - return self.open_tags[-1] - else: - return self.root - - def handle_startendtag(self, tag, attrs): - self.handle_starttag(tag, attrs) - if tag not in self.SELF_CLOSING_TAGS: - self.handle_endtag(tag) - - def handle_starttag(self, tag, attrs): - # Special case handling of 'class' attribute, so that comparisons of DOM - # instances are not sensitive to ordering of classes. - attrs = [ - (name, " ".join(sorted(value.split(" ")))) - if name == "class" - else (name, value) - for name, value in attrs - ] - element = Element(tag, attrs) - self.current.append(element) - if tag not in self.SELF_CLOSING_TAGS: - self.open_tags.append(element) - self.element_positions[element] = self.getpos() - - def handle_endtag(self, tag): - if not self.open_tags: - self.error("Unexpected end tag `%s` (%s)" % ( - tag, self.format_position())) - element = self.open_tags.pop() - while element.name != tag: - if not self.open_tags: - self.error("Unexpected end tag `%s` (%s)" % ( - tag, self.format_position())) - element = self.open_tags.pop() - - def handle_data(self, data): - self.current.append(data) - - def handle_charref(self, name): - self.current.append('&%s;' % name) - - def handle_entityref(self, name): - self.current.append('&%s;' % name) - - -def parse_html(html): - """ - Takes a string that contains *valid* HTML and turns it into a Python object - structure that can be easily compared against other HTML on semantic - equivalence. Syntactical differences like which quotation is used on - arguments will be ignored. - - """ - parser = Parser() - parser.feed(html) - parser.close() - document = parser.root - document.finalize() - # Removing ROOT element if it's not necessary - if len(document.children) == 1: - if not isinstance(document.children[0], six.string_types): - document = document.children[0] - return document diff --git a/lib/python2.7/site-packages/django/test/runner.py b/lib/python2.7/site-packages/django/test/runner.py deleted file mode 100644 index d8db8da..0000000 --- a/lib/python2.7/site-packages/django/test/runner.py +++ /dev/null @@ -1,291 +0,0 @@ -import os -from optparse import make_option - -from django.conf import settings -from django.core.exceptions import ImproperlyConfigured -from django.test import TestCase -from django.test.utils import setup_test_environment, teardown_test_environment -from django.utils import unittest -from django.utils.unittest import TestSuite, defaultTestLoader - - -class DiscoverRunner(object): - """ - A Django test runner that uses unittest2 test discovery. - """ - - test_loader = defaultTestLoader - reorder_by = (TestCase, ) - option_list = ( - make_option('-t', '--top-level-directory', - action='store', dest='top_level', default=None, - help='Top level of project for unittest discovery.'), - make_option('-p', '--pattern', action='store', dest='pattern', - default="test*.py", - help='The test matching pattern. Defaults to test*.py.'), - ) - - def __init__(self, pattern=None, top_level=None, - verbosity=1, interactive=True, failfast=False, - **kwargs): - - self.pattern = pattern - self.top_level = top_level - - self.verbosity = verbosity - self.interactive = interactive - self.failfast = failfast - - def setup_test_environment(self, **kwargs): - setup_test_environment() - settings.DEBUG = False - unittest.installHandler() - - def build_suite(self, test_labels=None, extra_tests=None, **kwargs): - suite = TestSuite() - test_labels = test_labels or ['.'] - extra_tests = extra_tests or [] - - discover_kwargs = {} - if self.pattern is not None: - discover_kwargs['pattern'] = self.pattern - if self.top_level is not None: - discover_kwargs['top_level_dir'] = self.top_level - - for label in test_labels: - kwargs = discover_kwargs.copy() - tests = None - - label_as_path = os.path.abspath(label) - - # if a module, or "module.ClassName[.method_name]", just run those - if not os.path.exists(label_as_path): - tests = self.test_loader.loadTestsFromName(label) - elif os.path.isdir(label_as_path) and not self.top_level: - # Try to be a bit smarter than unittest about finding the - # default top-level for a given directory path, to avoid - # breaking relative imports. (Unittest's default is to set - # top-level equal to the path, which means relative imports - # will result in "Attempted relative import in non-package."). - - # We'd be happy to skip this and require dotted module paths - # (which don't cause this problem) instead of file paths (which - # do), but in the case of a directory in the cwd, which would - # be equally valid if considered as a top-level module or as a - # directory path, unittest unfortunately prefers the latter. - - top_level = label_as_path - while True: - init_py = os.path.join(top_level, '__init__.py') - if os.path.exists(init_py): - try_next = os.path.dirname(top_level) - if try_next == top_level: - # __init__.py all the way down? give up. - break - top_level = try_next - continue - break - kwargs['top_level_dir'] = top_level - - - if not (tests and tests.countTestCases()): - # if no tests found, it's probably a package; try discovery - tests = self.test_loader.discover(start_dir=label, **kwargs) - - # make unittest forget the top-level dir it calculated from this - # run, to support running tests from two different top-levels. - self.test_loader._top_level_dir = None - - suite.addTests(tests) - - for test in extra_tests: - suite.addTest(test) - - return reorder_suite(suite, self.reorder_by) - - def setup_databases(self, **kwargs): - return setup_databases(self.verbosity, self.interactive, **kwargs) - - def run_suite(self, suite, **kwargs): - return unittest.TextTestRunner( - verbosity=self.verbosity, - failfast=self.failfast, - ).run(suite) - - def teardown_databases(self, old_config, **kwargs): - """ - Destroys all the non-mirror databases. - """ - old_names, mirrors = old_config - for connection, old_name, destroy in old_names: - if destroy: - connection.creation.destroy_test_db(old_name, self.verbosity) - - def teardown_test_environment(self, **kwargs): - unittest.removeHandler() - teardown_test_environment() - - def suite_result(self, suite, result, **kwargs): - return len(result.failures) + len(result.errors) - - def run_tests(self, test_labels, extra_tests=None, **kwargs): - """ - Run the unit tests for all the test labels in the provided list. - - Test labels should be dotted Python paths to test modules, test - classes, or test methods. - - A list of 'extra' tests may also be provided; these tests - will be added to the test suite. - - Returns the number of tests that failed. - """ - self.setup_test_environment() - suite = self.build_suite(test_labels, extra_tests) - old_config = self.setup_databases() - result = self.run_suite(suite) - self.teardown_databases(old_config) - self.teardown_test_environment() - return self.suite_result(suite, result) - - -def dependency_ordered(test_databases, dependencies): - """ - Reorder test_databases into an order that honors the dependencies - described in TEST_DEPENDENCIES. - """ - ordered_test_databases = [] - resolved_databases = set() - - # Maps db signature to dependencies of all it's aliases - dependencies_map = {} - - # sanity check - no DB can depend on it's own alias - for sig, (_, aliases) in test_databases: - all_deps = set() - for alias in aliases: - all_deps.update(dependencies.get(alias, [])) - if not all_deps.isdisjoint(aliases): - raise ImproperlyConfigured( - "Circular dependency: databases %r depend on each other, " - "but are aliases." % aliases) - dependencies_map[sig] = all_deps - - while test_databases: - changed = False - deferred = [] - - # Try to find a DB that has all it's dependencies met - for signature, (db_name, aliases) in test_databases: - if dependencies_map[signature].issubset(resolved_databases): - resolved_databases.update(aliases) - ordered_test_databases.append((signature, (db_name, aliases))) - changed = True - else: - deferred.append((signature, (db_name, aliases))) - - if not changed: - raise ImproperlyConfigured( - "Circular dependency in TEST_DEPENDENCIES") - test_databases = deferred - return ordered_test_databases - - -def reorder_suite(suite, classes): - """ - Reorders a test suite by test type. - - `classes` is a sequence of types - - All tests of type classes[0] are placed first, then tests of type - classes[1], etc. Tests with no match in classes are placed last. - """ - class_count = len(classes) - bins = [unittest.TestSuite() for i in range(class_count+1)] - partition_suite(suite, classes, bins) - for i in range(class_count): - bins[0].addTests(bins[i+1]) - return bins[0] - - -def partition_suite(suite, classes, bins): - """ - Partitions a test suite by test type. - - classes is a sequence of types - bins is a sequence of TestSuites, one more than classes - - Tests of type classes[i] are added to bins[i], - tests with no match found in classes are place in bins[-1] - """ - for test in suite: - if isinstance(test, unittest.TestSuite): - partition_suite(test, classes, bins) - else: - for i in range(len(classes)): - if isinstance(test, classes[i]): - bins[i].addTest(test) - break - else: - bins[-1].addTest(test) - - -def setup_databases(verbosity, interactive, **kwargs): - from django.db import connections, DEFAULT_DB_ALIAS - - # First pass -- work out which databases actually need to be created, - # and which ones are test mirrors or duplicate entries in DATABASES - mirrored_aliases = {} - test_databases = {} - dependencies = {} - default_sig = connections[DEFAULT_DB_ALIAS].creation.test_db_signature() - for alias in connections: - connection = connections[alias] - if connection.settings_dict['TEST_MIRROR']: - # If the database is marked as a test mirror, save - # the alias. - mirrored_aliases[alias] = ( - connection.settings_dict['TEST_MIRROR']) - else: - # Store a tuple with DB parameters that uniquely identify it. - # If we have two aliases with the same values for that tuple, - # we only need to create the test database once. - item = test_databases.setdefault( - connection.creation.test_db_signature(), - (connection.settings_dict['NAME'], set()) - ) - item[1].add(alias) - - if 'TEST_DEPENDENCIES' in connection.settings_dict: - dependencies[alias] = ( - connection.settings_dict['TEST_DEPENDENCIES']) - else: - if alias != DEFAULT_DB_ALIAS and connection.creation.test_db_signature() != default_sig: - dependencies[alias] = connection.settings_dict.get( - 'TEST_DEPENDENCIES', [DEFAULT_DB_ALIAS]) - - # Second pass -- actually create the databases. - old_names = [] - mirrors = [] - - for signature, (db_name, aliases) in dependency_ordered( - test_databases.items(), dependencies): - test_db_name = None - # Actually create the database for the first connection - for alias in aliases: - connection = connections[alias] - if test_db_name is None: - test_db_name = connection.creation.create_test_db( - verbosity, autoclobber=not interactive) - destroy = True - else: - connection.settings_dict['NAME'] = test_db_name - destroy = False - old_names.append((connection, db_name, destroy)) - - for alias, mirror_alias in mirrored_aliases.items(): - mirrors.append((alias, connections[alias].settings_dict['NAME'])) - connections[alias].settings_dict['NAME'] = ( - connections[mirror_alias].settings_dict['NAME']) - - return old_names, mirrors diff --git a/lib/python2.7/site-packages/django/test/signals.py b/lib/python2.7/site-packages/django/test/signals.py deleted file mode 100644 index a96bdff..0000000 --- a/lib/python2.7/site-packages/django/test/signals.py +++ /dev/null @@ -1,81 +0,0 @@ -import os -import time - -from django.conf import settings -from django.db import connections -from django.dispatch import receiver, Signal -from django.utils import timezone -from django.utils.functional import empty - -template_rendered = Signal(providing_args=["template", "context"]) - -setting_changed = Signal(providing_args=["setting", "value"]) - -# Most setting_changed receivers are supposed to be added below, -# except for cases where the receiver is related to a contrib app. - - -@receiver(setting_changed) -def update_connections_time_zone(**kwargs): - if kwargs['setting'] == 'TIME_ZONE': - # Reset process time zone - if hasattr(time, 'tzset'): - if kwargs['value']: - os.environ['TZ'] = kwargs['value'] - else: - os.environ.pop('TZ', None) - time.tzset() - - # Reset local time zone cache - timezone._localtime = None - - # Reset the database connections' time zone - if kwargs['setting'] == 'USE_TZ' and settings.TIME_ZONE != 'UTC': - USE_TZ, TIME_ZONE = kwargs['value'], settings.TIME_ZONE - elif kwargs['setting'] == 'TIME_ZONE' and not settings.USE_TZ: - USE_TZ, TIME_ZONE = settings.USE_TZ, kwargs['value'] - else: - # no need to change the database connnections' time zones - return - tz = 'UTC' if USE_TZ else TIME_ZONE - for conn in connections.all(): - conn.settings_dict['TIME_ZONE'] = tz - tz_sql = conn.ops.set_time_zone_sql() - if tz_sql: - conn.cursor().execute(tz_sql, [tz]) - - -@receiver(setting_changed) -def clear_context_processors_cache(**kwargs): - if kwargs['setting'] == 'TEMPLATE_CONTEXT_PROCESSORS': - from django.template import context - context._standard_context_processors = None - - -@receiver(setting_changed) -def clear_template_loaders_cache(**kwargs): - if kwargs['setting'] == 'TEMPLATE_LOADERS': - from django.template import loader - loader.template_source_loaders = None - - -@receiver(setting_changed) -def clear_serializers_cache(**kwargs): - if kwargs['setting'] == 'SERIALIZATION_MODULES': - from django.core import serializers - serializers._serializers = {} - - -@receiver(setting_changed) -def language_changed(**kwargs): - if kwargs['setting'] in ('LOCALE_PATHS', 'LANGUAGE_CODE'): - from django.utils.translation import trans_real - trans_real._default = None - if kwargs['setting'] == 'LOCALE_PATHS': - trans_real._translations = {} - -@receiver(setting_changed) -def file_storage_changed(**kwargs): - if kwargs['setting'] in ('MEDIA_ROOT', 'DEFAULT_FILE_STORAGE'): - from django.core.files.storage import default_storage - default_storage._wrapped = empty diff --git a/lib/python2.7/site-packages/django/test/simple.py b/lib/python2.7/site-packages/django/test/simple.py deleted file mode 100644 index f28b8a2..0000000 --- a/lib/python2.7/site-packages/django/test/simple.py +++ /dev/null @@ -1,253 +0,0 @@ -""" -This module is pending deprecation as of Django 1.6 and will be removed in -version 1.8. - -""" -import json -import re -import unittest as real_unittest -import warnings - -from django.db.models import get_app, get_apps -from django.test import _doctest as doctest -from django.test import runner -from django.test.utils import compare_xml, strip_quotes -from django.utils import unittest -from django.utils.importlib import import_module -from django.utils.module_loading import module_has_submodule - -__all__ = ('DjangoTestSuiteRunner',) - -warnings.warn( - "The django.test.simple module and DjangoTestSuiteRunner are deprecated; " - "use django.test.runner.DiscoverRunner instead.", - PendingDeprecationWarning) - -# The module name for tests outside models.py -TEST_MODULE = 'tests' - - -normalize_long_ints = lambda s: re.sub(r'(?<![\w])(\d+)L(?![\w])', '\\1', s) -normalize_decimals = lambda s: re.sub(r"Decimal\('(\d+(\.\d*)?)'\)", - lambda m: "Decimal(\"%s\")" % m.groups()[0], s) - - -class OutputChecker(doctest.OutputChecker): - def check_output(self, want, got, optionflags): - """ - The entry method for doctest output checking. Defers to a sequence of - child checkers - """ - checks = (self.check_output_default, - self.check_output_numeric, - self.check_output_xml, - self.check_output_json) - for check in checks: - if check(want, got, optionflags): - return True - return False - - def check_output_default(self, want, got, optionflags): - """ - The default comparator provided by doctest - not perfect, but good for - most purposes - """ - return doctest.OutputChecker.check_output(self, want, got, optionflags) - - def check_output_numeric(self, want, got, optionflags): - """Doctest does an exact string comparison of output, which means that - some numerically equivalent values aren't equal. This check normalizes - * long integers (22L) so that they equal normal integers. (22) - * Decimals so that they are comparable, regardless of the change - made to __repr__ in Python 2.6. - """ - return doctest.OutputChecker.check_output(self, - normalize_decimals(normalize_long_ints(want)), - normalize_decimals(normalize_long_ints(got)), - optionflags) - - def check_output_xml(self, want, got, optionsflags): - try: - return compare_xml(want, got) - except Exception: - return False - - def check_output_json(self, want, got, optionsflags): - """ - Tries to compare want and got as if they were JSON-encoded data - """ - want, got = strip_quotes(want, got) - try: - want_json = json.loads(want) - got_json = json.loads(got) - except Exception: - return False - return want_json == got_json - - -class DocTestRunner(doctest.DocTestRunner): - def __init__(self, *args, **kwargs): - doctest.DocTestRunner.__init__(self, *args, **kwargs) - self.optionflags = doctest.ELLIPSIS - - -doctestOutputChecker = OutputChecker() - - -def get_tests(app_module): - parts = app_module.__name__.split('.') - prefix, last = parts[:-1], parts[-1] - try: - test_module = import_module('.'.join(prefix + [TEST_MODULE])) - except ImportError: - # Couldn't import tests.py. Was it due to a missing file, or - # due to an import error in a tests.py that actually exists? - # app_module either points to a models.py file, or models/__init__.py - # Tests are therefore either in same directory, or one level up - if last == 'models': - app_root = import_module('.'.join(prefix)) - else: - app_root = app_module - - if not module_has_submodule(app_root, TEST_MODULE): - test_module = None - else: - # The module exists, so there must be an import error in the test - # module itself. - raise - return test_module - - -def make_doctest(module): - return doctest.DocTestSuite(module, - checker=doctestOutputChecker, - runner=DocTestRunner, - ) - - -def build_suite(app_module): - """ - Create a complete Django test suite for the provided application module. - """ - suite = unittest.TestSuite() - - # Load unit and doctests in the models.py module. If module has - # a suite() method, use it. Otherwise build the test suite ourselves. - if hasattr(app_module, 'suite'): - suite.addTest(app_module.suite()) - else: - suite.addTest(unittest.defaultTestLoader.loadTestsFromModule( - app_module)) - try: - suite.addTest(make_doctest(app_module)) - except ValueError: - # No doc tests in models.py - pass - - # Check to see if a separate 'tests' module exists parallel to the - # models module - test_module = get_tests(app_module) - if test_module: - # Load unit and doctests in the tests.py module. If module has - # a suite() method, use it. Otherwise build the test suite ourselves. - if hasattr(test_module, 'suite'): - suite.addTest(test_module.suite()) - else: - suite.addTest(unittest.defaultTestLoader.loadTestsFromModule( - test_module)) - try: - suite.addTest(make_doctest(test_module)) - except ValueError: - # No doc tests in tests.py - pass - return suite - - -def build_test(label): - """ - Construct a test case with the specified label. Label should be of the - form model.TestClass or model.TestClass.test_method. Returns an - instantiated test or test suite corresponding to the label provided. - - """ - parts = label.split('.') - if len(parts) < 2 or len(parts) > 3: - raise ValueError("Test label '%s' should be of the form app.TestCase " - "or app.TestCase.test_method" % label) - - # - # First, look for TestCase instances with a name that matches - # - app_module = get_app(parts[0]) - test_module = get_tests(app_module) - TestClass = getattr(app_module, parts[1], None) - - # Couldn't find the test class in models.py; look in tests.py - if TestClass is None: - if test_module: - TestClass = getattr(test_module, parts[1], None) - - try: - if issubclass(TestClass, (unittest.TestCase, real_unittest.TestCase)): - if len(parts) == 2: # label is app.TestClass - try: - return unittest.TestLoader().loadTestsFromTestCase( - TestClass) - except TypeError: - raise ValueError( - "Test label '%s' does not refer to a test class" - % label) - else: # label is app.TestClass.test_method - return TestClass(parts[2]) - except TypeError: - # TestClass isn't a TestClass - it must be a method or normal class - pass - - # - # If there isn't a TestCase, look for a doctest that matches - # - tests = [] - for module in app_module, test_module: - try: - doctests = make_doctest(module) - # Now iterate over the suite, looking for doctests whose name - # matches the pattern that was given - for test in doctests: - if test._dt_test.name in ( - '%s.%s' % (module.__name__, '.'.join(parts[1:])), - '%s.__test__.%s' % ( - module.__name__, '.'.join(parts[1:]))): - tests.append(test) - except ValueError: - # No doctests found. - pass - - # If no tests were found, then we were given a bad test label. - if not tests: - raise ValueError("Test label '%s' does not refer to a test" % label) - - # Construct a suite out of the tests that matched. - return unittest.TestSuite(tests) - - -class DjangoTestSuiteRunner(runner.DiscoverRunner): - - def build_suite(self, test_labels, extra_tests=None, **kwargs): - suite = unittest.TestSuite() - - if test_labels: - for label in test_labels: - if '.' in label: - suite.addTest(build_test(label)) - else: - app = get_app(label) - suite.addTest(build_suite(app)) - else: - for app in get_apps(): - suite.addTest(build_suite(app)) - - if extra_tests: - for test in extra_tests: - suite.addTest(test) - - return runner.reorder_suite(suite, (unittest.TestCase,)) diff --git a/lib/python2.7/site-packages/django/test/testcases.py b/lib/python2.7/site-packages/django/test/testcases.py deleted file mode 100644 index 85ff66a..0000000 --- a/lib/python2.7/site-packages/django/test/testcases.py +++ /dev/null @@ -1,1208 +0,0 @@ -from __future__ import unicode_literals - -from copy import copy -import difflib -import errno -from functools import wraps -import json -import os -import re -import socket -import sys -import select -import socket -import threading -import warnings - -from django.conf import settings -from django.contrib.staticfiles.handlers import StaticFilesHandler -from django.core import mail -from django.core.exceptions import ValidationError, ImproperlyConfigured -from django.core.handlers.wsgi import WSGIHandler -from django.core.management import call_command -from django.core.management.color import no_style -from django.core.management.commands import flush -from django.core.servers.basehttp import WSGIRequestHandler, WSGIServer -from django.core.urlresolvers import clear_url_caches, set_urlconf -from django.db import connection, connections, DEFAULT_DB_ALIAS, transaction -from django.db.models.loading import cache -from django.forms.fields import CharField -from django.http import QueryDict -from django.test.client import Client -from django.test.html import HTMLParseError, parse_html -from django.test.signals import template_rendered -from django.test.utils import (CaptureQueriesContext, ContextList, - override_settings, compare_xml) -from django.utils import six, unittest as ut2 -from django.utils.encoding import force_text -from django.utils.six.moves.urllib.parse import urlsplit, urlunsplit -from django.utils.unittest import skipIf # Imported here for backward compatibility -from django.utils.unittest.util import safe_repr -from django.views.static import serve - - -__all__ = ('TestCase', 'TransactionTestCase', - 'SimpleTestCase', 'skipIfDBFeature', 'skipUnlessDBFeature') - - -def to_list(value): - """ - Puts value into a list if it's not already one. - Returns an empty list if value is None. - """ - if value is None: - value = [] - elif not isinstance(value, list): - value = [value] - return value - -real_commit = transaction.commit -real_rollback = transaction.rollback -real_enter_transaction_management = transaction.enter_transaction_management -real_leave_transaction_management = transaction.leave_transaction_management -real_abort = transaction.abort - -def nop(*args, **kwargs): - return - -def disable_transaction_methods(): - transaction.commit = nop - transaction.rollback = nop - transaction.enter_transaction_management = nop - transaction.leave_transaction_management = nop - transaction.abort = nop - -def restore_transaction_methods(): - transaction.commit = real_commit - transaction.rollback = real_rollback - transaction.enter_transaction_management = real_enter_transaction_management - transaction.leave_transaction_management = real_leave_transaction_management - transaction.abort = real_abort - - -def assert_and_parse_html(self, html, user_msg, msg): - try: - dom = parse_html(html) - except HTMLParseError as e: - standardMsg = '%s\n%s' % (msg, e.msg) - self.fail(self._formatMessage(user_msg, standardMsg)) - return dom - - -class _AssertNumQueriesContext(CaptureQueriesContext): - def __init__(self, test_case, num, connection): - self.test_case = test_case - self.num = num - super(_AssertNumQueriesContext, self).__init__(connection) - - def __exit__(self, exc_type, exc_value, traceback): - super(_AssertNumQueriesContext, self).__exit__(exc_type, exc_value, traceback) - if exc_type is not None: - return - executed = len(self) - self.test_case.assertEqual( - executed, self.num, "%d queries executed, %d expected" % ( - executed, self.num - ) - ) - - -class _AssertTemplateUsedContext(object): - def __init__(self, test_case, template_name): - self.test_case = test_case - self.template_name = template_name - self.rendered_templates = [] - self.rendered_template_names = [] - self.context = ContextList() - - def on_template_render(self, sender, signal, template, context, **kwargs): - self.rendered_templates.append(template) - self.rendered_template_names.append(template.name) - self.context.append(copy(context)) - - def test(self): - return self.template_name in self.rendered_template_names - - def message(self): - return '%s was not rendered.' % self.template_name - - def __enter__(self): - template_rendered.connect(self.on_template_render) - return self - - def __exit__(self, exc_type, exc_value, traceback): - template_rendered.disconnect(self.on_template_render) - if exc_type is not None: - return - - if not self.test(): - message = self.message() - if len(self.rendered_templates) == 0: - message += ' No template was rendered.' - else: - message += ' Following templates were rendered: %s' % ( - ', '.join(self.rendered_template_names)) - self.test_case.fail(message) - - -class _AssertTemplateNotUsedContext(_AssertTemplateUsedContext): - def test(self): - return self.template_name not in self.rendered_template_names - - def message(self): - return '%s was rendered.' % self.template_name - - -class SimpleTestCase(ut2.TestCase): - - # The class we'll use for the test client self.client. - # Can be overridden in derived classes. - client_class = Client - - _warn_txt = ("save_warnings_state/restore_warnings_state " - "django.test.*TestCase methods are deprecated. Use Python's " - "warnings.catch_warnings context manager instead.") - - def __call__(self, result=None): - """ - Wrapper around default __call__ method to perform common Django test - set up. This means that user-defined Test Cases aren't required to - include a call to super().setUp(). - """ - testMethod = getattr(self, self._testMethodName) - skipped = (getattr(self.__class__, "__unittest_skip__", False) or - getattr(testMethod, "__unittest_skip__", False)) - - if not skipped: - try: - self._pre_setup() - except (KeyboardInterrupt, SystemExit): - raise - except Exception: - result.addError(self, sys.exc_info()) - return - super(SimpleTestCase, self).__call__(result) - if not skipped: - try: - self._post_teardown() - except (KeyboardInterrupt, SystemExit): - raise - except Exception: - result.addError(self, sys.exc_info()) - return - - def _pre_setup(self): - """Performs any pre-test setup. This includes: - - * Creating a test client. - * If the class has a 'urls' attribute, replace ROOT_URLCONF with it. - * Clearing the mail test outbox. - """ - self.client = self.client_class() - self._urlconf_setup() - mail.outbox = [] - - def _urlconf_setup(self): - set_urlconf(None) - if hasattr(self, 'urls'): - self._old_root_urlconf = settings.ROOT_URLCONF - settings.ROOT_URLCONF = self.urls - clear_url_caches() - - def _post_teardown(self): - """Performs any post-test things. This includes: - - * Putting back the original ROOT_URLCONF if it was changed. - """ - self._urlconf_teardown() - - def _urlconf_teardown(self): - set_urlconf(None) - if hasattr(self, '_old_root_urlconf'): - settings.ROOT_URLCONF = self._old_root_urlconf - clear_url_caches() - - def save_warnings_state(self): - """ - Saves the state of the warnings module - """ - warnings.warn(self._warn_txt, DeprecationWarning, stacklevel=2) - self._warnings_state = warnings.filters[:] - - def restore_warnings_state(self): - """ - Restores the state of the warnings module to the state - saved by save_warnings_state() - """ - warnings.warn(self._warn_txt, DeprecationWarning, stacklevel=2) - warnings.filters = self._warnings_state[:] - - def settings(self, **kwargs): - """ - A context manager that temporarily sets a setting and reverts - back to the original value when exiting the context. - """ - return override_settings(**kwargs) - - def assertRedirects(self, response, expected_url, status_code=302, - target_status_code=200, host=None, msg_prefix=''): - """Asserts that a response redirected to a specific URL, and that the - redirect URL can be loaded. - - Note that assertRedirects won't work for external links since it uses - TestClient to do a request. - """ - if msg_prefix: - msg_prefix += ": " - - if hasattr(response, 'redirect_chain'): - # The request was a followed redirect - self.assertTrue(len(response.redirect_chain) > 0, - msg_prefix + "Response didn't redirect as expected: Response" - " code was %d (expected %d)" % - (response.status_code, status_code)) - - self.assertEqual(response.redirect_chain[0][1], status_code, - msg_prefix + "Initial response didn't redirect as expected:" - " Response code was %d (expected %d)" % - (response.redirect_chain[0][1], status_code)) - - url, status_code = response.redirect_chain[-1] - - self.assertEqual(response.status_code, target_status_code, - msg_prefix + "Response didn't redirect as expected: Final" - " Response code was %d (expected %d)" % - (response.status_code, target_status_code)) - - else: - # Not a followed redirect - self.assertEqual(response.status_code, status_code, - msg_prefix + "Response didn't redirect as expected: Response" - " code was %d (expected %d)" % - (response.status_code, status_code)) - - url = response.url - scheme, netloc, path, query, fragment = urlsplit(url) - - redirect_response = response.client.get(path, QueryDict(query)) - - # Get the redirection page, using the same client that was used - # to obtain the original response. - self.assertEqual(redirect_response.status_code, target_status_code, - msg_prefix + "Couldn't retrieve redirection page '%s':" - " response code was %d (expected %d)" % - (path, redirect_response.status_code, target_status_code)) - - e_scheme, e_netloc, e_path, e_query, e_fragment = urlsplit( - expected_url) - if not (e_scheme or e_netloc): - expected_url = urlunsplit(('http', host or 'testserver', e_path, - e_query, e_fragment)) - - self.assertEqual(url, expected_url, - msg_prefix + "Response redirected to '%s', expected '%s'" % - (url, expected_url)) - - def assertContains(self, response, text, count=None, status_code=200, - msg_prefix='', html=False): - """ - Asserts that a response indicates that some content was retrieved - successfully, (i.e., the HTTP status code was as expected), and that - ``text`` occurs ``count`` times in the content of the response. - If ``count`` is None, the count doesn't matter - the assertion is true - if the text occurs at least once in the response. - """ - - # If the response supports deferred rendering and hasn't been rendered - # yet, then ensure that it does get rendered before proceeding further. - if (hasattr(response, 'render') and callable(response.render) - and not response.is_rendered): - response.render() - - if msg_prefix: - msg_prefix += ": " - - self.assertEqual(response.status_code, status_code, - msg_prefix + "Couldn't retrieve content: Response code was %d" - " (expected %d)" % (response.status_code, status_code)) - - if response.streaming: - content = b''.join(response.streaming_content) - else: - content = response.content - if not isinstance(text, bytes) or html: - text = force_text(text, encoding=response._charset) - content = content.decode(response._charset) - text_repr = "'%s'" % text - else: - text_repr = repr(text) - if html: - content = assert_and_parse_html(self, content, None, - "Response's content is not valid HTML:") - text = assert_and_parse_html(self, text, None, - "Second argument is not valid HTML:") - real_count = content.count(text) - if count is not None: - self.assertEqual(real_count, count, - msg_prefix + "Found %d instances of %s in response" - " (expected %d)" % (real_count, text_repr, count)) - else: - self.assertTrue(real_count != 0, - msg_prefix + "Couldn't find %s in response" % text_repr) - - def assertNotContains(self, response, text, status_code=200, - msg_prefix='', html=False): - """ - Asserts that a response indicates that some content was retrieved - successfully, (i.e., the HTTP status code was as expected), and that - ``text`` doesn't occurs in the content of the response. - """ - - # If the response supports deferred rendering and hasn't been rendered - # yet, then ensure that it does get rendered before proceeding further. - if (hasattr(response, 'render') and callable(response.render) - and not response.is_rendered): - response.render() - - if msg_prefix: - msg_prefix += ": " - - self.assertEqual(response.status_code, status_code, - msg_prefix + "Couldn't retrieve content: Response code was %d" - " (expected %d)" % (response.status_code, status_code)) - - content = response.content - if not isinstance(text, bytes) or html: - text = force_text(text, encoding=response._charset) - content = content.decode(response._charset) - text_repr = "'%s'" % text - else: - text_repr = repr(text) - if html: - content = assert_and_parse_html(self, content, None, - 'Response\'s content is not valid HTML:') - text = assert_and_parse_html(self, text, None, - 'Second argument is not valid HTML:') - self.assertEqual(content.count(text), 0, - msg_prefix + "Response should not contain %s" % text_repr) - - def assertFormError(self, response, form, field, errors, msg_prefix=''): - """ - Asserts that a form used to render the response has a specific field - error. - """ - if msg_prefix: - msg_prefix += ": " - - # Put context(s) into a list to simplify processing. - contexts = to_list(response.context) - if not contexts: - self.fail(msg_prefix + "Response did not use any contexts to " - "render the response") - - # Put error(s) into a list to simplify processing. - errors = to_list(errors) - - # Search all contexts for the error. - found_form = False - for i,context in enumerate(contexts): - if form not in context: - continue - found_form = True - for err in errors: - if field: - if field in context[form].errors: - field_errors = context[form].errors[field] - self.assertTrue(err in field_errors, - msg_prefix + "The field '%s' on form '%s' in" - " context %d does not contain the error '%s'" - " (actual errors: %s)" % - (field, form, i, err, repr(field_errors))) - elif field in context[form].fields: - self.fail(msg_prefix + "The field '%s' on form '%s'" - " in context %d contains no errors" % - (field, form, i)) - else: - self.fail(msg_prefix + "The form '%s' in context %d" - " does not contain the field '%s'" % - (form, i, field)) - else: - non_field_errors = context[form].non_field_errors() - self.assertTrue(err in non_field_errors, - msg_prefix + "The form '%s' in context %d does not" - " contain the non-field error '%s'" - " (actual errors: %s)" % - (form, i, err, non_field_errors)) - if not found_form: - self.fail(msg_prefix + "The form '%s' was not used to render the" - " response" % form) - - def assertFormsetError(self, response, formset, form_index, field, errors, - msg_prefix=''): - """ - Asserts that a formset used to render the response has a specific error. - - For field errors, specify the ``form_index`` and the ``field``. - For non-field errors, specify the ``form_index`` and the ``field`` as - None. - For non-form errors, specify ``form_index`` as None and the ``field`` - as None. - """ - # Add punctuation to msg_prefix - if msg_prefix: - msg_prefix += ": " - - # Put context(s) into a list to simplify processing. - contexts = to_list(response.context) - if not contexts: - self.fail(msg_prefix + 'Response did not use any contexts to ' - 'render the response') - - # Put error(s) into a list to simplify processing. - errors = to_list(errors) - - # Search all contexts for the error. - found_formset = False - for i, context in enumerate(contexts): - if formset not in context: - continue - found_formset = True - for err in errors: - if field is not None: - if field in context[formset].forms[form_index].errors: - field_errors = context[formset].forms[form_index].errors[field] - self.assertTrue(err in field_errors, - msg_prefix + "The field '%s' on formset '%s', " - "form %d in context %d does not contain the " - "error '%s' (actual errors: %s)" % - (field, formset, form_index, i, err, - repr(field_errors))) - elif field in context[formset].forms[form_index].fields: - self.fail(msg_prefix + "The field '%s' " - "on formset '%s', form %d in " - "context %d contains no errors" % - (field, formset, form_index, i)) - else: - self.fail(msg_prefix + "The formset '%s', form %d in " - "context %d does not contain the field '%s'" % - (formset, form_index, i, field)) - elif form_index is not None: - non_field_errors = context[formset].forms[form_index].non_field_errors() - self.assertFalse(len(non_field_errors) == 0, - msg_prefix + "The formset '%s', form %d in " - "context %d does not contain any non-field " - "errors." % (formset, form_index, i)) - self.assertTrue(err in non_field_errors, - msg_prefix + "The formset '%s', form %d " - "in context %d does not contain the " - "non-field error '%s' " - "(actual errors: %s)" % - (formset, form_index, i, err, - repr(non_field_errors))) - else: - non_form_errors = context[formset].non_form_errors() - self.assertFalse(len(non_form_errors) == 0, - msg_prefix + "The formset '%s' in " - "context %d does not contain any " - "non-form errors." % (formset, i)) - self.assertTrue(err in non_form_errors, - msg_prefix + "The formset '%s' in context " - "%d does not contain the " - "non-form error '%s' (actual errors: %s)" % - (formset, i, err, repr(non_form_errors))) - if not found_formset: - self.fail(msg_prefix + "The formset '%s' was not used to render " - "the response" % formset) - - def assertTemplateUsed(self, response=None, template_name=None, msg_prefix=''): - """ - Asserts that the template with the provided name was used in rendering - the response. Also usable as context manager. - """ - if response is None and template_name is None: - raise TypeError('response and/or template_name argument must be provided') - - if msg_prefix: - msg_prefix += ": " - - # Use assertTemplateUsed as context manager. - if not hasattr(response, 'templates') or (response is None and template_name): - if response: - template_name = response - response = None - context = _AssertTemplateUsedContext(self, template_name) - return context - - template_names = [t.name for t in response.templates] - if not template_names: - self.fail(msg_prefix + "No templates used to render the response") - self.assertTrue(template_name in template_names, - msg_prefix + "Template '%s' was not a template used to render" - " the response. Actual template(s) used: %s" % - (template_name, ', '.join(template_names))) - - def assertTemplateNotUsed(self, response=None, template_name=None, msg_prefix=''): - """ - Asserts that the template with the provided name was NOT used in - rendering the response. Also usable as context manager. - """ - if response is None and template_name is None: - raise TypeError('response and/or template_name argument must be provided') - - if msg_prefix: - msg_prefix += ": " - - # Use assertTemplateUsed as context manager. - if not hasattr(response, 'templates') or (response is None and template_name): - if response: - template_name = response - response = None - context = _AssertTemplateNotUsedContext(self, template_name) - return context - - template_names = [t.name for t in response.templates] - self.assertFalse(template_name in template_names, - msg_prefix + "Template '%s' was used unexpectedly in rendering" - " the response" % template_name) - - def assertRaisesMessage(self, expected_exception, expected_message, - callable_obj=None, *args, **kwargs): - """ - Asserts that the message in a raised exception matches the passed - value. - - Args: - expected_exception: Exception class expected to be raised. - expected_message: expected error message string value. - callable_obj: Function to be called. - args: Extra args. - kwargs: Extra kwargs. - """ - return six.assertRaisesRegex(self, expected_exception, - re.escape(expected_message), callable_obj, *args, **kwargs) - - def assertFieldOutput(self, fieldclass, valid, invalid, field_args=None, - field_kwargs=None, empty_value=''): - """ - Asserts that a form field behaves correctly with various inputs. - - Args: - fieldclass: the class of the field to be tested. - valid: a dictionary mapping valid inputs to their expected - cleaned values. - invalid: a dictionary mapping invalid inputs to one or more - raised error messages. - field_args: the args passed to instantiate the field - field_kwargs: the kwargs passed to instantiate the field - empty_value: the expected clean output for inputs in empty_values - - """ - if field_args is None: - field_args = [] - if field_kwargs is None: - field_kwargs = {} - required = fieldclass(*field_args, **field_kwargs) - optional = fieldclass(*field_args, - **dict(field_kwargs, required=False)) - # test valid inputs - for input, output in valid.items(): - self.assertEqual(required.clean(input), output) - self.assertEqual(optional.clean(input), output) - # test invalid inputs - for input, errors in invalid.items(): - with self.assertRaises(ValidationError) as context_manager: - required.clean(input) - self.assertEqual(context_manager.exception.messages, errors) - - with self.assertRaises(ValidationError) as context_manager: - optional.clean(input) - self.assertEqual(context_manager.exception.messages, errors) - # test required inputs - error_required = [force_text(required.error_messages['required'])] - for e in required.empty_values: - with self.assertRaises(ValidationError) as context_manager: - required.clean(e) - self.assertEqual(context_manager.exception.messages, - error_required) - self.assertEqual(optional.clean(e), empty_value) - # test that max_length and min_length are always accepted - if issubclass(fieldclass, CharField): - field_kwargs.update({'min_length':2, 'max_length':20}) - self.assertTrue(isinstance(fieldclass(*field_args, **field_kwargs), - fieldclass)) - - def assertHTMLEqual(self, html1, html2, msg=None): - """ - Asserts that two HTML snippets are semantically the same. - Whitespace in most cases is ignored, and attribute ordering is not - significant. The passed-in arguments must be valid HTML. - """ - dom1 = assert_and_parse_html(self, html1, msg, - 'First argument is not valid HTML:') - dom2 = assert_and_parse_html(self, html2, msg, - 'Second argument is not valid HTML:') - - if dom1 != dom2: - standardMsg = '%s != %s' % ( - safe_repr(dom1, True), safe_repr(dom2, True)) - diff = ('\n' + '\n'.join(difflib.ndiff( - six.text_type(dom1).splitlines(), - six.text_type(dom2).splitlines()))) - standardMsg = self._truncateMessage(standardMsg, diff) - self.fail(self._formatMessage(msg, standardMsg)) - - def assertHTMLNotEqual(self, html1, html2, msg=None): - """Asserts that two HTML snippets are not semantically equivalent.""" - dom1 = assert_and_parse_html(self, html1, msg, - 'First argument is not valid HTML:') - dom2 = assert_and_parse_html(self, html2, msg, - 'Second argument is not valid HTML:') - - if dom1 == dom2: - standardMsg = '%s == %s' % ( - safe_repr(dom1, True), safe_repr(dom2, True)) - self.fail(self._formatMessage(msg, standardMsg)) - - def assertInHTML(self, needle, haystack, count=None, msg_prefix=''): - needle = assert_and_parse_html(self, needle, None, - 'First argument is not valid HTML:') - haystack = assert_and_parse_html(self, haystack, None, - 'Second argument is not valid HTML:') - real_count = haystack.count(needle) - if count is not None: - self.assertEqual(real_count, count, - msg_prefix + "Found %d instances of '%s' in response" - " (expected %d)" % (real_count, needle, count)) - else: - self.assertTrue(real_count != 0, - msg_prefix + "Couldn't find '%s' in response" % needle) - - def assertJSONEqual(self, raw, expected_data, msg=None): - try: - data = json.loads(raw) - except ValueError: - self.fail("First argument is not valid JSON: %r" % raw) - if isinstance(expected_data, six.string_types): - try: - expected_data = json.loads(expected_data) - except ValueError: - self.fail("Second argument is not valid JSON: %r" % expected_data) - self.assertEqual(data, expected_data, msg=msg) - - def assertXMLEqual(self, xml1, xml2, msg=None): - """ - Asserts that two XML snippets are semantically the same. - Whitespace in most cases is ignored, and attribute ordering is not - significant. The passed-in arguments must be valid XML. - """ - try: - result = compare_xml(xml1, xml2) - except Exception as e: - standardMsg = 'First or second argument is not valid XML\n%s' % e - self.fail(self._formatMessage(msg, standardMsg)) - else: - if not result: - standardMsg = '%s != %s' % (safe_repr(xml1, True), safe_repr(xml2, True)) - self.fail(self._formatMessage(msg, standardMsg)) - - def assertXMLNotEqual(self, xml1, xml2, msg=None): - """ - Asserts that two XML snippets are not semantically equivalent. - Whitespace in most cases is ignored, and attribute ordering is not - significant. The passed-in arguments must be valid XML. - """ - try: - result = compare_xml(xml1, xml2) - except Exception as e: - standardMsg = 'First or second argument is not valid XML\n%s' % e - self.fail(self._formatMessage(msg, standardMsg)) - else: - if result: - standardMsg = '%s == %s' % (safe_repr(xml1, True), safe_repr(xml2, True)) - self.fail(self._formatMessage(msg, standardMsg)) - - -class TransactionTestCase(SimpleTestCase): - - # Subclasses can ask for resetting of auto increment sequence before each - # test case - reset_sequences = False - - # Subclasses can enable only a subset of apps for faster tests - available_apps = None - - def _pre_setup(self): - """Performs any pre-test setup. This includes: - - * If the class has an 'available_apps' attribute, restricting the app - cache to these applications, then firing post_syncdb -- it must run - with the correct set of applications for the test case. - * If the class has a 'fixtures' attribute, installing these fixtures. - """ - super(TransactionTestCase, self)._pre_setup() - if self.available_apps is not None: - cache.set_available_apps(self.available_apps) - for db_name in self._databases_names(include_mirrors=False): - flush.Command.emit_post_syncdb( - verbosity=0, interactive=False, database=db_name) - try: - self._fixture_setup() - except Exception: - if self.available_apps is not None: - cache.unset_available_apps() - raise - - def _databases_names(self, include_mirrors=True): - # If the test case has a multi_db=True flag, act on all databases, - # including mirrors or not. Otherwise, just on the default DB. - if getattr(self, 'multi_db', False): - return [alias for alias in connections - if include_mirrors or not connections[alias].settings_dict['TEST_MIRROR']] - else: - return [DEFAULT_DB_ALIAS] - - def _reset_sequences(self, db_name): - conn = connections[db_name] - if conn.features.supports_sequence_reset: - sql_list = \ - conn.ops.sequence_reset_by_name_sql(no_style(), - conn.introspection.sequence_list()) - if sql_list: - with transaction.commit_on_success_unless_managed(using=db_name): - cursor = conn.cursor() - for sql in sql_list: - cursor.execute(sql) - - def _fixture_setup(self): - for db_name in self._databases_names(include_mirrors=False): - # Reset sequences - if self.reset_sequences: - self._reset_sequences(db_name) - - if hasattr(self, 'fixtures'): - # We have to use this slightly awkward syntax due to the fact - # that we're using *args and **kwargs together. - call_command('loaddata', *self.fixtures, - **{'verbosity': 0, 'database': db_name, 'skip_validation': True}) - - def _post_teardown(self): - """Performs any post-test things. This includes: - - * Flushing the contents of the database, to leave a clean slate. If - the class has an 'available_apps' attribute, post_syncdb isn't fired. - * Force-closing the connection, so the next test gets a clean cursor. - """ - try: - self._fixture_teardown() - super(TransactionTestCase, self)._post_teardown() - # Some DB cursors include SQL statements as part of cursor - # creation. If you have a test that does rollback, the effect of - # these statements is lost, which can effect the operation of - # tests (e.g., losing a timezone setting causing objects to be - # created with the wrong time). To make sure this doesn't happen, - # get a clean connection at the start of every test. - for conn in connections.all(): - conn.close() - finally: - cache.unset_available_apps() - - def _fixture_teardown(self): - # Allow TRUNCATE ... CASCADE and don't emit the post_syncdb signal - # when flushing only a subset of the apps - for db_name in self._databases_names(include_mirrors=False): - call_command('flush', verbosity=0, interactive=False, - database=db_name, skip_validation=True, - reset_sequences=False, - allow_cascade=self.available_apps is not None, - inhibit_post_syncdb=self.available_apps is not None) - - def assertQuerysetEqual(self, qs, values, transform=repr, ordered=True): - items = six.moves.map(transform, qs) - if not ordered: - return self.assertEqual(set(items), set(values)) - values = list(values) - # For example qs.iterator() could be passed as qs, but it does not - # have 'ordered' attribute. - if len(values) > 1 and hasattr(qs, 'ordered') and not qs.ordered: - raise ValueError("Trying to compare non-ordered queryset " - "against more than one ordered values") - return self.assertEqual(list(items), values) - - def assertNumQueries(self, num, func=None, *args, **kwargs): - using = kwargs.pop("using", DEFAULT_DB_ALIAS) - conn = connections[using] - - context = _AssertNumQueriesContext(self, num, conn) - if func is None: - return context - - with context: - func(*args, **kwargs) - - -def connections_support_transactions(): - """ - Returns True if all connections support transactions. - """ - return all(conn.features.supports_transactions - for conn in connections.all()) - - -class TestCase(TransactionTestCase): - """ - Does basically the same as TransactionTestCase, but surrounds every test - with a transaction, monkey-patches the real transaction management routines - to do nothing, and rollsback the test transaction at the end of the test. - You have to use TransactionTestCase, if you need transaction management - inside a test. - """ - - def _fixture_setup(self): - if not connections_support_transactions(): - return super(TestCase, self)._fixture_setup() - - assert not self.reset_sequences, 'reset_sequences cannot be used on TestCase instances' - - self.atomics = {} - for db_name in self._databases_names(): - self.atomics[db_name] = transaction.atomic(using=db_name) - self.atomics[db_name].__enter__() - # Remove this when the legacy transaction management goes away. - disable_transaction_methods() - - for db_name in self._databases_names(include_mirrors=False): - if hasattr(self, 'fixtures'): - try: - call_command('loaddata', *self.fixtures, - **{ - 'verbosity': 0, - 'commit': False, - 'database': db_name, - 'skip_validation': True, - }) - except Exception: - self._fixture_teardown() - raise - - def _fixture_teardown(self): - if not connections_support_transactions(): - return super(TestCase, self)._fixture_teardown() - - # Remove this when the legacy transaction management goes away. - restore_transaction_methods() - for db_name in reversed(self._databases_names()): - # Hack to force a rollback - connections[db_name].needs_rollback = True - self.atomics[db_name].__exit__(None, None, None) - - -def _deferredSkip(condition, reason): - def decorator(test_func): - if not (isinstance(test_func, type) and - issubclass(test_func, TestCase)): - @wraps(test_func) - def skip_wrapper(*args, **kwargs): - if condition(): - raise ut2.SkipTest(reason) - return test_func(*args, **kwargs) - test_item = skip_wrapper - else: - test_item = test_func - test_item.__unittest_skip_why__ = reason - return test_item - return decorator - - -def skipIfDBFeature(feature): - """ - Skip a test if a database has the named feature - """ - return _deferredSkip(lambda: getattr(connection.features, feature), - "Database has feature %s" % feature) - - -def skipUnlessDBFeature(feature): - """ - Skip a test unless a database has the named feature - """ - return _deferredSkip(lambda: not getattr(connection.features, feature), - "Database doesn't support feature %s" % feature) - - -class QuietWSGIRequestHandler(WSGIRequestHandler): - """ - Just a regular WSGIRequestHandler except it doesn't log to the standard - output any of the requests received, so as to not clutter the output for - the tests' results. - """ - - def log_message(*args): - pass - - -if sys.version_info >= (3, 3, 0): - _ImprovedEvent = threading.Event -elif sys.version_info >= (2, 7, 0): - _ImprovedEvent = threading._Event -else: - class _ImprovedEvent(threading._Event): - """ - Does the same as `threading.Event` except it overrides the wait() method - with some code borrowed from Python 2.7 to return the set state of the - event (see: http://hg.python.org/cpython/rev/b5aa8aa78c0f/). This allows - to know whether the wait() method exited normally or because of the - timeout. This class can be removed when Django supports only Python >= 2.7. - """ - - def wait(self, timeout=None): - self._Event__cond.acquire() - try: - if not self._Event__flag: - self._Event__cond.wait(timeout) - return self._Event__flag - finally: - self._Event__cond.release() - - -class StoppableWSGIServer(WSGIServer): - """ - The code in this class is borrowed from the `SocketServer.BaseServer` class - in Python 2.6. The important functionality here is that the server is non- - blocking and that it can be shut down at any moment. This is made possible - by the server regularly polling the socket and checking if it has been - asked to stop. - Note for the future: Once Django stops supporting Python 2.6, this class - can be removed as `WSGIServer` will have this ability to shutdown on - demand and will not require the use of the _ImprovedEvent class whose code - is borrowed from Python 2.7. - """ - - def __init__(self, *args, **kwargs): - super(StoppableWSGIServer, self).__init__(*args, **kwargs) - self.__is_shut_down = _ImprovedEvent() - self.__serving = False - - def serve_forever(self, poll_interval=0.5): - """ - Handle one request at a time until shutdown. - - Polls for shutdown every poll_interval seconds. - """ - self.__serving = True - self.__is_shut_down.clear() - while self.__serving: - r, w, e = select.select([self], [], [], poll_interval) - if r: - self._handle_request_noblock() - self.__is_shut_down.set() - - def shutdown(self): - """ - Stops the serve_forever loop. - - Blocks until the loop has finished. This must be called while - serve_forever() is running in another thread, or it will - deadlock. - """ - self.__serving = False - if not self.__is_shut_down.wait(2): - raise RuntimeError( - "Failed to shutdown the live test server in 2 seconds. The " - "server might be stuck or generating a slow response.") - - def handle_request(self): - """Handle one request, possibly blocking. - """ - fd_sets = select.select([self], [], [], None) - if not fd_sets[0]: - return - self._handle_request_noblock() - - def _handle_request_noblock(self): - """ - Handle one request, without blocking. - - I assume that select.select has returned that the socket is - readable before this function was called, so there should be - no risk of blocking in get_request(). - """ - try: - request, client_address = self.get_request() - except socket.error: - return - if self.verify_request(request, client_address): - try: - self.process_request(request, client_address) - except Exception: - self.handle_error(request, client_address) - self.close_request(request) - - -class _MediaFilesHandler(StaticFilesHandler): - """ - Handler for serving the media files. This is a private class that is - meant to be used solely as a convenience by LiveServerThread. - """ - - def get_base_dir(self): - return settings.MEDIA_ROOT - - def get_base_url(self): - return settings.MEDIA_URL - - def serve(self, request): - relative_url = request.path[len(self.base_url[2]):] - return serve(request, relative_url, document_root=self.get_base_dir()) - - -class LiveServerThread(threading.Thread): - """ - Thread for running a live http server while the tests are running. - """ - - def __init__(self, host, possible_ports, connections_override=None): - self.host = host - self.port = None - self.possible_ports = possible_ports - self.is_ready = threading.Event() - self.error = None - self.connections_override = connections_override - super(LiveServerThread, self).__init__() - - def run(self): - """ - Sets up the live server and databases, and then loops over handling - http requests. - """ - if self.connections_override: - # Override this thread's database connections with the ones - # provided by the main thread. - for alias, conn in self.connections_override.items(): - connections[alias] = conn - try: - # Create the handler for serving static and media files - handler = StaticFilesHandler(_MediaFilesHandler(WSGIHandler())) - - # Go through the list of possible ports, hoping that we can find - # one that is free to use for the WSGI server. - for index, port in enumerate(self.possible_ports): - try: - self.httpd = StoppableWSGIServer( - (self.host, port), QuietWSGIRequestHandler) - except socket.error as e: - if (index + 1 < len(self.possible_ports) and - e.errno == errno.EADDRINUSE): - # This port is already in use, so we go on and try with - # the next one in the list. - continue - else: - # Either none of the given ports are free or the error - # is something else than "Address already in use". So - # we let that error bubble up to the main thread. - raise - else: - # A free port was found. - self.port = port - break - - self.httpd.set_app(handler) - self.is_ready.set() - self.httpd.serve_forever() - except Exception as e: - self.error = e - self.is_ready.set() - - def join(self, timeout=None): - if hasattr(self, 'httpd'): - # Stop the WSGI server - self.httpd.shutdown() - self.httpd.server_close() - super(LiveServerThread, self).join(timeout) - - -class LiveServerTestCase(TransactionTestCase): - """ - Does basically the same as TransactionTestCase but also launches a live - http server in a separate thread so that the tests may use another testing - framework, such as Selenium for example, instead of the built-in dummy - client. - Note that it inherits from TransactionTestCase instead of TestCase because - the threads do not share the same transactions (unless if using in-memory - sqlite) and each thread needs to commit all their transactions so that the - other thread can see the changes. - """ - - @property - def live_server_url(self): - return 'http://%s:%s' % ( - self.server_thread.host, self.server_thread.port) - - @classmethod - def setUpClass(cls): - connections_override = {} - for conn in connections.all(): - # If using in-memory sqlite databases, pass the connections to - # the server thread. - if (conn.settings_dict['ENGINE'].rsplit('.', 1)[-1] in ('sqlite3', 'spatialite') - and conn.settings_dict['NAME'] == ':memory:'): - # Explicitly enable thread-shareability for this connection - conn.allow_thread_sharing = True - connections_override[conn.alias] = conn - - # Launch the live server's thread - specified_address = os.environ.get( - 'DJANGO_LIVE_TEST_SERVER_ADDRESS', 'localhost:8081') - - # The specified ports may be of the form '8000-8010,8080,9200-9300' - # i.e. a comma-separated list of ports or ranges of ports, so we break - # it down into a detailed list of all possible ports. - possible_ports = [] - try: - host, port_ranges = specified_address.split(':') - for port_range in port_ranges.split(','): - # A port range can be of either form: '8000' or '8000-8010'. - extremes = list(map(int, port_range.split('-'))) - assert len(extremes) in [1, 2] - if len(extremes) == 1: - # Port range of the form '8000' - possible_ports.append(extremes[0]) - else: - # Port range of the form '8000-8010' - for port in range(extremes[0], extremes[1] + 1): - possible_ports.append(port) - except Exception: - msg = 'Invalid address ("%s") for live server.' % specified_address - six.reraise(ImproperlyConfigured, ImproperlyConfigured(msg), sys.exc_info()[2]) - cls.server_thread = LiveServerThread( - host, possible_ports, connections_override) - cls.server_thread.daemon = True - cls.server_thread.start() - - # Wait for the live server to be ready - cls.server_thread.is_ready.wait() - if cls.server_thread.error: - # Clean up behind ourselves, since tearDownClass won't get called in - # case of errors. - cls._tearDownClassInternal() - raise cls.server_thread.error - - super(LiveServerTestCase, cls).setUpClass() - - @classmethod - def _tearDownClassInternal(cls): - # There may not be a 'server_thread' attribute if setUpClass() for some - # reasons has raised an exception. - if hasattr(cls, 'server_thread'): - # Terminate the live server's thread - cls.server_thread.join() - - # Restore sqlite connections' non-sharability - for conn in connections.all(): - if (conn.settings_dict['ENGINE'].rsplit('.', 1)[-1] in ('sqlite3', 'spatialite') - and conn.settings_dict['NAME'] == ':memory:'): - conn.allow_thread_sharing = False - - @classmethod - def tearDownClass(cls): - cls._tearDownClassInternal() - super(LiveServerTestCase, cls).tearDownClass() diff --git a/lib/python2.7/site-packages/django/test/utils.py b/lib/python2.7/site-packages/django/test/utils.py deleted file mode 100644 index 818ccaf..0000000 --- a/lib/python2.7/site-packages/django/test/utils.py +++ /dev/null @@ -1,469 +0,0 @@ -from contextlib import contextmanager -import logging -import re -import sys -from threading import local -import time -import warnings -from functools import wraps -from xml.dom.minidom import parseString, Node - -from django.conf import settings, UserSettingsHolder -from django.core import mail -from django.core.signals import request_started -from django.db import reset_queries -from django.http import request -from django.template import Template, loader, TemplateDoesNotExist -from django.template.loaders import cached -from django.test.signals import template_rendered, setting_changed -from django.utils.encoding import force_str -from django.utils import six -from django.utils.translation import deactivate -from django.utils.unittest import skipUnless - - -__all__ = ( - 'Approximate', 'ContextList', 'get_runner', 'override_settings', - 'requires_tz_support', 'setup_test_environment', 'teardown_test_environment', -) - -RESTORE_LOADERS_ATTR = '_original_template_source_loaders' -TZ_SUPPORT = hasattr(time, 'tzset') - - -class Approximate(object): - def __init__(self, val, places=7): - self.val = val - self.places = places - - def __repr__(self): - return repr(self.val) - - def __eq__(self, other): - if self.val == other: - return True - return round(abs(self.val - other), self.places) == 0 - - -class ContextList(list): - """A wrapper that provides direct key access to context items contained - in a list of context objects. - """ - def __getitem__(self, key): - if isinstance(key, six.string_types): - for subcontext in self: - if key in subcontext: - return subcontext[key] - raise KeyError(key) - else: - return super(ContextList, self).__getitem__(key) - - def __contains__(self, key): - try: - self[key] - except KeyError: - return False - return True - - def keys(self): - """ - Flattened keys of subcontexts. - """ - keys = set() - for subcontext in self: - for dict in subcontext: - keys |= set(dict.keys()) - return keys - - -def instrumented_test_render(self, context): - """ - An instrumented Template render method, providing a signal - that can be intercepted by the test system Client - """ - template_rendered.send(sender=self, template=self, context=context) - return self.nodelist.render(context) - - -def setup_test_environment(): - """Perform any global pre-test setup. This involves: - - - Installing the instrumented test renderer - - Set the email backend to the locmem email backend. - - Setting the active locale to match the LANGUAGE_CODE setting. - """ - Template._original_render = Template._render - Template._render = instrumented_test_render - - # Storing previous values in the settings module itself is problematic. - # Store them in arbitrary (but related) modules instead. See #20636. - - mail._original_email_backend = settings.EMAIL_BACKEND - settings.EMAIL_BACKEND = 'django.core.mail.backends.locmem.EmailBackend' - - request._original_allowed_hosts = settings.ALLOWED_HOSTS - settings.ALLOWED_HOSTS = ['*'] - - mail.outbox = [] - - deactivate() - - -def teardown_test_environment(): - """Perform any global post-test teardown. This involves: - - - Restoring the original test renderer - - Restoring the email sending functions - - """ - Template._render = Template._original_render - del Template._original_render - - settings.EMAIL_BACKEND = mail._original_email_backend - del mail._original_email_backend - - settings.ALLOWED_HOSTS = request._original_allowed_hosts - del request._original_allowed_hosts - - del mail.outbox - - -warn_txt = ("get_warnings_state/restore_warnings_state functions from " - "django.test.utils are deprecated. Use Python's warnings.catch_warnings() " - "context manager instead.") - - -def get_warnings_state(): - """ - Returns an object containing the state of the warnings module - """ - # There is no public interface for doing this, but this implementation of - # get_warnings_state and restore_warnings_state appears to work on Python - # 2.4 to 2.7. - warnings.warn(warn_txt, DeprecationWarning, stacklevel=2) - return warnings.filters[:] - - -def restore_warnings_state(state): - """ - Restores the state of the warnings module when passed an object that was - returned by get_warnings_state() - """ - warnings.warn(warn_txt, DeprecationWarning, stacklevel=2) - warnings.filters = state[:] - - -def get_runner(settings, test_runner_class=None): - if not test_runner_class: - test_runner_class = settings.TEST_RUNNER - - test_path = test_runner_class.split('.') - # Allow for Python 2.5 relative paths - if len(test_path) > 1: - test_module_name = '.'.join(test_path[:-1]) - else: - test_module_name = '.' - test_module = __import__(test_module_name, {}, {}, force_str(test_path[-1])) - test_runner = getattr(test_module, test_path[-1]) - return test_runner - - -def setup_test_template_loader(templates_dict, use_cached_loader=False): - """ - Changes Django to only find templates from within a dictionary (where each - key is the template name and each value is the corresponding template - content to return). - - Use meth:`restore_template_loaders` to restore the original loaders. - """ - if hasattr(loader, RESTORE_LOADERS_ATTR): - raise Exception("loader.%s already exists" % RESTORE_LOADERS_ATTR) - - def test_template_loader(template_name, template_dirs=None): - "A custom template loader that loads templates from a dictionary." - try: - return (templates_dict[template_name], "test:%s" % template_name) - except KeyError: - raise TemplateDoesNotExist(template_name) - - if use_cached_loader: - template_loader = cached.Loader(('test_template_loader',)) - template_loader._cached_loaders = (test_template_loader,) - else: - template_loader = test_template_loader - - setattr(loader, RESTORE_LOADERS_ATTR, loader.template_source_loaders) - loader.template_source_loaders = (template_loader,) - return template_loader - - -def restore_template_loaders(): - """ - Restores the original template loaders after - :meth:`setup_test_template_loader` has been run. - """ - loader.template_source_loaders = getattr(loader, RESTORE_LOADERS_ATTR) - delattr(loader, RESTORE_LOADERS_ATTR) - - -class override_settings(object): - """ - Acts as either a decorator, or a context manager. If it's a decorator it - takes a function and returns a wrapped function. If it's a contextmanager - it's used with the ``with`` statement. In either event entering/exiting - are called before and after, respectively, the function/block is executed. - """ - def __init__(self, **kwargs): - self.options = kwargs - - def __enter__(self): - self.enable() - - def __exit__(self, exc_type, exc_value, traceback): - self.disable() - - def __call__(self, test_func): - from django.test import SimpleTestCase - if isinstance(test_func, type): - if not issubclass(test_func, SimpleTestCase): - raise Exception( - "Only subclasses of Django SimpleTestCase can be decorated " - "with override_settings") - original_pre_setup = test_func._pre_setup - original_post_teardown = test_func._post_teardown - - def _pre_setup(innerself): - self.enable() - original_pre_setup(innerself) - - def _post_teardown(innerself): - original_post_teardown(innerself) - self.disable() - test_func._pre_setup = _pre_setup - test_func._post_teardown = _post_teardown - return test_func - else: - @wraps(test_func) - def inner(*args, **kwargs): - with self: - return test_func(*args, **kwargs) - return inner - - def enable(self): - override = UserSettingsHolder(settings._wrapped) - for key, new_value in self.options.items(): - setattr(override, key, new_value) - self.wrapped = settings._wrapped - settings._wrapped = override - for key, new_value in self.options.items(): - setting_changed.send(sender=settings._wrapped.__class__, - setting=key, value=new_value) - - def disable(self): - settings._wrapped = self.wrapped - del self.wrapped - for key in self.options: - new_value = getattr(settings, key, None) - setting_changed.send(sender=settings._wrapped.__class__, - setting=key, value=new_value) - - -def compare_xml(want, got): - """Tries to do a 'xml-comparison' of want and got. Plain string - comparison doesn't always work because, for example, attribute - ordering should not be important. Comment nodes are not considered in the - comparison. - - Based on http://codespeak.net/svn/lxml/trunk/src/lxml/doctestcompare.py - """ - _norm_whitespace_re = re.compile(r'[ \t\n][ \t\n]+') - def norm_whitespace(v): - return _norm_whitespace_re.sub(' ', v) - - def child_text(element): - return ''.join([c.data for c in element.childNodes - if c.nodeType == Node.TEXT_NODE]) - - def children(element): - return [c for c in element.childNodes - if c.nodeType == Node.ELEMENT_NODE] - - def norm_child_text(element): - return norm_whitespace(child_text(element)) - - def attrs_dict(element): - return dict(element.attributes.items()) - - def check_element(want_element, got_element): - if want_element.tagName != got_element.tagName: - return False - if norm_child_text(want_element) != norm_child_text(got_element): - return False - if attrs_dict(want_element) != attrs_dict(got_element): - return False - want_children = children(want_element) - got_children = children(got_element) - if len(want_children) != len(got_children): - return False - for want, got in zip(want_children, got_children): - if not check_element(want, got): - return False - return True - - def first_node(document): - for node in document.childNodes: - if node.nodeType != Node.COMMENT_NODE: - return node - - want, got = strip_quotes(want, got) - want = want.replace('\\n','\n') - got = got.replace('\\n','\n') - - # If the string is not a complete xml document, we may need to add a - # root element. This allow us to compare fragments, like "<foo/><bar/>" - if not want.startswith('<?xml'): - wrapper = '<root>%s</root>' - want = wrapper % want - got = wrapper % got - - # Parse the want and got strings, and compare the parsings. - want_root = first_node(parseString(want)) - got_root = first_node(parseString(got)) - - return check_element(want_root, got_root) - - -def strip_quotes(want, got): - """ - Strip quotes of doctests output values: - - >>> strip_quotes("'foo'") - "foo" - >>> strip_quotes('"foo"') - "foo" - """ - def is_quoted_string(s): - s = s.strip() - return (len(s) >= 2 - and s[0] == s[-1] - and s[0] in ('"', "'")) - - def is_quoted_unicode(s): - s = s.strip() - return (len(s) >= 3 - and s[0] == 'u' - and s[1] == s[-1] - and s[1] in ('"', "'")) - - if is_quoted_string(want) and is_quoted_string(got): - want = want.strip()[1:-1] - got = got.strip()[1:-1] - elif is_quoted_unicode(want) and is_quoted_unicode(got): - want = want.strip()[2:-1] - got = got.strip()[2:-1] - return want, got - - -def str_prefix(s): - return s % {'_': '' if six.PY3 else 'u'} - - -class CaptureQueriesContext(object): - """ - Context manager that captures queries executed by the specified connection. - """ - def __init__(self, connection): - self.connection = connection - - def __iter__(self): - return iter(self.captured_queries) - - def __getitem__(self, index): - return self.captured_queries[index] - - def __len__(self): - return len(self.captured_queries) - - @property - def captured_queries(self): - return self.connection.queries[self.initial_queries:self.final_queries] - - def __enter__(self): - self.use_debug_cursor = self.connection.use_debug_cursor - self.connection.use_debug_cursor = True - self.initial_queries = len(self.connection.queries) - self.final_queries = None - request_started.disconnect(reset_queries) - return self - - def __exit__(self, exc_type, exc_value, traceback): - self.connection.use_debug_cursor = self.use_debug_cursor - request_started.connect(reset_queries) - if exc_type is not None: - return - self.final_queries = len(self.connection.queries) - - -class IgnoreDeprecationWarningsMixin(object): - - warning_class = DeprecationWarning - - def setUp(self): - super(IgnoreDeprecationWarningsMixin, self).setUp() - self.catch_warnings = warnings.catch_warnings() - self.catch_warnings.__enter__() - warnings.filterwarnings("ignore", category=self.warning_class) - - def tearDown(self): - self.catch_warnings.__exit__(*sys.exc_info()) - super(IgnoreDeprecationWarningsMixin, self).tearDown() - - -class IgnorePendingDeprecationWarningsMixin(IgnoreDeprecationWarningsMixin): - - warning_class = PendingDeprecationWarning - - -@contextmanager -def patch_logger(logger_name, log_level): - """ - Context manager that takes a named logger and the logging level - and provides a simple mock-like list of messages received - """ - calls = [] - def replacement(msg): - calls.append(msg) - logger = logging.getLogger(logger_name) - orig = getattr(logger, log_level) - setattr(logger, log_level, replacement) - try: - yield calls - finally: - setattr(logger, log_level, orig) - - -class TransRealMixin(object): - """This is the only way to reset the translation machinery. Otherwise - the test suite occasionally fails because of global state pollution - between tests.""" - def flush_caches(self): - from django.utils.translation import trans_real - trans_real._translations = {} - trans_real._active = local() - trans_real._default = None - trans_real._accepted = {} - trans_real._checked_languages = {} - - def tearDown(self): - self.flush_caches() - super(TransRealMixin, self).tearDown() - - -# On OSes that don't provide tzset (Windows), we can't set the timezone -# in which the program runs. As a consequence, we must skip tests that -# don't enforce a specific timezone (with timezone.override or equivalent), -# or attempt to interpret naive datetimes in the default timezone. - -requires_tz_support = skipUnless(TZ_SUPPORT, - "This test relies on the ability to run a program in an arbitrary " - "time zone, but your operating system isn't able to do that.") |