diff --git a/mypy/stubgen.py b/mypy/stubgen.py index f2d31b7b94ee..81dc583be2c1 100644 --- a/mypy/stubgen.py +++ b/mypy/stubgen.py @@ -28,6 +28,7 @@ import glob import imp +import importlib import os.path import sys @@ -50,10 +51,9 @@ def generate_stub(path, output_dir, _all_=None, target=None, add_header=False, m ast.accept(gen) if not target: target = os.path.join(output_dir, os.path.basename(path)) - for i in range(target.count('/')): - subdir = os.path.dirname(target) - if subdir and not os.path.isdir(subdir): - os.makedirs(subdir) + subdir = os.path.dirname(target) + if subdir and not os.path.isdir(subdir): + os.makedirs(subdir) with open(target, 'w') as file: if add_header: write_header(file, module) @@ -62,13 +62,10 @@ def generate_stub(path, output_dir, _all_=None, target=None, add_header=False, m def generate_stub_for_module(module, output_dir, quiet=False, add_header=False, sigs={}, class_sigs={}): - mod = __import__(module) + mod = importlib.import_module(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 = module.replace('.', '/') + '.pyi' target = os.path.join(output_dir, target) generate_stub_for_c_module(module_name=module, target=target, @@ -76,12 +73,11 @@ def generate_stub_for_module(module, output_dir, quiet=False, add_header=False, 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') + target = module.replace('.', '/') + if os.path.basename(mod.__file__) == '__init__.py': + target += '/__init__.pyi' else: - target = os.path.join(target, modfnam.replace('.py', '.pyi')) + 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) diff --git a/mypy/stubgenc.py b/mypy/stubgenc.py index 0fdcfa51948e..27b1bd58e6f4 100644 --- a/mypy/stubgenc.py +++ b/mypy/stubgenc.py @@ -3,6 +3,7 @@ The public interface is via the mypy.stubgen module. """ +import importlib import os.path import re @@ -14,8 +15,11 @@ def generate_stub_for_c_module(module_name, target, add_header=True, sigs={}, class_sigs={}): - module = __import__(module_name) + 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 = [] done = set() items = sorted(module.__dict__.items(), key=lambda x: x[0]) @@ -105,7 +109,10 @@ def generate_c_function_stub(module, name, obj, output, self_var=None, sigs={}, else: sig = sigs.get(name, '(*args, **kwargs)') sig = sig[1:-1] - if not sig: + if sig: + if sig.split(',', 1)[0] == self_var: + self_arg = '' + else: self_arg = self_arg.replace(', ', '') output.append('def %s(%s%s): pass' % (name, self_arg, sig)) @@ -125,6 +132,11 @@ def generate_c_type_stub(module, class_name, obj, output, sigs={}, class_sigs={} self_var = 'self' if attr == '__new__': # TODO: We should support __new__. + if '__init__' in obj.__dict__: + # Avoid duplicate functions if both are present. + # But is there any case where .__new__() has a + # better signature than __init__() ? + continue attr = '__init__' generate_c_function_stub(module, attr, value, methods, self_var, sigs=sigs, class_name=class_name, class_sigs=class_sigs)