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 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 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)
def register(linter): ''' Register the transformation functions. ''' try: MANAGER.register_transform(nodes.Class, rootlogger_transform) except AttributeError: MANAGER.register_transform(nodes.ClassDef, rootlogger_transform)
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)
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")
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)
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))
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)
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)
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))
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)
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)
names = [] for elt in node.args[1].elts: 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() node = extract_node('namedtuple(%(typename)s, (%(fields)s,)) ' % {'typename': typename, 'fields': ",".join(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, )
from importlib import import_module def register(linter): pass def add_dynamic_attr(cls, klass): parser = klass.create_parser() import argparse for action in parser._actions: if isinstance(action, argparse._HelpAction): continue if isinstance(action, (argparse._StoreTrueAction, argparse._StoreTrueAction)): cls.locals[action.dest] = [bool] elif isinstance(action, argparse._CountAction): cls.locals[action.dest] = [int] elif isinstance(action, (argparse._AppendAction, argparse._AppendConstAction)): cls.locals[action.dest] = [list] else: cls.locals[action.dest] = [action.type] def transform(cls): if cls.name in ['AnsibleTriage', 'DefaultTriager']: mod = import_module(cls.parent.name) add_dynamic_attr(cls, getattr(mod, cls.name)) MANAGER.register_transform(scoped_nodes.ClassDef, transform)
"""Certbot ACME PyLint plugin. http://docs.pylint.org/plugins.html """ from astroid import MANAGER from astroid import nodes def register(unused_linter): """Register this module as PyLint plugin.""" def _transform(cls): # fix the "no-member" error on instances of # letsencrypt.acme.util.ImmutableMap subclasses (instance # attributes are initialized dynamically based on __slots__) # TODO: this is too broad and applies to any tested class... if cls.slots() is not None: for slot in cls.slots(): cls.locals[slot.value] = [nodes.EmptyNode()] if cls.name == 'JSONObjectWithFields': # _fields is magically introduced by JSONObjectWithFieldsMeta cls.locals['_fields'] = [nodes.EmptyNode()] MANAGER.register_transform(nodes.Class, _transform)
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, )
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)
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 bool(cls.is_subtype_of(type_name)) and cls.qname() != type_name def apply_type_shim(cls: ClassDef, _context: Any = 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)
# 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 understanding boto3.ServiceRequest()""" import astroid from astroid import MANAGER, extract_node BOTO_SERVICE_FACTORY_QUALIFIED_NAME = "boto3.resources.base.ServiceResource" def service_request_transform(node): """Transform ServiceResource to look like dynamic classes""" code = """ def __getattr__(self, attr): return 0 """ func_getattr = extract_node(code) node.locals["__getattr__"] = [func_getattr] return node def _looks_like_boto3_service_request(node): return node.qname() == BOTO_SERVICE_FACTORY_QUALIFIED_NAME MANAGER.register_transform( astroid.ClassDef, service_request_transform, _looks_like_boto3_service_request )
if not isinstance(node.args[1], (List, Tuple)): raise UseInferenceDefault names = [] for elt in node.args[1].elts: if not isinstance(elt, (List, Tuple)): raise UseInferenceDefault if len(elt.elts) != 2: raise UseInferenceDefault names.append(elt.elts[0].as_string()) typename = node.args[0].as_string() node = extract_node('namedtuple(%(typename)s, (%(fields)s,)) ' % { 'typename': typename, 'fields': ",".join(names) }) return node.infer(context=context) def looks_like_typing_namedtuple(node): func = node.func if isinstance(func, nodes.Attribute): return func.attrname == 'NamedTuple' if isinstance(func, nodes.Name): return func.name == 'NamedTuple' return False MANAGER.register_transform(nodes.Call, inference_tip(infer_typing_namedtuple), looks_like_typing_namedtuple)
from astroid import nodes from astroid.builder import AstroidBuilder MODULE_TRANSFORMS = {} # 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'' '''
return node.name in TYPING_MEMBERS elif isinstance(node, nodes.Attribute): return node.attrname in TYPING_MEMBERS elif isinstance(node, nodes.Subscript): return _looks_like_typing_subscript(node.value) return False def infer_typing_attr(node, context=None): """Infer a typing.X[...] subscript""" try: value = next(node.value.infer()) except InferenceError as exc: raise UseInferenceDefault from exc if not value.qname().startswith("typing."): raise UseInferenceDefault node = extract_node(TYPING_TYPE_TEMPLATE.format(value.qname().split(".")[-1])) return node.infer(context=context) 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 )
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 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)
def _infer_object__new__decorator(node, context=None): if not node.decorators: raise UseInferenceDefault for decorator in node.decorators.nodes: if isinstance(decorator, nodes.Attribute): if decorator.as_string() == OBJECT_DUNDER_NEW: return iter((node.instantiate_class(),)) raise UseInferenceDefault # Builtins inference register_builtin_transform(infer_bool, 'bool') register_builtin_transform(infer_super, 'super') register_builtin_transform(infer_callable, 'callable') 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') # Infer object.__new__ calls MANAGER.register_transform( nodes.ClassDef, inference_tip(_infer_object__new__decorator) )
def register(linter): ''' Register the transformation functions. ''' MANAGER.register_transform(nodes.Class, rootlogger_transform)
from astroid import MANAGER, nodes, inference_tip, BRAIN_MODULES_DIR sys.path.append(BRAIN_MODULES_DIR) import py2stdlib logger = logging.getLogger(__name__) # pylint: disable=invalid-name def _looks_like_nt_with_defaults(node): func = node.func if type(func) == nodes.Getattr: # pylint: disable=unidiomatic-typecheck return func.attrname == 'namedtuple_with_defaults' elif type(func) == nodes.Name: # pylint: disable=unidiomatic-typecheck return func.name == 'namedtuple_with_defaults' return False def nt_with_defaults_transform(node, *args, **kwargs): node.args = node.args[:2] return py2stdlib.infer_named_tuple(node, *args, **kwargs) def register(_linter): pass MANAGER.register_transform(nodes.CallFunc, inference_tip(nt_with_defaults_transform), _looks_like_nt_with_defaults)
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 )
from astroid import MANAGER from astroid import scoped_nodes from google.appengine.api import memcache from google.appengine.ext import ndb def register(linter): pass def transform(modu): if modu.name == 'google.appengine.ext.ndb': for f in [f for f in ndb.__dict__.keys() if 'Property' in f]: modu.locals[f] = [scoped_nodes.Class(f, None)] if modu.name == 'google.appengine.api.memcache': for f in memcache.__dict__.keys(): modu.locals[f] = [scoped_nodes.Class(f, None)] 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)
def register(linter): '''Register the transform function during plugin registration.''' MANAGER.register_transform(nodes.Module, transform)
pass def disconnect(self, receiver): pass def emit(self, *args): pass """) signal_cls = module["NotPySideSignal"] node.instance_attrs["connect"] = signal_cls["connect"] node.instance_attrs["disconnect"] = signal_cls["disconnect"] node.instance_attrs["emit"] = signal_cls["emit"] 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) MANAGER.register_transform( nodes.ClassDef, transform_pyside_signal, lambda node: node.qname() == "PySide.QtCore.Signal", )
if not isinstance(decorator, astroid.Call): continue func = helpers.safe_infer(decorator.func) if func in (None, astroid.Uninferable): continue if isinstance(func, astroid.FunctionDef) and func.qname() == LRU_CACHE: return True return False def _looks_like_functools_partial(node): """Check if the given Call node is a functools.partial call""" if isinstance(node.func, astroid.Name): return node.func.name == "partial" elif isinstance(node.func, astroid.Attribute): return (node.func.attrname == "partial" and isinstance(node.func.expr, astroid.Name) and node.func.expr.name == "functools") 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_functools_partial, )
"""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, _looks_like_decorated_with_six_add_metaclass, )
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("namedtuple({typename}, {fields})".format( typename=typename, fields=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.Call, inference_tip(infer_typing_namedtuple), _looks_like_typing_namedtuple)
raise astroid.UseInferenceDefault try: elts = random.sample(inferred_sequence.elts, length.value) except ValueError: raise astroid.UseInferenceDefault 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 )
def shutdown(self): pass ''')) 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() ''') 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) register_module_extender(MANAGER, 'hashlib', hashlib_transform) register_module_extender(MANAGER, 'collections', collections_transform) register_module_extender(MANAGER, 'subprocess', subprocess_transform) register_module_extender(MANAGER, 'multiprocessing.managers', multiprocessing_managers_transform) register_module_extender(MANAGER, 'multiprocessing', multiprocessing_transform) register_module_extender(MANAGER, 'threading', thread_transform)
func = node.func 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)
return node.name == "type" return False def infer_type_sub(node, context=None): """ Infer a type[...] subscript :param node: node to infer :type node: astroid.node_classes.NodeNG :param context: inference context :type context: astroid.context.InferenceContext :return: the inferred node :rtype: nodes.NodeNG """ node_scope, _ = node.scope().lookup("type") if node_scope.qname() != "builtins": raise UseInferenceDefault() class_src = """ class type: def __class_getitem__(cls, key): return cls """ node = extract_node(class_src) return node.infer(context=context) if PY39: MANAGER.register_transform(nodes.Name, inference_tip(infer_type_sub), _looks_like_type_subscript)
""" 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)
def register(linter): """Register all transforms with the linter.""" MANAGER.register_transform(astroid.Call, transform_declare) MANAGER.register_transform(astroid.Module, transform_conf_module)
from astroid import MANAGER, node_classes from astroid import scoped_nodes from playero_transforms.execs import exec_transform from playero_transforms.classes import classes_transform from playero_transforms.modules import modules_transform from playero_transforms.functions import function_transform from playero_checkers.query_checker import QueryChecker from playero_checkers.cache_statistics_writer import CacheStatisticWriter from libs.funcs import * cache.collectStats = int(getConfig().get("optionals", "collect_cache_stats")) def register(linter): """required method to auto register this checker""" linter.register_checker(QueryChecker(linter)) linter.register_checker(CacheStatisticWriter(linter, cache)) MANAGER.register_transform(scoped_nodes.Module, modules_transform) MANAGER.register_transform(scoped_nodes.Class, classes_transform) MANAGER.register_transform(node_classes.CallFunc, function_transform) MANAGER.register_transform(node_classes.Exec, exec_transform)
"""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, _looks_like_decorated_with_six_add_metaclass, )
import sys from astroid import MANAGER, scoped_nodes, extract_node from astroid.builder import AstroidBuilder def register(_linter): pass def transform(f): if f.name == 'logger': for prop in ['debug', 'info', 'warning', 'error', 'addHandler']: f.instance_attrs[prop] = extract_node( 'def {name}(arg): return'.format(name=prop)) MANAGER.register_transform(scoped_nodes.FunctionDef, transform)
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)
from astroid import MANAGER, arguments, nodes, inference_tip, UseInferenceDefault def infer_namespace(node, context=None): callsite = arguments.CallSite.from_call(node, context=context) if not callsite.keyword_arguments: # Cannot make sense of it. raise UseInferenceDefault() class_node = nodes.ClassDef("Namespace", "docstring") class_node.parent = node.parent for attr in set(callsite.keyword_arguments): fake_node = nodes.EmptyNode() fake_node.parent = class_node fake_node.attrname = attr class_node.instance_attrs[attr] = [fake_node] return iter((class_node.instantiate_class(), )) def _looks_like_namespace(node): func = node.func if isinstance(func, nodes.Attribute): return (func.attrname == "Namespace" and isinstance(func.expr, nodes.Name) and func.expr.name == "argparse") return False MANAGER.register_transform(nodes.Call, inference_tip(infer_namespace), _looks_like_namespace)
## 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)
def erp5_package_transform(node): """' erp5/' directory on the filesystem is different from 'erp5' module when running ERP5, so replace entirely this node completely to avoid pylint checking erp5/ directory structure for module and returns errors... """ # Cannot call string_build() as this would be called again and again erp5_package_node = nodes.Module('erp5', None) erp5_package_node.package = True erp5_package_node._absolute_import_activated = True return erp5_package_node MANAGER.register_transform(nodes.Module, erp5_package_transform, lambda n: n.name == 'erp5') 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
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)
def import_skeletons_module(): for dirpath, dirnames, filenames in os.walk(SKELETONS_DIR): for filename in filenames: if filename.endswith(".py"): if not dirpath.startswith(SKELETONS_DIR): raise Exception("Expected root to start with python skeletons directory") # TODO: make this better path = dirpath[len(SKELETONS_DIR) + 1:].replace("/", ".") if filename.endswith("__init__.py"): module_name = path else: module_name = path + "." + filename[:-len(".py")] if module_name.startswith("."): module_name = module_name[1:] if module_name != "": MODULES_TO_PATH[module_name] = os.path.join(dirpath, filename) TRANSFORMS[module_name] = import_a_module(module_name) import_skeletons_module() def transform(module): try: tr = TRANSFORMS[module.name] except KeyError: pass else: tr(module) MANAGER.register_transform(nodes.Module, transform)
return node.attrname in TYPING_MEMBERS elif isinstance(node, nodes.Subscript): return _looks_like_typing_subscript(node.value) return False def infer_typing_attr(node, context=None): """Infer a typing.X[...] subscript""" try: value = next(node.value.infer()) except InferenceError as exc: raise UseInferenceDefault from exc if not value.qname().startswith('typing.'): raise UseInferenceDefault node = extract_node(TYPING_TYPE_TEMPLATE.format(value.qname().split('.')[-1])) return node.infer(context=context) 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, )
def register(linter): """Register transform with the linter.""" MANAGER.register_transform(astroid.ClassDef, mutable_record_transform)
'ad_subdomains': dir(list) }, { 'ad_treedomains': dir(list) }, ] } 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.ClassDef, fix_ipa_classes) def ipaplatform_constants_transform(): return AstroidBuilder(MANAGER).string_build( textwrap.dedent(''' from ipaplatform.base.constants import constants, User, Group __all__ = ('constants', 'User', 'Group') ''')) def ipaplatform_paths_transform(): return AstroidBuilder(MANAGER).string_build( textwrap.dedent(''' from ipaplatform.base.paths import paths __all__ = ('paths',)
# SPDX-License-Identifier: BSD-3-Clause from astroid import MANAGER, ClassDef, Name, Subscript def transform(cls): """Pretend that any class inheriting from 'Dict' also inherits from 'dict'. Works around PyLint not knowing about operations on the 'Dict' class. https://github.com/PyCQA/pylint/issues/3129 """ for index, base in enumerate(cls.bases): if isinstance(base, Subscript): if isinstance(base.value, Name): if base.value.name == 'Dict': cls.bases.append(Name('dict', parent=cls)) def register(linter): pass MANAGER.register_transform(ClassDef, transform)