# -*- coding: utf-8 -*- # Copyright (c) 2013-2014 LOGILAB S.A. (Paris, FRANCE) # Copyright (c) 2014 Google, Inc. # Copyright (c) 2014 Cole Robinson # Copyright (c) 2015-2016, 2018 Claudiu Popa # Copyright (c) 2015-2016 Ceridwen # Copyright (c) 2015 David Shea # Copyright (c) 2016 Jakub Wilk # Copyright (c) 2016 Giuseppe Scrivano # Copyright (c) 2018 Christoph Reiter # Copyright (c) 2019 Philipp Hörist # 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 Python 2 GObject introspection bindings. Helps with understanding everything imported from 'gi.repository' """ import inspect import itertools import sys import re import warnings from astroid import MANAGER, AstroidBuildingError, nodes from astroid.builder import AstroidBuilder _inspected_modules = {} _identifier_re = r"^[A-Za-z_]\w*$" _special_methods = frozenset( { "__lt__", "__le__", "__eq__", "__ne__", "__ge__", "__gt__", "__iter__", "__getitem__", "__setitem__", "__delitem__", "__len__", "__bool__", "__nonzero__", "__next__", "__str__", "__len__", "__contains__", "__enter__", "__exit__", "__repr__", "__getattr__", "__setattr__", "__delattr__", "__del__", "__hash__", } ) def _gi_build_stub(parent): """ Inspect the passed module recursively and build stubs for functions, classes, etc. """ classes = {} functions = {} constants = {} methods = {} for name in dir(parent): if name.startswith("__") and name not in _special_methods: continue # Check if this is a valid name in python if not re.match(_identifier_re, name): continue try: obj = getattr(parent, name) except: continue if inspect.isclass(obj): classes[name] = obj elif inspect.isfunction(obj) or inspect.isbuiltin(obj): functions[name] = obj elif inspect.ismethod(obj) or inspect.ismethoddescriptor(obj): methods[name] = obj elif ( str(obj).startswith(", ) # Only accept function calls with two constant arguments if len(node.args) != 2: return False if not all(isinstance(arg, nodes.Const) for arg in node.args): return False 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 )