Exemple #1
0
def _six_fail_hook(modname):
    """Fix six.moves imports due to the dynamic nature of this
    class.

    Construct a pseudo-module which contains all the necessary imports
    for six

    :param modname: Name of failed module
    :type modname: str

    :return: An astroid module
    :rtype: nodes.Module
    """

    attribute_of = (modname != "six.moves" and
                    modname.startswith("six.moves"))
    if modname != 'six.moves' and not attribute_of:
        raise AstroidBuildingError(modname=modname)
    module = AstroidBuilder(MANAGER).string_build(_IMPORTS)
    module.name = 'six.moves'
    if attribute_of:
        # Facilitate import of submodules in Moves
        start_index = len(module.name)
        attribute = modname[start_index:].lstrip(".").replace(".", "_")
        try:
            import_attr = module.getattr(attribute)[0]
        except AttributeInferenceError:
            raise AstroidBuildingError(modname=modname)
        if isinstance(import_attr, nodes.Import):
            submodule = MANAGER.ast_from_module_name(import_attr.names[0][0])
            return submodule
    # Let dummy submodule imports pass through
    # This will cause an Uninferable result, which is okay
    return module
 def test_nameconstant(self):
     # used to fail for Python 3.4
     builder = AstroidBuilder()
     astroid = builder.string_build("def test(x=True): pass")
     default = astroid.body[0].args.args[0]
     self.assertEqual(default.name, 'x')
     self.assertEqual(next(default.infer()).value, True)
Exemple #3
0
def six_moves_transform():
    code = dedent('''
    class Moves(object):
    {}
    moves = Moves()
    ''').format(_indent(_IMPORTS, "    "))
    module = AstroidBuilder(MANAGER).string_build(code)
    module.name = 'six.moves'
    return module
def infer_enum_class(node):
    """ Specific inference for enums. """
    for basename in node.basenames:
        # TODO: doesn't handle subclasses yet. This implementation
        # is a hack to support enums.
        if basename not in ENUM_BASE_NAMES:
            continue
        if node.root().name == "enum":
            # Skip if the class is directly from enum module.
            break
        for local, values in node.locals.items():
            if any(not isinstance(value, nodes.AssignName) for value in values):
                continue

            targets = []
            stmt = values[0].statement()
            if isinstance(stmt, nodes.Assign):
                if isinstance(stmt.targets[0], nodes.Tuple):
                    targets = stmt.targets[0].itered()
                else:
                    targets = stmt.targets
            elif isinstance(stmt, nodes.AnnAssign):
                targets = [stmt.target]

            inferred_return_value = None
            if isinstance(stmt.value, nodes.Const):
                if isinstance(stmt.value.value, str):
                    inferred_return_value = '"{}"'.format(stmt.value.value)
                else:
                    inferred_return_value = stmt.value.value

            new_targets = []
            for target in targets:
                # Replace all the assignments with our mocked class.
                classdef = dedent(
                    """
                class {name}({types}):
                    @property
                    def value(self):
                        return {return_value}
                    @property
                    def name(self):
                        return {name}
                """.format(
                        name=target.name,
                        types=", ".join(node.basenames),
                        return_value=inferred_return_value,
                    )
                )
                fake = AstroidBuilder(MANAGER).string_build(classdef)[target.name]
                fake.parent = target.parent
                for method in node.mymethods():
                    fake.locals[method.name] = [method]
                new_targets.append(fake.instantiate_class())
            node.locals[local] = new_targets
        break
    return node
Exemple #5
0
def rebuild_ast(tree, modname='', package=False):
    manager = AstroidManager()
    builder = AstroidBuilder(manager)
    rebuilder = TreeRebuilder(manager)
    module = rebuilder.visit_module(tree, modname=modname, package=package)
    module._from_nodes = rebuilder._from_nodes
    module._delayed_assattr = rebuilder._delayed_assattr
    module = builder._post_build(module, 'utf8')
    return module
    def test_with_infer_assnames(self):
        builder = AstroidBuilder()
        data = """
with open('a.txt') as stream, open('b.txt'):
    stream.read()
"""
        astroid = builder.string_build(data, __name__, __file__)
        # Used to crash due to the fact that the second
        # context manager didn't use an assignment name.
        list(astroid.nodes_of_class(nodes.CallFunc))[-1].infered()
def _extend_str(class_node, rvalue):
    """function to extend builtin str/unicode class"""
    code = dedent(
        """
    class whatever(object):
        def join(self, iterable):
            return {rvalue}
        def replace(self, old, new, count=None):
            return {rvalue}
        def format(self, *args, **kwargs):
            return {rvalue}
        def encode(self, encoding='ascii', errors=None):
            return ''
        def decode(self, encoding='ascii', errors=None):
            return u''
        def capitalize(self):
            return {rvalue}
        def title(self):
            return {rvalue}
        def lower(self):
            return {rvalue}
        def upper(self):
            return {rvalue}
        def swapcase(self):
            return {rvalue}
        def index(self, sub, start=None, end=None):
            return 0
        def find(self, sub, start=None, end=None):
            return 0
        def count(self, sub, start=None, end=None):
            return 0
        def strip(self, chars=None):
            return {rvalue}
        def lstrip(self, chars=None):
            return {rvalue}
        def rstrip(self, chars=None):
            return {rvalue}
        def rjust(self, width, fillchar=None):
            return {rvalue}
        def center(self, width, fillchar=None):
            return {rvalue}
        def ljust(self, width, fillchar=None):
            return {rvalue}
    """
    )
    code = code.format(rvalue=rvalue)
    fake = AstroidBuilder(MANAGER).string_build(code)["whatever"]
    for method in fake.mymethods():
        method.parent = class_node
        method.lineno = None
        method.col_offset = None
        if "__class__" in method.locals:
            method.locals["__class__"] = [class_node]
        class_node.locals[method.name] = [method]
        method.parent = class_node
    def test_io_is__io(self):
        # _io module calls itself io. This leads
        # to cyclic dependencies when astroid tries to resolve
        # what io.BufferedReader is. The code that handles this
        # is in astroid.raw_building.imported_member, which verifies
        # the true name of the module.
        import _io

        builder = AstroidBuilder()
        module = builder.inspect_build(_io)
        buffered_reader = module.getattr('BufferedReader')[0]
        self.assertEqual(buffered_reader.root().name, 'io')
def redbaron_transform(module):
    """ Let pylint know the redbaron module """
    if module.name != 'redbaron':
        return

    astroid_mgr = AstroidBuilder(MANAGER)

    fake = astroid_mgr.string_build(PYTEST_STUB)
    for stub in ('NameNode', 'PassNode'):
        text = NODE_PLACEHOLDER_CLASS_STUB.format(name=stub)
        fake = astroid_mgr.string_build(text)
        module.locals[stub] = fake.locals[stub]
def _extend_str(class_node, rvalue):
    """function to extend builtin str/unicode class"""
    # TODO(cpopa): this approach will make astroid to believe
    # that some arguments can be passed by keyword, but
    # unfortunately, strings and bytes don't accept keyword arguments.
    code = dedent('''
    class whatever(object):
        def join(self, iterable):
            return {rvalue}
        def replace(self, old, new, count=None):
            return {rvalue}
        def format(self, *args, **kwargs):
            return {rvalue}
        def encode(self, encoding='ascii', errors=None):
            return ''
        def decode(self, encoding='ascii', errors=None):
            return u''
        def capitalize(self):
            return {rvalue}
        def title(self):
            return {rvalue}
        def lower(self):
            return {rvalue}
        def upper(self):
            return {rvalue}
        def swapcase(self):
            return {rvalue}
        def index(self, sub, start=None, end=None):
            return 0
        def find(self, sub, start=None, end=None):
            return 0
        def count(self, sub, start=None, end=None):
            return 0
        def strip(self, chars=None):
            return {rvalue}
        def lstrip(self, chars=None):
            return {rvalue}
        def rstrip(self, chars=None):
            return {rvalue}
        def rjust(self, width, fillchar=None):
            return {rvalue}
        def center(self, width, fillchar=None):
            return {rvalue}
        def ljust(self, width, fillchar=None):
            return {rvalue}
    ''')
    code = code.format(rvalue=rvalue)
    fake = AstroidBuilder(MANAGER).string_build(code)['whatever']
    for method in fake.mymethods():
        class_node.locals[method.name] = [method]
        method.parent = class_node
def transform(cls):
    if cls.name == 'scoped_session':
        builder = AstroidBuilder(MANAGER)
        module_node = builder.module_build(sys.modules[Session.__module__])
        session_cls_node = [
            c for c in module_node.get_children()
            if getattr(c, "type", None) == "class" and c.name == Session.__name__
        ][0]

        for prop in Session.public_methods:
            cls.locals[prop] = [
                c for c in session_cls_node.get_children() 
                if getattr(c, "type", None) == "method" and c.name == prop
            ]
def pytest_transform(module):
    """ Let pylint know the pytest module """
    pytest = ('pytest', 'py.test')
    if module.name not in pytest:
        return

    astroid_mgr = AstroidBuilder(MANAGER)

    fake = astroid_mgr.string_build(PYTEST_STUB)
    for complex_stub in ('mark',):
        module.locals[complex_stub] = fake.locals[complex_stub]

    for stub in ('skip', 'xfail', 'fixture', 'test', 'raises'):
        text = PLACEHOLDER_CLASS_STUB.format(name=stub)
        fake = astroid_mgr.string_build(text)
        module.locals[stub] = fake.locals[stub]
    def test_filter_stmts_scoping(self):
        builder = AstroidBuilder()
        data = """
def test():
    compiler = int()
    class B(compiler.__class__):
        pass
    compiler = B()
    return compiler
"""
        astroid = builder.string_build(data, __name__, __file__)
        test = astroid['test']
        result = next(test.infer_call_result(astroid))
        self.assertIsInstance(result, Instance)
        base = next(result._proxied.bases[0].infer())
        self.assertEqual(base.name, 'int')
Exemple #14
0
    def __init__(self, type_constraints) -> None:
        """Initialize a type store with all the built-in types from the typeshed module."""
        self.type_constraints = type_constraints
        self.classes = defaultdict(lambda: defaultdict(list))
        self.functions = defaultdict(list)
        self.methods = defaultdict(list)

        builder = AstroidBuilder()
        module = builder.file_build(TYPE_SHED_PATH)

        self._parse_classes(module)
        self._parse_functions(module)

        # Add in initializers
        for klass_name, methods in self.classes.items():
            if '__init__' in methods:
                self.functions[klass_name] = [class_callable(init) for init, _ in methods['__init__']]
Exemple #15
0
def set_source_text(text):
    global _reporter
    global _linter
    assert isinstance(_reporter, Reporter)
    assert isinstance(_linter, lint.PyLinter)

    _reporter.reset()
    builder = AstroidBuilder()
    try:
        astroid_module = builder.string_build(text)
    except:
        return

    _linter.set_current_module("<stdin>")
    _linter.check_astroid_module(astroid_module, _walker, _raw_checkers, _token_checkers)
    assert isinstance(text, str)
    _reporter.improve_errors_positions(text)
def infer_enum_class(node):
    """ Specific inference for enums. """
    names = set(('Enum', 'IntEnum', 'enum.Enum', 'enum.IntEnum'))
    for basename in node.basenames:
        # TODO: doesn't handle subclasses yet. This implementation
        # is a hack to support enums.
        if basename not in names:
            continue
        if node.root().name == 'enum':
            # Skip if the class is directly from enum module.
            break
        for local, values in node.locals.items():
            if any(not isinstance(value, nodes.AssignName)
                   for value in values):
                continue

            stmt = values[0].statement()
            if isinstance(stmt, nodes.Assign):
                if isinstance(stmt.targets[0], nodes.Tuple):
                    targets = stmt.targets[0].itered()
                else:
                    targets = stmt.targets
            elif isinstance(stmt, nodes.AnnAssign):
                targets = [stmt.target]

            new_targets = []
            for target in targets:
                # Replace all the assignments with our mocked class.
                classdef = dedent('''
                class %(name)s(%(types)s):
                    @property
                    def value(self):
                        # Not the best return.
                        return None
                    @property
                    def name(self):
                        return %(name)r
                ''' % {'name': target.name, 'types': ', '.join(node.basenames)})
                fake = AstroidBuilder(MANAGER).string_build(classdef)[target.name]
                fake.parent = target.parent
                for method in node.mymethods():
                    fake.locals[method.name] = [method]
                new_targets.append(fake.instantiate_class())
            node.locals[local] = new_targets
        break
    return node
    def test_decorator_callchain_issue42(self):
        builder = AstroidBuilder()
        data = """

def test():
    def factory(func):
        def newfunc():
            func()
        return newfunc
    return factory

@test()
def crash():
    pass
"""
        astroid = builder.string_build(data, __name__, __file__)
        self.assertEqual(astroid['crash'].type, 'function')
    def test_numpy_crash(self):
        """test don't crash on numpy"""
        #a crash occured somewhere in the past, and an
        # InferenceError instead of a crash was better, but now we even infer!
        try:
            import numpy # pylint: disable=unused-variable
        except ImportError:
            self.skipTest('test skipped: numpy is not available')
        builder = AstroidBuilder()
        data = """
from numpy import multiply

multiply(1, 2, 3)
"""
        astroid = builder.string_build(data, __name__, __file__)
        callfunc = astroid.body[1].value.func
        inferred = callfunc.inferred()
        self.assertEqual(len(inferred), 1)
    def test_new_style_class_detection(self):
        try:
            import pygtk
        except ImportError:
            self.skipTest('test skipped: pygtk is not available')
        # XXX may fail on some pygtk version, because objects in
        # gobject._gobject have __module__ set to gobject :(
        builder = AstroidBuilder()
        data = """
import pygtk
pygtk.require("2.6")
import gobject

class A(gobject.GObject):
    pass
"""
        astroid = builder.string_build(data, __name__, __file__)
        a = astroid['A']
        self.assertTrue(a.newstyle)
def _settings_transform():
    module = AstroidBuilder(AstroidManager()).string_build(
        textwrap.dedent("""
            class Settings(object):
                os = None
                arch = None
                compiler = None
                build_type = None
            """)
    )
    return module['Settings']
def infer_named_tuple(node, context=None):
    """Specific inference function for namedtuple Call node"""
    class_node, name, attributes = infer_func_form(node,
                                                   nodes.Tuple._proxied,
                                                   context=context)
    call_site = arguments.CallSite.from_call(node)
    func = next(
        extract_node('import collections; collections.namedtuple').infer())
    try:
        rename = next(call_site.infer_argument(func, 'rename',
                                               context)).bool_value()
    except InferenceError:
        rename = False

    if rename:
        attributes = _get_renamed_namedtuple_atributes(attributes)

    replace_args = ', '.join('{arg}=None'.format(arg=arg)
                             for arg in attributes)

    field_def = ("    {name} = property(lambda self: self[{index:d}], "
                 "doc='Alias for field number {index:d}')")
    field_defs = '\n'.join(
        field_def.format(name=name, index=index)
        for index, name in enumerate(attributes))
    fake = AstroidBuilder(MANAGER).string_build(
        '''
class %(name)s(tuple):
    __slots__ = ()
    _fields = %(fields)r
    def _asdict(self):
        return self.__dict__
    @classmethod
    def _make(cls, iterable, new=tuple.__new__, len=len):
        return new(cls, iterable)
    def _replace(self, %(replace_args)s):
        return self
    def __getnewargs__(self):
        return tuple(self)
%(field_defs)s
    ''' % {
            'name': name,
            'fields': attributes,
            'field_defs': field_defs,
            'replace_args': replace_args
        })
    class_node.locals['_asdict'] = fake.body[0].locals['_asdict']
    class_node.locals['_make'] = fake.body[0].locals['_make']
    class_node.locals['_replace'] = fake.body[0].locals['_replace']
    class_node.locals['_fields'] = fake.body[0].locals['_fields']
    for attr in attributes:
        class_node.locals[attr] = fake.body[0].locals[attr]
    # we use UseInferenceDefault, we can't be a generator so return an iterator
    return iter([class_node])
    def test_recursion_regression_issue25(self):
        builder = AstroidBuilder()
        data = """
import recursion as base

_real_Base = base.Base

class Derived(_real_Base):
    pass

def run():
    base.Base = Derived
"""
        astroid = builder.string_build(data, __name__, __file__)
        # Used to crash in _is_metaclass, due to wrong
        # ancestors chain
        classes = astroid.nodes_of_class(nodes.Class)
        for klass in classes:
            # triggers the _is_metaclass call
            klass.type
Exemple #23
0
def thread_transform():
    return AstroidBuilder(MANAGER).string_build('''
class lock(object):
    def acquire(self, blocking=True):
        pass
    def release(self):
        pass

def Lock():
    return lock()
''')
    def test_recursion_regression_issue25(self):
        builder = AstroidBuilder()
        data = """
import recursion as base

_real_Base = base.Base

class Derived(_real_Base):
    pass

def run():
    base.Base = Derived
"""
        astroid = builder.string_build(data, __name__, __file__)
        # Used to crash in _is_metaclass, due to wrong
        # ancestors chain
        classes = astroid.nodes_of_class(nodes.Class)
        for klass in classes:
            # triggers the _is_metaclass call
            klass.type
Exemple #25
0
def ipaplatform_services_transform():
    return AstroidBuilder(MANAGER).string_build(
        textwrap.dedent('''
    from ipaplatform.base.services import knownservices
    from ipaplatform.base.services import timedate_services
    from ipaplatform.base.services import service
    from ipaplatform.base.services import wellknownservices
    from ipaplatform.base.services import wellknownports
    __all__ = ('knownservices', 'timedate_services', 'service',
               'wellknownservices', 'wellknownports')
    '''))
Exemple #26
0
def infer_named_tuple(node, context=None):
    """Specific inference function for namedtuple Call node"""
    tuple_base_name = nodes.Name(name="tuple", parent=node.root())
    class_node, name, attributes = infer_func_form(node,
                                                   tuple_base_name,
                                                   context=context)
    call_site = arguments.CallSite.from_call(node, context=context)
    func = next(
        extract_node("import collections; collections.namedtuple").infer())
    try:
        rename = next(call_site.infer_argument(func, "rename",
                                               context)).bool_value()
    except InferenceError:
        rename = False

    if rename:
        attributes = _get_renamed_namedtuple_attributes(attributes)

    replace_args = ", ".join("{arg}=None".format(arg=arg)
                             for arg in attributes)
    field_def = ("    {name} = property(lambda self: self[{index:d}], "
                 "doc='Alias for field number {index:d}')")
    field_defs = "\n".join(
        field_def.format(name=name, index=index)
        for index, name in enumerate(attributes))
    fake = AstroidBuilder(MANAGER).string_build(
        """
class %(name)s(tuple):
    __slots__ = ()
    _fields = %(fields)r
    def _asdict(self):
        return self.__dict__
    @classmethod
    def _make(cls, iterable, new=tuple.__new__, len=len):
        return new(cls, iterable)
    def _replace(self, %(replace_args)s):
        return self
    def __getnewargs__(self):
        return tuple(self)
%(field_defs)s
    """ % {
            "name": name,
            "fields": attributes,
            "field_defs": field_defs,
            "replace_args": replace_args,
        })
    class_node.locals["_asdict"] = fake.body[0].locals["_asdict"]
    class_node.locals["_make"] = fake.body[0].locals["_make"]
    class_node.locals["_replace"] = fake.body[0].locals["_replace"]
    class_node.locals["_fields"] = fake.body[0].locals["_fields"]
    for attr in attributes:
        class_node.locals[attr] = fake.body[0].locals[attr]
    # we use UseInferenceDefault, we can't be a generator so return an iterator
    return iter([class_node])
Exemple #27
0
def transform(module):
    '''Add fake locals to a module's namespace.'''
    # Generate the path to the fake module
    dirname = os.path.dirname(__file__)
    path = os.path.join(dirname, module.name + '.py')
    if not os.path.exists(path):
        return
    # If the file exists, add fakes to the module's namespace
    fake = AstroidBuilder(MANAGER).file_build(path)
    for name, obj in fake.locals.iteritems():
        module.locals.setdefault(name, []).extend(obj)
Exemple #28
0
 def zip_import_data(self, filepath):
     if zipimport is None:
         return None
     from astroid.builder import AstroidBuilder
     builder = AstroidBuilder(self)
     for ext in ('.zip', '.egg'):
         try:
             eggpath, resource = filepath.rsplit(ext + os.path.sep, 1)
         except ValueError:
             continue
         try:
             importer = zipimport.zipimporter(eggpath + ext)
             zmodname = resource.replace(os.path.sep, '.')
             if importer.is_package(resource):
                 zmodname = zmodname + '.__init__'
             module = builder.string_build(importer.get_source(resource),
                                           zmodname, filepath)
             return module
         except:
             continue
     return None
Exemple #29
0
def mechanize_transform():
    return AstroidBuilder(MANAGER).string_build("""

class Browser(object):
    def open(self, url, data=None, timeout=None):
        return None
    def open_novisit(self, url, data=None, timeout=None):
        return None
    def open_local_file(self, filename):
        return None

""")
Exemple #30
0
 def zip_import_data(self, filepath):
     if zipimport is None:
         return None
     from astroid.builder import AstroidBuilder
     builder = AstroidBuilder(self)
     for ext in ('.zip', '.egg'):
         try:
             eggpath, resource = filepath.rsplit(ext + '/', 1)
         except ValueError:
             continue
         try:
             importer = zipimport.zipimporter(eggpath + ext)
             zmodname = resource.replace('/', '.')
             if importer.is_package(resource):
                 zmodname = zmodname + '.__init__'
             module = builder.string_build(importer.get_source(resource),
                                           zmodname, filepath)
             return module
         except:
             continue
     return None
Exemple #31
0
def handle_session(cls):
    """Handle the sqlalchemy.orm.scoping.scoped_session."""
    if cls.name == 'scoped_session':
        source_files = cls.parent.source_file.split('/')
        source_files[-1] = 'session.py'
        module = AstroidBuilder(MANAGER).file_build('/'.join(source_files),
                                                    'sqlalchemy.orm.session')
        session = module.locals.get('Session')[0]
        for method in Session.public_methods:
            cls.locals[method] = session.locals[method]

        return cls
Exemple #32
0
def infer_enum_class(node, context=None):
    """ Specific inference for enums. """
    names = set(('Enum', 'IntEnum', 'enum.Enum', 'enum.IntEnum'))
    for basename in node.basenames:
        # TODO: doesn't handle subclasses yet.
        if basename not in names:
            continue
        if node.root().name == 'enum':
            # Skip if the class is directly from enum module.
            break
        for local, values in node.locals.items():
            if any(not isinstance(value, nodes.AssName) for value in values):
                continue
            parent = values[0].parent
            real_value = parent.value
            new_targets = []
            for target in parent.targets:
                # Replace all the assignments with our mocked class.
                classdef = dedent('''
                class %(name)s(object):
                    @property
                    def value(self):
                        return %(value)s
                    @property
                    def name(self):
                        return %(name)r
                    %(name)s = %(value)s
                ''' % {
                    'name': target.name,
                    'value': real_value.as_string()
                })
                fake = AstroidBuilder(MANAGER).string_build(classdef)[
                    target.name]
                fake.parent = target.parent
                for method in node.mymethods():
                    fake.locals[method.name] = [method]
                new_targets.append(fake.instanciate_class())
            node.locals[local] = new_targets
        break
    return node
Exemple #33
0
def subprocess_transform():
    if PY3K:
        communicate = (bytes('string', 'ascii'), bytes('string', 'ascii'))
        init = """
    def __init__(self, args, bufsize=0, executable=None,
                 stdin=None, stdout=None, stderr=None,
                 preexec_fn=None, close_fds=False, shell=False,
                 cwd=None, env=None, universal_newlines=False,
                 startupinfo=None, creationflags=0, restore_signals=True,
                 start_new_session=False, pass_fds=()):
        pass
        """
    else:
        communicate = ('string', 'string')
        init = """
    def __init__(self, args, bufsize=0, executable=None,
                 stdin=None, stdout=None, stderr=None,
                 preexec_fn=None, close_fds=False, shell=False,
                 cwd=None, env=None, universal_newlines=False,
                 startupinfo=None, creationflags=0):
        pass
        """
    if PY33:
        wait_signature = 'def wait(self, timeout=None)'
    else:
        wait_signature = 'def wait(self)'
    return AstroidBuilder(MANAGER).string_build(
        '''

class Popen(object):
    returncode = pid = 0
    stdin = stdout = stderr = file()

    %(init)s

    def communicate(self, input=None):
        return %(communicate)r
    %(wait_signature)s:
        return self.returncode
    def poll(self):
        return self.returncode
    def send_signal(self, signal):
        pass
    def terminate(self):
        pass
    def kill(self):
        pass
   ''' % {
            'init': init,
            'communicate': communicate,
            'wait_signature': wait_signature
        })
Exemple #34
0
def _import_gi_module(modname):
    # we only consider gi.repository submodules
    if not modname.startswith("gi.repository."):
        raise AstroidBuildingError(modname=modname)
    # build astroid representation unless we already tried so
    if modname not in _inspected_modules:
        modnames = [modname]
        optional_modnames = []

        # GLib and GObject may have some special case handling
        # in pygobject that we need to cope with. However at
        # least as of pygobject3-3.13.91 the _glib module doesn't
        # exist anymore, so if treat these modules as optional.
        if modname == "gi.repository.GLib":
            optional_modnames.append("gi._glib")
        elif modname == "gi.repository.GObject":
            optional_modnames.append("gi._gobject")

        try:
            modcode = ""
            for m in itertools.chain(modnames, optional_modnames):
                try:
                    with warnings.catch_warnings():
                        # Just inspecting the code can raise gi deprecation
                        # warnings, so ignore them.
                        try:
                            from gi import (  # pylint:disable=import-error
                                PyGIDeprecationWarning, PyGIWarning,
                            )

                            warnings.simplefilter("ignore",
                                                  PyGIDeprecationWarning)
                            warnings.simplefilter("ignore", PyGIWarning)
                        except Exception:  # pylint:disable=broad-except
                            pass

                        __import__(m)
                        modcode += _gi_build_stub(sys.modules[m])
                except ImportError:
                    if m not in optional_modnames:
                        raise
        except ImportError:
            astng = _inspected_modules[modname] = None
        else:
            astng = AstroidBuilder(AstroidManager()).string_build(
                modcode, modname)
            _inspected_modules[modname] = astng
    else:
        astng = _inspected_modules[modname]
    if astng is None:
        raise AstroidBuildingError(modname=modname)
    return astng
def pkg_resources_transform():
    return AstroidBuilder(MANAGER).string_build('''
def require(*requirements):
    return pkg_resources.working_set.require(*requirements)

def run_script(requires, script_name):
    return pkg_resources.working_set.run_script(requires, script_name)

def iter_entry_points(group, name=None):
    return pkg_resources.working_set.iter_entry_points(group, name)

def resource_exists(package_or_requirement, resource_name):
    return get_provider(package_or_requirement).has_resource(resource_name)

def resource_isdir(package_or_requirement, resource_name):
    return get_provider(package_or_requirement).resource_isdir(
        resource_name)

def resource_filename(package_or_requirement, resource_name):
    return get_provider(package_or_requirement).get_resource_filename(
        self, resource_name)

def resource_stream(package_or_requirement, resource_name):
    return get_provider(package_or_requirement).get_resource_stream(
        self, resource_name)

def resource_string(package_or_requirement, resource_name):
    return get_provider(package_or_requirement).get_resource_string(
        self, resource_name)

def resource_listdir(package_or_requirement, resource_name):
    return get_provider(package_or_requirement).resource_listdir(
        resource_name)

def extraction_error():
    pass

def get_cache_path(archive_name, names=()):
    extract_path = self.extraction_path or get_default_cache()
    target_path = os.path.join(extract_path, archive_name+'-tmp', *names)
    return target_path

def postprocess(tempname, filename):
    pass

def set_extraction_path(path):
    pass

def cleanup_resources(force=False):
    pass

''')
def transform(module):
    if module.name == 'numpy':
        fake = AstroidBuilder(manager=MANAGER).string_build('''
import numpy
class array(numpy.ndarray):
    pass

class recarray(numpy.ndarray):
    pass
''')

        for name in ("array", "recarray"):
            module.locals[name] = fake.locals[name]
Exemple #37
0
    def zip_import_data(self, filepath):
        if zipimport is None:
            return None
        from astroid.builder import AstroidBuilder

        builder = AstroidBuilder(self)
        for ext in (".zip", ".egg"):
            try:
                eggpath, resource = filepath.rsplit(ext + os.path.sep, 1)
            except ValueError:
                continue
            try:
                importer = zipimport.zipimporter(eggpath + ext)
                zmodname = resource.replace(os.path.sep, ".")
                if importer.is_package(resource):
                    zmodname = zmodname + ".__init__"
                module = builder.string_build(importer.get_source(resource),
                                              zmodname, filepath)
                return module
            except Exception:  # pylint: disable=broad-except
                continue
        return None
Exemple #38
0
def nose_transform():
    """Custom transform for the nose.tools module."""

    builder = AstroidBuilder(MANAGER)
    stub = AstroidBuilder(MANAGER).string_build('''__all__ = []''')
    unittest_module = builder.module_build(unittest.case)
    case = unittest_module['TestCase']
    all_entries = ['ok_', 'eq_']

    for method_name, method in case.locals.items():
        if method_name.startswith('assert') and '_' not in method_name:
            pep8_name = _pep8(method_name)
            all_entries.append(pep8_name)
            stub[pep8_name] = method[0]

    # Update the __all__ variable, since nose.tools
    # does this manually with .append.
    all_assign = stub['__all__'].parent
    all_object = List(all_entries)
    all_object.parent = all_assign
    all_assign.value = all_object
    return stub
Exemple #39
0
def infer_enum_class(node, context=None):
    """ Specific inference for enums. """
    names = set(('Enum', 'IntEnum', 'enum.Enum', 'enum.IntEnum'))
    for basename in node.basenames:
        # TODO: doesn't handle subclasses yet.
        if basename not in names:
            continue
        if node.root().name == 'enum':
            # Skip if the class is directly from enum module.
            break
        for local, values in node.locals.items():
            if any(not isinstance(value, nodes.AssName)
                   for value in values):
                continue
            parent = values[0].parent
            real_value = parent.value
            new_targets = []
            for target in parent.targets:
                # Replace all the assignments with our mocked class.
                classdef = dedent('''
                class %(name)s(object):
                    @property
                    def value(self):
                        return %(value)s
                    @property
                    def name(self):
                        return %(name)r
                    %(name)s = %(value)s
                ''' % {'name': target.name,
                       'value': real_value.as_string()})
                fake = AstroidBuilder(MANAGER).string_build(classdef)[target.name]
                fake.parent = target.parent
                for method in node.mymethods():
                    fake.locals[method.name] = [method]
                new_targets.append(fake.instanciate_class())
            node.locals[local] = new_targets
        break
    return node
class Python3TC(TestCase):
    def setUp(self):
        self.manager = AstroidManager()
        self.builder = AstroidBuilder(self.manager)
        self.manager.astroid_cache.clear()

    @require_version('3.0')
    def test_starred_notation(self):
        astroid = self.builder.string_build("*a, b = [1, 2, 3]", 'test', 'test')

        # Get the star node
        node = next(next(next(astroid.get_children()).get_children()).get_children())

        self.assertTrue(isinstance(node.ass_type(), Assign))
Exemple #41
0
 def ast_from_module(self, module, modname=None):
     """given an imported module, return the astroid object"""
     modname = modname or module.__name__
     if modname in self.astroid_cache:
         return self.astroid_cache[modname]
     try:
         # some builtin modules don't have __file__ attribute
         filepath = module.__file__
         if modutils.is_python_source(filepath):
             return self.ast_from_file(filepath, modname)
     except AttributeError:
         pass
     from astroid.builder import AstroidBuilder
     return AstroidBuilder(self).module_build(module, modname)
Exemple #42
0
def multiprocessing_transform():
    module = AstroidBuilder(MANAGER).string_build(
        dedent('''
    from multiprocessing.managers import SyncManager
    def Manager():
        return SyncManager()
    '''))
    if not PY34:
        return module

    # On Python 3.4, multiprocessing uses a getattr lookup inside contexts,
    # in order to get the attributes they need. Since it's extremely
    # dynamic, we use this approach to fake it.
    node = AstroidBuilder(MANAGER).string_build(
        dedent('''
    from multiprocessing.context import DefaultContext, BaseContext
    default = DefaultContext()
    base = BaseContext()
    '''))
    try:
        context = next(node['default'].infer())
        base = next(node['base'].infer())
    except InferenceError:
        return module

    for node in (context, base):
        for key, value in node.locals.items():
            if key.startswith("_"):
                continue

            value = value[0]
            if isinstance(value, nodes.FunctionDef):
                # We need to rebound this, since otherwise
                # it will have an extra argument (self).
                value = BoundMethod(value, node)
            module[key] = value
    return module
Exemple #43
0
def _buildAstroidModuleFromComponentModuleName(modname):
    from Products.ERP5.ERP5Site import getSite
    from Acquisition import aq_base
    portal = getSite()
    component_tool = aq_base(portal.portal_components)
    component_obj = None
    component_id = modname[len('erp5.component.'):]
    if '_version' in modname:
        try:
            obj = getattr(component_tool,
                          component_id.replace('_version', '', 1))
        except AttributeError:
            raise AstroidBuildingException()
        if obj.getValidationState() in ('modified', 'validated'):
            component_obj = obj
        else:
            raise AstroidBuildingException()

    else:
        try:
            package, reference = component_id.split('.', 1)
        except ValueError:
            raise AstroidBuildingException()
        for version in portal.getVersionPriorityNameList():
            try:
                obj = getattr(component_tool,
                              '%s.%s.%s' % (package, version, reference))
            except AttributeError:
                continue

            if obj.getValidationState() in ('modified', 'validated'):
                version_modname = 'erp5.component.%s.%s_version.%s' % (
                    package, version, reference)
                module = MANAGER.astroid_cache.get(
                    version_modname,
                    _buildAstroidModuleFromComponentModuleName(
                        version_modname))
                MANAGER.astroid_cache[modname] = module
                return module

    if component_obj is None:
        raise AstroidBuildingException()

    # module_build() could also be used but this requires importing
    # the ZODB Component and also monkey-patch it to support PEP-302
    # for __file__ starting with '<'
    module = AstroidBuilder(MANAGER).string_build(
        component_obj.getTextContent(validated_only=True), modname)
    return module
Exemple #44
0
def handle_session(cls):
    """Handle the sqlalchemy.orm.scoping.scoped_session."""
    if cls.name == "scoped_session":
        source_files = cls.parent.file.split("/")
        source_files[-1] = "session.py"
        module = AstroidBuilder(MANAGER).file_build(
            "/".join(source_files), "sqlalchemy.orm.session"
        )
        session = module.locals.get("Session")[0]
        for method in Session.public_methods:
            cls.locals[method] = session.locals[method]

        return cls

    return None
Exemple #45
0
def multiprocessing_managers_transform():
    return AstroidBuilder(MANAGER).string_build(
        dedent('''
    import array
    import threading
    import multiprocessing.pool as pool

    import six

    class Namespace(object):
        pass

    class Value(object):
        def __init__(self, typecode, value, lock=True):
            self._typecode = typecode
            self._value = value
        def get(self):
            return self._value
        def set(self, value):
            self._value = value
        def __repr__(self):
            return '%s(%r, %r)'%(type(self).__name__, self._typecode, self._value)
        value = property(get, set)

    def Array(typecode, sequence, lock=True):
        return array.array(typecode, sequence)

    class SyncManager(object):
        Queue = JoinableQueue = six.moves.queue.Queue
        Event = threading.Event
        RLock = threading.RLock
        BoundedSemaphore = threading.BoundedSemaphore
        Condition = threading.Condition
        Barrier = threading.Barrier
        Pool = pool.Pool
        list = list
        dict = dict
        Value = Value
        Array = Array
        Namespace = Namespace
        __enter__ = lambda self: self
        __exit__ = lambda *args: args
        
        def start(self, initializer=None, initargs=None):
            pass
        def shutdown(self):
            pass
    '''))
Exemple #46
0
def cubicweb_transform(module):
    # handle objectify_predicate decorator (and its former name until bw compat
    # is kept). Only look at module level functions, should be enough.
    for assnodes in module.locals.values():
        for node in assnodes:
            if isinstance(node, FunctionDef) and node.decorators:
                for decorator in node.decorators.nodes:
                    try:
                        for infered in decorator.infer():
                            if infered.name in ('objectify_predicate',
                                                'objectify_selector'):
                                turn_function_to_class(node)
                                break
                        else:
                            continue
                        break
                    except InferenceError:
                        continue
    # add yams base types into 'yams.buildobjs', astng doesn't grasp globals()
    # magic in there
    if module.name == 'yams.buildobjs':
        from yams import BASE_TYPES
        for etype in BASE_TYPES:
            module.locals[etype] = [ClassDef(etype, None)]
    # add data() to uiprops module
    elif module.name.split('.')[-1] == 'uiprops':
        fake = AstroidBuilder(MANAGER).string_build('''
def data(string):
  return u''
''')
        module.locals['data'] = fake.locals['data']
    # handle lower case with underscores for relation names in schema.py
    if not module.qname().endswith('.schema'):
        return
    schema_locals = module.locals
    for assnodes in schema_locals.values():
        for node in assnodes:
            if not isinstance(node, ClassDef):
                continue
            # XXX can we infer ancestor classes? it would be better to know for sure that
            # one of the mother classes is yams.buildobjs.RelationDefinition for instance
            for base in node.basenames:
                if base in ('RelationDefinition', 'ComputedRelation',
                            'RelationType'):
                    new_name = node.name.replace('_', '').capitalize()
                    schema_locals[new_name] = schema_locals[node.name]
                    del schema_locals[node.name]
                    node.name = new_name
Exemple #47
0
def _import_gi_module(modname):
    # we only consider gi.repository submodules
    if not modname.startswith('gi.repository.'):
        raise AstroidBuildingException()
    # build astroid representation unless we already tried so
    if modname not in _inspected_modules:
        modnames = [modname]
        optional_modnames = []

        # GLib and GObject may have some special case handling
        # in pygobject that we need to cope with. However at
        # least as of pygobject3-3.13.91 the _glib module doesn't
        # exist anymore, so if treat these modules as optional.
        if modname == 'gi.repository.GLib':
            optional_modnames.append('gi._glib')
        elif modname == 'gi.repository.GObject':
            optional_modnames.append('gi._gobject')

        try:
            modcode = ''
            for m in itertools.chain(modnames, optional_modnames):
                try:
                    __import__(m)
                    with warnings.catch_warnings():
                        # Just inspecting the code can raise gi deprecation
                        # warnings, so ignore them.
                        try:
                            from gi import PyGIDeprecationWarning
                            warnings.simplefilter("ignore",
                                                  PyGIDeprecationWarning)
                        except Exception:
                            pass

                        modcode += _gi_build_stub(sys.modules[m])
                except ImportError:
                    if m not in optional_modnames:
                        raise
        except ImportError:
            astng = _inspected_modules[modname] = None
        else:
            astng = AstroidBuilder(MANAGER).string_build(modcode, modname)
            _inspected_modules[modname] = astng
    else:
        astng = _inspected_modules[modname]
    if astng is None:
        raise AstroidBuildingException('Failed to import module %r' % modname)
    return astng
Exemple #48
0
    def ast_from_module(self, module: types.ModuleType, modname: str = None):
        """given an imported module, return the astroid object"""
        modname = modname or module.__name__
        if modname in self.astroid_cache:
            return self.astroid_cache[modname]
        try:
            # some builtin modules don't have __file__ attribute
            filepath = module.__file__
            if is_python_source(filepath):
                return self.ast_from_file(filepath, modname)
        except AttributeError:
            pass

        # pylint: disable=import-outside-toplevel; circular import
        from astroid.builder import AstroidBuilder

        return AstroidBuilder(self).module_build(module, modname)
Exemple #49
0
def _add_transform(package_name, *class_names):
    """Transform package's classes."""
    transforms_dir = os.path.join(os.path.dirname(__file__), 'transforms')
    fake_module_path = os.path.join(transforms_dir, '%s.py' % re.sub(r'\.', '_', package_name))

    with open(fake_module_path) as modulefile:
        fake_module = modulefile.read()

    fake = AstroidBuilder(MANAGER).string_build(fake_module)

    def set_fake_locals(module):
        """Set fake locals for package."""
        if module.name != package_name:
            return
        for class_name in class_names:
            module.locals[class_name] = fake.locals[class_name]

    MANAGER.register_transform(nodes.Module, set_fake_locals)
Exemple #50
0
def hashlib_transform(module):
    template = '''

class %s(object):
  def __init__(self, value=''): pass
  def digest(self):
    return u''
  def update(self, value): pass
  def hexdigest(self):
    return u''
'''

    algorithms = ('md5', 'sha1', 'sha224', 'sha256', 'sha384', 'sha512')
    classes = "".join(template % hashfunc for hashfunc in algorithms)

    fake = AstroidBuilder(MANAGER).string_build(classes)

    for hashfunc in algorithms:
        module.locals[hashfunc] = fake.locals[hashfunc]
Exemple #51
0
    def test_ancestors_patching_class_recursion(self):
        node = AstroidBuilder().string_build(textwrap.dedent("""
        import string
        Template = string.Template

        class A(Template):
            pass

        class B(A):
            pass

        def test(x=False):
            if x:
                string.Template = A
            else:
                string.Template = B
        """))
        klass = node['A']
        ancestors = list(klass.ancestors())
        self.assertEqual(ancestors[0].qname(), 'string.Template')
Exemple #52
0
 def ast_from_file(self, filepath, modname=None, fallback=True, source=False):
     """given a module name, return the astroid object"""
     try:
         filepath = get_source_file(filepath, include_no_ext=True)
         source = True
     except NoSourceFile:
         pass
     if modname is None:
         try:
             modname = '.'.join(modpath_from_file(filepath))
         except ImportError:
             modname = filepath
     if modname in self.astroid_cache and self.astroid_cache[modname].file == filepath:
         return self.astroid_cache[modname]
     if source:
         from astroid.builder import AstroidBuilder
         return AstroidBuilder(self).file_build(filepath, modname)
     elif fallback and modname:
         return self.ast_from_module_name(modname)
     raise AstroidBuildingException('unable to get astroid for file %s' %
                                    filepath)
Exemple #53
0
def infer_named_tuple(node, context=None):
    """Specific inference function for namedtuple Call node"""
    class_node, name, attributes = infer_func_form(node, nodes.Tuple._proxied,
                                                   context=context)
    fake = AstroidBuilder(MANAGER).string_build('''
class %(name)s(tuple):
    _fields = %(fields)r
    def _asdict(self):
        return self.__dict__
    @classmethod
    def _make(cls, iterable, new=tuple.__new__, len=len):
        return new(cls, iterable)
    def _replace(self, **kwds):
        return self
    ''' % {'name': name, 'fields': attributes})
    class_node._locals['_asdict'] = fake.body[0]._locals['_asdict']
    class_node._locals['_make'] = fake.body[0]._locals['_make']
    class_node._locals['_replace'] = fake.body[0]._locals['_replace']
    class_node._locals['_fields'] = fake.body[0]._locals['_fields']
    # we use UseInferenceDefault, we can't be a generator so return an iterator
    return iter([class_node])
Exemple #54
0
def _six_fail_hook(modname):
    if modname != 'six.moves':
        raise AstroidBuildingException
    module = AstroidBuilder(MANAGER).string_build(_IMPORTS)
    module.name = 'six.moves'
    return module
 def setUp(self):
     self.manager = AstroidManager()
     self.builder = AstroidBuilder(self.manager)
     self.manager.astroid_cache.clear()
 def test_living_property(self):
     builder = AstroidBuilder()
     builder._done = {}
     builder._module = sys.modules[__name__]
     builder.object_build(build_module('module_name', ''), Whatever)
 def setUp(self):
     self.manager = AstroidManager()
     self.manager.clear_cache() # take care of borg
     self.builder = AstroidBuilder(self.manager)
class Python3TC(TestCase):
    def setUp(self):
        self.manager = AstroidManager()
        self.builder = AstroidBuilder(self.manager)
        self.manager.astroid_cache.clear()

    @require_version('3.0')
    def test_starred_notation(self):
        astroid = self.builder.string_build("*a, b = [1, 2, 3]", 'test', 'test')

        # Get the star node
        node = next(next(next(astroid.get_children()).get_children()).get_children())

        self.assertTrue(isinstance(node.ass_type(), Assign))

    @require_version('3.3')
    def test_yield_from(self):
        body = dedent("""
        def func():
            yield from iter([1, 2])
        """)
        astroid = self.builder.string_build(body)
        func = astroid.body[0]
        self.assertIsInstance(func, Function)
        yieldfrom_stmt = func.body[0]

        self.assertIsInstance(yieldfrom_stmt, Discard)
        self.assertIsInstance(yieldfrom_stmt.value, YieldFrom)
        self.assertEqual(yieldfrom_stmt.as_string(),
                         'yield from iter([1, 2])')

    @require_version('3.3')
    def test_yield_from_is_generator(self):
        body = dedent("""
        def func():
            yield from iter([1, 2])
        """)
        astroid = self.builder.string_build(body)
        func = astroid.body[0]
        self.assertIsInstance(func, Function)
        self.assertTrue(func.is_generator())

    @require_version('3.3')
    def test_yield_from_as_string(self):
        body = dedent("""
        def func():
            yield from iter([1, 2])
            value = yield from other()
        """)
        astroid = self.builder.string_build(body)
        func = astroid.body[0]
        self.assertEqual(func.as_string().strip(), body.strip())

    # metaclass tests

    @require_version('3.0')
    def test_simple_metaclass(self):
        astroid = self.builder.string_build("class Test(metaclass=type): pass")
        klass = astroid.body[0]

        metaclass = klass.metaclass()
        self.assertIsInstance(metaclass, Class)
        self.assertEqual(metaclass.name, 'type')

    @require_version('3.0')
    def test_metaclass_error(self):
        astroid = self.builder.string_build("class Test(metaclass=typ): pass")
        klass = astroid.body[0]
        self.assertFalse(klass.metaclass())

    @require_version('3.0')
    def test_metaclass_imported(self): 
        astroid = self.builder.string_build(dedent("""
        from abc import ABCMeta 
        class Test(metaclass=ABCMeta): pass"""))
        klass = astroid.body[1]

        metaclass = klass.metaclass()
        self.assertIsInstance(metaclass, Class)
        self.assertEqual(metaclass.name, 'ABCMeta')       

    @require_version('3.0')
    def test_as_string(self):
        body = dedent("""
        from abc import ABCMeta 
        class Test(metaclass=ABCMeta): pass""")
        astroid = self.builder.string_build(body)
        klass = astroid.body[1]

        self.assertEqual(klass.as_string(), 
                         '\n\nclass Test(metaclass=ABCMeta):\n    pass\n')

    @require_version('3.0')
    def test_old_syntax_works(self):
        astroid = self.builder.string_build(dedent("""
        class Test:
            __metaclass__ = type
        class SubTest(Test): pass
        """))
        klass = astroid['SubTest']
        metaclass = klass.metaclass()
        self.assertIsInstance(metaclass, Class)
        self.assertEqual(metaclass.name, 'type')

    @require_version('3.0')
    def test_metaclass_yes_leak(self):
        astroid = self.builder.string_build(dedent("""
        # notice `ab` instead of `abc`
        from ab import ABCMeta

        class Meta(metaclass=ABCMeta): pass
        """))
        klass = astroid['Meta']
        self.assertIsNone(klass.metaclass())

    @require_version('3.0')
    def test_metaclass_ancestors(self):
        astroid = self.builder.string_build(dedent("""
        from abc import ABCMeta

        class FirstMeta(metaclass=ABCMeta): pass
        class SecondMeta(metaclass=type):
            pass

        class Simple:
            pass

        class FirstImpl(FirstMeta): pass
        class SecondImpl(FirstImpl): pass
        class ThirdImpl(Simple, SecondMeta):
            pass
        """))
        classes = {
            'ABCMeta': ('FirstImpl', 'SecondImpl'),
            'type': ('ThirdImpl', )
        }
        for metaclass, names in classes.items():
            for name in names:
                impl = astroid[name]
                meta = impl.metaclass()
                self.assertIsInstance(meta, Class)
                self.assertEqual(meta.name, metaclass)
class Python3TC(TestCase):
    def setUp(self):
        self.manager = AstroidManager()
        self.builder = AstroidBuilder(self.manager)
        self.manager.astroid_cache.clear()

    @require_version('3.0')
    def test_starred_notation(self):
        astroid = self.builder.string_build("*a, b = [1, 2, 3]", 'test', 'test')

        # Get the star node
        node = next(next(next(astroid.get_children()).get_children()).get_children())

        self.assertTrue(isinstance(node.ass_type(), Assign))

    @require_version('3.3')
    def test_yield_from(self):
        body = dedent("""
        def func():
            yield from iter([1, 2])
        """)
        astroid = self.builder.string_build(body)
        func = astroid.body[0]
        self.assertIsInstance(func, Function)
        yieldfrom_stmt = func.body[0]

        self.assertIsInstance(yieldfrom_stmt, Discard)
        self.assertIsInstance(yieldfrom_stmt.value, YieldFrom)
        self.assertEqual(yieldfrom_stmt.as_string(),
                         'yield from iter([1, 2])')

    @require_version('3.3')
    def test_yield_from_is_generator(self):
        body = dedent("""
        def func():
            yield from iter([1, 2])
        """)
        astroid = self.builder.string_build(body)
        func = astroid.body[0]
        self.assertIsInstance(func, Function)
        self.assertTrue(func.is_generator())

    @require_version('3.3')
    def test_yield_from_as_string(self):
        body = dedent("""
        def func():
            yield from iter([1, 2])
            value = yield from other()
        """)
        astroid = self.builder.string_build(body)
        func = astroid.body[0]
        self.assertEqual(func.as_string().strip(), body.strip())

    # metaclass tests

    @require_version('3.0')
    def test_simple_metaclass(self):
        astroid = self.builder.string_build("class Test(metaclass=type): pass")
        klass = astroid.body[0]

        metaclass = klass.metaclass()
        self.assertIsInstance(metaclass, Class)
        self.assertEqual(metaclass.name, 'type')

    @require_version('3.0')
    def test_metaclass_error(self):
        astroid = self.builder.string_build("class Test(metaclass=typ): pass")
        klass = astroid.body[0]
        self.assertFalse(klass.metaclass())

    @require_version('3.0')
    def test_metaclass_imported(self): 
        astroid = self.builder.string_build(dedent("""
        from abc import ABCMeta 
        class Test(metaclass=ABCMeta): pass"""))
        klass = astroid.body[1]

        metaclass = klass.metaclass()
        self.assertIsInstance(metaclass, Class)
        self.assertEqual(metaclass.name, 'ABCMeta')       

    @require_version('3.0')
    def test_as_string(self):
        body = dedent("""
        from abc import ABCMeta 
        class Test(metaclass=ABCMeta): pass""")
        astroid = self.builder.string_build(body)
        klass = astroid.body[1]

        self.assertEqual(klass.as_string(), 
                         '\n\nclass Test(metaclass=ABCMeta):\n    pass\n')

    @require_version('3.0')
    def test_old_syntax_works(self):
        astroid = self.builder.string_build(dedent("""
        class Test:
            __metaclass__ = type
        class SubTest(Test): pass
        """))
        klass = astroid['SubTest']
        metaclass = klass.metaclass()
        self.assertIsInstance(metaclass, Class)
        self.assertEqual(metaclass.name, 'type')