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
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
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
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
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)
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)
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)
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)
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)
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)
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)
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
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)
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)