def check(part, got_stdout, got_eval=constants.NOT_EVALED, runstate=None,<EOL>unmatched=None):

if unmatched is None:<EOL><INDENT>unmatched = []<EOL><DEDENT>trailing_gots = unmatched + [got_stdout]<EOL>success = False<EOL>exceptions = []<EOL>for i in range(<NUM_LIT:1>, len(trailing_gots) + <NUM_LIT:1>):<EOL><INDENT>got_ = '<STR_LIT>'.join(trailing_gots[-i:])<EOL>try:<EOL><INDENT>checker.check_got_vs_want(part.want, got_, got_eval, runstate)<EOL><DEDENT>except checker.GotWantException as ex:<EOL><INDENT>exceptions.append(ex)<EOL><DEDENT>else:<EOL><INDENT>success = True<EOL>break<EOL><DEDENT><DEDENT>if not success:<EOL><INDENT>raise exceptions[-<NUM_LIT:1>]<EOL><DEDENT>

r"""
        Check if the "got" output obtained by running this test matches the
        "want" target. Note there are two types of "got" output: (1) output
        from stdout and (2) evaled output. If both are specified, then want may
        match either value.

        Args:
            got_stdout (str): output from stdout
            got_eval (str): output from an eval statement
            runstate (directive.RuntimeState): runner options
            unmatched (list): if specified, the want statement is allowed
                to match any trailing sequence of unmatched output and
                got_stdout from this doctest part.

        Raises:
            xdoctest.checker.GotWantException - If the "got" differs from this
                parts want.

        Example:
            >>> import pytest
            >>> got_stdout = 'more text\n'
            >>> unmatched = ['some text\n']
            >>> self = DoctestPart(None, want_lines=['some text', 'more text'])
            >>> self.check(got_stdout, unmatched=unmatched)
            >>> # Leading junk doesnt matter if we match a trailing sequence
            >>> self.check(got_stdout, unmatched=['junk\n'] + unmatched)
            >>> # fail when want doesnt match any trailing sequence
            >>> with pytest.raises(checker.GotWantException):
            >>>     self.check(got_stdout)
            >>> with pytest.raises(checker.GotWantException):
            >>>     self.check(got_stdout, ['some text\n', 'junk\n'])


def format_part(self, linenos=True, want=True, startline=<NUM_LIT:1>, n_digits=None,<EOL>colored=False, partnos=False, prefix=True):

from xdoctest import utils<EOL>src_text = self.source<EOL>if prefix:<EOL><INDENT>src_text = utils.indent(src_text, '<STR_LIT>')<EOL><DEDENT>want_text = self.want if self.want else '<STR_LIT>'<EOL>if n_digits is None:<EOL><INDENT>endline = startline + self.n_lines<EOL>n_digits = math.log(max(<NUM_LIT:1>, endline), <NUM_LIT:10>)<EOL>n_digits = int(math.ceil(n_digits))<EOL><DEDENT>part_lines = src_text.splitlines()<EOL>n_spaces = <NUM_LIT:0><EOL>if linenos:<EOL><INDENT>n_spaces += n_digits + <NUM_LIT:1><EOL>start = startline + self.line_offset<EOL>part_lines = add_line_numbers(part_lines, n_digits=n_digits,<EOL>start=start)<EOL><DEDENT>if partnos:<EOL><INDENT>part_lines = [<EOL>'<STR_LIT>'.format(self.partno, line)<EOL>for line in part_lines<EOL>]<EOL>n_spaces += <NUM_LIT:4> + <NUM_LIT:1>  <EOL><DEDENT>want_lines = []<EOL>if want_text:<EOL><INDENT>want_fmt = '<STR_LIT:U+0020>' * n_spaces + '<STR_LIT>'<EOL>for line in want_text.splitlines():<EOL><INDENT>if want:<EOL><INDENT>want_lines.append(want_fmt.format(line=line))<EOL><DEDENT><DEDENT><DEDENT>part_text = '<STR_LIT:\n>'.join(part_lines)<EOL>want_text = '<STR_LIT:\n>'.join(want_lines)<EOL>if colored:<EOL><INDENT>part_text = utils.highlight_code(part_text, '<STR_LIT>')<EOL>want_text = utils.color_text(want_text, '<STR_LIT>')<EOL><DEDENT>if want_lines:<EOL><INDENT>part_text += '<STR_LIT:\n>' + want_text<EOL><DEDENT>return part_text<EOL>

Customizable formatting of the source and want for this doctest.

CommandLine:
    python -m xdoctest.doctest_part DoctestPart.format_part

Args:
    linenos (bool): show line numbers
    want (bool): include the want value if it exists
    startline (int): offsets the line numbering
    n_digits (int): number of digits to use for line numbers
    colored (bool): pygmentize the colde
    partnos (bool): if True, shows the part number in the string
    prefix (bool): if False, exclude the doctest `>>> ` prefix

CommandLine:
    python -m xdoctest.doctest_part DoctestPart.format_part:0

Example:
    >>> from xdoctest.parser import *
    >>> self = DoctestPart(exec_lines=['print(123)'],
    >>>                    want_lines=['123'], line_offset=0, partno=1)
    >>> # xdoctest: -NORMALIZE_WHITESPACE
    >>> print(self.format_part(partnos=True))
    (p1) 1 >>> print(123)
           123

Example:
    >>> from xdoctest.parser import *
    >>> self = DoctestPart(exec_lines=['print(123)'],
    >>>                    want_lines=['123'], line_offset=0, partno=1)
    >>> # xdoctest: -NORMALIZE_WHITESPACE
    >>> print(self.format_part(partnos=False, prefix=False,
    >>>                       linenos=False, want=False))
    print(123)


def _update_argparse_cli(self, add_argument, prefix=None, defaults={}):

def str_lower(x):<EOL><INDENT>return str.lower(str(x))<EOL><DEDENT>add_argument_kws = [<EOL>(['<STR_LIT>'], dict(dest='<STR_LIT>', action='<STR_LIT>',<EOL>default=self['<STR_LIT>'],<EOL>help=('<STR_LIT>'))),<EOL>(['<STR_LIT>'], dict(dest='<STR_LIT>', action='<STR_LIT:store_true>',<EOL>default=self['<STR_LIT>'],<EOL>help=('<STR_LIT>'<EOL>'<STR_LIT>'<EOL>'<STR_LIT>'))),<EOL>(['<STR_LIT>'], dict(dest='<STR_LIT>',<EOL>type=str_lower,<EOL>choices=('<STR_LIT:none>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>',),<EOL>default=self['<STR_LIT>'],<EOL>help=('<STR_LIT>'))),<EOL>(['<STR_LIT>'], dict(type=str_lower, default=None, dest='<STR_LIT>',<EOL>help='<STR_LIT>')),<EOL>(['<STR_LIT>'], dict(type=str, default=None, dest='<STR_LIT>',<EOL>help='<STR_LIT>')),<EOL>(['<STR_LIT>'], dict(type=int, default=defaults.get('<STR_LIT>', <NUM_LIT:3>), dest='<STR_LIT>',<EOL>help='<STR_LIT>')),<EOL>]<EOL>if prefix is None:<EOL><INDENT>prefix = ['<STR_LIT>']<EOL><DEDENT>for alias, kw in add_argument_kws:<EOL><INDENT>alias = [<EOL>a.replace('<STR_LIT>', '<STR_LIT>' + p + '<STR_LIT:->') if p else a<EOL>for a in alias for p in prefix<EOL>]<EOL>if prefix[<NUM_LIT:0>]:<EOL><INDENT>kw['<STR_LIT>'] = prefix[<NUM_LIT:0>] + '<STR_LIT:_>' + kw['<STR_LIT>']<EOL><DEDENT>add_argument(*alias, **kw)<EOL><DEDENT>


return self.modpath + '<STR_LIT>' + self.callname + '<STR_LIT::>' + str(self.num)<EOL>


self._parse()<EOL>for part in self._parts:<EOL><INDENT>if part.want:<EOL><INDENT>yield part.want<EOL><DEDENT><DEDENT>


def format_parts(self, linenos=True, colored=None, want=True,<EOL>offset_linenos=None, prefix=True):

self._parse()<EOL>colored = self.config.getvalue('<STR_LIT>', colored)<EOL>partnos = self.config.getvalue('<STR_LIT>')<EOL>offset_linenos = self.config.getvalue('<STR_LIT>', offset_linenos)<EOL>n_digits = None<EOL>startline = <NUM_LIT:1><EOL>if linenos:<EOL><INDENT>if offset_linenos:<EOL><INDENT>startline = self.lineno<EOL><DEDENT>n_lines = sum(p.n_lines for p in self._parts)<EOL>endline = startline + n_lines<EOL>n_digits = math.log(max(<NUM_LIT:1>, endline), <NUM_LIT:10>)<EOL>n_digits = int(math.ceil(n_digits))<EOL><DEDENT>for part in self._parts:<EOL><INDENT>part_text = part.format_part(linenos=linenos, want=want,<EOL>startline=startline,<EOL>n_digits=n_digits, prefix=prefix,<EOL>colored=colored, partnos=partnos)<EOL>yield part_text<EOL><DEDENT>


def format_src(self, linenos=True, colored=None, want=True,<EOL>offset_linenos=None, prefix=True):

formated_parts = list(self.format_parts(linenos=linenos,<EOL>colored=colored, want=want,<EOL>offset_linenos=offset_linenos,<EOL>prefix=prefix))<EOL>full_source = '<STR_LIT:\n>'.join(formated_parts)<EOL>return full_source<EOL>

Adds prefix and line numbers to a doctest

Args:
    linenos (bool): if True, adds line numbers to output

    colored (bool): if True highlight text with ansi colors. Default
        is specified in the config.

    want (bool): if True includes "want" lines (default False).

    offset_linenos (bool): if True offset line numbers to agree with
        their position in the source text file (default False).

    prefix (bool): if False, exclude the doctest `>>> ` prefix

Example:
    >>> from xdoctest.core import *
    >>> from xdoctest import core
    >>> testables = parse_doctestables(core.__file__)
    >>> self = next(testables)
    >>> self._parse()
    >>> print(self.format_src())
    >>> print(self.format_src(linenos=False, colored=False))
    >>> assert not self.is_disabled()


if not self._parts:<EOL><INDENT>info = dict(callname=self.callname, modpath=self.modpath,<EOL>lineno=self.lineno, fpath=self.fpath)<EOL>self._parts = parser.DoctestParser().parse(self.docsrc, info)<EOL>self._parts = [p for p in self._parts<EOL>if not isinstance(p, six.string_types)]<EOL><DEDENT>for partno, part in enumerate(self._parts):<EOL><INDENT>part.partno = partno<EOL><DEDENT>

Divide the given string into examples and intervening text.

Example:
    >>> s = 'I am a dummy example with three parts'
    >>> x = 10
    >>> print(s)
    I am a dummy example with three parts
    >>> s = 'My purpose it so demonstrate how wants work here'
    >>> print('The new want applies ONLY to stdout')
    >>> print('given before the last want')
    >>> '''
        this wont hurt the test at all
        even though its multiline '''
    >>> y = 20
    The new want applies ONLY to stdout
    given before the last want
    >>> # Parts from previous examples are executed in the same context
    >>> print(x + y)
    30

    this is simply text, and doesnt apply to the previous doctest the
    <BLANKLINE> directive is still in effect.

Example:
    >>> from xdoctest import parser
    >>> from xdoctest.docstr import docscrape_google
    >>> from xdoctest import doctest_example
    >>> DocTest = doctest_example.DocTest
    >>> docstr = DocTest._parse.__doc__
    >>> blocks = docscrape_google.split_google_docblocks(docstr)
    >>> doclineno = DocTest._parse.__code__.co_firstlineno
    >>> key, (docsrc, offset) = blocks[-2]
    >>> lineno = doclineno + offset
    >>> self = DocTest(docsrc, doctest_example.__file__, '_parse', 0,
    >>>                lineno)
    >>> self._parse()
    >>> assert len(self._parts) >= 3
    >>> #p1, p2, p3 = self._parts
    >>> self.run()


compileflags = <NUM_LIT:0><EOL>for key in __future__.all_feature_names:<EOL><INDENT>feature = namespace.get(key, None)<EOL>if feature is getattr(__future__, key):<EOL><INDENT>compileflags |= feature.compiler_flag<EOL><DEDENT><DEDENT>return compileflags<EOL>

Return the compiler-flags associated with the future features that
have been imported into the given namespace (i.e. globals).


def run(self, verbose=None, on_error=None):

on_error = self.config.getvalue('<STR_LIT>', on_error)<EOL>verbose = self.config.getvalue('<STR_LIT>', verbose)<EOL>if on_error not in {'<STR_LIT>', '<STR_LIT>'}:<EOL><INDENT>raise KeyError(on_error)<EOL><DEDENT>self._parse()  <EOL>self.pre_run(verbose)<EOL>self._import_module()<EOL>test_globals, compileflags = self._test_globals()<EOL>self.logged_evals.clear()<EOL>self.logged_stdout.clear()<EOL>self._unmatched_stdout = []<EOL>self.skipped_parts = []<EOL>self.exc_info = None<EOL>self._suppressed_stdout = verbose <= <NUM_LIT:1><EOL>default_state = self.config['<STR_LIT>']<EOL>runstate = self._runstate = directive.RuntimeState(default_state)<EOL>runstate.set_report_style(self.config['<STR_LIT>'].lower())<EOL>global_exec = self.config.getvalue('<STR_LIT>')<EOL>if global_exec:<EOL><INDENT>global_source = utils.codeblock(global_exec.replace('<STR_LIT>', '<STR_LIT:\n>'))<EOL>global_code = compile(<EOL>global_source, mode='<STR_LIT>',<EOL>filename='<STR_LIT>' + self.node + '<STR_LIT::>' + '<STR_LIT>',<EOL>flags=compileflags, dont_inherit=True<EOL>)<EOL>exec(global_code, test_globals)<EOL><DEDENT>cap = utils.CaptureStdout(supress=self._suppressed_stdout)<EOL>with warnings.catch_warnings(record=True) as self.warn_list:<EOL><INDENT>for partx, part in enumerate(self._parts):<EOL><INDENT>runstate.update(part.directives)<EOL>if runstate['<STR_LIT>']:<EOL><INDENT>self.skipped_parts.append(part)<EOL>continue<EOL><DEDENT>self.failed_part = part<EOL>got_eval = constants.NOT_EVALED<EOL>try:<EOL><INDENT>mode = '<STR_LIT>' if part.use_eval else '<STR_LIT>'<EOL>self._partfilename = '<STR_LIT>' + self.node + '<STR_LIT:>>'<EOL>code = compile(<EOL>part.source, mode=mode,<EOL>filename=self._partfilename,<EOL>flags=compileflags, dont_inherit=True<EOL>)<EOL><DEDENT>except KeyboardInterrupt:  <EOL><INDENT>raise<EOL><DEDENT>except Exception:<EOL><INDENT>raise<EOL><DEDENT>try:<EOL><INDENT>try:<EOL><INDENT>with cap:<EOL><INDENT>if part.use_eval:<EOL><INDENT>got_eval = eval(code, test_globals)<EOL><DEDENT>else:<EOL><INDENT>exec(code, test_globals)<EOL><DEDENT><DEDENT>self.logged_evals[partx] = got_eval<EOL>self.logged_stdout[partx] = cap.text<EOL><DEDENT>except Exception as ex:<EOL><INDENT>if part.want:<EOL><INDENT>exception = sys.exc_info()<EOL>traceback.format_exception_only(*exception[:<NUM_LIT:2>])<EOL>exc_got = traceback.format_exception_only(*exception[:<NUM_LIT:2>])[-<NUM_LIT:1>]<EOL>want = part.want<EOL>checker.check_exception(exc_got, want, runstate)<EOL><DEDENT>else:<EOL><INDENT>raise<EOL><DEDENT><DEDENT>else:<EOL><INDENT>"""<STR_LIT>"""<EOL>if part.want:<EOL><INDENT>got_stdout = cap.text<EOL>if not runstate['<STR_LIT>']:<EOL><INDENT>part.check(got_stdout, got_eval, runstate,<EOL>unmatched=self._unmatched_stdout)<EOL><DEDENT>self._unmatched_stdout = []<EOL><DEDENT>else:<EOL><INDENT>self._unmatched_stdout.append(cap.text)<EOL><DEDENT><DEDENT><DEDENT>except KeyboardInterrupt:  <EOL><INDENT>raise<EOL><DEDENT>except (exceptions.ExitTestException,<EOL>exceptions._pytest.outcomes.Skipped):<EOL><INDENT>if verbose > <NUM_LIT:0>:<EOL><INDENT>print('<STR_LIT>')<EOL><DEDENT>break<EOL><DEDENT>except parser.GotWantException:<EOL><INDENT>self.exc_info = sys.exc_info()<EOL>if on_error == '<STR_LIT>':<EOL><INDENT>raise<EOL><DEDENT>break<EOL><DEDENT>except Exception:<EOL><INDENT>ex_type, ex_value, tb = sys.exc_info()<EOL>DEBUG = <NUM_LIT:0><EOL>if DEBUG:<EOL><INDENT>print('<STR_LIT>', file=sys.stderr)<EOL>print('<STR_LIT>'.join(traceback.format_tb(tb)), file=sys.stderr)<EOL>print('<STR_LIT>', file=sys.stderr)<EOL><DEDENT>def traverse_traceback(tb):<EOL><INDENT>sub_tb = tb<EOL>yield sub_tb<EOL>while sub_tb.tb_next is not None:<EOL><INDENT>sub_tb = sub_tb.tb_next<EOL>yield sub_tb<EOL><DEDENT><DEDENT>found_lineno = None<EOL>for sub_tb in traverse_traceback(tb):<EOL><INDENT>tb_filename = sub_tb.tb_frame.f_code.co_filename<EOL>if tb_filename == self._partfilename:<EOL><INDENT>found_lineno = sub_tb.tb_lineno<EOL>break<EOL><DEDENT><DEDENT>if DEBUG:<EOL><INDENT>print('<STR_LIT>', file=sys.stderr)<EOL>print('<STR_LIT>'.format(found_lineno), file=sys.stderr)<EOL>print('<STR_LIT>'.join(traceback.format_tb(sub_tb)), file=sys.stderr)<EOL>print('<STR_LIT>', file=sys.stderr)<EOL><DEDENT>if found_lineno is None:<EOL><INDENT>if DEBUG:<EOL><INDENT>print('<STR_LIT>')<EOL>sys.exit(<NUM_LIT:1>)<EOL><DEDENT>raise ValueError('<STR_LIT>')<EOL><DEDENT>else:<EOL><INDENT>self.failed_tb_lineno = found_lineno<EOL><DEDENT>self.exc_info = (ex_type, ex_value, tb)<EOL>if on_error == '<STR_LIT>':<EOL><INDENT>raise<EOL><DEDENT>break<EOL><DEDENT>finally:<EOL><INDENT>assert cap.text is not None<EOL>self.logged_evals[partx] = got_eval<EOL>self.logged_stdout[partx] = cap.text<EOL><DEDENT><DEDENT><DEDENT>if self.exc_info is None:<EOL><INDENT>self.failed_part = None<EOL><DEDENT>if len(self.skipped_parts) == len(self._parts):<EOL><INDENT>if self.mode == '<STR_LIT>':<EOL><INDENT>import pytest<EOL>pytest.skip()<EOL><DEDENT><DEDENT>return self.post_run(verbose)<EOL>

Executes the doctest, checks the results, reports the outcome.


if self.exc_info is None:<EOL><INDENT>return None<EOL><DEDENT>else:<EOL><INDENT>ex_type, ex_value, tb = self.exc_info<EOL>offset = self.failed_part.line_offset<EOL>if isinstance(ex_value, parser.GotWantException):<EOL><INDENT>offset += self.failed_part.n_exec_lines + <NUM_LIT:1><EOL><DEDENT>else:<EOL><INDENT>offset += self.failed_tb_lineno<EOL><DEDENT>offset -= <NUM_LIT:1><EOL>return offset<EOL><DEDENT>

Determine which line in the doctest failed.


<EOL>if self.exc_info is None:<EOL><INDENT>return []<EOL><DEDENT>ex_type, ex_value, tb = self.exc_info<EOL>fail_offset = self.failed_line_offset()<EOL>fail_lineno = self.failed_lineno()<EOL>lines = [<EOL>'<STR_LIT>'.format(ex_type.__name__),<EOL>self._color(self.block_prefix + '<STR_LIT>', '<STR_LIT>'),<EOL>'<STR_LIT>'.format(self.node, fail_offset + <NUM_LIT:1>) +<EOL>self._color('<STR_LIT>', '<STR_LIT>'),<EOL>]<EOL>colored = self.config['<STR_LIT>']<EOL>if fail_lineno is not None:<EOL><INDENT>fpath = '<STR_LIT>' if self.fpath is None else self.fpath<EOL>lines += ['<STR_LIT>'.format(fpath, fail_lineno) +<EOL>self._color('<STR_LIT>', '<STR_LIT>')]<EOL><DEDENT>def r1_strip_nl(text):<EOL><INDENT>return text[:-<NUM_LIT:1>] if text.endswith('<STR_LIT:\n>') else text<EOL><DEDENT>textgen = self.format_parts(colored=colored, linenos=True,<EOL>want=False)<EOL>n_digits = <NUM_LIT:1><EOL>before_part_lines = []<EOL>fail_part_lines = []<EOL>after_parts_lines = []<EOL>temp = [before_part_lines, fail_part_lines, after_parts_lines]<EOL>tindex = <NUM_LIT:0><EOL>indent_text = '<STR_LIT:U+0020>' * (<NUM_LIT:5> + n_digits)<EOL>for partx, (part, part_text) in enumerate(zip(self._parts, textgen)):<EOL><INDENT>if part in self.skipped_parts:<EOL><INDENT>continue<EOL><DEDENT>part_out = r1_strip_nl(self.logged_stdout.get(partx, '<STR_LIT>'))<EOL>if part is self.failed_part:<EOL><INDENT>tindex += <NUM_LIT:1><EOL><DEDENT>temp[tindex] += [utils.indent(part_text, '<STR_LIT:U+0020>' * <NUM_LIT:4>)]<EOL>if part_out:<EOL><INDENT>temp[tindex] += [utils.indent(part_out, indent_text)]<EOL><DEDENT>if part is self.failed_part:<EOL><INDENT>tindex += <NUM_LIT:1><EOL><DEDENT><DEDENT>lines += [self._color(self.block_prefix + '<STR_LIT>', '<STR_LIT>')]<EOL>if before_part_lines:<EOL><INDENT>lines += ['<STR_LIT>']<EOL>lines += before_part_lines<EOL><DEDENT>if fail_part_lines:<EOL><INDENT>lines += ['<STR_LIT>']<EOL>lines += fail_part_lines<EOL><DEDENT>if after_parts_lines:<EOL><INDENT>lines += ['<STR_LIT>']<EOL>lines += after_parts_lines<EOL><DEDENT>lines += [self._color(self.block_prefix + '<STR_LIT>', '<STR_LIT>')]<EOL>if hasattr(ex_value, '<STR_LIT>'):<EOL><INDENT>lines += [<EOL>ex_value.output_difference(self._runstate, colored=colored),<EOL>ex_value.output_repr_difference(self._runstate)<EOL>]<EOL><DEDENT>else:<EOL><INDENT>if with_tb:<EOL><INDENT>tblines = traceback.format_exception(*self.exc_info)<EOL>def _alter_traceback_linenos(self, tblines):<EOL><INDENT>def overwrite_lineno(linepart):<EOL><INDENT>old_linestr = linepart[-<NUM_LIT:1>]  <EOL>rel_lineno = self.failed_part.line_offset + tb_lineno<EOL>abs_lineno = self.lineno + rel_lineno - <NUM_LIT:1><EOL>new_linestr = '<STR_LIT>'.format(<EOL>rel=rel_lineno,<EOL>abs=abs_lineno,<EOL>)<EOL>linepart = linepart[:-<NUM_LIT:1>] + [new_linestr]<EOL>return linepart<EOL><DEDENT>new_tblines = []<EOL>for i, line in enumerate(tblines):<EOL><INDENT>if '<STR_LIT>' in line:<EOL><INDENT>continue<EOL><DEDENT>if self._partfilename in line:<EOL><INDENT>tbparts = line.split('<STR_LIT:U+002C>')<EOL>tb_lineno = int(tbparts[-<NUM_LIT:2>].strip().split()[<NUM_LIT:1>])<EOL>linepart = tbparts[-<NUM_LIT:2>].split('<STR_LIT:U+0020>')<EOL>linepart = overwrite_lineno(linepart)<EOL>tbparts[-<NUM_LIT:2>] = '<STR_LIT:U+0020>'.join(linepart)<EOL>new_line = '<STR_LIT:U+002C>'.join(tbparts)<EOL>failed_ctx = self.failed_part.orig_lines[tb_lineno - <NUM_LIT:1>]<EOL>extra = '<STR_LIT:U+0020>' + failed_ctx<EOL>line = (new_line + extra + '<STR_LIT:\n>')<EOL><DEDENT>new_tblines.append(line)<EOL><DEDENT>return new_tblines<EOL><DEDENT>new_tblines = _alter_traceback_linenos(self, tblines)<EOL>if colored:<EOL><INDENT>tbtext = '<STR_LIT:\n>'.join(new_tblines)<EOL>tbtext = utils.highlight_code(tbtext, lexer_name='<STR_LIT>',<EOL>stripall=True)<EOL>new_tblines = tbtext.splitlines()<EOL><DEDENT>lines += new_tblines<EOL><DEDENT><DEDENT>lines += [self._color(self.block_prefix + '<STR_LIT>', '<STR_LIT>')]<EOL>lines += ['<STR_LIT>']<EOL>lines += ['<STR_LIT:U+0020>' + self.cmdline]<EOL>return lines<EOL>

r"""
        Constructs lines detailing information about a failed doctest

        CommandLine:
            python -m xdoctest.core DocTest.repr_failure:0
            python -m xdoctest.core DocTest.repr_failure:1
            python -m xdoctest.core DocTest.repr_failure:2

        Example:
            >>> from xdoctest.core import *
            >>> docstr = utils.codeblock(
                '''
                >>> x = 1
                >>> print(x + 1)
                2
                >>> print(x + 3)
                3
                >>> print(x + 100)
                101
                ''')
            >>> parsekw = dict(fpath='foo.txt', callname='bar', lineno=42)
            >>> self = list(parse_docstr_examples(docstr, **parsekw))[0]
            >>> summary = self.run(on_error='return', verbose=0)
            >>> print('[res]' + '\n[res]'.join(self.repr_failure()))

        Example:
            >>> from xdoctest.core import *
            >>> docstr = utils.codeblock(
                r'''
                >>> 1
                1
                >>> print('.▴  .\n.▴ ▴.') # xdoc: -NORMALIZE_WHITESPACE
                . ▴ .
                .▴ ▴.
                ''')
            >>> parsekw = dict(fpath='foo.txt', callname='bar', lineno=42)
            >>> self = list(parse_docstr_examples(docstr, **parsekw))[0]
            >>> summary = self.run(on_error='return', verbose=1)
            >>> print('[res]' + '\n[res]'.join(self.repr_failure()))

        Example:
            >>> from xdoctest.core import *
            >>> docstr = utils.codeblock(
                '''
                >>> assert True
                >>> assert False
                >>> x = 100
                ''')
            >>> self = list(parse_docstr_examples(docstr))[0]
            >>> summary = self.run(on_error='return', verbose=0)
            >>> print('[res]' + '\n[res]'.join(self.repr_failure()))


def _color(self, text, color, enabled=None):

colored = self.config.getvalue('<STR_LIT>', enabled)<EOL>if colored:<EOL><INDENT>text = utils.color_text(text, color)<EOL><DEDENT>return text<EOL>

conditionally color text based on config and flags


def _pkgutil_submodule_names(modpath, with_pkg=False, with_mod=True):

package_name = modpath_to_modname(modpath)<EOL>if isfile(modpath):<EOL><INDENT>yield package_name<EOL><DEDENT>else:<EOL><INDENT>import pkgutil<EOL>prefix = package_name + '<STR_LIT:.>'<EOL>walker = pkgutil.walk_packages([modpath], prefix=prefix,<EOL>onerror=lambda x: None)  <EOL>for importer, modname, ispkg in walker:<EOL><INDENT>if not ispkg and with_mod:<EOL><INDENT>yield modname<EOL><DEDENT>elif ispkg and with_pkg:<EOL><INDENT>yield modname<EOL><DEDENT><DEDENT><DEDENT>

Ignore:
    x = sorted(submodule_paths(modname_to_modpath('ubelt')))
    y = sorted(_pkgutil_submodule_names(modname_to_modpath('ubelt')))
    x = [modpath_to_modname(p, hide_init=False, hide_main=False) for p in x]
    print('x = {!r}'.format(x))
    print('y = {!r}'.format(y))

Notes:
    this will take into account pyc files, we choose not to.


import argparse<EOL>from os.path import exists<EOL>from xdoctest import utils<EOL>parser = argparse.ArgumentParser(<EOL>prog='<STR_LIT>',<EOL>description=utils.codeblock(<EOL>'''<STR_LIT>''')<EOL>)<EOL>parser.add_argument(<EOL>'<STR_LIT>', nargs='<STR_LIT:*>', help=utils.codeblock(<EOL>'''<STR_LIT>'''))<EOL>from xdoctest import doctest_example<EOL>from xdoctest import runner<EOL>runner._update_argparse_cli(parser.add_argument)<EOL>doctest_example.Config()._update_argparse_cli(parser.add_argument)<EOL>args, unknown = parser.parse_known_args()<EOL>ns = args.__dict__.copy()<EOL>modname = ns['<STR_LIT>']<EOL>command = ns['<STR_LIT>']<EOL>arg = ns['<STR_LIT>']<EOL>style = ns['<STR_LIT>']<EOL>durations = ns['<STR_LIT>']<EOL>if ns['<STR_LIT:time>']:<EOL><INDENT>durations = <NUM_LIT:0><EOL><DEDENT>errors = []<EOL>if modname is None:<EOL><INDENT>if len(arg) == <NUM_LIT:0>:<EOL><INDENT>errors += ['<STR_LIT>']<EOL><DEDENT>else:<EOL><INDENT>modname = arg.pop(<NUM_LIT:0>)<EOL><DEDENT><DEDENT>if command is None:<EOL><INDENT>if len(arg) == <NUM_LIT:0>:<EOL><INDENT>command = '<STR_LIT:all>'<EOL><DEDENT>else:<EOL><INDENT>command = arg.pop(<NUM_LIT:0>)<EOL><DEDENT><DEDENT>if errors:<EOL><INDENT>if len(errors) == <NUM_LIT:1>:<EOL><INDENT>errmsg = errors[<NUM_LIT:0>]<EOL><DEDENT>else:<EOL><INDENT>listed_errors = '<STR_LIT:U+002CU+0020>'.join(['<STR_LIT>'.format(c, e)<EOL>for c, e in enumerate(errors, start=<NUM_LIT:1>)])<EOL>errmsg = '<STR_LIT>'.format(len(errors), listed_errors)<EOL><DEDENT>parser.error(errmsg)<EOL><DEDENT>import xdoctest<EOL>options = ns['<STR_LIT>']<EOL>if options is None:<EOL><INDENT>options = '<STR_LIT>'<EOL>if exists('<STR_LIT>'):<EOL><INDENT>from six.moves import configparser<EOL>parser = configparser.ConfigParser()<EOL>parser.read('<STR_LIT>')<EOL>try:<EOL><INDENT>options = parser.get('<STR_LIT>', '<STR_LIT>')<EOL><DEDENT>except configparser.NoOptionError:<EOL><INDENT>pass<EOL><DEDENT><DEDENT>ns['<STR_LIT>'] = options<EOL><DEDENT>from xdoctest import doctest_example<EOL>config = doctest_example.Config()._populate_from_cli(ns)<EOL>xdoctest.doctest_module(modname, argv=[command], style=style,<EOL>verbose=config['<STR_LIT>'], config=config,<EOL>durations=durations)<EOL>

python -m xdoctest xdoctest all
python -m xdoctest networkx all --options=+IGNORE_WHITESPACE


<EOL>ansi_escape3 = re.compile(r'<STR_LIT>', flags=re.IGNORECASE)<EOL>text = ansi_escape3.sub('<STR_LIT>', text)<EOL>return text<EOL>

r"""
    Removes all ansi directives from the string.

    References:
        http://stackoverflow.com/questions/14693701/remove-ansi
        https://stackoverflow.com/questions/13506033/filtering-out-ansi-escape-sequences

    Examples:
        >>> line = '\t\u001b[0;35mBlabla\u001b[0m     \u001b[0;36m172.18.0.2\u001b[0m'
        >>> escaped_line = strip_ansi(line)
        >>> assert escaped_line == '\tBlabla     172.18.0.2'


if color is None:<EOL><INDENT>return text<EOL><DEDENT>try:<EOL><INDENT>import pygments<EOL>import pygments.console<EOL>if sys.platform.startswith('<STR_LIT:win32>'):  <EOL><INDENT>import colorama<EOL>colorama.init()<EOL><DEDENT>ansi_text = pygments.console.colorize(color, text)<EOL>return ansi_text<EOL><DEDENT>except ImportError:  <EOL><INDENT>return text<EOL><DEDENT>

r"""
    Colorizes text a single color using ansii tags.

    Args:
        text (str): text to colorize
        color (str): may be one of the following: yellow, blink, lightgray,
            underline, darkyellow, blue, darkblue, faint, fuchsia, black,
            white, red, brown, turquoise, bold, darkred, darkgreen, reset,
            standout, darkteal, darkgray, overline, purple, green, teal, fuscia

    Returns:
        str: text : colorized text.
            If pygments is not installed plain text is returned.

    Example:
        >>> text = 'raw text'
        >>> assert color_text(text, 'red') == '\x1b[31;01mraw text\x1b[39;49;00m'
        >>> assert color_text(text, None) == 'raw text'


if isinstance(text, six.text_type):<EOL><INDENT>return text<EOL><DEDENT>elif isinstance(text, six.binary_type):<EOL><INDENT>return text.decode('<STR_LIT:utf8>')<EOL><DEDENT>else:  <EOL><INDENT>raise ValueError('<STR_LIT>'.format(text))<EOL><DEDENT>

Casts bytes into utf8 (mostly for python2 compatibility)

References:
    http://stackoverflow.com/questions/12561063/python-extract-data-from-file

CommandLine:
    python -m xdoctest.utils ensure_unicode

Example:
    >>> assert ensure_unicode('my ünicôdé strįng') == 'my ünicôdé strįng'
    >>> assert ensure_unicode('text1') == 'text1'
    >>> assert ensure_unicode('text1'.encode('utf8')) == 'text1'
    >>> assert ensure_unicode('ï»¿text1'.encode('utf8')) == 'ï»¿text1'
    >>> import codecs
    >>> assert (codecs.BOM_UTF8 + 'text»¿'.encode('utf8')).decode('utf8')


return prefix + text.replace('<STR_LIT:\n>', '<STR_LIT:\n>' + prefix)<EOL>

r"""
    Indents a block of text

    Args:
        text (str): text to indent
        prefix (str): prefix to add to each line (default = '    ')

    Returns:
        str: indented text

    CommandLine:
        python -m xdoctest.utils ensure_unicode

    Example:
        >>> text = 'Lorem ipsum\ndolor sit amet'
        >>> prefix = '    '
        >>> result = indent(text, prefix)
        >>> assert all(t.startswith(prefix) for t in result.split('\n'))


def highlight_code(text, lexer_name='<STR_LIT>', **kwargs):

<EOL>lexer_name = {<EOL>'<STR_LIT>': '<STR_LIT>',<EOL>'<STR_LIT:h>': '<STR_LIT>',<EOL>'<STR_LIT>': '<STR_LIT>',<EOL>'<STR_LIT>': '<STR_LIT>',<EOL>'<STR_LIT:c>': '<STR_LIT>',<EOL>}.get(lexer_name.replace('<STR_LIT:.>', '<STR_LIT>'), lexer_name)<EOL>try:<EOL><INDENT>import pygments<EOL>import pygments.lexers<EOL>import pygments.formatters<EOL>import pygments.formatters.terminal<EOL>formater = pygments.formatters.terminal.TerminalFormatter(bg='<STR_LIT>')<EOL>lexer = pygments.lexers.get_lexer_by_name(lexer_name, ensurenl=False, **kwargs)<EOL>new_text = pygments.highlight(text, lexer, formater)<EOL><DEDENT>except ImportError:  <EOL><INDENT>new_text = text<EOL><DEDENT>return new_text<EOL>

Highlights a block of text using ansi tags based on language syntax.

Args:
    text (str): plain text to highlight
    lexer_name (str): name of language
    **kwargs: passed to pygments.lexers.get_lexer_by_name

Returns:
    str: text : highlighted text
        If pygments is not installed, the plain text is returned.

CommandLine:
    python -c "import pygments.formatters; print(list(pygments.formatters.get_all_formatters()))"

Example:
    >>> text = 'import xdoctest as xdoc; print(xdoc)'
    >>> new_text = highlight_code(text)
    >>> print(new_text)


def add_line_numbers(source, start=<NUM_LIT:1>, n_digits=None):

was_string = isinstance(source, six.string_types)<EOL>part_lines = source.splitlines() if was_string else source<EOL>if n_digits is None:<EOL><INDENT>endline = start + len(part_lines)<EOL>n_digits = math.log(max(<NUM_LIT:1>, endline), <NUM_LIT:10>)<EOL>n_digits = int(math.ceil(n_digits))<EOL><DEDENT>src_fmt = '<STR_LIT>'<EOL>part_lines = [<EOL>src_fmt.format(n_digits=n_digits, count=count, line=line)<EOL>for count, line in enumerate(part_lines, start=start)<EOL>]<EOL>if was_string:<EOL><INDENT>return '<STR_LIT:\n>'.join(part_lines)<EOL><DEDENT>else:<EOL><INDENT>return part_lines<EOL><DEDENT>

Prefixes code with line numbers

Example:
    >>> print(chr(10).join(add_line_numbers(['a', 'b', 'c'])))
    1 a
    2 b
    3 c
    >>> print(add_line_numbers(chr(10).join(['a', 'b', 'c'])))
    1 a
    2 b
    3 c


return textwrap.dedent(block_str).strip('<STR_LIT:\n>')<EOL>

Wraps multiline string blocks and returns unindented code.
Useful for templated code defined in indented parts of code.

Args:
    block_str (str): typically in the form of a multiline string

Returns:
    str: the unindented string

Example:
    >>> # Simulate an indented part of code
    >>> if True:
    ...     # notice the indentation on this will be normal
    ...     codeblock_version = codeblock(
    ...             '''
    ...             def foo():
    ...                 return 'bar'
    ...             '''
    ...         )
    ...     # notice the indentation and newlines on this will be odd
    ...     normal_version = ('''
    ...         def foo():
    ...             return 'bar'
    ...     ''')
    >>> assert normal_version != codeblock_version
    >>> print('Without codeblock')
    >>> print(normal_version)
    >>> print('With codeblock')
    >>> print(codeblock_version)


if True:<EOL><INDENT>import importlib<EOL>module = importlib.import_module(modname)<EOL><DEDENT>else:<EOL><INDENT>if '<STR_LIT:.>' in modname:<EOL><INDENT>fromlist = modname.split('<STR_LIT:.>')[-<NUM_LIT:1>]<EOL>fromlist_ = list(map(str, fromlist))  <EOL>module = __import__(modname, {}, {}, fromlist_, <NUM_LIT:0>)<EOL><DEDENT>else:<EOL><INDENT>module = __import__(modname, {}, {}, [], <NUM_LIT:0>)<EOL><DEDENT><DEDENT>return module<EOL>

Imports a module from its string name (__name__)

Args:
    modname (str):  module name

Returns:
    module: module

Example:
    >>> # test with modules that wont be imported in normal circumstances
    >>> # todo write a test where we gaurentee this
    >>> modname_list = [
    >>>     'pickletools',
    >>>     'lib2to3.fixes.fix_apply',
    >>> ]
    >>> #assert not any(m in sys.modules for m in modname_list)
    >>> modules = [import_module_from_name(modname) for modname in modname_list]
    >>> assert [m.__name__ for m in modules] == modname_list
    >>> assert all(m in sys.modules for m in modname_list)


import os<EOL>if not os.path.exists(modpath):<EOL><INDENT>import re<EOL>import zipimport<EOL>pat = '<STR_LIT>' + re.escape(os.path.sep) + '<STR_LIT>'<EOL>parts = re.split(pat, modpath, flags=re.IGNORECASE)<EOL>if len(parts) > <NUM_LIT:2>:<EOL><INDENT>archivepath = '<STR_LIT>'.join(parts[:-<NUM_LIT:1>])[:-<NUM_LIT:1>]<EOL>internal = parts[-<NUM_LIT:1>]<EOL>modname = os.path.splitext(internal)[<NUM_LIT:0>]<EOL>modname = os.path.normpath(modname)<EOL>if os.path.exists(archivepath):<EOL><INDENT>zimp_file = zipimport.zipimporter(archivepath)<EOL>module = zimp_file.load_module(modname)<EOL>return module<EOL><DEDENT><DEDENT>raise IOError('<STR_LIT>'.format(modpath))<EOL><DEDENT>else:<EOL><INDENT>module = _custom_import_modpath(modpath)<EOL>return module<EOL><DEDENT>

Imports a module via its path

Args:
    modpath (PathLike): path to the module on disk or within a zipfile.

Returns:
    module: the imported module

References:
    https://stackoverflow.com/questions/67631/import-module-given-path

Notes:
    If the module is part of a package, the package will be imported first.
    These modules may cause problems when reloading via IPython magic

    This can import a module from within a zipfile. To do this modpath
    should specify the path to the zipfile and the path to the module
    within that zipfile separated by a colon or pathsep.
    E.g. `/path/to/archive.zip:mymodule.py`

Warning:
    It is best to use this with paths that will not conflict with
    previously existing modules.

    If the modpath conflicts with a previously existing module name. And
    the target module does imports of its own relative to this conflicting
    path. In this case, the module that was loaded first will win.

    For example if you try to import '/foo/bar/pkg/mod.py' from the folder
    structure:
      - foo/
        +- bar/
           +- pkg/
              +  __init__.py
              |- mod.py
              |- helper.py

   If there exists another module named `pkg` already in sys.modules
   and mod.py does something like `from . import helper`, Python will
   assume helper belongs to the `pkg` module already in sys.modules.
   This can cause a NameError or worse --- a incorrect helper module.

Example:
    >>> import xdoctest
    >>> modpath = xdoctest.__file__
    >>> module = import_module_from_path(modpath)
    >>> assert module is xdoctest

Example:
    >>> # Test importing a module from within a zipfile
    >>> import zipfile
    >>> from xdoctest import utils
    >>> from os.path import join, expanduser
    >>> import os
    >>> dpath = expanduser('~/.cache/xdoctest')
    >>> dpath = utils.ensuredir(dpath)
    >>> #dpath = utils.TempDir().ensure()
    >>> # Write to an external module named bar
    >>> external_modpath = join(dpath, 'bar.py')
    >>> open(external_modpath, 'w').write('testvar = 1')
    >>> internal = 'folder/bar.py'
    >>> # Move the external bar module into a zipfile
    >>> zippath = join(dpath, 'myzip.zip')
    >>> with zipfile.ZipFile(zippath, 'w') as myzip:
    >>>     myzip.write(external_modpath, internal)
    >>> # Import the bar module from within the zipfile
    >>> modpath = zippath + ':' + internal
    >>> modpath = zippath + os.path.sep + internal
    >>> module = import_module_from_path(modpath)
    >>> assert module.__name__ == os.path.normpath('folder/bar')
    >>> assert module.testvar == 1

Doctest:
    >>> import pytest
    >>> with pytest.raises(IOError):
    >>>     import_module_from_path('does-not-exist')
    >>> with pytest.raises(IOError):
    >>>     import_module_from_path('does-not-exist.zip/')


return (self.redirect is not None and<EOL>hasattr(self.redirect, '<STR_LIT>') and self.redirect.isatty())<EOL>

Returns true of the redirect is a terminal.

Notes:
    Needed for IPython.embed to work properly when this class is used
    to override stdout / stderr.


self.cap_stdout.seek(self._pos)<EOL>text = self.cap_stdout.read()<EOL>self._pos = self.cap_stdout.tell()<EOL>self.parts.append(text)<EOL>self.text = text<EOL>


if isinstance(dpath, (list, tuple)):  <EOL><INDENT>dpath = join(*dpath)<EOL><DEDENT>if not exists(dpath):<EOL><INDENT>try:<EOL><INDENT>os.makedirs(normpath(dpath), mode=mode)<EOL><DEDENT>except OSError:  <EOL><INDENT>raise<EOL><DEDENT><DEDENT>return dpath<EOL>

Ensures that directory will exist. creates new dir with sticky bits by
default

Args:
    dpath (str): dir to ensure. Can also be a tuple to send to join
    mode (int): octal mode of directory (default 0o1777)

Returns:
    str: path - the ensured directory


from xdoctest import utils<EOL>from xdoctest import runner<EOL>COLOR = '<STR_LIT>'<EOL>def cprint(msg, color=COLOR):<EOL><INDENT>print(utils.color_text(str(msg), COLOR))<EOL><DEDENT>cprint('<STR_LIT>'<EOL>'<STR_LIT>'<EOL>'<STR_LIT>'<EOL>'<STR_LIT:\n>', COLOR)<EOL>cprint('<STR_LIT>')<EOL>cprint('<STR_LIT>')<EOL>print(utils.indent(<EOL>utils.add_line_numbers(utils.highlight_code(source, '<STR_LIT>'))))<EOL>print('<STR_LIT>')<EOL>import hashlib<EOL>hasher = hashlib.sha1()<EOL>hasher.update(source.encode('<STR_LIT:utf8>'))<EOL>hashid = hasher.hexdigest()[<NUM_LIT:0>:<NUM_LIT:8>]<EOL>with utils.TempDir() as temp:<EOL><INDENT>dpath = temp.dpath<EOL>modpath = join(dpath, '<STR_LIT>' + hashid + '<STR_LIT>')<EOL>with open(modpath, '<STR_LIT:w>') as file:<EOL><INDENT>file.write(source)<EOL><DEDENT>with utils.CaptureStdout(supress=False) as cap:<EOL><INDENT>runner.doctest_module(modpath, '<STR_LIT:all>', argv=['<STR_LIT>'], style=style)<EOL><DEDENT><DEDENT>cprint('<STR_LIT>', COLOR)<EOL>return cap.text<EOL>

TODO: run case is over-duplicated and should be separated into a test utils directory


def parse_freeform_docstr_examples(docstr, callname=None, modpath=None,<EOL>lineno=<NUM_LIT:1>, fpath=None, asone=True):

def doctest_from_parts(parts, num, curr_offset):<EOL><INDENT>nested = [<EOL>p.orig_lines<EOL>if p.want is None else<EOL>p.orig_lines + p.want.splitlines()<EOL>for p in parts<EOL>]<EOL>docsrc = '<STR_LIT:\n>'.join(list(it.chain.from_iterable(nested)))<EOL>docsrc = textwrap.dedent(docsrc)<EOL>example = doctest_example.DocTest(docsrc, modpath=modpath,<EOL>callname=callname, num=num,<EOL>lineno=lineno + curr_offset,<EOL>fpath=fpath)<EOL>unoffset = parts[<NUM_LIT:0>].line_offset<EOL>for p in parts:<EOL><INDENT>p.line_offset -= unoffset<EOL><DEDENT>example._parts = parts<EOL>return example<EOL><DEDENT>if DEBUG:<EOL><INDENT>print('<STR_LIT>'.format(<EOL>callname, modpath))<EOL><DEDENT>respect_google_headers = True<EOL>if respect_google_headers:  <EOL><INDENT>special_skip_patterns = [<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>]<EOL><DEDENT>else:<EOL><INDENT>special_skip_patterns = []  <EOL><DEDENT>special_skip_patterns_ = tuple([<EOL>p.lower() for p in special_skip_patterns<EOL>])<EOL>def _start_ignoring(prev):<EOL><INDENT>return (special_skip_patterns_ and<EOL>isinstance(prev, six.string_types) and<EOL>prev.strip().lower().endswith(special_skip_patterns_))<EOL><DEDENT>info = dict(callname=callname, modpath=modpath, lineno=lineno, fpath=fpath)<EOL>all_parts = list(parser.DoctestParser().parse(docstr, info))<EOL>curr_parts = []<EOL>curr_offset = <NUM_LIT:0><EOL>num = <NUM_LIT:0><EOL>prev_part = None<EOL>ignoring = False<EOL>for part in all_parts:<EOL><INDENT>if isinstance(part, six.string_types):<EOL><INDENT>if asone:<EOL><INDENT>if not curr_parts:<EOL><INDENT>curr_offset += part.count('<STR_LIT:\n>') + <NUM_LIT:1><EOL><DEDENT><DEDENT>else:  <EOL><INDENT>if curr_parts:<EOL><INDENT>example = doctest_from_parts(curr_parts, num, curr_offset)<EOL>yield example<EOL>curr_offset += sum(p.n_lines for p in curr_parts)<EOL>num += <NUM_LIT:1><EOL>curr_parts = []<EOL><DEDENT>curr_offset += part.count('<STR_LIT:\n>') + <NUM_LIT:1><EOL><DEDENT>ignoring = False<EOL><DEDENT>else:<EOL><INDENT>if ignoring or _start_ignoring(prev_part):<EOL><INDENT>ignoring = True<EOL>if asone:<EOL><INDENT>if not curr_parts:<EOL><INDENT>curr_offset += part.n_lines<EOL><DEDENT><DEDENT>else:<EOL><INDENT>curr_offset += part.n_lines<EOL><DEDENT><DEDENT>else:<EOL><INDENT>curr_parts.append(part)<EOL><DEDENT><DEDENT>prev_part = part<EOL><DEDENT>if curr_parts:<EOL><INDENT>example = doctest_from_parts(curr_parts, num, curr_offset)<EOL>yield example<EOL><DEDENT>

Finds free-form doctests in a docstring. This is similar to the original
doctests because these tests do not requires a google/numpy style header.

Some care is taken to avoid enabling tests that look like disabled google
doctests / scripts.

Args:
    asone (bool): if False doctests are broken into multiple examples
       based on spacing. (default True)

    lineno (int): the line number (starting from 1) of the docstring.
        (i.e. if you were to go to this line number in the source file
         the starting quotes of the docstr would be on this line).

Raises:
    xdoctest.exceptions.DoctestParseError: if an error occurs in parsing

CommandLine:
    python -m xdoctest.core parse_freeform_docstr_examples

Example:
    >>> from xdoctest import core
    >>> from xdoctest import utils
    >>> docstr = utils.codeblock(
        '''
        freeform
        >>> doctest
        >>> hasmultilines
        whoppie
        >>> 'butthis is the same doctest'

        >>> secondone

        Script:
            >>> 'special case, dont parse me'

        DisableDoctest:
            >>> 'special case, dont parse me'
            want

        AnythingElse:
            >>> 'general case, parse me'
            want
        ''')
    >>> examples = list(parse_freeform_docstr_examples(docstr, asone=True))
    >>> assert len(examples) == 1
    >>> examples = list(parse_freeform_docstr_examples(docstr, asone=False))
    >>> assert len(examples) == 3


def parse_google_docstr_examples(docstr, callname=None, modpath=None, lineno=<NUM_LIT:1>,<EOL>fpath=None, eager_parse=True):

try:<EOL><INDENT>blocks = docscrape_google.split_google_docblocks(docstr)<EOL><DEDENT>except exceptions.MalformedDocstr:<EOL><INDENT>print('<STR_LIT>'.format(<EOL>callname, modpath, lineno))<EOL>print('<STR_LIT>')<EOL>raise<EOL><DEDENT>example_blocks = []<EOL>example_tags = ('<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>')<EOL>for type, block in blocks:<EOL><INDENT>if type.startswith(example_tags):<EOL><INDENT>example_blocks.append((type, block))<EOL><DEDENT><DEDENT>for num, (type, (docsrc, offset)) in enumerate(example_blocks):<EOL><INDENT>label_lineno = lineno + offset<EOL>body_lineno = label_lineno + <NUM_LIT:1><EOL>example = doctest_example.DocTest(docsrc, modpath, callname, num,<EOL>lineno=body_lineno, fpath=fpath,<EOL>block_type=type)<EOL>if eager_parse:<EOL><INDENT>example._parse()<EOL><DEDENT>yield example<EOL><DEDENT>

Parses Google-style doctests from a docstr and generates example objects

Args:
    lineno (int): the line number (starting from 1) of the docstring.
        (i.e. if you were to go to this line number in the source file
         the starting quotes of the docstr would be on this line).

Raises:
    .exceptions.MalformedDocstr: if an error occurs in finding google blocks
    .exceptions.DoctestParseError: if an error occurs in parsing


def parse_auto_docstr_examples(docstr, *args, **kwargs):

if DEBUG:<EOL><INDENT>print('<STR_LIT>')<EOL><DEDENT>n_found = <NUM_LIT:0><EOL>try:<EOL><INDENT>for example in parse_google_docstr_examples(docstr, *args, **kwargs):<EOL><INDENT>n_found += <NUM_LIT:1><EOL>yield example<EOL><DEDENT><DEDENT>except Exception:<EOL><INDENT>if n_found > <NUM_LIT:0>:<EOL><INDENT>raise<EOL><DEDENT><DEDENT>if n_found == <NUM_LIT:0>:<EOL><INDENT>if DEBUG:<EOL><INDENT>print('<STR_LIT>')<EOL><DEDENT>for example in parse_freeform_docstr_examples(docstr, *args, **kwargs):<EOL><INDENT>yield example<EOL><DEDENT><DEDENT>

First try to parse google style, but if no tests are found use freeform
style.


def parse_docstr_examples(docstr, callname=None, modpath=None, lineno=<NUM_LIT:1>,<EOL>style='<STR_LIT>', fpath=None, parser_kw={}):

if DEBUG:<EOL><INDENT>print('<STR_LIT>'<EOL>'<STR_LIT>'.format(callname, modpath))<EOL><DEDENT>if style == '<STR_LIT>':<EOL><INDENT>parser = parse_freeform_docstr_examples<EOL><DEDENT>elif style == '<STR_LIT>':<EOL><INDENT>parser = parse_google_docstr_examples<EOL><DEDENT>elif style == '<STR_LIT>':<EOL><INDENT>parser = parse_auto_docstr_examples<EOL><DEDENT>else:<EOL><INDENT>raise KeyError('<STR_LIT>'.format(<EOL>style, DOCTEST_STYLES))<EOL><DEDENT>if DEBUG:<EOL><INDENT>print('<STR_LIT>'.format(parser))<EOL><DEDENT>n_parsed = <NUM_LIT:0><EOL>try:<EOL><INDENT>for example in parser(docstr, callname=callname, modpath=modpath,<EOL>fpath=fpath, lineno=lineno, **parser_kw):<EOL><INDENT>n_parsed += <NUM_LIT:1><EOL>yield example<EOL><DEDENT><DEDENT>except Exception as ex:<EOL><INDENT>if DEBUG:<EOL><INDENT>print('<STR_LIT>')<EOL><DEDENT>msg = ('<STR_LIT>'<EOL>'<STR_LIT>')<EOL>msg = msg.format(callname, modpath, lineno, repr(ex))<EOL>if isinstance(ex, exceptions.DoctestParseError):<EOL><INDENT>msg += '<STR_LIT>'.format(ex.string)<EOL>msg += '<STR_LIT>'.format(repr(ex.orig_ex))<EOL>if isinstance(ex.orig_ex, SyntaxError):<EOL><INDENT>extra_help = '<STR_LIT>'<EOL>if ex.orig_ex.text:<EOL><INDENT>extra_help += utils.ensure_unicode(ex.orig_ex.text)<EOL><DEDENT>if ex.orig_ex.offset is not None:<EOL><INDENT>extra_help += '<STR_LIT:U+0020>' * (ex.orig_ex.offset - <NUM_LIT:1>) + '<STR_LIT>'<EOL><DEDENT>if extra_help:<EOL><INDENT>msg += '<STR_LIT:\n>' + extra_help<EOL><DEDENT><DEDENT><DEDENT>print('<STR_LIT>'.format(msg))<EOL>warnings.warn(msg)<EOL>if isinstance(ex, exceptions.MalformedDocstr):<EOL><INDENT>pass<EOL><DEDENT>elif isinstance(ex, exceptions.DoctestParseError):<EOL><INDENT>pass<EOL><DEDENT>else:<EOL><INDENT>raise<EOL><DEDENT><DEDENT>if DEBUG:<EOL><INDENT>print('<STR_LIT>'.format(n_parsed))<EOL><DEDENT>

Parses doctests from a docstr and generates example objects.
The style influences which tests are found.

Args:
    docstr (str): a previously extracted docstring

    callname (str): function or class name or class and method name

    modpath (PathLike): original module the docstring is from

    lineno (int): the line number (starting from 1) of the docstring.
        (i.e. if you were to go to this line number in the source file
         the starting quotes of the docstr would be on this line).

    style (str): expected doctest style (e.g. google, freeform, auto)

    fpath (PathLike): the file that the docstring is from
        (if the file was not a module, needed for backwards compatibility)

    parser_kw (dict): passed to the parser

CommandLine:
    python -m xdoctest.core parse_docstr_examples

Example:
    >>> from xdoctest.core import *
    >>> from xdoctest import utils
    >>> docstr = utils.codeblock(
    ...    '''
    ...    >>> 1 + 1  # xdoctest: +SKIP
    ...    2
    ...    >>> 2 + 2
    ...    4
    ...    ''')
    >>> examples = list(parse_docstr_examples(docstr, 'name', fpath='foo.txt', style='freeform'))
    >>> print(len(examples))
    1
    >>> examples = list(parse_docstr_examples(docstr, fpath='foo.txt'))


modpath = static.modname_to_modpath(modpath_or_name)<EOL>if modpath is None:<EOL><INDENT>if six.PY2:<EOL><INDENT>if modpath_or_name.endswith('<STR_LIT>'):<EOL><INDENT>modpath_or_name = modpath_or_name[:-<NUM_LIT:1>]<EOL><DEDENT><DEDENT>if exists(modpath_or_name):<EOL><INDENT>modpath = modpath_or_name<EOL><DEDENT>else:<EOL><INDENT>raise ValueError('<STR_LIT>'.format(modpath_or_name))<EOL><DEDENT><DEDENT>return modpath<EOL>

if modpath_or_name is a name, statically converts it to a path


def package_calldefs(modpath_or_name, exclude=[], ignore_syntax_errors=True):

pkgpath = _rectify_to_modpath(modpath_or_name)<EOL>modpaths = static.package_modpaths(pkgpath, with_pkg=True, with_libs=True)<EOL>modpaths = list(modpaths)<EOL>for modpath in modpaths:<EOL><INDENT>modname = static.modpath_to_modname(modpath)<EOL>if any(fnmatch(modname, pat) for pat in exclude):<EOL><INDENT>continue<EOL><DEDENT>if not exists(modpath):<EOL><INDENT>warnings.warn(<EOL>'<STR_LIT>'<EOL>'<STR_LIT>'.format(modname))<EOL>continue<EOL><DEDENT>FORCE_DYNAMIC = '<STR_LIT>' in sys.argv<EOL>ALLOW_DYNAMIC = '<STR_LIT>' in sys.argv<EOL>needs_dynamic = False<EOL>if FORCE_DYNAMIC:<EOL><INDENT>do_dynamic = True<EOL><DEDENT>else:<EOL><INDENT>needs_dynamic = modpath.endswith(static._platform_pylib_exts())<EOL>do_dynamic = needs_dynamic and ALLOW_DYNAMIC<EOL><DEDENT>if do_dynamic:<EOL><INDENT>try:<EOL><INDENT>calldefs = dynamic.parse_dynamic_calldefs(modpath)<EOL><DEDENT>except ImportError as ex:<EOL><INDENT>msg = '<STR_LIT>'<EOL>msg = msg.format(modname, modpath, type(ex), ex)<EOL>warnings.warn(msg)<EOL><DEDENT>except Exception as ex:<EOL><INDENT>msg = '<STR_LIT>'<EOL>msg = msg.format(modname, modpath, type(ex), ex)<EOL>warnings.warn(msg)<EOL>raise<EOL><DEDENT>else:<EOL><INDENT>yield calldefs, modpath<EOL><DEDENT><DEDENT>else:<EOL><INDENT>if needs_dynamic:<EOL><INDENT>continue<EOL><DEDENT>try:<EOL><INDENT>calldefs = static.parse_calldefs(fpath=modpath)<EOL><DEDENT>except SyntaxError as ex:<EOL><INDENT>msg = '<STR_LIT>'<EOL>msg = msg.format(modname, modpath, ex)<EOL>if ignore_syntax_errors:<EOL><INDENT>warnings.warn(msg)  <EOL>continue<EOL><DEDENT>else:<EOL><INDENT>raise SyntaxError(msg)<EOL><DEDENT><DEDENT>else:<EOL><INDENT>yield calldefs, modpath<EOL><DEDENT><DEDENT><DEDENT>

Statically generates all callable definitions in a module or package

Args:
    modpath_or_name (str): path to or name of the module to be tested
    exclude (List[str]): glob-patterns of file names to exclude
    ignore_syntax_errors (bool): if False raise an error when syntax errors
        occur in a doctest (default True)

Example:
    >>> modpath_or_name = 'xdoctest.core'
    >>> testables = list(package_calldefs(modpath_or_name))
    >>> assert len(testables) == 1
    >>> calldefs, modpath = testables[0]
    >>> assert static.modpath_to_modname(modpath) == modpath_or_name
    >>> assert 'package_calldefs' in calldefs


return '<STR_LIT>'.format(key, pattern)<EOL>


optpart = optpart.strip()<EOL>optpart = optpart.replace('<STR_LIT:U+0020>', '<STR_LIT>')<EOL>paren_pos = optpart.find('<STR_LIT:(>')<EOL>if paren_pos > -<NUM_LIT:1>:<EOL><INDENT>args = [optpart[paren_pos + <NUM_LIT:1>:optpart.find('<STR_LIT:)>')]]<EOL>optpart = optpart[:paren_pos]<EOL><DEDENT>else:<EOL><INDENT>args = []<EOL><DEDENT>if optpart.startswith(('<STR_LIT:+>', '<STR_LIT:->')):<EOL><INDENT>positive = not optpart.startswith('<STR_LIT:->')<EOL>name = optpart[<NUM_LIT:1>:]<EOL><DEDENT>else:<EOL><INDENT>positive = True<EOL>name = optpart<EOL><DEDENT>name = name.upper()<EOL>if name not in COMMANDS:<EOL><INDENT>msg = '<STR_LIT>'.format(optpart)<EOL>warnings.warn(msg)<EOL><DEDENT>else:<EOL><INDENT>directive = Directive(name, positive, args, inline)<EOL>return directive<EOL><DEDENT>

Parses the information in the directive from the "optpart"

optstrs are:
    optionally prefixed with `+` (default) or `-`
    comma separated
    may contain one paren enclosed argument (experimental)
    all spaces are ignored

Returns:
    Directive: the parsed directive

Example:
    >>> print(str(parse_directive_optstr('+IGNORE_WHITESPACE')))
    <Directive(+IGNORE_WHITESPACE)>


def set_report_style(self, reportchoice, state=None):

<EOL>if state is None:<EOL><INDENT>state = self._global_state<EOL><DEDENT>for k in state.keys():<EOL><INDENT>if k.startswith('<STR_LIT>'):<EOL><INDENT>state[k] = False<EOL><DEDENT><DEDENT>state['<STR_LIT>' + reportchoice.upper()] = True<EOL>

Example:
    >>> from xdoctest.directive import *
    >>> runstate = RuntimeState()
    >>> assert runstate['REPORT_UDIFF']
    >>> runstate.set_report_style('ndiff')
    >>> assert not runstate['REPORT_UDIFF']
    >>> assert runstate['REPORT_NDIFF']


<EOL>inline = not all(line.strip().startswith('<STR_LIT:#>')<EOL>for line in text.splitlines())<EOL>for comment in static.extract_comments(text):<EOL><INDENT>m = DIRECTIVE_RE.match(comment[<NUM_LIT:1>:].strip())<EOL>if m:<EOL><INDENT>for key, optstr in m.groupdict().items():<EOL><INDENT>if optstr:<EOL><INDENT>for optpart in optstr.split('<STR_LIT:U+002C>'):<EOL><INDENT>directive = parse_directive_optstr(optpart, inline)<EOL>if directive:<EOL><INDENT>yield directive<EOL><DEDENT><DEDENT><DEDENT><DEDENT><DEDENT><DEDENT>

Parses directives from a line or repl line

Args:
    text (str): must correspond to exactly one PS1 line and its PS2
        followups.

Yeilds:
    Directive: directive: the parsed directives

Notes:
    The original `doctest` module sometimes yeilded false positives for a
    directive pattern. Because `xdoctest` is parsing the text, this issue
    does not occur.

Example:
    >>> from xdoctest.directive import Directive
    >>> text = '# xdoc: + SKIP'
    >>> print(', '.join(list(map(str, Directive.extract(text)))))
    <Directive(+SKIP)>

    >>> # Directive with args
    >>> text = '# xdoctest: requires(--show)'
    >>> print(', '.join(list(map(str, Directive.extract(text)))))
    <Directive(+REQUIRES(--show))>

    >>> # Malformatted directives are ignored
    >>> text = '# xdoctest: does_not_exist, skip'
    >>> import pytest
    >>> with pytest.warns(None) as record:
    >>>     print(', '.join(list(map(str, Directive.extract(text)))))
    <Directive(+SKIP)>

    >>> # Two directives in one line
    >>> text = '# xdoctest: +ELLIPSIS, -NORMALIZE_WHITESPACE'
    >>> print(', '.join(list(map(str, Directive.extract(text)))))
    <Directive(+ELLIPSIS)>, <Directive(-NORMALIZE_WHITESPACE)>

Example:
    >>> any(Directive.extract(' # xdoctest: skip'))
    True
    >>> any(Directive.extract(' # badprefix: not-a-directive'))
    False
    >>> any(Directive.extract(' # xdoctest: skip'))
    True
    >>> any(Directive.extract(' # badprefix: not-a-directive'))
    False


if self.name == '<STR_LIT>':<EOL><INDENT>if argv is None:<EOL><INDENT>argv = sys.argv<EOL><DEDENT>arg, = self.unpack_args(<NUM_LIT:1>)<EOL>SYS_PLATFORM_TAGS = ['<STR_LIT:win32>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>']<EOL>OS_NAME_TAGS = ['<STR_LIT>', '<STR_LIT>', '<STR_LIT>']<EOL>if self.positive:<EOL><INDENT>key = '<STR_LIT>'<EOL>if arg.startswith('<STR_LIT:->'):<EOL><INDENT>value = arg not in argv<EOL><DEDENT>elif arg.startswith('<STR_LIT>'):<EOL><INDENT>parts = arg.split('<STR_LIT::>')<EOL>if len(parts) != <NUM_LIT:2>:<EOL><INDENT>raise ValueError('<STR_LIT>')<EOL><DEDENT>modname = parts[<NUM_LIT:1>]<EOL>value = not _module_exists(modname)<EOL><DEDENT>elif arg.lower() in SYS_PLATFORM_TAGS:<EOL><INDENT>value = not sys.platform.startswith(arg.lower())<EOL><DEDENT>elif arg.lower() in OS_NAME_TAGS:<EOL><INDENT>value = not os.name.startswith(arg.lower())<EOL><DEDENT>else:<EOL><INDENT>msg = utils.codeblock(<EOL>'''<STR_LIT>''').replace('<STR_LIT:\n>', '<STR_LIT:U+0020>').strip().format(arg)<EOL>raise ValueError(msg)<EOL><DEDENT><DEDENT>else:<EOL><INDENT>key = '<STR_LIT>'<EOL>value = True<EOL><DEDENT><DEDENT>else:<EOL><INDENT>key = self.name<EOL>value = self.positive<EOL><DEDENT>return key, value<EOL>

Example:
    >>> Directive('SKIP').state_item()
    ('SKIP', True)
    >>> Directive('SKIP', inline=True).state_item()
    ('SKIP', True)
    >>> Directive('REQUIRES', args=['-s']).state_item(argv=['-s'])
    ('SKIP', False)
    >>> Directive('REQUIRES', args=['-s']).state_item(argv=[])
    ('SKIP', True)
    >>> Directive('ELLIPSIS', args=['-s']).state_item(argv=[])
    ('ELLIPSIS', True)

Doctest:
    >>> # requirement directive with module
    >>> directive = list(Directive.extract('# xdoctest: requires(module:xdoctest)'))[0]
    >>> print('directive = {}'.format(directive))
    >>> print('directive.state_item() = {}'.format(directive.state_item()))
    directive = <Directive(+REQUIRES(module:xdoctest))>
    directive.state_item() = ('SKIP', False)

    >>> directive = list(Directive.extract('# xdoctest: requires(module:motamodule)'))[0]
    >>> print('directive = {}'.format(directive))
    >>> print('directive.state_item() = {}'.format(directive.state_item()))
    directive = <Directive(+REQUIRES(module:motamodule))>
    directive.state_item() = ('SKIP', True)


def _print_summary_report(run_summary, parse_warnlist, n_seconds,<EOL>enabled_examples, durations, config=None):

def cprint(text, color):<EOL><INDENT>if config is not None and config.get('<STR_LIT>', True):<EOL><INDENT>print(utils.color_text(text, color))<EOL><DEDENT>else:<EOL><INDENT>print(text)<EOL><DEDENT><DEDENT>failed = run_summary.get('<STR_LIT>', [])<EOL>warned = run_summary.get('<STR_LIT>', [])<EOL>if parse_warnlist:<EOL><INDENT>cprint('<STR_LIT>'.format(<EOL>len(parse_warnlist)), '<STR_LIT>')<EOL>for warn_idx, warn in enumerate(parse_warnlist, start=<NUM_LIT:1>):<EOL><INDENT>cprint('<STR_LIT>'.format(<EOL>warn_idx, len(parse_warnlist)), '<STR_LIT>')<EOL>print(utils.indent(<EOL>warnings.formatwarning(warn.message, warn.category,<EOL>warn.filename, warn.lineno)))<EOL><DEDENT><DEDENT>if warned:<EOL><INDENT>cprint('<STR_LIT>'.format(len(warned)), '<STR_LIT>')<EOL>for warn_idx, example in enumerate(warned, start=<NUM_LIT:1>):<EOL><INDENT>cprint('<STR_LIT>'.format(warn_idx, len(warned)),<EOL>'<STR_LIT>')<EOL>print('<STR_LIT>'.format(example))<EOL>for warn in example.warn_list:<EOL><INDENT>print(utils.indent(<EOL>warnings.formatwarning(warn.message, warn.category,<EOL>warn.filename, warn.lineno)))<EOL><DEDENT><DEDENT><DEDENT>if failed and len(enabled_examples) > <NUM_LIT:1>:<EOL><INDENT>cprint('<STR_LIT>'.format(len(failed)), '<STR_LIT>')<EOL>for fail_idx, example in enumerate(failed, start=<NUM_LIT:1>):<EOL><INDENT>cprint('<STR_LIT>'.format(fail_idx, len(failed)), '<STR_LIT>')<EOL>print(utils.indent('<STR_LIT:\n>'.join(example.repr_failure())))<EOL><DEDENT><DEDENT>if failed:<EOL><INDENT>cprint('<STR_LIT>', '<STR_LIT>')<EOL>for example in failed:<EOL><INDENT>print(example.cmdline)<EOL><DEDENT><DEDENT>n_passed = run_summary.get('<STR_LIT>', <NUM_LIT:0>)<EOL>n_failed = run_summary.get('<STR_LIT>', <NUM_LIT:0>)<EOL>n_warnings = len(warned) + len(parse_warnlist)<EOL>pairs = zip([n_failed, n_passed, n_warnings],<EOL>['<STR_LIT>', '<STR_LIT>', '<STR_LIT>'])<EOL>parts = ['<STR_LIT>'.format(n=n, t=t) for n, t in pairs  if n > <NUM_LIT:0>]<EOL>_fmtstr = '<STR_LIT>' + '<STR_LIT:U+0020>'.join(parts) + '<STR_LIT>'<EOL>summary_line = _fmtstr.format(n_seconds=n_seconds)<EOL>if n_failed > <NUM_LIT:0>:<EOL><INDENT>cprint(summary_line, '<STR_LIT>')<EOL><DEDENT>elif n_warnings > <NUM_LIT:0>:<EOL><INDENT>cprint(summary_line, '<STR_LIT>')<EOL><DEDENT>else:<EOL><INDENT>cprint(summary_line, '<STR_LIT>')<EOL><DEDENT>if durations is not None:<EOL><INDENT>times = run_summary.get('<STR_LIT>', {})<EOL>test_time_tups = sorted(times.items(), key=lambda x: x[<NUM_LIT:1>])<EOL>if durations > <NUM_LIT:0>:<EOL><INDENT>test_time_tups = test_time_tups[-durations:]<EOL><DEDENT>for example, n_secs in test_time_tups:<EOL><INDENT>print('<STR_LIT>'.format(n_secs, example.cmdline))<EOL><DEDENT><DEDENT>


for calldefs, _modpath in core.package_calldefs(modpath):<EOL><INDENT>for callname, calldef in calldefs.items():<EOL><INDENT>if calldef.args is not None:<EOL><INDENT>n_args = len(calldef.args.args) - len(calldef.args.defaults)<EOL>if n_args == <NUM_LIT:0>:<EOL><INDENT>docsrc = '<STR_LIT>'.format(callname)<EOL>example = doctest_example.DocTest(docsrc=docsrc,<EOL>modpath=_modpath,<EOL>callname=callname,<EOL>block_type='<STR_LIT>')<EOL>example.mode = '<STR_LIT>'<EOL>yield example<EOL><DEDENT><DEDENT><DEDENT><DEDENT>

Find functions in `modpath` args  with no args (so we can automatically
make a dummy docstring).


def _run_examples(enabled_examples, verbose, config=None):

n_total = len(enabled_examples)<EOL>print('<STR_LIT>' % n_total)<EOL>summaries = []<EOL>failed = []<EOL>warned = []<EOL>times = {}<EOL>FIRST_TEST_HACK = False  <EOL>on_error = '<STR_LIT>' if n_total > <NUM_LIT:1> else '<STR_LIT>'<EOL>on_error = '<STR_LIT>'<EOL>for example in enabled_examples:<EOL><INDENT>try:<EOL><INDENT>try:<EOL><INDENT>tic = time.time()<EOL>summary = example.run(verbose=verbose, on_error=on_error)<EOL>toc = time.time()<EOL>if FIRST_TEST_HACK:<EOL><INDENT>tic = time.time()<EOL>summary = example.run(verbose=verbose, on_error=on_error)<EOL>toc = time.time()<EOL>FIRST_TEST_HACK = False<EOL><DEDENT>n_seconds = toc - tic<EOL>times[example] = n_seconds<EOL><DEDENT>except Exception:<EOL><INDENT>print('<STR_LIT:\n>'.join(example.repr_failure(with_tb=False)))<EOL>raise<EOL><DEDENT>summaries.append(summary)<EOL>if example.warn_list:<EOL><INDENT>warned.append(example)<EOL><DEDENT>if summary['<STR_LIT>']:<EOL><INDENT>if verbose == <NUM_LIT:0>:<EOL><INDENT>sys.stdout.write('<STR_LIT:.>')<EOL>sys.stdout.flush()<EOL><DEDENT><DEDENT>else:<EOL><INDENT>failed.append(example)<EOL>if verbose == <NUM_LIT:0>:<EOL><INDENT>sys.stdout.write('<STR_LIT:F>')<EOL>sys.stdout.flush()<EOL><DEDENT>if on_error == '<STR_LIT>':<EOL><INDENT>print('<STR_LIT:\n>'.join(example.repr_failure()))<EOL>ex_value = example.exc_info[<NUM_LIT:1>]<EOL>raise ex_value<EOL><DEDENT><DEDENT><DEDENT>except KeyboardInterrupt:<EOL><INDENT>print('<STR_LIT>')<EOL>break<EOL><DEDENT><DEDENT>if verbose == <NUM_LIT:0>:<EOL><INDENT>print('<STR_LIT>')<EOL><DEDENT>n_passed = sum(s['<STR_LIT>'] for s in summaries)<EOL>if config is not None and config.get('<STR_LIT>', True):<EOL><INDENT>print(utils.color_text('<STR_LIT>', '<STR_LIT>'))<EOL><DEDENT>else:<EOL><INDENT>print('<STR_LIT>')<EOL><DEDENT>if n_total > <NUM_LIT:1>:<EOL><INDENT>print('<STR_LIT>')<EOL>print('<STR_LIT>'  % (n_passed, n_total))<EOL><DEDENT>run_summary = {<EOL>'<STR_LIT>': failed,<EOL>'<STR_LIT>': warned,<EOL>'<STR_LIT:action>': '<STR_LIT>',<EOL>'<STR_LIT>': len(warned),<EOL>'<STR_LIT>': n_passed,<EOL>'<STR_LIT>': n_total - n_passed,<EOL>'<STR_LIT>': n_total,<EOL>'<STR_LIT>': times,<EOL>}<EOL>return run_summary<EOL>

Internal helper, loops over each example, runs it, returns a summary


if six.PY2:<EOL><INDENT>fpath = fpath.replace('<STR_LIT>', '<STR_LIT>')<EOL><DEDENT>if source is None:  <EOL><INDENT>try:<EOL><INDENT>with open(fpath, '<STR_LIT:rb>') as file_:<EOL><INDENT>source = file_.read().decode('<STR_LIT:utf-8>')<EOL><DEDENT><DEDENT>except Exception as ex:<EOL><INDENT>try:<EOL><INDENT>with open(fpath, '<STR_LIT:rb>') as file_:<EOL><INDENT>source = file_.read()<EOL><DEDENT><DEDENT>except Exception:<EOL><INDENT>print('<STR_LIT>'.format(fpath))<EOL>raise<EOL><DEDENT><DEDENT><DEDENT>try:<EOL><INDENT>self = TopLevelVisitor.parse(source)<EOL>return self.calldefs<EOL><DEDENT>except Exception:  <EOL><INDENT>if fpath:<EOL><INDENT>print('<STR_LIT>' % (fpath,))<EOL><DEDENT>else:<EOL><INDENT>print('<STR_LIT>')<EOL><DEDENT>raise<EOL><DEDENT>

Statically finds top-level callable functions and methods in python source

Args:
    source (str): python text
    fpath (str): filepath to read if source is not specified

Returns:
    dict(str, CallDefNode): map of callnames to tuples with def info

Example:
    >>> from xdoctest import static_analysis
    >>> fpath = static_analysis.__file__.replace('.pyc', '.py')
    >>> calldefs = parse_calldefs(fpath=fpath)
    >>> assert 'parse_calldefs' in calldefs


if isinstance(node, ast.Num):<EOL><INDENT>value = node.n<EOL><DEDENT>elif isinstance(node, ast.Str):<EOL><INDENT>value = node.s<EOL><DEDENT>elif isinstance(node, ast.List):<EOL><INDENT>value = list(map(_parse_static_node_value, node.elts))<EOL><DEDENT>elif isinstance(node, ast.Tuple):<EOL><INDENT>value = tuple(map(_parse_static_node_value, node.elts))<EOL><DEDENT>elif isinstance(node, (ast.Dict)):<EOL><INDENT>keys = map(_parse_static_node_value, node.keys)<EOL>values = map(_parse_static_node_value, node.values)<EOL>value = OrderedDict(zip(keys, values))<EOL><DEDENT>elif six.PY3 and isinstance(node, (ast.NameConstant)):<EOL><INDENT>value = node.value<EOL><DEDENT>elif (six.PY2 and isinstance(node, ast.Name) and<EOL>node.id in ['<STR_LIT:None>', '<STR_LIT:True>', '<STR_LIT:False>']):<EOL><INDENT>value = {'<STR_LIT:None>': None, '<STR_LIT:True>': True, '<STR_LIT:False>': False}[node.id]<EOL><DEDENT>else:<EOL><INDENT>print(node.__dict__)<EOL>raise TypeError('<STR_LIT>'<EOL>'<STR_LIT>'.format(type(node)))<EOL><DEDENT>return value<EOL>

Extract a constant value from a node if possible


def parse_static_value(key, source=None, fpath=None):

if source is None:  <EOL><INDENT>try:<EOL><INDENT>with open(fpath, '<STR_LIT:rb>') as file_:<EOL><INDENT>source = file_.read().decode('<STR_LIT:utf-8>')<EOL><DEDENT><DEDENT>except Exception as ex:<EOL><INDENT>with open(fpath, '<STR_LIT:rb>') as file_:<EOL><INDENT>source = file_.read()<EOL><DEDENT><DEDENT><DEDENT>pt = ast.parse(source)<EOL>class AssignentVisitor(ast.NodeVisitor):<EOL><INDENT>def visit_Assign(self, node):<EOL><INDENT>for target in node.targets:<EOL><INDENT>target_id = getattr(target, '<STR_LIT:id>', None)<EOL>if target_id == key:<EOL><INDENT>self.value = _parse_static_node_value(node.value)<EOL><DEDENT><DEDENT><DEDENT><DEDENT>sentinal = object()<EOL>visitor = AssignentVisitor()<EOL>visitor.value = sentinal<EOL>visitor.visit(pt)<EOL>if visitor.value is sentinal:<EOL><INDENT>raise NameError('<STR_LIT>'.format(key))<EOL><DEDENT>return visitor.value<EOL>

Statically parse a constant variable's value from python code.

TODO: This does not belong here. Move this to an external static analysis
library.

Args:
    key (str): name of the variable
    source (str): python text
    fpath (str): filepath to read if source is not specified

Example:
    >>> from xdoctest.static_analysis import parse_static_value
    >>> key = 'foo'
    >>> source = 'foo = 123'
    >>> assert parse_static_value(key, source=source) == 123
    >>> source = 'foo = "123"'
    >>> assert parse_static_value(key, source=source) == '123'
    >>> source = 'foo = [1, 2, 3]'
    >>> assert parse_static_value(key, source=source) == [1, 2, 3]
    >>> source = 'foo = (1, 2, "3")'
    >>> assert parse_static_value(key, source=source) == (1, 2, "3")
    >>> source = 'foo = {1: 2, 3: 4}'
    >>> assert parse_static_value(key, source=source) == {1: 2, 3: 4}
    >>> source = 'foo = None'
    >>> assert parse_static_value(key, source=source) == None
    >>> #parse_static_value('bar', source=source)
    >>> #parse_static_value('bar', source='foo=1; bar = [1, foo]')


import sysconfig<EOL>tags = []<EOL>if six.PY2:<EOL><INDENT>multiarch = sysconfig.get_config_var('<STR_LIT>')<EOL>if multiarch is not None:<EOL><INDENT>tags.append(multiarch)<EOL><DEDENT><DEDENT>else:<EOL><INDENT>tags.append(sysconfig.get_config_var('<STR_LIT>'))<EOL>tags.append('<STR_LIT>')  <EOL><DEDENT>tags = [t for t in tags if t]<EOL>return tags<EOL>

Returns valid tags an extension module might have


import sysconfig<EOL>valid_exts = []<EOL>if six.PY2:<EOL><INDENT>base_ext = '<STR_LIT:.>' + sysconfig.get_config_var('<STR_LIT>').split('<STR_LIT:.>')[-<NUM_LIT:1>]<EOL><DEDENT>else:<EOL><INDENT>base_ext = '<STR_LIT:.>' + sysconfig.get_config_var('<STR_LIT>').split('<STR_LIT:.>')[-<NUM_LIT:1>]<EOL><DEDENT>for tag in _extension_module_tags():<EOL><INDENT>valid_exts.append('<STR_LIT:.>' + tag + base_ext)<EOL><DEDENT>valid_exts.append(base_ext)<EOL>return tuple(valid_exts)<EOL>

Returns .so, .pyd, or .dylib depending on linux, win or mac.
On python3 return the previous with and without abi (e.g.
.cpython-35m-x86_64-linux-gnu) flags. On python2 returns with
and without multiarch.


def normalize_modpath(modpath, hide_init=True, hide_main=False):

if six.PY2:<EOL><INDENT>if modpath.endswith('<STR_LIT>'):<EOL><INDENT>modpath = modpath[:-<NUM_LIT:1>]<EOL><DEDENT><DEDENT>if hide_init:<EOL><INDENT>if basename(modpath) == '<STR_LIT>':<EOL><INDENT>modpath = dirname(modpath)<EOL>hide_main = True<EOL><DEDENT><DEDENT>else:<EOL><INDENT>modpath_with_init = join(modpath, '<STR_LIT>')<EOL>if exists(modpath_with_init):<EOL><INDENT>modpath = modpath_with_init<EOL><DEDENT><DEDENT>if hide_main:<EOL><INDENT>if basename(modpath) == '<STR_LIT>':<EOL><INDENT>parallel_init = join(dirname(modpath), '<STR_LIT>')<EOL>if exists(parallel_init):<EOL><INDENT>modpath = dirname(modpath)<EOL><DEDENT><DEDENT><DEDENT>return modpath<EOL>

Normalizes __init__ and __main__ paths.

Notes:
    Adds __init__ if reasonable, but only removes __main__ by default

Args:
    hide_init (bool): if True, always return package modules
       as __init__.py files otherwise always return the dpath.
    hide_init (bool): if True, always strip away main files otherwise
       ignore __main__.py.

CommandLine:
    xdoctest -m xdoctest.static_analysis normalize_modpath

Example:
    >>> import xdoctest.static_analysis as static
    >>> modpath = static.__file__
    >>> assert static.normalize_modpath(modpath) == modpath.replace('.pyc', '.py')
    >>> dpath = dirname(modpath)
    >>> res0 = static.normalize_modpath(dpath, hide_init=0, hide_main=0)
    >>> res1 = static.normalize_modpath(dpath, hide_init=0, hide_main=1)
    >>> res2 = static.normalize_modpath(dpath, hide_init=1, hide_main=0)
    >>> res3 = static.normalize_modpath(dpath, hide_init=1, hide_main=1)
    >>> assert res0.endswith('__init__.py')
    >>> assert res1.endswith('__init__.py')
    >>> assert not res2.endswith('.py')
    >>> assert not res3.endswith('.py')


def package_modpaths(pkgpath, with_pkg=False, with_mod=True, followlinks=True,<EOL>recursive=True, with_libs=False, check=True):

if isfile(pkgpath):<EOL><INDENT>yield pkgpath<EOL><DEDENT>else:<EOL><INDENT>if with_pkg:<EOL><INDENT>root_path = join(pkgpath, '<STR_LIT>')<EOL>if not check or exists(root_path):<EOL><INDENT>yield root_path<EOL><DEDENT><DEDENT>valid_exts = ['<STR_LIT>']<EOL>if with_libs:<EOL><INDENT>valid_exts += _platform_pylib_exts()<EOL><DEDENT>for dpath, dnames, fnames in os.walk(pkgpath, followlinks=followlinks):<EOL><INDENT>ispkg = exists(join(dpath, '<STR_LIT>'))<EOL>if ispkg or not check:<EOL><INDENT>check = True  <EOL>if with_mod:<EOL><INDENT>for fname in fnames:<EOL><INDENT>if splitext(fname)[<NUM_LIT:1>] in valid_exts:<EOL><INDENT>if fname != '<STR_LIT>':<EOL><INDENT>path = join(dpath, fname)<EOL>yield path<EOL><DEDENT><DEDENT><DEDENT><DEDENT>if with_pkg:<EOL><INDENT>for dname in dnames:<EOL><INDENT>path = join(dpath, dname, '<STR_LIT>')<EOL>if exists(path):<EOL><INDENT>yield path<EOL><DEDENT><DEDENT><DEDENT><DEDENT>else:<EOL><INDENT>del dnames[:]<EOL><DEDENT>if not recursive:<EOL><INDENT>break<EOL><DEDENT><DEDENT><DEDENT>

r"""
    Finds sub-packages and sub-modules belonging to a package.

    Args:
        pkgpath (str): path to a module or package
        with_pkg (bool): if True includes package __init__ files (default =
            False)
        with_mod (bool): if True includes module files (default = True)
        exclude (list): ignores any module that matches any of these patterns
        recursive (bool): if False, then only child modules are included
        with_libs (bool): if True then compiled shared libs will be returned as well
        check (bool): if False, then then pkgpath is considered a module even
            if it does not contain an __init__ file.

    Yields:
        str: module names belonging to the package

    References:
        http://stackoverflow.com/questions/1707709/list-modules-in-py-package

    Example:
        >>> from xdoctest.static_analysis import *
        >>> pkgpath = modname_to_modpath('xdoctest')
        >>> paths = list(package_modpaths(pkgpath))
        >>> print('\n'.join(paths))
        >>> names = list(map(modpath_to_modname, paths))
        >>> assert 'xdoctest.core' in names
        >>> assert 'xdoctest.__main__' in names
        >>> assert 'xdoctest' not in names
        >>> print('\n'.join(names))


if six.PY2:<EOL><INDENT>if modpath.endswith('<STR_LIT>'):<EOL><INDENT>modpath = modpath[:-<NUM_LIT:1>]<EOL><DEDENT><DEDENT>modpath_ = abspath(expanduser(modpath))<EOL>if check:<EOL><INDENT>if not exists(modpath_):<EOL><INDENT>if not exists(modpath):<EOL><INDENT>raise ValueError('<STR_LIT>'.format(modpath))<EOL><DEDENT>raise ValueError('<STR_LIT>'.format(modpath))<EOL><DEDENT>if isdir(modpath_) and not exists(join(modpath, '<STR_LIT>')):<EOL><INDENT>raise ValueError('<STR_LIT>'.format(modpath))<EOL><DEDENT><DEDENT>full_dpath, fname_ext = split(modpath_)<EOL>_relmod_parts = [fname_ext]<EOL>dpath = full_dpath<EOL>while exists(join(dpath, '<STR_LIT>')):<EOL><INDENT>dpath, dname = split(dpath)<EOL>_relmod_parts.append(dname)<EOL><DEDENT>relmod_parts = _relmod_parts[::-<NUM_LIT:1>]<EOL>rel_modpath = os.path.sep.join(relmod_parts)<EOL>return dpath, rel_modpath<EOL>

Splits the modpath into the dir that must be in PYTHONPATH for the module
to be imported and the modulepath relative to this directory.

Args:
    modpath (str): module filepath
    check (bool): if False, does not raise an error if modpath is a
        directory and does not contain an `__init__.py` file.

Returns:
    tuple: (directory, rel_modpath)

Raises:
    ValueError: if modpath does not exist or is not a package

Example:
    >>> from xdoctest import static_analysis
    >>> modpath = static_analysis.__file__.replace('.pyc', '.py')
    >>> modpath = abspath(modpath)
    >>> dpath, rel_modpath = split_modpath(modpath)
    >>> recon = join(dpath, rel_modpath)
    >>> assert recon == modpath
    >>> assert rel_modpath == join('xdoctest', 'static_analysis.py')


def modpath_to_modname(modpath, hide_init=True, hide_main=False, check=True,<EOL>relativeto=None):

if check and relativeto is None:<EOL><INDENT>if not exists(modpath):<EOL><INDENT>raise ValueError('<STR_LIT>'.format(modpath))<EOL><DEDENT><DEDENT>modpath_ = abspath(expanduser(modpath))<EOL>modpath_ = normalize_modpath(modpath_, hide_init=hide_init,<EOL>hide_main=hide_main)<EOL>if relativeto:<EOL><INDENT>dpath = dirname(abspath(expanduser(relativeto)))<EOL>rel_modpath = relpath(modpath_, dpath)<EOL><DEDENT>else:<EOL><INDENT>dpath, rel_modpath = split_modpath(modpath_, check=check)<EOL><DEDENT>modname = splitext(rel_modpath)[<NUM_LIT:0>]<EOL>if '<STR_LIT:.>' in modname:<EOL><INDENT>modname, abi_tag = modname.split('<STR_LIT:.>')<EOL><DEDENT>modname = modname.replace('<STR_LIT:/>', '<STR_LIT:.>')<EOL>modname = modname.replace('<STR_LIT:\\>', '<STR_LIT:.>')<EOL>return modname<EOL>

Determines importable name from file path

Converts the path to a module (__file__) to the importable python name
(__name__) without importing the module.

The filename is converted to a module name, and parent directories are
recursively included until a directory without an __init__.py file is
encountered.

Args:
    modpath (str): module filepath
    hide_init (bool): removes the __init__ suffix (default True)
    hide_main (bool): removes the __main__ suffix (default False)
    check (bool): if False, does not raise an error if modpath is a dir
        and does not contain an __init__ file.
    relativeto (str, optional): if specified, all checks are ignored and
        this is considered the path to the root module.

Returns:
    str: modname

Raises:
    ValueError: if check is True and the path does not exist

CommandLine:
    xdoctest -m xdoctest.static_analysis modpath_to_modname

Example:
    >>> from xdoctest import static_analysis
    >>> modpath = static_analysis.__file__.replace('.pyc', '.py')
    >>> modpath = modpath.replace('.pyc', '.py')
    >>> modname = modpath_to_modname(modpath)
    >>> assert modname == 'xdoctest.static_analysis'

Example:
    >>> import xdoctest
    >>> assert modpath_to_modname(xdoctest.__file__.replace('.pyc', '.py')) == 'xdoctest'
    >>> assert modpath_to_modname(dirname(xdoctest.__file__.replace('.pyc', '.py'))) == 'xdoctest'

Example:
    >>> modpath = modname_to_modpath('_ctypes')
    >>> modname = modpath_to_modname(modpath)
    >>> assert modname == '_ctypes'


def modname_to_modpath(modname, hide_init=True, hide_main=False, sys_path=None):

modpath = _syspath_modname_to_modpath(modname, sys_path)<EOL>if modpath is None:<EOL><INDENT>return None<EOL><DEDENT>modpath = normalize_modpath(modpath, hide_init=hide_init,<EOL>hide_main=hide_main)<EOL>return modpath<EOL>

Finds the path to a python module from its name.

Determines the path to a python module without directly import it

Converts the name of a module (__name__) to the path (__file__) where it is
located without importing the module. Returns None if the module does not
exist.

Args:
    modname (str): module filepath
    hide_init (bool): if False, __init__.py will be returned for packages
    hide_main (bool): if False, and hide_init is True, __main__.py will be
        returned for packages, if it exists.
    sys_path (list): if specified overrides `sys.path` (default None)

Returns:
    str: modpath - path to the module, or None if it doesn't exist

CommandLine:
    python -m xdoctest.static_analysis modname_to_modpath:0
    pytest  /home/joncrall/code/xdoctest/xdoctest/static_analysis.py::modname_to_modpath:0

Example:
    >>> modname = 'xdoctest.__main__'
    >>> modpath = modname_to_modpath(modname, hide_main=False)
    >>> assert modpath.endswith('__main__.py')
    >>> modname = 'xdoctest'
    >>> modpath = modname_to_modpath(modname, hide_init=False)
    >>> assert modpath.endswith('__init__.py')
    >>> modpath = basename(modname_to_modpath('_ctypes'))
    >>> assert 'ctypes' in modpath


import pkgutil<EOL>loader = pkgutil.find_loader(modname)<EOL>if loader is None:<EOL><INDENT>raise Exception('<STR_LIT>'.format(modname))<EOL><DEDENT>modpath = loader.get_filename().replace('<STR_LIT>', '<STR_LIT>')<EOL>return modpath<EOL>

faster version of `_syspath_modname_to_modpath` using builtin python
mechanisms, but unfortunately it doesn't play nice with pytest.

Example:
    >>> # xdoctest: +SKIP
    >>> modname = 'xdoctest.static_analysis'
    >>> _pkgutil_modname_to_modpath(modname)
    ...static_analysis.py
    >>> _pkgutil_modname_to_modpath('_ctypes')
    ..._ctypes...

Ignore:
    >>> _pkgutil_modname_to_modpath('cv2')


def _syspath_modname_to_modpath(modname, sys_path=None, exclude=None):

def _isvalid(modpath, base):<EOL><INDENT>subdir = dirname(modpath)<EOL>while subdir and subdir != base:<EOL><INDENT>if not exists(join(subdir, '<STR_LIT>')):<EOL><INDENT>return False<EOL><DEDENT>subdir = dirname(subdir)<EOL><DEDENT>return True<EOL><DEDENT>_fname_we = modname.replace('<STR_LIT:.>', os.path.sep)<EOL>candidate_fnames = [<EOL>_fname_we + '<STR_LIT>',<EOL>]<EOL>candidate_fnames += [_fname_we + ext for ext in _platform_pylib_exts()]<EOL>if sys_path is None:<EOL><INDENT>sys_path = sys.path<EOL><DEDENT>candidate_dpaths = ['<STR_LIT:.>' if p == '<STR_LIT>' else p for p in sys_path]<EOL>if exclude:<EOL><INDENT>def normalize(p):<EOL><INDENT>if sys.platform.startswith('<STR_LIT:win32>'):  <EOL><INDENT>return realpath(p).lower()<EOL><DEDENT>else:<EOL><INDENT>return realpath(p)<EOL><DEDENT><DEDENT>real_exclude = {normalize(p) for p in exclude}<EOL>candidate_dpaths = [p for p in candidate_dpaths<EOL>if normalize(p) not in real_exclude]<EOL><DEDENT>for dpath in candidate_dpaths:<EOL><INDENT>modpath = join(dpath, _fname_we)<EOL>if exists(modpath):<EOL><INDENT>if isfile(join(modpath, '<STR_LIT>')):<EOL><INDENT>if _isvalid(modpath, dpath):<EOL><INDENT>return modpath<EOL><DEDENT><DEDENT><DEDENT>for fname in candidate_fnames:<EOL><INDENT>modpath = join(dpath, fname)<EOL>if isfile(modpath):<EOL><INDENT>if _isvalid(modpath, dpath):<EOL><INDENT>return modpath<EOL><DEDENT><DEDENT><DEDENT><DEDENT>

syspath version of modname_to_modpath

Args:
    modname (str): name of module to find
    sys_path (List[PathLike], default=None):
        if specified overrides `sys.path`
    exclude (List[PathLike], default=None):
        list of directory paths. if specified prevents these directories
        from being searched.

Notes:
    This is much slower than the pkgutil mechanisms.

CommandLine:
    python -m xdoctest.static_analysis _syspath_modname_to_modpath

Example:
    >>> print(_syspath_modname_to_modpath('xdoctest.static_analysis'))
    ...static_analysis.py
    >>> print(_syspath_modname_to_modpath('xdoctest'))
    ...xdoctest
    >>> print(_syspath_modname_to_modpath('_ctypes'))
    ..._ctypes...
    >>> assert _syspath_modname_to_modpath('xdoctest', sys_path=[]) is None
    >>> assert _syspath_modname_to_modpath('xdoctest.static_analysis', sys_path=[]) is None
    >>> assert _syspath_modname_to_modpath('_ctypes', sys_path=[]) is None
    >>> assert _syspath_modname_to_modpath('this', sys_path=[]) is None

Example:
    >>> # test what happens when the module is not visible in the path
    >>> modname = 'xdoctest.static_analysis'
    >>> modpath = _syspath_modname_to_modpath(modname)
    >>> exclude = [split_modpath(modpath)[0]]
    >>> found = _syspath_modname_to_modpath(modname, exclude=exclude)
    >>> # this only works if installed in dev mode, pypi fails
    >>> assert found is None, 'should not have found {}'.format(found)


def is_modname_importable(modname, sys_path=None, exclude=None):

modpath = _syspath_modname_to_modpath(modname, sys_path=sys_path,<EOL>exclude=exclude)<EOL>flag = bool(modpath is not None)<EOL>return flag<EOL>

Determines if a modname is importable based on your current sys.path

Args:
    modname (str): name of module to check
    sys_path (list): if specified overrides `sys.path` (default None)
    exclude (list): list of directory paths. if specified prevents these
        directories from being searched.

Returns:
    bool: True if the module could be imported

Example:
    >>> is_modname_importable('xdoctest')
    True
    >>> is_modname_importable('not_a_real_module')
    False
    >>> is_modname_importable('xdoctest', sys_path=[])
    False


<EOL>lines = list(lines)<EOL>iterable = (line for line in lines if line)<EOL>def _readline():<EOL><INDENT>return next(iterable)<EOL><DEDENT>try:<EOL><INDENT>for t in tokenize.generate_tokens(_readline):<EOL><INDENT>pass<EOL><DEDENT><DEDENT>except tokenize.TokenError as ex:<EOL><INDENT>message = ex.args[<NUM_LIT:0>]<EOL>if message.startswith('<STR_LIT>'):<EOL><INDENT>return False<EOL><DEDENT>raise<EOL><DEDENT>except IndentationError as ex:<EOL><INDENT>message = ex.args[<NUM_LIT:0>]<EOL>if message.startswith('<STR_LIT>'):<EOL><INDENT>return False<EOL><DEDENT>raise<EOL><DEDENT>else:<EOL><INDENT>if not only_tokens:<EOL><INDENT>try:<EOL><INDENT>text = '<STR_LIT:\n>'.join(lines)<EOL>six_axt_parse(text)<EOL><DEDENT>except SyntaxError:<EOL><INDENT>return False<EOL><DEDENT><DEDENT>return True<EOL><DEDENT>

r"""
    Checks if the lines have balanced parens, brakets, curlies and strings

    Args:
        lines (list): list of strings

    Returns:
        bool: False if the statement is not balanced

    CommandLine:
        xdoctest -m xdoctest.static_analysis is_balanced_statement

    Doctest:
        >>> assert is_balanced_statement(['print(foobar)'])
        >>> assert is_balanced_statement(['foo = bar']) is True
        >>> assert is_balanced_statement(['foo = (']) is False
        >>> assert is_balanced_statement(['foo = (', "')(')"]) is True
        >>> assert is_balanced_statement(
        ...     ['foo = (', "'''", ")]'''", ')']) is True
        >>> assert is_balanced_statement(
        ...     ['foo = ', "'''", ")]'''", ')']) is False
        >>> #assert is_balanced_statement(['foo = ']) is False
        >>> #assert is_balanced_statement(['== ']) is False
        >>> lines = ['def foo():', '', '    x = 1', 'assert True', '']
        >>> assert is_balanced_statement(lines)

    Doctest:
        >>> from xdoctest.static_analysis import *
        >>> source_parts = [
        >>>     'setup(',
        >>>     "    name='extension',",
        >>>     '    ext_modules=[',
        >>>     '        CppExtension(',
        >>>     "            name='extension',",
        >>>     "            sources=['extension.cpp'],",
        >>>     "            extra_compile_args=['-g'])),",
        >>>     '    ],',
        >>> ]
        >>> print('\n'.join(source_parts))
        >>> assert not is_balanced_statement(source_parts)
        >>> source_parts = [
        >>>     'setup(',
        >>>     "    name='extension',",
        >>>     '    ext_modules=[',
        >>>     '        CppExtension(',
        >>>     "            name='extension',",
        >>>     "            sources=['extension.cpp'],",
        >>>     "            extra_compile_args=['-g']),",
        >>>     '    ],',
        >>>     '        cmdclass={',
        >>>     "            'build_ext': BuildExtension",
        >>>     '        })',
        >>> ]
        >>> print('\n'.join(source_parts))
        >>> assert is_balanced_statement(source_parts)


if isinstance(source, six.string_types):<EOL><INDENT>lines = source.splitlines()<EOL><DEDENT>else:<EOL><INDENT>lines = source<EOL><DEDENT>iterable = (line for line in lines if line)<EOL>def _readline():<EOL><INDENT>return next(iterable)<EOL><DEDENT>try:<EOL><INDENT>for t in tokenize.generate_tokens(_readline):<EOL><INDENT>if t[<NUM_LIT:0>] == tokenize.COMMENT:<EOL><INDENT>yield t[<NUM_LIT:1>]<EOL><DEDENT><DEDENT><DEDENT>except tokenize.TokenError as ex:<EOL><INDENT>pass<EOL><DEDENT>

Returns the text in each comment in a block of python code.
Uses tokenize to account for quotations.

CommandLine:
    python -m xdoctest.static_analysis extract_comments

Example:
    >>> from xdoctest import utils
    >>> source = utils.codeblock(
    >>>    '''
           # comment 1
           a = '# not a comment'  # comment 2
           c = 3
           ''')
    >>> comments = list(extract_comments(source))
    >>> assert comments == ['# comment 1', '# comment 2']
    >>> comments = list(extract_comments(source.splitlines()))
    >>> assert comments == ['# comment 1', '# comment 2']


def six_axt_parse(source_block, filename='<STR_LIT>', compatible=True):

<EOL>if compatible and six.PY2:<EOL><INDENT>import __future__<EOL>flags = ast.PyCF_ONLY_AST<EOL>flags |= __future__.print_function.compiler_flag<EOL>pt = compile(source_block, filename=filename, mode='<STR_LIT>', flags=flags)<EOL><DEDENT>else:<EOL><INDENT>pt = ast.parse(source_block, filename=filename)<EOL><DEDENT>return pt<EOL>

Python 2/3 compatible replacement for ast.parse(source_block, filename='<source_block>')


self = cls(source)<EOL>pt = self.syntax_tree()<EOL>self.visit(pt)<EOL>lineno_end = source.count('<STR_LIT:\n>') + <NUM_LIT:2>  <EOL>self.process_finished(lineno_end)<EOL>return self<EOL>

main entry point

executes parsing algorithm and populates self.calldefs


self.sourcelines = self.source.splitlines()<EOL>source_utf8  = self.source.encode('<STR_LIT:utf8>')<EOL>pt = ast.parse(source_utf8)<EOL>return pt<EOL>


if self._finish_queue:<EOL><INDENT>if isinstance(node, int):<EOL><INDENT>lineno_end = node<EOL><DEDENT>else:<EOL><INDENT>lineno_end = getattr(node, '<STR_LIT>', None)<EOL><DEDENT>while self._finish_queue:<EOL><INDENT>calldef = self._finish_queue.pop()<EOL>calldef.lineno_end = lineno_end<EOL><DEDENT><DEDENT>

process (get ending lineno) for everything marked as finished


def _docstr_line_workaround(self, docstr, sourcelines, endpos):

<EOL>start = endpos<EOL>stop = endpos + <NUM_LIT:1><EOL>trips = ("<STR_LIT>", '<STR_LIT>')<EOL>endline = sourcelines[stop - <NUM_LIT:1>]<EOL>for trip in trips:<EOL><INDENT>pattern = re.escape(trip) + r'<STR_LIT>'<EOL>endline_ = re.sub(pattern, trip, endline).strip()<EOL>if endline_.endswith(trip):<EOL><INDENT>nlines = docstr.count('<STR_LIT:\n>')<EOL>cand_start_ = stop - nlines - <NUM_LIT:1><EOL>startline = sourcelines[cand_start_]<EOL>if startline.strip().startswith((trip, '<STR_LIT:r>' + trip)):<EOL><INDENT>start = cand_start_<EOL>break<EOL><DEDENT>else:<EOL><INDENT>start = stop - <NUM_LIT:1><EOL><DEDENT><DEDENT><DEDENT>return start, stop<EOL>

r"""
        Args:
            docstr (str): the extracted docstring.

            sourcelines (list): a list of all lines in the file. We assume
                the docstring exists as a pure string literal in the source.
                In other words, no postprocessing via split, format, or any
                other dynamic programatic modification should be made to the
                docstrings. Python's docstring extractor assumes this as well.

            endpos (int): line position (starting at 0) the docstring ends on.
                Note: positions are 0 based but linenos are 1 based.

        Returns:
            tuple[Int, Int]: start, stop:
                start: the line position (0 based) the docstring starts on
                stop: the line position (0 based) that the docstring stops

                such that sourcelines[start:stop] will contain the docstring
        CommandLine:
            python -m xdoctest.static_analysis TopLevelVisitor._docstr_line_workaround

        Example:
            >>> from xdoctest.static_analysis import *
            >>> sq = chr(39)  # single quote
            >>> dq = chr(34)  # double quote
            >>> source = utils.codeblock(
                '''
                def func0():
                    {ddd} docstr0 {ddd}
                def func1():
                    {ddd}
                    docstr1 {ddd}
                def func2():
                    {ddd} docstr2
                    {ddd}
                def func3():
                    {ddd}
                    docstr3
                    {ddd}  # foobar
                def func5():
                    {ddd}pathological case
                    {sss} # {ddd} # {sss} # {ddd} # {ddd}
                def func6():
                    " single quoted docstr "
                def func7():
                    r{ddd}
                    raw line
                    {ddd}
                ''').format(ddd=dq * 3, sss=sq * 3)
            >>> print(utils.add_line_numbers(utils.highlight_code(source), start=0))
            >>> targets = [
            >>>     (1, 2),
            >>>     (3, 5),
            >>>     (6, 8),
            >>>     (9, 12),
            >>>     (13, 15),
            >>>     (16, 17),
            >>>     (18, 21),
            >>> ]
            >>> self = TopLevelVisitor.parse(source)
            >>> pt = ast.parse(source.encode('utf8'))
            >>> print('\n\n====\n\n')
            >>> for i in range(len(targets)):
            >>>     print('----------')
            >>>     sourcelines = source.splitlines()
            >>>     funcnode = pt.body[i]
            >>>     docnode = funcnode.body[0]
            >>>     docstr = ast.get_docstring(funcnode, clean=False)
            >>>     endpos = docnode.lineno - 1
            >>>     start, end = self._docstr_line_workaround(docstr, sourcelines, endpos)
            >>>     print('got  = {}, {}'.format(start, end))
            >>>     print('want = {}, {}'.format(*targets[i]))
            >>>     assert targets[i] == (start, end)
            >>>     print('----------')


docstr = ast.get_docstring(node, clean=False)<EOL>if docstr is not None:<EOL><INDENT>docnode = node.body[<NUM_LIT:0>]<EOL>doclineno, doclineno_end = self._docnode_line_workaround(docnode)<EOL><DEDENT>else:<EOL><INDENT>doclineno = None<EOL>doclineno_end = None<EOL><DEDENT>return (docstr, doclineno, doclineno_end)<EOL>

Example:
    >>> source = utils.codeblock(
        '''
        def foo():
            'docstr'
        ''')
    >>> self = TopLevelVisitor(source)
    >>> node = self.syntax_tree().body[0]
    >>> self._get_docstring(node)
    ('docstr', 2, 2)


<EOL>if node.decorator_list:<EOL><INDENT>linex = node.lineno - <NUM_LIT:1><EOL>pattern = r'<STR_LIT>' + node.name<EOL>while not re.match(pattern, self.sourcelines[linex]):<EOL><INDENT>linex += <NUM_LIT:1><EOL><DEDENT>lineno = linex + <NUM_LIT:1><EOL><DEDENT>else:<EOL><INDENT>lineno = node.lineno<EOL><DEDENT>return lineno<EOL>

Example:
    >>> source = utils.codeblock(
        '''
        @bar
        @baz
        def foo():
            'docstr'
        ''')
    >>> self = TopLevelVisitor(source)
    >>> node = self.syntax_tree().body[0]
    >>> self._workaround_func_lineno(node)
    3


from os.path import dirname, join<EOL>import ast<EOL>modname = setupkw['<STR_LIT:name>']<EOL>init_fpath = join(dirname(__file__), modname, '<STR_LIT>')<EOL>with open(init_fpath) as file_:<EOL><INDENT>sourcecode = file_.read()<EOL><DEDENT>pt = ast.parse(sourcecode)<EOL>class VersionVisitor(ast.NodeVisitor):<EOL><INDENT>def visit_Assign(self, node):<EOL><INDENT>for target in node.targets:<EOL><INDENT>if target.id == '<STR_LIT>':<EOL><INDENT>self.version = node.value.s<EOL><DEDENT><DEDENT><DEDENT><DEDENT>visitor = VersionVisitor()<EOL>visitor.visit(pt)<EOL>return visitor.version<EOL>

Statically parse the version number from __init__.py


from os.path import dirname, join, exists<EOL>import re<EOL>require_fpath = join(dirname(__file__), fname)<EOL>if exists(require_fpath):<EOL><INDENT>with open(require_fpath, '<STR_LIT:r>') as f:<EOL><INDENT>packages = []<EOL>for line in f.readlines():<EOL><INDENT>line = line.strip()<EOL>if line and not line.startswith('<STR_LIT:#>'):<EOL><INDENT>if line.startswith('<STR_LIT>'):<EOL><INDENT>package = line.split('<STR_LIT>')[<NUM_LIT:1>]<EOL>packages.append(package)<EOL><DEDENT>else:<EOL><INDENT>pat = '<STR_LIT:|>'.join(['<STR_LIT:>>', '<STR_LIT>', '<STR_LIT>'])<EOL>package = re.split(pat, line)[<NUM_LIT:0>]<EOL>packages.append(package)<EOL><DEDENT><DEDENT><DEDENT>return packages<EOL><DEDENT><DEDENT>return []<EOL>

Parse the package dependencies listed in a requirements file but strips
specific versioning information.

CommandLine:
    python -c "import setup; print(setup.parse_requirements())"


from os.path import dirname, join, exists<EOL>readme_fpath = join(dirname(__file__), '<STR_LIT>')<EOL>if exists(readme_fpath):<EOL><INDENT>with open(readme_fpath, '<STR_LIT:r>') as f:<EOL><INDENT>text = f.read()<EOL><DEDENT>return text<EOL><DEDENT>return '<STR_LIT>'<EOL>

Parse the description in the README file

CommandLine:
    pandoc --from=markdown --to=rst --output=README.rst README.md
    python -c "import setup; print(setup.parse_description())"


with open(join(abspath(dirname(__file__)), *pathcomponents)) as thefile:<EOL><INDENT>return thefile.read()<EOL><DEDENT>

Read the contents of a file located relative to setup.py