示例#1
0
def register(_):
    """ Registers this plugin to pylint

    pylint calls this function when loading
    """
    MANAGER.register_transform(nodes.Module, pytest_transform)
    MANAGER.register_transform(nodes.Module, redbaron_transform)
def register_builtin_transform(transform, builtin_name):
    """Register a new transform function for the given *builtin_name*.

    The transform function must accept two parameters, a node and
    an optional context.
    """

    def _transform_wrapper(node, context=None):
        result = transform(node, context=context)
        if result:
            if not result.parent:
                # Let the transformation function determine
                # the parent for its result. Otherwise,
                # we set it to be the node we transformed from.
                result.parent = node

            if result.lineno is None:
                result.lineno = node.lineno
            if result.col_offset is None:
                result.col_offset = node.col_offset
        return iter([result])

    MANAGER.register_transform(
        nodes.Call,
        inference_tip(_transform_wrapper),
        partial(_builtin_filter_predicate, builtin_name=builtin_name),
    )
 def tearDown(self):
     # Since we may have created a brainless manager, leading
     # to a new cache builtin module and proxy classes in the constants,
     # clear out the global manager cache.
     MANAGER.clear_cache()
     sys.path.pop(0)
     sys.path_importer_cache.pop(resources.find('data'), None)
示例#4
0
 def tearDown(self):
     # Since we may have created a brainless manager, leading
     # to a new cache builtin module and proxy classes in the constants,
     # clear out the global manager cache.
     MANAGER.clear_cache(self._builtins)
     MANAGER.always_load_extensions = False
     sys.path.pop(0)
     sys.path_importer_cache.pop(resources.find("data"), None)
def register(linter):
    """
    Register new linter checkers and transformers
    Called when loaded by pylint's load-plugins option.
    We register our tranformation function here.
    """

    MANAGER.register_transform(nodes.Module, transform)
示例#6
0
文件: lint.py 项目: TurBoss/pywincffi
def register(_):  # pragma: no cover
    """
    An entrypoint that pylint uses to search for and register
    plugins with the given ``linter``
    """
    functions = \
        functions_in_file(FUNCTIONS_HEADER) | functions_in_file(SOURCE_MAIN)
    constants = constants_in_file(CONSTANTS_HEADER)
    MANAGER.register_transform(
        scoped_nodes.Class,
        partial(transform, constants=constants, functions=functions),
        predicate=lambda node: node.name == "FFILibrary")
示例#7
0
def _add_transform(package_name, *class_names):
    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):
        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)
示例#8
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
示例#9
0
 def test_regex_flags(self):
     import re
     names = [name for name in dir(re) if name.isupper()]
     re_ast = MANAGER.ast_from_module_name('re')
     for name in names:
         self.assertIn(name, re_ast)
         self.assertEqual(next(re_ast[name].infer()).value, getattr(re, name))
def get_project(module, name=None):
    """return a astroid project representation"""
    # flush cache
    MANAGER._modules_by_name = {}
    def _astroid_wrapper(func, modname):
        return func(modname)
    return MANAGER.project_from_files([module], _astroid_wrapper,
                                      project_name=name)
示例#11
0
def register_builtin_transform(transform, builtin_name):
    """Register a new transform function for the given *builtin_name*.

    The transform function must accept two parameters, a node and
    an optional context.
    """
    def _transform_wrapper(node, context=None):
        result = transform(node, context=context)
        if result:
            result.parent = node
            result.lineno = node.lineno
            result.col_offset = node.col_offset
        return iter([result])

    MANAGER.register_transform(nodes.CallFunc,
                               inference_tip(_transform_wrapper),
                               lambda n: (isinstance(n.func, nodes.Name) and
                                          n.func.name == builtin_name))
示例#12
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]  # pylint: disable=protected-access

    MANAGER.register_transform(nodes.Module, set_fake_locals)
示例#13
0
def _check(module_name='', level='all', local_config='', output=None):
    """Check a module for problems, printing a report.

    The `module_name` can take several inputs:
      - string of a directory, or file to check (`.py` extension optional).
      - list of strings of directories or files -- can have multiple.
      - no argument -- checks the python file containing the function call.
    `level` is used to specify which checks should be made.
    `local_config` is a dict of config options or string (config file name).
    `output` is an absolute path to capture pyta data output. Default std out.
    """
    MANAGER.clear_cache()

    # Add reporters to an internal pylint data structure, for use with setting
    # custom pyta options in a Tuple, before (re)setting reporter.
    for reporter in REPORTERS:
        VALIDATORS[reporter.__name__] = reporter
    linter = reset_linter(config=local_config)

    current_reporter = reset_reporter(linter, output)
    patch_all()  # Monkeypatch pylint (override certain methods)

    # Try to check file, issue error message for invalid files.
    try:
        for locations in _get_valid_files_to_check(current_reporter, module_name):
            for file_py in get_file_paths(locations):
                if not _verify_pre_check(file_py):
                    continue  # Check the other files
                # Load config file in user location. Construct new linter each
                # time, so config options don't bleed to unintended files.
                linter = reset_linter(config=local_config, file_linted=file_py)
                # Assume the local config will NOT set a new reporter.
                linter.set_reporter(current_reporter)
                current_reporter.register_file(file_py)
                linter.check(file_py)  # Lint !
                current_reporter.print_messages(level)
                current_reporter.reset_messages()  # Clear lists for any next file.
        current_reporter.output_blob()
        return current_reporter
    except Exception as e:
        print('[ERROR] Unexpected error encountered! Please report this to your instructor (and attach the code that caused the error).')
        print('[ERROR] Error message: "{}"'.format(e))
        raise e
示例#14
0
def transform_model_class(cls):
    if cls.is_subtype_of('django.db.models.base.Model'):
        core_exceptions = MANAGER.ast_from_module_name('django.core.exceptions')
        # add DoesNotExist exception
        DoesNotExist = Class('DoesNotExist', None)
        DoesNotExist.bases = core_exceptions.lookup('ObjectDoesNotExist')[1]
        cls.locals['DoesNotExist'] = [DoesNotExist]
        # add MultipleObjectsReturned exception
        MultipleObjectsReturned = Class('MultipleObjectsReturned', None)
        MultipleObjectsReturned.bases = core_exceptions.lookup(
            'MultipleObjectsReturned')[1]
        cls.locals['MultipleObjectsReturned'] = [MultipleObjectsReturned]
        # add objects manager
        if 'objects' not in cls.locals:
            try:
                Manager = MANAGER.ast_from_module_name(
                    'django.db.models.manager').lookup('Manager')[1][0]
                QuerySet = MANAGER.ast_from_module_name(
                    'django.db.models.query').lookup('QuerySet')[1][0]
            except IndexError:
                pass
            else:
                if isinstance(Manager.body[0], Pass):
                    # for django >= 1.7
                    for func_name, func_list in QuerySet.locals.items():
                        if (not func_name.startswith('_') and
                                func_name not in Manager.locals):
                            func = func_list[0]
                            if (isinstance(func, Function) and
                                    'queryset_only' not in func.instance_attrs):
                                f = Function(func_name, None)
                                f.args = Arguments()
                                Manager.locals[func_name] = [f]
                cls.locals['objects'] = [Instance(Manager)]
        # add id field
        if 'id' not in cls.locals:
            try:
                AutoField = MANAGER.ast_from_module_name(
                    'django.db.models.fields').lookup('AutoField')[1][0]
            except IndexError:
                pass
            else:
                cls.locals['id'] = [Instance(AutoField)]
示例#15
0
 def get_ast(self, filepath, modname):
     """return a ast(roid) representation for a module"""
     try:
         return MANAGER.ast_from_file(filepath, modname, source=True)
     except SyntaxError as ex:
         self.add_message('E0001', line=ex.lineno, args=ex.msg)
     except AstroidBuildingException as ex:
         self.add_message('F0010', args=ex)
     except Exception as ex:
         import traceback
         traceback.print_exc()
         self.add_message('F0002', args=(ex.__class__, ex))
示例#16
0
def apply_type_shim(cls, context=None):

    if cls.name in _STR_FIELDS:
        base_node = scoped_nodes.builtin_lookup('str')
    elif cls.name in _INT_FIELDS:
        base_node = scoped_nodes.builtin_lookup('int')
    elif cls.name in _BOOL_FIELDS:
        base_node = scoped_nodes.builtin_lookup('bool')
    elif cls.name == 'FloatField':
        base_node = scoped_nodes.builtin_lookup('float')
    elif cls.name == 'DecimalField':
        base_node = MANAGER.ast_from_module_name('decimal').lookup('Decimal')
    elif cls.name in ('SplitDateTimeField', 'DateTimeField'):
        base_node = MANAGER.ast_from_module_name('datetime').lookup('datetime')
    elif cls.name == 'TimeField':
        base_node = MANAGER.ast_from_module_name('datetime').lookup('time')
    elif cls.name == 'DateField':
        base_node = MANAGER.ast_from_module_name('datetime').lookup('date')
    elif cls.name == 'ManyToManyField':
        base_node = MANAGER.ast_from_module_name('django.db.models.query').lookup('QuerySet')
    elif cls.name in ('ImageField', 'FileField'):
        base_node = MANAGER.ast_from_module_name('django.core.files.base').lookup('File')
    else:
        return iter([cls])

    return iter([cls] + base_node[1])
示例#17
0
 def test_hashlib(self):
     """Tests that brain extensions for hashlib work."""
     hashlib_module = MANAGER.ast_from_module_name('hashlib')
     for class_name in ['md5', 'sha1']:
         class_obj = hashlib_module[class_name]
         self.assertIn('update', class_obj)
         self.assertIn('digest', class_obj)
         self.assertIn('hexdigest', class_obj)
         self.assertEqual(len(class_obj['__init__'].args.args), 2)
         self.assertEqual(len(class_obj['__init__'].args.defaults), 1)
         self.assertEqual(len(class_obj['update'].args.args), 2)
         self.assertEqual(len(class_obj['digest'].args.args), 1)
         self.assertEqual(len(class_obj['hexdigest'].args.args), 1)
示例#18
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:
            # This changed from locals to _locals between astroid 1.3 and 1.4
            if hasattr(module, '_locals'):
                module._locals[class_name].extend(fake._locals[class_name])  # pylint: disable=protected-access
            else:
                module.locals[class_name].extend(fake.locals[class_name])

    MANAGER.register_transform(nodes.Module, set_fake_locals)
def register(dummy_linter):
    """Pylint calls this hook to actually activate the plugin"""

    checker = ImportRewriterVisitor()

    MANAGER.register_transform(nodes.Import, checker.visit_import)
    MANAGER.register_transform(nodes.From, checker.visit_from)
    MANAGER.register_transform(nodes.Module, checker.visit_module)
示例#20
0
 def test_hashlib(self):
     """Tests that brain extensions for hashlib work."""
     hashlib_module = MANAGER.ast_from_module_name("hashlib")
     for class_name in ["md5", "sha1"]:
         class_obj = hashlib_module[class_name]
         self.assertIn("update", class_obj)
         self.assertIn("digest", class_obj)
         self.assertIn("hexdigest", class_obj)
         self.assertIn("block_size", class_obj)
         self.assertIn("digest_size", class_obj)
         self.assertEqual(len(class_obj["__init__"].args.args), 2)
         self.assertEqual(len(class_obj["__init__"].args.defaults), 1)
         self.assertEqual(len(class_obj["update"].args.args), 2)
         self.assertEqual(len(class_obj["digest"].args.args), 1)
         self.assertEqual(len(class_obj["hexdigest"].args.args), 1)
 def test_pylint_config_attr(self):
     try:
         from pylint import lint
     except ImportError:
         self.skipTest('pylint not available')
     mod = MANAGER.ast_from_module_name('pylint.lint')
     pylinter = mod['PyLinter']
     expect = ['OptionsManagerMixIn', 'object', 'MessagesHandlerMixIn',
               'ReportsHandlerMixIn', 'BaseTokenChecker', 'BaseChecker',
               'OptionsProviderMixIn']
     self.assertListEqual([c.name for c in pylinter.ancestors()],
                          expect)
     self.assertTrue(list(Instance(pylinter).getattr('config')))
     infered = list(Instance(pylinter).igetattr('config'))
     self.assertEqual(len(infered), 1)
     self.assertEqual(infered[0].root().name, 'optparse')
     self.assertEqual(infered[0].name, 'Values')
示例#22
0
 def test_pylint_config_attr(self):
     try:
         from pylint import lint
     except ImportError:
         self.skipTest("pylint not available")
     mod = MANAGER.ast_from_module_name("pylint.lint")
     pylinter = mod["PyLinter"]
     expect = [
         "OptionsManagerMixIn",
         "object",
         "MessagesHandlerMixIn",
         "ReportsHandlerMixIn",
         "BaseTokenChecker",
         "BaseChecker",
         "OptionsProviderMixIn",
     ]
     self.assertListEqual([c.name for c in pylinter.ancestors()], expect)
     self.assertTrue(list(Instance(pylinter).getattr("config")))
     infered = list(Instance(pylinter).igetattr("config"))
     self.assertEqual(len(infered), 1)
     self.assertEqual(infered[0].root().name, "optparse")
     self.assertEqual(infered[0].name, "Values")
示例#23
0
def apply_type_shim(cls, context=None):

    if cls.name in _STR_FIELDS:
        base_nodes = scoped_nodes.builtin_lookup('str')
    elif cls.name in _INT_FIELDS:
        base_nodes = scoped_nodes.builtin_lookup('int')
    elif cls.name in _BOOL_FIELDS:
        base_nodes = scoped_nodes.builtin_lookup('bool')
    elif cls.name == 'FloatField':
        base_nodes = scoped_nodes.builtin_lookup('float')
    elif cls.name == 'DecimalField':
        if sys.version_info >= (3, 5):
            # I dunno, I'm tired and this works :(
            base_nodes = MANAGER.ast_from_module_name('_decimal').lookup('Decimal')
        else:
            base_nodes = MANAGER.ast_from_module_name('decimal').lookup('Decimal')
    elif cls.name in ('SplitDateTimeField', 'DateTimeField'):
        base_nodes = MANAGER.ast_from_module_name('datetime').lookup('datetime')
    elif cls.name == 'TimeField':
        base_nodes = MANAGER.ast_from_module_name('datetime').lookup('time')
    elif cls.name == 'DateField':
        base_nodes = MANAGER.ast_from_module_name('datetime').lookup('date')
    elif cls.name == 'ManyToManyField':
        base_nodes = MANAGER.ast_from_module_name('django.db.models.query').lookup('QuerySet')
    elif cls.name in ('ImageField', 'FileField'):
        base_nodes = MANAGER.ast_from_module_name('django.core.files.base').lookup('File')
    else:
        return iter([cls])

    # XXX: for some reason, with python3, this particular line triggers a
    # check in the StdlibChecker for deprecated methods; one of these nodes
    # is an ImportFrom which has no qname() method, causing the checker
    # to die...
    if utils.PY3:
        base_nodes = [n for n in base_nodes[1] if not isinstance(n, nodes.ImportFrom)]
    else:
        base_nodes = list(base_nodes[1])

    return iter([cls] + base_nodes)
示例#24
0
    python_requires_class = MANAGER.ast_from_module_name(
        "conans.client.graph.python_requires").lookup("PyRequires")

    dynamic_fields = {
        "conan_data": str_class,
        "build_requires": build_requires_class,
        "info_build": info_class,
        "info": info_class,
        "copy": file_copier_class,
        "copy_deps": file_importer_class,
        "python_requires": [str_class, python_requires_class],
    }

    for f, t in dynamic_fields.items():
        node.locals[f] = [t]


MANAGER.register_transform(
    astroid.ClassDef, transform_conanfile,
    lambda node: node.qname() == "conans.model.conan_file.ConanFile")


def _python_requires_member():
    return astroid.parse("""
        from conans.client.graph.python_requires import ConanPythonRequire
        python_requires = ConanPythonRequire()
        """)


astroid.register_module_extender(astroid.MANAGER, "conans", _python_requires_member)
示例#25
0
def dataclass_transform(node):
    """Rewrite a dataclass to be easily understood by pylint"""

    for assign_node in node.body:
        if not isinstance(assign_node, (astroid.AnnAssign, astroid.Assign)):
            continue

        if (isinstance(assign_node, astroid.AnnAssign)
                and isinstance(assign_node.annotation, astroid.Subscript) and
            (isinstance(assign_node.annotation.value, astroid.Name)
             and assign_node.annotation.value.name == "ClassVar"
             or isinstance(assign_node.annotation.value, astroid.Attribute)
             and assign_node.annotation.value.attrname == "ClassVar")):
            continue

        targets = (assign_node.targets if hasattr(assign_node, "targets") else
                   [assign_node.target])
        for target in targets:
            rhs_node = astroid.Unknown(
                lineno=assign_node.lineno,
                col_offset=assign_node.col_offset,
                parent=assign_node,
            )
            node.instance_attrs[target.name] = [rhs_node]
            node.locals[target.name] = [rhs_node]


MANAGER.register_transform(astroid.ClassDef, dataclass_transform,
                           is_decorated_with_dataclass)
示例#26
0
    # this method is expected by pylint for plugins, however we don't
    # want to register any checkers
    pass


MODULE_TRANSFORMS = {}


def transform(module):
    try:
        tr = MODULE_TRANSFORMS[module.name]
    except KeyError:
        pass
    else:
        tr(module)


MANAGER.register_transform(nodes.Module, transform)


def celery_transform(module):
    fake = AstroidBuilder(MANAGER).string_build('''
class task_dummy(object):
    def __call__(self):
        pass
''')
    module.locals['task'] = fake.locals['task_dummy']


MODULE_TRANSFORMS['celery'] = celery_transform
示例#27
0
            property_name = property_name.replace(
                "-", "_")  # Note: We do the same in Python code
            property_type = property_data.get("type", None)

            if isinstance(property_type, (list, tuple)):
                # Hack for attributes with multiple types (e.g. string, null)
                property_type = property_type[0]

            if property_type == "object":
                node = nodes.Dict()
            elif property_type == "array":
                node = nodes.List()
            elif property_type == "integer":
                node = scoped_nodes.builtin_lookup("int")[1][0]
            elif property_type == "number":
                node = scoped_nodes.builtin_lookup("float")[1][0]
            elif property_type == "string":
                node = scoped_nodes.builtin_lookup("str")[1][0]
            elif property_type == "boolean":
                node = scoped_nodes.builtin_lookup("bool")[1][0]
            elif property_type == "null":
                node = scoped_nodes.builtin_lookup("None")[1][0]
            else:
                # Unknown type
                node = astroid.ClassDef(property_name, None)

            cls.locals[property_name] = [node]


MANAGER.register_transform(astroid.ClassDef, transform)
示例#28
0
MODULE_TRANSFORMS = {}
PY3K = sys.version_info > (3, 0)

# module specific transformation functions #####################################


def transform(module):
    try:
        tr = MODULE_TRANSFORMS[module.name]
    except KeyError:
        pass
    else:
        tr(module)


MANAGER.register_transform(nodes.Module, transform)

# module specific transformation functions #####################################


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''
'''
示例#29
0
 def test_hashlib_py36(self):
     hashlib_module = MANAGER.ast_from_module_name('hashlib')
     for class_name in ['sha3_224', 'sha3_512', 'shake_128']:
         class_obj = hashlib_module[class_name]
         self._assert_hashlib_class(class_obj)
示例#30
0
    if "id" not in cls.locals:
        cls.locals["id"] = [nodes.ClassDef("id", None)]


def is_model_field(cls: ClassDef) -> bool:
    """
    Guard to apply this transform to Model Fields only
    """
    type_name = "tortoise.fields.base.Field"
    return cls.is_subtype_of(type_name) and cls.qname() != type_name


def apply_type_shim(cls: ClassDef, _context=None) -> Iterator[ClassDef]:
    """
    Morphs model fields to representative type
    """
    base_nodes: List[ClassDef] = [cls]

    # Use the type inference standard
    try:
        base_nodes.extend(list(cls.getattr("field_type")[0].infer()))
    except AstroidError:
        pass

    return iter(base_nodes)


MANAGER.register_transform(nodes.ClassDef, inference_tip(apply_type_shim),
                           is_model_field)
MANAGER.register_transform(nodes.ClassDef, transform_model, is_model)
示例#31
0
def infer_key_classes(node, context=None):
    keyword_args = []
    if node.keywords:
        keyword_args = [kw.value for kw in node.keywords if kw.arg == 'to']
    all_args = chain(node.args, keyword_args)

    for arg in all_args:
        # typically the class of the foreign key will
        # be the first argument, so we'll go from left to right
        if isinstance(arg, (nodes.Name, nodes.Attribute)):
            try:
                key_cls = None
                for inferred in arg.infer(context=context):
                    key_cls = inferred
                    break
            except InferenceError:
                continue
            else:
                if key_cls is not None:
                    break
        elif isinstance(arg, nodes.Const):
            try:
                # can be 'self' , 'Model' or 'app.Model'
                if arg.value == 'self':
                    module_name = ''
                    # for relations with `to` first parent be Keyword(arg='to')
                    # and we need to go deeper in parent tree to get model name
                    if isinstance(arg.parent,
                                  nodes.Keyword) and arg.parent.arg == 'to':
                        model_name = arg.parent.parent.parent.parent.name
                    else:
                        model_name = arg.parent.parent.parent.name
                else:
                    module_name, _, model_name = arg.value.rpartition('.')
            except AttributeError:
                break

            # when ForeignKey is specified only by class name we assume that
            # this class must be found in the current module
            if not module_name:
                current_module = node.frame()
                while not isinstance(current_module, nodes.Module):
                    current_module = current_module.parent.frame()

                module_name = current_module.name
            elif not module_name.endswith('models'):
                # otherwise Django allows specifying an app name first, e.g.
                # ForeignKey('auth.User') so we try to convert that to
                # 'auth.models', 'User' which works nicely with the `endswith()`
                # comparison below
                module_name += '.models'
                # ensure that module is loaded in astroid_cache, for cases when models is a package
                if module_name not in MANAGER.astroid_cache:
                    MANAGER.ast_from_module_name(module_name)

            # create list from dict_values, because it may be modified in a loop
            for module in list(MANAGER.astroid_cache.values()):
                # only load model classes from modules which match the module in
                # which *we think* they are defined. This will prevent infering
                # other models of the same name which are found elsewhere!
                if model_name in module.locals and module.name.endswith(
                        module_name):
                    class_defs = _get_model_class_defs_from_module(
                        module, model_name, module_name)

                    if class_defs:
                        return iter([class_defs[0].instantiate_class()])
    else:
        raise UseInferenceDefault
    return iter([key_cls.instantiate_class()])
示例#32
0
        raise astroid.UseInferenceDefault

    try:
        elts = random.sample(inferred_sequence.elts, length.value)
    except ValueError as exc:
        raise astroid.UseInferenceDefault from exc

    new_node = astroid.List(lineno=node.lineno,
                            col_offset=node.col_offset,
                            parent=node.scope())
    new_elts = [
        _clone_node_with_lineno(elt, parent=new_node, lineno=new_node.lineno)
        for elt in elts
    ]
    new_node.postinit(new_elts)
    return iter((new_node, ))


def _looks_like_random_sample(node):
    func = node.func
    if isinstance(func, astroid.Attribute):
        return func.attrname == "sample"
    if isinstance(func, astroid.Name):
        return func.name == "sample"
    return False


MANAGER.register_transform(astroid.Call,
                           astroid.inference_tip(infer_random_sample),
                           _looks_like_random_sample)
示例#33
0
        if not isinstance(elt, (nodes.List, nodes.Tuple)):
            raise UseInferenceDefault
        if len(elt.elts) != 2:
            raise UseInferenceDefault
        names.append(elt.elts[0].as_string())

    typename = node.args[0].as_string()
    if names:
        field_names = "({},)".format(",".join(names))
    else:
        field_names = "''"
    node = extract_node(f"namedtuple({typename}, {field_names})")
    return infer_named_tuple(node, context)


MANAGER.register_transform(nodes.Call, inference_tip(infer_named_tuple),
                           _looks_like_namedtuple)
MANAGER.register_transform(nodes.Call, inference_tip(infer_enum),
                           _looks_like_enum)
MANAGER.register_transform(
    nodes.ClassDef,
    infer_enum_class,
    predicate=lambda cls: any(basename for basename in cls.basenames
                              if basename in ENUM_BASE_NAMES),
)
MANAGER.register_transform(nodes.ClassDef,
                           inference_tip(infer_typing_namedtuple_class),
                           _has_namedtuple_base)
MANAGER.register_transform(
    nodes.FunctionDef,
    inference_tip(infer_typing_namedtuple_function),
    lambda node: node.name == "NamedTuple" and getattr(node.root(), "name",
示例#34
0
# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html
# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER
"""Astroid hooks for the UUID module."""

from astroid import MANAGER
from astroid import nodes


def _patch_uuid_class(node):
    # The .int member is patched using __dict__
    node.locals['int'] = [nodes.Const(0, parent=node)]


MANAGER.register_transform(nodes.ClassDef, _patch_uuid_class,
                           lambda node: node.qname() == 'uuid.UUID')
示例#35
0
    module.name = 'six.moves'
    return module

def transform_six_add_metaclass(node):
    """Check if the given class node is decorated with *six.add_metaclass*

    If so, inject its argument as the metaclass of the underlying class.
    """
    if not node.decorators:
        return

    for decorator in node.decorators.nodes:
        if not isinstance(decorator, nodes.Call):
            continue

        try:
            func = next(decorator.func.infer())
        except InferenceError:
            continue
        if func.qname() == SIX_ADD_METACLASS and decorator.args:
            metaclass = decorator.args[0]
            node._metaclass = metaclass
            return node


register_module_extender(MANAGER, 'six', six_moves_transform)
register_module_extender(MANAGER, 'requests.packages.urllib3.packages.six',
                         six_moves_transform)
MANAGER.register_failed_import_hook(_six_fail_hook)
MANAGER.register_transform(nodes.ClassDef, transform_six_add_metaclass)
示例#36
0
def register(_):
    """Register plugins with pylint."""
    MANAGER.register_transform(astroid.FunctionDef,
                               pylint_sqlalchemy.dml_no_argument.strip_dml)
示例#37
0
def transform_model(cls):
    """
    Anything that uses the ModelMeta needs _meta and id.
    Also keep track of relationships and make them in the related model class.
    """
    if cls.name != 'Model':
        appname = 'models'
        for mcls in cls.get_children():
            if isinstance(mcls, ClassDef):
                for attr in mcls.get_children():
                    if isinstance(attr, Assign):
                        if attr.targets[0].name == 'app':
                            appname = attr.value.value

        mname = '{}.{}'.format(appname, cls.name)
        MODELS[mname] = cls

        for relname, relval in FUTURE_RELATIONS.get(mname, []):
            cls.locals[relname] = relval

        for attr in cls.get_children():
            if isinstance(attr, Assign):
                try:
                    attrname = attr.value.func.attrname
                except AttributeError:
                    pass
                else:
                    if attrname in ['ForeignKeyField', 'ManyToManyField']:
                        tomodel = attr.value.args[0].value
                        relname = ''
                        if attr.value.keywords:
                            for keyword in attr.value.keywords:
                                if keyword.arg == 'related_name':
                                    relname = keyword.value.value

                        if relname:
                            # Injected model attributes need to also have the relation manager
                            if attrname == 'ManyToManyField':
                                relval = [
                                    attr.value.func,
                                    MANAGER.ast_from_module_name(
                                        'tortoise.fields').lookup(
                                            'ManyToManyRelationManager')[1][0]
                                ]
                            else:
                                relval = [
                                    attr.value.func,
                                    MANAGER.ast_from_module_name(
                                        'tortoise.fields').lookup(
                                            'RelationQueryContainer')[1][0]
                                ]

                            if tomodel in MODELS:
                                MODELS[tomodel].locals[relname] = relval
                            else:
                                FUTURE_RELATIONS.setdefault(tomodel,
                                                            []).append(
                                                                (relname,
                                                                 relval))

    cls.locals['_meta'] = [
        MANAGER.ast_from_module_name('tortoise.models').lookup('MetaInfo')[1]
        [0].instantiate_class()
    ]
    if 'id' not in cls.locals:
        cls.locals['id'] = [nodes.ClassDef('id', None)]
示例#38
0
def transform_model(cls: ClassDef) -> None:
    """
    Anything that uses the ModelMeta needs _meta and id.
    Also keep track of relationships and make them in the related model class.
    """
    if cls.name != "Model":
        appname = "models"
        for mcls in cls.get_children():
            if isinstance(mcls, ClassDef):
                for attr in mcls.get_children():
                    if isinstance(attr, Assign):
                        if attr.targets[0].name == "app":
                            appname = attr.value.value

        mname = f"{appname}.{cls.name}"
        MODELS[mname] = cls

        for relname, relval in FUTURE_RELATIONS.get(mname, []):
            cls.locals[relname] = relval

        for attr in cls.get_children():
            if isinstance(attr, (Assign, AnnAssign)):
                try:
                    attrname = attr.value.func.attrname
                except AttributeError:
                    pass
                else:
                    if attrname in [
                            "OneToOneField", "ForeignKeyField",
                            "ManyToManyField"
                    ]:
                        tomodel = attr.value.args[0].value
                        relname = ""
                        if attr.value.keywords:
                            for keyword in attr.value.keywords:
                                if keyword.arg == "related_name":
                                    relname = keyword.value.value

                        if not relname:
                            relname = cls.name.lower() + "s"

                        # Injected model attributes need to also have the relation manager
                        if attrname == "ManyToManyField":
                            relval = [
                                # attr.value.func,
                                MANAGER.ast_from_module_name(
                                    "tortoise.fields.relational").lookup(
                                        "ManyToManyFieldInstance")[1][0],
                                MANAGER.ast_from_module_name(
                                    "tortoise.fields.relational").lookup(
                                        "ManyToManyRelation")[1][0],
                            ]
                        elif attrname == "ForeignKeyField":
                            relval = [
                                MANAGER.ast_from_module_name(
                                    "tortoise.fields.relational").lookup(
                                        "ForeignKeyFieldInstance")[1][0],
                                MANAGER.ast_from_module_name(
                                    "tortoise.fields.relational").lookup(
                                        "ReverseRelation")[1][0],
                            ]
                        elif attrname == "OneToOneField":
                            relval = [
                                MANAGER.ast_from_module_name(
                                    "tortoise.fields.relational").lookup(
                                        "OneToOneFieldInstance")[1][0],
                                MANAGER.ast_from_module_name(
                                    "tortoise.fields.relational").lookup(
                                        "OneToOneRelation")[1][0],
                            ]

                        if tomodel in MODELS:
                            MODELS[tomodel].locals[relname] = relval
                        else:
                            FUTURE_RELATIONS.setdefault(tomodel, []).append(
                                (relname, relval))

    cls.locals["_meta"] = [
        MANAGER.ast_from_module_name("tortoise.models").lookup("MetaInfo")[1]
        [0].instantiate_class()
    ]
    if "id" not in cls.locals:
        cls.locals["id"] = [nodes.ClassDef("id", None)]
示例#39
0
 def test_hashlib(self):
     """Tests that brain extensions for hashlib work."""
     hashlib_module = MANAGER.ast_from_module_name('hashlib')
     for class_name in ['md5', 'sha1']:
         class_obj = hashlib_module[class_name]
         self._assert_hashlib_class(class_obj)
def register(linter):
  """Register transform with the linter."""
  MANAGER.register_transform(astroid.ClassDef, mutable_record_transform)
示例#41
0
    if isinstance(func, nodes.Attribute):
        if func.attrname != "require_version":
            return False
        if isinstance(func.expr, nodes.Name) and func.expr.name == "gi":
            return True

        return False

    if isinstance(func, nodes.Name):
        return func.name == "require_version"

    return False


def _register_require_version(node):
    # Load the gi.require_version locally
    try:
        import gi

        gi.require_version(node.args[0].value, node.args[1].value)
    except Exception:
        pass

    return node


MANAGER.register_failed_import_hook(_import_gi_module)
MANAGER.register_transform(
    nodes.Call, _register_require_version, _looks_like_require_version
)
示例#42
0
    if isinstance(func, nodes.Attribute):
        if func.attrname != "require_version":
            return False
        if isinstance(func.expr, nodes.Name) and func.expr.name == "gi":
            return True

        return False

    if isinstance(func, nodes.Name):
        return func.name == "require_version"

    return False


def _register_require_version(node):
    # Load the gi.require_version locally
    try:
        import gi

        gi.require_version(node.args[0].value, node.args[1].value)
    except Exception:
        pass

    return node


MANAGER.register_failed_import_hook(_import_gi_module)
MANAGER.register_transform(
    nodes.Call, _register_require_version, _looks_like_require_version
)
示例#43
0
from astroid import MANAGER
from astroid import scoped_nodes

NAME_DEF_GET_PLUGIN_RESOURCE = 'getPluginResources'
NAME_DEF_GET_PLUGIN_INFO = 'getPluginInfo'


def transform(cls):

    if NAME_DEF_GET_PLUGIN_RESOURCE not in cls.locals \
            or NAME_DEF_GET_PLUGIN_INFO not in cls.locals:
        print '======= Module: ' + cls.name + ' ======='
    if NAME_DEF_GET_PLUGIN_RESOURCE not in cls.locals:
        print 'No required function ' + NAME_DEF_GET_PLUGIN_RESOURCE

    if NAME_DEF_GET_PLUGIN_INFO not in cls.locals:
        print 'No required function ' + NAME_DEF_GET_PLUGIN_INFO


def register(_):
    pass


MANAGER.register_transform(scoped_nodes.Module, transform)
    for decorator_attribute in node.decorators.nodes:
        if decorator_attribute.as_string() in decorator_names:
            return True
    return False


def attr_attributes_transform(node):
    """Given that the ClassNode has an attr decorator,
    rewrite class attributes as instance attributes
    """
    for cdefbodynode in node.body:
        if not isinstance(cdefbodynode, astroid.Assign):
            continue
        if isinstance(cdefbodynode.value, astroid.Call):
            if cdefbodynode.value.func.as_string() != ATTR_IB:
                continue
        for target in cdefbodynode.targets:

            rhs_node = astroid.Unknown(
                lineno=cdefbodynode.lineno,
                col_offset=cdefbodynode.col_offset,
                parent=cdefbodynode
            )
            node.locals[target.name] = [rhs_node]


MANAGER.register_transform(
    astroid.Class,
    attr_attributes_transform,
    is_decorated_with_attrs)
示例#45
0
    return _build_dict_with_elements([])


# Builtins inference
register_builtin_transform(infer_bool, "bool")
register_builtin_transform(infer_super, "super")
register_builtin_transform(infer_callable, "callable")
register_builtin_transform(infer_property, "property")
register_builtin_transform(infer_getattr, "getattr")
register_builtin_transform(infer_hasattr, "hasattr")
register_builtin_transform(infer_tuple, "tuple")
register_builtin_transform(infer_set, "set")
register_builtin_transform(infer_list, "list")
register_builtin_transform(infer_dict, "dict")
register_builtin_transform(infer_frozenset, "frozenset")
register_builtin_transform(infer_type, "type")
register_builtin_transform(infer_slice, "slice")
register_builtin_transform(infer_isinstance, "isinstance")
register_builtin_transform(infer_issubclass, "issubclass")
register_builtin_transform(infer_len, "len")
register_builtin_transform(infer_str, "str")
register_builtin_transform(infer_int, "int")
register_builtin_transform(infer_dict_fromkeys, "dict.fromkeys")

# Infer object.__new__ calls
MANAGER.register_transform(
    nodes.ClassDef,
    inference_tip(_infer_object__new__decorator),
    _infer_object__new__decorator_check,
)
示例#46
0
    module.name = 'six.moves'
    return module

def transform_six_add_metaclass(node):
    """Check if the given class node is decorated with *six.add_metaclass*

    If so, inject its argument as the metaclass of the underlying class.
    """
    if not node.decorators:
        return

    for decorator in node.decorators.nodes:
        if not isinstance(decorator, nodes.Call):
            continue

        try:
            func = next(decorator.func.infer())
        except InferenceError:
            continue
        if func.qname() == SIX_ADD_METACLASS and decorator.args:
            metaclass = decorator.args[0]
            node._metaclass = metaclass
            return node


register_module_extender(MANAGER, 'six', six_moves_transform)
register_module_extender(MANAGER, 'requests.packages.urllib3.packages.six',
                         six_moves_transform)
MANAGER.register_failed_import_hook(_six_fail_hook)
MANAGER.register_transform(nodes.ClassDef, transform_six_add_metaclass)
示例#47
0
                # 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


MANAGER.register_transform(nodes.Call, inference_tip(infer_named_tuple),
                           _looks_like_namedtuple)
MANAGER.register_transform(nodes.Call, inference_tip(infer_enum),
                           _looks_like_enum)
MANAGER.register_transform(nodes.ClassDef, infer_enum_class)
示例#48
0
 def get_ast(self, filepath, modname):
     """return a ast(roid) representation for a module"""
     try:
         return MANAGER.ast_from_file(filepath, modname, source=True)
     except SyntaxError, ex:
         self.add_message('E0001', line=ex.lineno, args=ex.msg)
示例#49
0
 def get_ast(self, filepath, modname):
     """return a ast(roid) representation for a module"""
     try:
         return MANAGER.ast_from_file(filepath, modname, source=True)
     except SyntaxError, ex:
         self.add_message('syntax-error', line=ex.lineno, args=ex.msg)
示例#50
0
# pylint plugin to suppress false positives of type "method x has no y member".
# Based on: https://stackoverflow.com/a/51678586/1014208
from astroid import MANAGER, extract_node, scoped_nodes

FUNCTION_TO_WHITELISTED_PROPS = {
    'logger': ('debug', 'info', 'warning', 'error', 'addHandler', 'handlers',
               'setLevel'),
}


def register(_):
    pass


def transform(f):
    for prop in FUNCTION_TO_WHITELISTED_PROPS.get(f.name, []):
        f.instance_attrs[prop] = extract_node(
            'def {name}(arg): return'.format(name=prop))


MANAGER.register_transform(scoped_nodes.FunctionDef, transform)
示例#51
0

def register(linter):
    pass


def transform(cls):
    if cls.name.endswith('API') or 'schema' in cls.locals:
        # This is a class which defines attributes in "schema" variable using json schema.
        # Those attributes are then assigned during run time inside the constructor
        fqdn = cls.qname()
        module_name, class_name = fqdn.rsplit('.', 1)

        module = __import__(module_name, fromlist=[class_name])
        actual_cls = getattr(module, class_name)

        schema = actual_cls.schema

        if not isinstance(schema, dict):
            # Not a class we are interested in
            return

        properties = schema.get('properties', {}).keys()

        for property_name in properties:
            property_name = property_name.replace('-', '_')  # Note: We do the same in Python code
            cls.locals[property_name] = [scoped_nodes.Class(property_name, None)]


MANAGER.register_transform(scoped_nodes.Class, transform)
示例#52
0
            func = "{}.{}".format(import_from.modname, base.func.name)
    except (AttributeError, KeyError, IndexError):
        return False
    return func == SIX_WITH_METACLASS


def transform_six_with_metaclass(node):
    """Check if the given class node is defined with *six.with_metaclass*

    If so, inject its argument as the metaclass of the underlying class.
    """
    call = node.bases[0]
    node._metaclass = call.args[0]
    node.bases = call.args[1:]


register_module_extender(MANAGER, "six", six_moves_transform)
register_module_extender(MANAGER, "requests.packages.urllib3.packages.six",
                         six_moves_transform)
MANAGER.register_failed_import_hook(_six_fail_hook)
MANAGER.register_transform(
    nodes.ClassDef,
    transform_six_add_metaclass,
    _looks_like_decorated_with_six_add_metaclass,
)
MANAGER.register_transform(
    nodes.ClassDef,
    transform_six_with_metaclass,
    _looks_like_nested_from_six_with_metaclass,
)
示例#53
0
        class_def = nodes.ClassDef(
            name=node.args[0].attrname,
            lineno=0,
            col_offset=0,
            parent=node.parent,
        )
        class_def.postinit(
            bases=[], body=[], decorators=None, metaclass=create_typing_metaclass()
        )
        return class_def

    return None


MANAGER.register_transform(
    nodes.Call,
    inference_tip(infer_typing_typevar_or_newtype),
    looks_like_typing_typevar_or_newtype,
)
MANAGER.register_transform(
    nodes.Subscript, inference_tip(infer_typing_attr), _looks_like_typing_subscript
)

if PY39:
    MANAGER.register_transform(
        nodes.FunctionDef, infer_typedDict, _looks_like_typedDict
    )

if PY37:
    MANAGER.register_transform(nodes.Call, infer_typing_alias, _looks_like_typing_alias)
示例#54
0
            ]
        },
        'replicas',
        'clients',
        'ad_domains',
    ]
}


def fix_ipa_classes(cls):
    class_name_with_module = "{}.{}".format(cls.root().name, cls.name)
    if class_name_with_module in ipa_class_members:
        fake_class(cls, ipa_class_members[class_name_with_module])


MANAGER.register_transform(scoped_nodes.Class, fix_ipa_classes)


def pytest_config_transform():
    """pylint.config attribute
    """
    return AstroidBuilder(MANAGER).string_build(
        textwrap.dedent('''
    from _pytest.config import get_config
    config = get_config()
    '''))


register_module_extender(MANAGER, 'pytest', pytest_config_transform)

示例#55
0
## Usage: 
# export PYTHONPATH=`pwd`:$PYTHONPATH
# pylint --load-plugins ignoretest examples/kulan.py 

from astroid import MANAGER
from astroid import scoped_nodes

def register(linter):
  pass

def transform(modu):
    for m in list(modu):
        try:
            if m.startswith("test_") and modu[m].is_function:
                print("Ignore function: %s" % m)
                modu.body.remove(modu[m])
        except:
            continue

MANAGER.register_transform(scoped_nodes.Module, transform)
示例#56
0

def transform_pyqt_signal(node):
    module = parse('''
    class pyqtSignal(object):
        def connect(self, slot, type=None, no_receiver_check=False):
            pass
        def disconnect(self, slot):
            pass
        def emit(self, *args):
            pass
    ''')
    signal_cls = module['pyqtSignal']
    node._instance_attrs['emit'] = signal_cls['emit']
    node._instance_attrs['disconnect'] = signal_cls['disconnect']
    node._instance_attrs['connect'] = signal_cls['connect']


def pyqt4_qtcore_transform():
    return AstroidBuilder(MANAGER).string_build('''

def SIGNAL(signal_name): pass

class QObject(object):
    def emit(self, signal): pass
''')


register_module_extender(MANAGER, 'PyQt4.QtCore', pyqt4_qtcore_transform)
MANAGER.register_transform(nodes.FunctionDef, transform_pyqt_signal,
                           _looks_like_signal)
示例#57
0
"""
Pylint_ plugin to fix invalid errors about the :mod:`logging` module.

.. _Pylint: https://pypi.python.org/pypi/pylint
"""

from astroid import MANAGER, scoped_nodes, nodes


def register(linter):
    """No-op (required by Pylint)."""


def verboselogs_class_transform(cls):
    """Make Pylint aware of ``RootLogger.verbose()`` and ``RootLogger.spam()``."""
    if cls.name == 'RootLogger':
        for meth in ['verbose', 'spam']:
            cls.locals[meth] = [scoped_nodes.Function(meth, None)]


def verboselogs_module_transform(mod):
    """Make Pylint aware of ``logging.VERBOSE`` and ``logging.SPAM``."""
    if mod.name == 'logging':
        for const in ['VERBOSE', 'SPAM']:
            mod.locals[const] = [nodes.Const(const)]


# Register the above methods with Pylint.
MANAGER.register_transform(scoped_nodes.Class, verboselogs_class_transform)
MANAGER.register_transform(scoped_nodes.Module, verboselogs_module_transform)
示例#58
0
def register(_):
    'Register web2py transformer, called by pylint'
    MANAGER.register_transform(scoped_nodes.Module, web2py_transform)
示例#59
0
def register(linter):
    '''Register the transform function during plugin registration.'''
    MANAGER.register_transform(nodes.Module, transform)
示例#60
0
    if not node.decorators:
        return False
    for decorator in node.decorators.nodes:
        if not isinstance(decorator, astroid.Call):
            continue
        if _looks_like_functools_member(decorator, "lru_cache"):
            return True
    return False


def _looks_like_functools_member(node, member):
    """Check if the given Call node is a functools.partial call"""
    if isinstance(node.func, astroid.Name):
        return node.func.name == member
    elif isinstance(node.func, astroid.Attribute):
        return (node.func.attrname == member
                and isinstance(node.func.expr, astroid.Name)
                and node.func.expr.name == "functools")


_looks_like_partial = partial(_looks_like_functools_member, member="partial")

MANAGER.register_transform(astroid.FunctionDef, _transform_lru_cache,
                           _looks_like_lru_cache)

MANAGER.register_transform(
    astroid.Call,
    astroid.inference_tip(_functools_partial_inference),
    _looks_like_partial,
)