Пример #1
0
def generate_stub_for_module(module: str, output_dir: str, quiet: bool = False,
                             add_header: bool = False, sigs: Dict[str, str] = {},
                             class_sigs: Dict[str, str] = {},
                             pyversion: Tuple[int, int] = defaults.PYTHON3_VERSION) -> None:
    if pyversion[0] == 2:
        module_path, module_all = load_python2_module_info(module)
    else:
        mod = importlib.import_module(module)
        imp.reload(mod)
        if is_c_module(mod):
            target = module.replace('.', '/') + '.pyi'
            target = os.path.join(output_dir, target)
            generate_stub_for_c_module(module_name=module,
                                       target=target,
                                       add_header=add_header,
                                       sigs=sigs,
                                       class_sigs=class_sigs)
            return target
        module_path = mod.__file__
        module_all = getattr(mod, '__all__', None)
    target = module.replace('.', '/')
    if os.path.basename(module_path) == '__init__.py':
        target += '/__init__.pyi'
    else:
        target += '.pyi'
    target = os.path.join(output_dir, target)
    generate_stub(module_path, output_dir, module_all,
                  target=target, add_header=add_header, module=module, pyversion=pyversion)
    if not quiet:
        print('Created %s' % target)
    return target
Пример #2
0
def find_module_path_and_all(
        module: str, pyversion: Tuple[int, int], no_import: bool,
        search_path: List[str],
        interpreter: str) -> Optional[Tuple[str, Optional[List[str]]]]:
    """Find module and determine __all__.

    Return None if the module is a C module. Return (module_path, __all__) if
    Python module. Raise an exception or exit if failed.
    """
    module_path = None  # type: Optional[str]
    if not no_import:
        if pyversion[0] == 2:
            module_path, module_all = load_python_module_info(
                module, interpreter)
        else:
            # TODO: Support custom interpreters.
            try:
                mod = importlib.import_module(module)
            except Exception:
                raise CantImport(module)
            if is_c_module(mod):
                return None
            module_path = mod.__file__
            module_all = getattr(mod, '__all__', None)
    else:
        # Find module by going through search path.
        search_paths = SearchPaths(('.', ) + tuple(search_path), (), (), ())
        module_path = FindModuleCache(search_paths).find_module(module)
        if not module_path:
            raise SystemExit(
                "Can't find module '{}' (consider using --search-path)".format(
                    module))
        module_all = None
    return module_path, module_all
Пример #3
0
def find_module_path_and_all(module: str, pyversion: Tuple[int, int],
                             no_import: bool,
                             search_path: List[str],
                             interpreter: str) -> Optional[Tuple[str,
                                                                 Optional[List[str]]]]:
    """Find module and determine __all__.

    Return None if the module is a C module. Return (module_path, __all__) if
    Python module. Raise an exception or exit if failed.
    """
    module_path = None  # type: Optional[str]
    if not no_import:
        if pyversion[0] == 2:
            module_path, module_all = load_python_module_info(module, interpreter)
        else:
            # TODO: Support custom interpreters.
            try:
                mod = importlib.import_module(module)
            except Exception:
                raise CantImport(module)
            if is_c_module(mod):
                return None
            module_path = mod.__file__
            module_all = getattr(mod, '__all__', None)
    else:
        # Find module by going through search path.
        search_paths = SearchPaths(('.',) + tuple(search_path), (), (), ())
        module_path = FindModuleCache(search_paths).find_module(module)
        if not module_path:
            raise SystemExit(
                "Can't find module '{}' (consider using --search-path)".format(module))
        module_all = None
    return module_path, module_all
Пример #4
0
def walk_packages(packages: List[str]) -> Iterator[str]:
    """Iterates through all packages and sub-packages in the given list.

    Python packages have a __path__ attribute defined, which pkgutil uses to determine
    the package hierarchy.  However, packages in C extensions do not have this attribute,
    so we have to roll out our own.
    """
    for package_name in packages:
        package = importlib.import_module(package_name)
        yield package.__name__
        # get the path of the object (needed by pkgutil)
        path = getattr(package, '__path__', None)
        if path is None:
            # object has no path; this means it's either a module inside a package
            # (and thus no sub-packages), or it could be a C extension package.
            if is_c_module(package):
                # This is a C extension module, now get the list of all sub-packages
                # using the inspect module
                subpackages = [package.__name__ + "." + name
                               for name, val in inspect.getmembers(package)
                               if inspect.ismodule(val)
                               and val.__name__ == package.__name__ + "." + name]
                # recursively iterate through the subpackages
                for submodule in walk_packages(subpackages):
                    yield submodule
            # It's a module inside a package.  There's nothing else to walk/yield.
        else:
            all_packages = pkgutil.walk_packages(path, prefix=package.__name__ + ".",
                                                 onerror=lambda r: None)
            for importer, qualified_name, ispkg in all_packages:
                yield qualified_name
Пример #5
0
def generate_stub_for_module(module, output_dir, quiet=False, add_header=False, sigs={},
                             class_sigs={}):
    mod = __import__(module)
    imp.reload(mod)
    components = module.split('.')
    for attr in components[1:]:
        mod = getattr(mod, attr)
    if is_c_module(mod):
        target = '/'.join(components[:-1] + [components[-1] + '.pyi'])
        target = os.path.join(output_dir, target)
        generate_stub_for_c_module(module_name=module,
                                   target=target,
                                   add_header=add_header,
                                   sigs=sigs,
                                   class_sigs=class_sigs)
    else:
        target = '/'.join(module.split('.')[:-1])
        modfnam = os.path.basename(mod.__file__)
        if modfnam == '__init__.py':
            target = os.path.join(target, module.split('.')[-1], '__init__.pyi')
        else:
            target = os.path.join(target, modfnam.replace('.py', '.pyi'))
        target = os.path.join(output_dir, target)
        generate_stub(mod.__file__, output_dir, getattr(mod, '__all__', None),
                      target=target, add_header=add_header, module=module)
    if not quiet:
        print('Created %s' % target)
Пример #6
0
def generate_stub_for_module(module,
                             output_dir,
                             quiet=False,
                             add_header=False,
                             sigs={},
                             class_sigs={}):
    mod = importlib.import_module(module)
    imp.reload(mod)
    if is_c_module(mod):
        target = module.replace('.', '/') + '.pyi'
        target = os.path.join(output_dir, target)
        generate_stub_for_c_module(module_name=module,
                                   target=target,
                                   add_header=add_header,
                                   sigs=sigs,
                                   class_sigs=class_sigs)
    else:
        target = module.replace('.', '/')
        if os.path.basename(mod.__file__) == '__init__.py':
            target += '/__init__.pyi'
        else:
            target += '.pyi'
        target = os.path.join(output_dir, target)
        generate_stub(mod.__file__,
                      output_dir,
                      getattr(mod, '__all__', None),
                      target=target,
                      add_header=add_header,
                      module=module)
    if not quiet:
        print('Created %s' % target)
Пример #7
0
def generate_stub_for_module(module, output_dir, quiet=False, add_header=False, sigs={},
                             class_sigs={}, pyversion=defaults.PYTHON3_VERSION):
    if pyversion[0] == 2:
        module_path, module_all = load_python2_module_info(module)
    else:
        mod = importlib.import_module(module)
        imp.reload(mod)
        if is_c_module(mod):
            target = module.replace('.', '/') + '.pyi'
            target = os.path.join(output_dir, target)
            generate_stub_for_c_module(module_name=module,
                                       target=target,
                                       add_header=add_header,
                                       sigs=sigs,
                                       class_sigs=class_sigs)
            return
        module_path = mod.__file__
        module_all = getattr(mod, '__all__', None)
    target = module.replace('.', '/')
    if os.path.basename(module_path) == '__init__.py':
        target += '/__init__.pyi'
    else:
        target += '.pyi'
    target = os.path.join(output_dir, target)
    generate_stub(module_path, output_dir, module_all,
                  target=target, add_header=add_header, module=module, pyversion=pyversion)
    if not quiet:
        print('Created %s' % target)
Пример #8
0
def generate_stub_for_module(module,
                             output_dir,
                             quiet=False,
                             add_header=False,
                             sigs={},
                             class_sigs={}):
    mod = __import__(module)
    imp.reload(mod)
    components = module.split('.')
    for attr in components[1:]:
        mod = getattr(mod, attr)
    if is_c_module(mod):
        target = '/'.join(components[:-1] + [components[-1] + '.py'])
        target = os.path.join(output_dir, target)
        generate_stub_for_c_module(module_name=module,
                                   target=target,
                                   add_header=add_header,
                                   sigs=sigs,
                                   class_sigs=class_sigs)
    else:
        target = '/'.join(module.split('.')[:-1])
        modfnam = os.path.basename(mod.__file__)
        if modfnam == '__init__.py':
            target = os.path.join(target, module.split('.')[-1], '__init__.py')
        else:
            target = os.path.join(target, modfnam)
        target = os.path.join(output_dir, target)
        generate_stub(mod.__file__,
                      output_dir,
                      getattr(mod, '__all__', None),
                      target=target,
                      add_header=add_header,
                      module=module)
    if not quiet:
        print('Created %s' % target)
Пример #9
0
def generate_stub_for_c_module(
    module_name: str,
    target: str,
    add_header: bool = True,
    sigs: Dict[str, str] = {},
    class_sigs: Dict[str, str] = {},
) -> None:
    module = importlib.import_module(module_name)
    assert is_c_module(module), '%s is not a C module' % module_name
    subdir = os.path.dirname(target)
    if subdir and not os.path.isdir(subdir):
        os.makedirs(subdir)
    functions = []  # type: List[str]
    done = set()
    items = sorted(module.__dict__.items(), key=lambda x: x[0])
    for name, obj in items:
        if is_c_function(obj):
            generate_c_function_stub(module, name, obj, functions, sigs=sigs)
            done.add(name)
    types = []  # type: List[str]
    for name, obj in items:
        if name.startswith('__') and name.endswith('__'):
            continue
        if is_c_type(obj):
            generate_c_type_stub(module,
                                 name,
                                 obj,
                                 types,
                                 sigs=sigs,
                                 class_sigs=class_sigs)
            done.add(name)
    variables = []
    for name, obj in items:
        if name.startswith('__') and name.endswith('__'):
            continue
        if name not in done:
            type_str = type(obj).__name__
            if type_str not in ('int', 'str', 'bytes', 'float', 'bool'):
                type_str = 'Any'
            variables.append('%s: %s' % (name, type_str))
    output = []
    for line in variables:
        output.append(line)
    if output and functions:
        output.append('')
    for line in functions:
        output.append(line)
    for line in types:
        if line.startswith('class') and output and output[-1]:
            output.append('')
        output.append(line)
    output = add_typing_import(output)
    with open(target, 'w') as file:
        if add_header:
            write_header(file, module_name)
        for line in output:
            file.write('%s\n' % line)
Пример #10
0
def generate_stub_for_c_module(module_name,
                               target,
                               add_header=True,
                               sigs={},
                               class_sigs={}):
    module = __import__(module_name)
    assert is_c_module(module), '%s is not a C module' % module_name
    functions = []
    done = set()
    items = sorted(module.__dict__.items(), key=lambda x: x[0])
    for name, obj in items:
        if is_c_function(obj):
            generate_c_function_stub(module, name, obj, functions, sigs=sigs)
            done.add(name)
    types = []
    for name, obj in items:
        if name.startswith('__') and name.endswith('__'):
            continue
        if is_c_type(obj):
            generate_c_type_stub(module,
                                 name,
                                 obj,
                                 types,
                                 sigs=sigs,
                                 class_sigs=class_sigs)
            done.add(name)
    variables = []
    for name, obj in items:
        if name.startswith('__') and name.endswith('__'):
            continue
        if name not in done:
            type_str = type(obj).__name__
            if type_str not in ('int', 'str', 'bytes', 'float', 'bool'):
                type_str = 'Any'
            variables.append('%s = ... # type: %s' % (name, type_str))
    output = []
    for line in variables:
        output.append(line)
    if output and functions:
        output.append('')
    for line in functions:
        output.append(line)
    for line in types:
        if line.startswith('class') and output and output[-1]:
            output.append('')
        output.append(line)
    output = add_typing_import(output)
    with open(target, 'w') as file:
        if add_header:
            write_header(file, module_name)
        for line in output:
            file.write('%s\n' % line)
Пример #11
0
def generate_stub_for_c_module(module_name, target, add_header=True, sigs={}, class_sigs={}):
    module = __import__(module_name)
    assert is_c_module(module), '%s is not a C module' % module_name
    functions = []
    done = set()
    items = sorted(module.__dict__.items(), key=lambda x: x[0])
    for name, obj in items:
        if is_c_function(obj):
            generate_c_function_stub(module, name, obj, functions, sigs=sigs)
            done.add(name)
    types = []
    for name, obj in items:
        if name.startswith('__') and name.endswith('__'):
            continue
        if is_c_type(obj):
            generate_c_type_stub(module, name, obj, types, sigs=sigs, class_sigs=class_sigs)
            done.add(name)
    variables = []
    for name, obj in items:
        if name.startswith('__') and name.endswith('__'):
            continue
        if name not in done:
            type_str = type(obj).__name__
            if type_str not in ('int', 'str', 'bytes', 'float', 'bool'):
                type_str = 'Any'
            variables.append('%s = Undefined(%s)' % (name, type_str))
    output = []
    for line in variables:
        output.append(line)
    if output and functions:
        output.append('')
    for line in functions:
        output.append(line)
    for line in types:
        if line.startswith('class') and output and output[-1]:
            output.append('')
        output.append(line)
    output = add_typing_import(output)
    with open(target, 'w') as file:
        if add_header:
            write_header(file, module_name)
        for line in output:
            file.write('%s\n' % line)
Пример #12
0
def find_module_path_and_all(
        module: str, pyversion: Tuple[int, int], no_import: bool,
        search_path: List[str],
        interpreter: str) -> Optional[Tuple[str, Optional[List[str]]]]:
    """Find module and determine __all__.

    Return None if the module is a C module. Return (module_path, __all__) if
    Python module. Raise an exception or exit if failed.
    """
    module_path = None  # type: Optional[str]
    if not no_import:
        if pyversion[0] == 2:
            module_path, module_all = load_python_module_info(
                module, interpreter)
        else:
            # TODO: Support custom interpreters.
            try:
                mod = importlib.import_module(module)
            except Exception:
                # Print some debugging output that might help diagnose problems.
                print('=== debug dump follows ===')
                traceback.print_exc()
                print('sys.path:')
                for entry in sys.path:
                    print('    %r' % entry)
                print('PYTHONPATH: %s' % os.getenv("PYTHONPATH"))
                dump_dir(os.getcwd())
                print('=== end of debug dump ===')
                raise CantImport(module)
            if is_c_module(mod):
                return None
            module_path = mod.__file__
            module_all = getattr(mod, '__all__', None)
    else:
        # Find module by going through search path.
        module_path = mypy.build.FindModuleCache().find_module(
            module, ['.'] + search_path)
        if not module_path:
            raise SystemExit(
                "Can't find module '{}' (consider using --search-path)".format(
                    module))
        module_all = None
    return module_path, module_all
Пример #13
0
def generate_stub_for_module(module, output_dir, quiet=False, add_header=False, sigs={},
                             class_sigs={}):
    mod = importlib.import_module(module)
    imp.reload(mod)
    if is_c_module(mod):
        target = module.replace('.', '/') + '.pyi'
        target = os.path.join(output_dir, target)
        generate_stub_for_c_module(module_name=module,
                                   target=target,
                                   add_header=add_header,
                                   sigs=sigs,
                                   class_sigs=class_sigs)
    else:
        target = module.replace('.', '/')
        if os.path.basename(mod.__file__) == '__init__.py':
            target += '/__init__.pyi'
        else:
            target += '.pyi'
        target = os.path.join(output_dir, target)
        generate_stub(mod.__file__, output_dir, getattr(mod, '__all__', None),
                      target=target, add_header=add_header, module=module)
    if not quiet:
        print('Created %s' % target)
Пример #14
0
def generate_stub_for_c_module(
        module_name: str,
        target: str,
        sigs: Optional[Dict[str, str]] = None,
        class_sigs: Optional[Dict[str, str]] = None) -> None:
    """Generate stub for C module.

    This combines simple runtime introspection (looking for docstrings and attributes
    with simple builtin types) and signatures inferred from .rst documentation (if given).

    If directory for target doesn't exist it will be created. Existing stub
    will be overwritten.
    """
    module = importlib.import_module(module_name)
    assert is_c_module(module), '%s is not a C module' % module_name
    subdir = os.path.dirname(target)
    if subdir and not os.path.isdir(subdir):
        os.makedirs(subdir)
    imports = []  # type: List[str]
    functions = []  # type: List[str]
    done = set()
    items = sorted(module.__dict__.items(), key=lambda x: x[0])
    for name, obj in items:
        if is_c_function(obj):
            generate_c_function_stub(module,
                                     name,
                                     obj,
                                     functions,
                                     imports=imports,
                                     sigs=sigs)
            done.add(name)
    types = []  # type: List[str]
    for name, obj in items:
        if name.startswith('__') and name.endswith('__'):
            continue
        if is_c_type(obj):
            generate_c_type_stub(module,
                                 name,
                                 obj,
                                 types,
                                 imports=imports,
                                 sigs=sigs,
                                 class_sigs=class_sigs)
            done.add(name)
    variables = []
    for name, obj in items:
        if name.startswith('__') and name.endswith('__'):
            continue
        if name not in done and not inspect.ismodule(obj):
            type_str = type(obj).__name__
            if type_str not in ('int', 'str', 'bytes', 'float', 'bool'):
                type_str = 'Any'
            variables.append('%s: %s' % (name, type_str))
    output = []
    for line in sorted(set(imports)):
        output.append(line)
    for line in variables:
        output.append(line)
    if output and functions:
        output.append('')
    for line in functions:
        output.append(line)
    for line in types:
        if line.startswith('class') and output and output[-1]:
            output.append('')
        output.append(line)
    output = add_typing_import(output)
    with open(target, 'w') as file:
        for line in output:
            file.write('%s\n' % line)
Пример #15
0
def generate_stub_for_c_module(module_name: str,
                               target: str,
                               add_header: bool = True,
                               sigs: Optional[Dict[str, str]] = None,
                               class_sigs: Optional[Dict[str, str]] = None) -> None:
    """Generate stub for C module.

    This combines simple runtime introspection (looking for docstrings and attributes
    with simple builtin types) and signatures inferred from .rst documentation (if given).

    If directory for target doesn't exist it will be created. Existing stub
    will be overwritten.
    """
    module = importlib.import_module(module_name)
    assert is_c_module(module), '%s is not a C module' % module_name
    subdir = os.path.dirname(target)
    if subdir and not os.path.isdir(subdir):
        os.makedirs(subdir)
    imports = []  # type: List[str]
    functions = []  # type: List[str]
    done = set()
    items = sorted(module.__dict__.items(), key=lambda x: x[0])
    for name, obj in items:
        if is_c_function(obj):
            generate_c_function_stub(module, name, obj, functions, imports=imports, sigs=sigs)
            done.add(name)
    types = []  # type: List[str]
    for name, obj in items:
        if name.startswith('__') and name.endswith('__'):
            continue
        if is_c_type(obj):
            generate_c_type_stub(module, name, obj, types, imports=imports, sigs=sigs,
                                 class_sigs=class_sigs)
            done.add(name)
    variables = []
    for name, obj in items:
        if name.startswith('__') and name.endswith('__'):
            continue
        if name not in done and not inspect.ismodule(obj):
            type_str = type(obj).__name__
            if type_str not in ('int', 'str', 'bytes', 'float', 'bool'):
                type_str = 'Any'
            variables.append('%s: %s' % (name, type_str))
    output = []
    for line in sorted(set(imports)):
        output.append(line)
    for line in variables:
        output.append(line)
    if output and functions:
        output.append('')
    for line in functions:
        output.append(line)
    for line in types:
        if line.startswith('class') and output and output[-1]:
            output.append('')
        output.append(line)
    output = add_typing_import(output)
    with open(target, 'w') as file:
        if add_header:
            write_header(file, module_name)
        for line in output:
            file.write('%s\n' % line)