def _getargs(self, node, args): self.match_args(node, args) sig, = self.signatures callargs = { name: var for name, var, _ in sig.signature.iter_args(args) } # typing.NamedTuple doesn't support rename or verbose name_var = callargs["typename"] fields_var = callargs["fields"] fields = abstract.get_atomic_python_constant(fields_var) # The fields is a list of tuples, so we need to deeply unwrap them. fields = [abstract.get_atomic_python_constant(t) for t in fields] # We need the actual string for the field names and the AtomicAbstractValue # for the field types. names = [] types = [] for field in fields: if (len(field) != 2 or any(not self._is_str_instance(v) for v in field[0].data)): # Note that we don't need to check field[1] because both 'str' # (forward reference) and 'type' are valid for it. sig, = self.signatures bad_param = abstract.BadParam(name="fields", expected=self._fields_type) raise abstract.WrongArgTypes(sig.signature, args, self.vm, bad_param) name, typ = field names.append(abstract.get_atomic_python_constant(name)) types.append(abstract.get_atomic_value(typ)) return name_var, names, types
def _getargs(self, node, args): self._match_args(node, args) # Normally we would use typing.NamedTuple.__new__ to match args to # parameters, but we can't import typing. # TODO(tsudol): Replace with typing.NamedTuple.__new__. f = function.Signature.from_param_names("typing.NamedTuple", ["typename", "fields"]) callargs = { arg_name: arg_var for arg_name, arg_var, _ in f.iter_args(args) } # typing.NamedTuple doesn't support rename or verbose name_var = callargs["typename"] fields_var = callargs["fields"] fields = abstract.get_atomic_python_constant(fields_var) # The fields is a list of tuples, so we need to deeply unwrap them. fields = [abstract.get_atomic_python_constant(t) for t in fields] # We need the actual string for the field names and the AtomicAbstractValue # for the field types. names = [] types = [] for field in fields: if (len(field) != 2 or any(not self._is_str_instance(v) for v in field[0].data)): # Note that we don't need to check field[1] because both 'str' # (forward reference) and 'type' are valid for it. sig, = self.signatures bad_param = abstract.BadParam(name="fields", expected=self._fields_type) raise abstract.WrongArgTypes(sig.signature, args, self.vm, bad_param) name, typ = field names.append(abstract.get_atomic_python_constant(name)) types.append(abstract.get_atomic_value(typ)) return name_var, names, types
def call(self, node, _, args): result = self.vm.program.NewVariable() num_args = len(args.posargs) if 1 <= num_args and num_args <= 2: super_objects = args.posargs[1].bindings if num_args == 2 else [ None ] for cls in args.posargs[0].bindings: if not isinstance( cls.data, (abstract.Class, abstract.AMBIGUOUS_OR_EMPTY)): bad = abstract.BadParam(name="cls", expected=self.vm.convert.type_type) raise abstract.WrongArgTypes(self._SIGNATURE, args, self.vm, bad_param=bad) for obj in super_objects: if obj: result.AddBinding( SuperInstance(cls.data, obj.data, self.vm), [cls, obj], node) else: result.AddBinding( SuperInstance(cls.data, None, self.vm), [cls], node) else: raise abstract.WrongArgCount(self._SIGNATURE, args, self.vm) return node, result
def call(self, node, _, args): result = self.vm.program.NewVariable() num_args = len(args.posargs) if num_args == 0 and self.vm.PY3: # The implicit type argument is available in a freevar named '__class__'. cls_var = None for i, free_var in enumerate(self.vm.frame.f_code.co_freevars): if free_var == abstract.BuildClass.CLOSURE_NAME: cls_var = self.vm.frame.cells[ len(self.vm.frame.f_code.co_cellvars) + i] break if not (cls_var and cls_var.bindings): self.vm.errorlog.invalid_super_call( self.vm.frames, message="Missing __class__ closure for super call.", details= "Is 'super' being called from a method defined in a class?" ) return node, self.vm.convert.create_new_unsolvable(node) # The implicit super object argument is the first positional argument to # the function calling 'super'. self_arg = self.vm.frame.first_posarg if not self_arg: self.vm.errorlog.invalid_super_call( self.vm.frames, message="Missing 'self' argument to 'super' call.") return node, self.vm.convert.create_new_unsolvable(node) super_objects = self_arg.bindings elif 1 <= num_args and num_args <= 2: cls_var = args.posargs[0] super_objects = args.posargs[1].bindings if num_args == 2 else [ None ] else: raise abstract.WrongArgCount(self._SIGNATURE, args, self.vm) for cls in cls_var.bindings: if not isinstance(cls.data, (abstract.Class, abstract.AMBIGUOUS_OR_EMPTY)): bad = abstract.BadParam(name="cls", expected=self.vm.convert.type_type) raise abstract.WrongArgTypes(self._SIGNATURE, args, self.vm, bad_param=bad) for obj in super_objects: if obj: result.AddBinding( SuperInstance(cls.data, obj.data, self.vm), [cls, obj], node) else: result.AddBinding(SuperInstance(cls.data, None, self.vm), [cls], node) return node, result