def apply_type_shim(cls, _context=None): """ Morphs model fields to representative type """ if cls.name in ['IntField', 'SmallIntField']: base_nodes = scoped_nodes.builtin_lookup('int') elif cls.name in ['CharField', 'TextField']: base_nodes = scoped_nodes.builtin_lookup('str') elif cls.name == 'BooleanField': base_nodes = scoped_nodes.builtin_lookup('bool') elif cls.name == 'FloatField': base_nodes = scoped_nodes.builtin_lookup('float') elif cls.name == 'DecimalField': base_nodes = MANAGER.ast_from_module_name('decimal').lookup('Decimal') elif cls.name == 'DatetimeField': base_nodes = MANAGER.ast_from_module_name('datetime').lookup( 'datetime') elif cls.name == 'DateField': base_nodes = MANAGER.ast_from_module_name('datetime').lookup('date') elif cls.name == 'ForeignKeyField': base_nodes = MANAGER.ast_from_module_name('tortoise.fields').lookup( 'BackwardFKRelation') elif cls.name == 'ManyToManyField': base_nodes = MANAGER.ast_from_module_name('tortoise.fields').lookup( 'ManyToManyRelationManager') else: return iter([cls]) return iter([cls] + base_nodes[1])
def transform_conanfile(node): """Transform definition of ConanFile class so dynamic fields are visible to pylint""" str_class = astroid.builtin_lookup("str") info_class = MANAGER.ast_from_module_name("conans.model.info").lookup( "ConanInfo") build_requires_class = MANAGER.ast_from_module_name( "conans.client.graph.graph_manager").lookup("_RecipeBuildRequires") file_copier_class = MANAGER.ast_from_module_name( "conans.client.file_copier").lookup("FileCopier") file_importer_class = MANAGER.ast_from_module_name( "conans.client.importer").lookup("_FileImporter") dynamic_fields = { "source_folder": str_class, "build_folder": str_class, "package_folder": str_class, "install_folder": str_class, "build_requires": build_requires_class, "info_build": info_class, "info": info_class, "copy": file_copier_class, "copy_deps": file_importer_class, } for f, t in dynamic_fields.items(): node.locals[f] = [t]
def transform(cls): if 'NodeDriver' in cls.basenames: fqdn = cls.qname() module_name, _ = fqdn.rsplit('.', 1) # Assign connection class variable on it which is otherwise assigned # dynamically at the run time if 'connectionCls' not in cls.locals: # connectionCls not explicitly defined on the driver class return connection_cls_name = cls.locals['connectionCls'][0].parent.value.name connection_cls_node = MANAGER.ast_from_module_name(module_name).lookup( connection_cls_name)[1] if len(connection_cls_node) >= 1: if isinstance(connection_cls_node[0], node_classes.ImportFrom): # Connection class is imported and not directly defined in the driver class module connection_cls_module_name = connection_cls_node[0].modname connection_cls_node = MANAGER.ast_from_module_name( connection_cls_module_name).lookup( connection_cls_name)[1][0] cls.instance_attrs['connection'] = [ connection_cls_node.instantiate_class() ] else: # Connection class is defined directly in the driver module cls.instance_attrs['connection'] = [ connection_cls_node[0].instantiate_class() ] return
def apply_type_shim(cls, _context=None) -> Iterator: """ Morphs model fields to representative type """ if cls.name in ["IntField", "SmallIntField"]: base_nodes = scoped_nodes.builtin_lookup("int") elif cls.name in ["CharField", "TextField"]: base_nodes = scoped_nodes.builtin_lookup("str") elif cls.name == "BooleanField": base_nodes = scoped_nodes.builtin_lookup("bool") elif cls.name == "FloatField": base_nodes = scoped_nodes.builtin_lookup("float") elif cls.name == "DecimalField": base_nodes = MANAGER.ast_from_module_name("decimal").lookup("Decimal") elif cls.name == "DatetimeField": base_nodes = MANAGER.ast_from_module_name("datetime").lookup("datetime") elif cls.name == "DateField": base_nodes = MANAGER.ast_from_module_name("datetime").lookup("date") elif cls.name == "ForeignKeyField": base_nodes = MANAGER.ast_from_module_name("tortoise.fields").lookup("BackwardFKRelation") elif cls.name == "ManyToManyField": base_nodes = MANAGER.ast_from_module_name("tortoise.fields").lookup( "ManyToManyRelationManager" ) else: return iter([cls]) return iter([cls] + base_nodes[1])
def transform_model(cls) -> 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 = '{}.{}'.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)]
def apply_type_shim(cls, context=None): # noqa 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 == 'DurationField': base_nodes = MANAGER.ast_from_module_name('datetime').lookup( 'timedelta') elif cls.name == 'UUIDField': base_nodes = MANAGER.ast_from_module_name('uuid').lookup('UUID') 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') elif cls.name == 'ArrayField': base_nodes = scoped_nodes.builtin_lookup('list') elif cls.name in ('HStoreField', 'JSONField'): base_nodes = scoped_nodes.builtin_lookup('dict') elif cls.name in _RANGE_FIELDS: base_nodes = MANAGER.ast_from_module_name('psycopg2._range').lookup( 'Range') 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)
def _six_fail_hook(modname): """Fix six.moves imports due to the dynamic nature of this class. Construct a pseudo-module which contains all the necessary imports for six :param modname: Name of failed module :type modname: str :return: An astroid module :rtype: nodes.Module """ attribute_of = (modname != "six.moves" and modname.startswith("six.moves")) if modname != 'six.moves' and not attribute_of: raise AstroidBuildingError(modname=modname) module = AstroidBuilder(MANAGER).string_build(_IMPORTS) module.name = 'six.moves' if attribute_of: # Facilitate import of submodules in Moves start_index = len(module.name) attribute = modname[start_index:].lstrip(".").replace(".", "_") try: import_attr = module.getattr(attribute)[0] except AttributeInferenceError: raise AstroidBuildingError(modname=modname) if isinstance(import_attr, nodes.Import): submodule = MANAGER.ast_from_module_name(import_attr.names[0][0]) return submodule # Let dummy submodule imports pass through # This will cause an Uninferable result, which is okay return module
def _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 as exc: raise AstroidBuildingError(modname=modname) from exc if isinstance(import_attr, nodes.Import): submodule = MANAGER.ast_from_module_name(import_attr.names[0][0]) return submodule # Let dummy submodule imports pass through # This will cause an Uninferable result, which is okay return module
def test_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 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) for class_name in ['blake2b', 'blake2s']: class_obj = hashlib_module[class_name] self.assertEqual(len(class_obj['__init__'].args.args), 3)
def get_manager(current_name = None): from astroid import MANAGER if not current_name: return MANAGER.astroid_cache #return MANAGER.ast_from_module_name(current_name) ast = MANAGER.astroid_cache.get(current_name, None) if not ast: ast = MANAGER.ast_from_module_name(current_name) return ast
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)]
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)]
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])
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)
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')
def test_pylint_config_attr(self): try: from pylint import lint # pylint: disable=unused-variable 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'))) inferred = list(Instance(pylinter).igetattr('config')) self.assertEqual(len(inferred), 1) self.assertEqual(inferred[0].root().name, 'optparse') self.assertEqual(inferred[0].name, 'Values')
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")
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)
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 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: try: MANAGER.ast_from_module_name(module_name) except AstroidImportError: pass # 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()])
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) and 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)]
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)
def infer_key_classes(node, context=None): from django.core.exceptions import ImproperlyConfigured # pylint: disable=import-outside-toplevel 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') try: module_name = _module_name_from_django_model_resolution(model_name, module_name) except LookupError: # If Django's model resolution fails we try to convert that to # 'auth.models', 'User' which works nicely with the `endswith()` # comparison below module_name += '.models' except ImproperlyConfigured as exep: raise RuntimeError("DJANGO_SETTINGS_MODULE required for resolving ForeignKey " "string references, see Usage section in README at " "https://pypi.org/project/pylint-django/!") from exep # 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()])