How to use the xdoctest.static_analysis function in xdoctest

To help you get started, we’ve selected a few xdoctest examples, based on popular ways it is used in public projects.

Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.

github Erotemic / xdoctest / testing / test_static.py View on Github external
def biz():
            """
            multiline 1-1-0 """

        class Spam(object):
            """ multiline 0-2-1
            ---
            """
            def eggs():
                """ multiline 0-2-0
                ---"""
                pass
        ''')

    self = static.TopLevelVisitor.parse(source)
    calldefs = self.calldefs

    sourcelines = source.split('\n')

    for k, calldef in calldefs.items():
        line = sourcelines[calldef.lineno - 1]
        callname = calldef.callname
        # Ensure linenumbers correspond with start of func/class def
        assert callname.split('.')[-1] in line
        docsrc_lines = sourcelines[calldef.doclineno - 1:calldef.doclineno_end]
        # Ensure linenumbers correspond with start and end of doctest
        assert docsrc_lines[0].strip().startswith('"""')
        assert docsrc_lines[-1].strip().endswith('"""')
github Erotemic / xdoctest / xdoctest / core.py View on Github external
'Is it an old pyc file?'.format(modname))
            continue

        FORCE_DYNAMIC = '--xdoc-force-dynamic' in sys.argv
        # if false just skip extension modules
        # ALLOW_DYNAMIC = '--no-xdoc-dynamic' not in sys.argv
        ALLOW_DYNAMIC = '--allow-xdoc-dynamic' in sys.argv

        needs_dynamic = False

        if FORCE_DYNAMIC:
            # Force dynamic parsing for everything
            do_dynamic = True
        else:
            # Some modules can only be parsed dynamically
            needs_dynamic = modpath.endswith(static._platform_pylib_exts())
            do_dynamic = needs_dynamic and ALLOW_DYNAMIC

        if do_dynamic:
            try:
                calldefs = dynamic.parse_dynamic_calldefs(modpath)
            except ImportError as ex:
                # Some modules are just c modules
                msg = 'Cannot dynamically parse module={} at path={}.\nCaused by: {!r} {}'
                msg = msg.format(modname, modpath, type(ex), ex)
                warnings.warn(msg)
            except Exception as ex:
                msg = 'Cannot dynamically parse module={} at path={}.\nCaused by: {!r} {}'
                msg = msg.format(modname, modpath, type(ex), ex)
                warnings.warn(msg)
                raise
            else:
github Erotemic / xdoctest / xdoctest / dynamic_analysis.py View on Github external
>>> for key, calldef in sorted(calldefs.items()):
        ...     print('key = {!r}'.format(key))
        ...     print(' * calldef.callname = {}'.format(calldef.callname))
        ...     if calldef.docstr is None:
        ...         print(' * len(calldef.docstr) = {}'.format(calldef.docstr))
        ...     else:
        ...         print(' * len(calldef.docstr) = {}'.format(len(calldef.docstr)))
    """
    from xdoctest import static_analysis as static
    from xdoctest import utils  # NOQA
    # Possible option for dynamic parsing
    module = utils.import_module_from_path(modpath)
    calldefs = {}

    if getattr(module, '__doc__'):
        calldefs['__doc__'] = static.CallDefNode(
            callname='__doc__',
            docstr=module.__doc__,
            lineno=0,
            doclineno=1,
            doclineno_end=1,
            args=None
        )

    for key, val in iter_module_doctestables(module):
        # if hasattr(val, '__doc__'):
        if hasattr(val, '__doc__') and hasattr(val, '__name__'):
            calldefs[key] = static.CallDefNode(
                callname=val.__name__,
                docstr=val.__doc__,
                lineno=0,
                doclineno=1,
github Erotemic / xdoctest / xdoctest / utils.py View on Github external
"""
    Args:
        modpath (str): path to the module

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

    Example:
        >>> from xdoctest import utils
        >>> modpath = utils.__file__
        >>> module = import_module_from_path(modpath)
        >>> assert module is utils
    """
    # the importlib version doesnt work in pytest
    import xdoctest.static_analysis as static
    dpath, rel_modpath = static.split_modpath(modpath)
    modname = static.modpath_to_modname(modpath)
    with PythonPathContext(dpath):
        try:
            module = import_module_from_name(modname)
        except Exception:
            print('Failed to import modname={} with modpath={}'.format(
                modname, modpath))
            raise
    # TODO: use this implementation once pytest fixes importlib
    # if six.PY2:  # nocover
    #     import imp
    #     module = imp.load_source(modname, modpath)
    # elif sys.version_info[0:2] <= (3, 4):  # nocover
    #     assert sys.version_info[0:2] <= (3, 2), '3.0 to 3.2 is not supported'
    #     from importlib.machinery import SourceFileLoader
    #     module = SourceFileLoader(modname, modpath).load_module()
github Erotemic / xdoctest / xdoctest / doctest_example.py View on Github external
def cmdline(self):
        """
        A cli-instruction that can be used to execute *this* doctest.

        Returns:
            str:
        """
        if self.mode == 'pytest':
            return 'pytest ' + self.node
        elif self.mode == 'native':
            ALLOW_MODNAME_CMDLINE = False
            if ALLOW_MODNAME_CMDLINE:
                # not 100% reliable if any dynamic code has executed before
                # or we are doing self-testing
                in_path = static.is_modname_importable(self.modname)
                if in_path:
                    # should be able to find the module by name
                    return 'python -m xdoctest ' + self.modname + ' ' + self.unique_callname
                else:
                    # needs the full path to be able to run the module
                    return 'python -m xdoctest ' + self.modpath + ' ' + self.unique_callname
            else:
                # Probably safer to always use the path
                return 'python -m xdoctest ' + self.modpath + ' ' + self.unique_callname
        else:
            raise KeyError(self.mode)
github Erotemic / ubelt / ubelt / _internal / static_autogen.py View on Github external
for rel_modname in imports:
        sub_modpath = import_paths[rel_modname]
        try:
            if six.PY2:
                with open(sub_modpath, 'r') as file:
                    source = file.read()
            else:
                with open(sub_modpath, 'r', encoding='utf8') as file:
                    source = file.read()
        except Exception as ex:  # nocover
            raise IOError('Error reading {}, caused by {}'.format(
                sub_modpath, repr(ex)))
        valid_callnames = None
        if use_all:  # pragma: nobranch
            try:
                valid_callnames = static.parse_static_value('__all__', source)
            except NameError:
                pass
        if valid_callnames is None:
            # The __all__ variable is not specified or we dont care
            top_level = static.TopLevelVisitor.parse(source)
            attrnames = list(top_level.assignments) + list(top_level.calldefs.keys())
            # list of names we wont export by default
            invalid_callnames = dir(builtins)
            valid_callnames = []
            for attr in attrnames:
                if '.' in attr or attr.startswith('_'):
                    continue
                if attr in invalid_callnames:  # nocover
                    continue
                valid_callnames.append(attr)
        from_imports.append((rel_modname, sorted(valid_callnames)))