def test_signature_insert_varargs_and_kwargs(self): # def f(x, *args, y, **kwargs): ... sig = function.Signature( name="f", param_names=("x", ), varargs_name="args", kwonly_params={"y"}, kwargs_name="kwargs", defaults={}, annotations={}, late_annotations={}, ) # f(1, 2, y=3, z=4) int_inst = self._vm.convert.primitive_class_instances[int] int_binding = int_inst.to_variable(self._node).bindings[0] arg_dict = { "x": int_binding, "_1": int_binding, "y": int_binding, "z": int_binding } sig = sig.insert_varargs_and_kwargs(arg_dict) self.assertEqual(sig.name, "f") self.assertSequenceEqual(sig.param_names, ("x", "_1", "z")) self.assertEqual(sig.varargs_name, "args") self.assertSetEqual(sig.kwonly_params, {"y"}) self.assertEqual(sig.kwargs_name, "kwargs") self.assertFalse(sig.annotations) self.assertFalse(sig.late_annotations)
class Property(abstract.PyTDClass): """Property method decorator.""" _KEYS = ["fget", "fset", "fdel", "doc"] # Minimal signature, only used for constructing exceptions. _SIGNATURE = function.Signature("property", tuple(_KEYS), None, set(), None, {}, {}, {}) def __init__(self, vm): super(Property, self).__init__("property", vm.lookup_builtin("__builtin__.property"), vm) self.module = "__builtin__" def _get_args(self, args): ret = dict(zip(self._KEYS, args.posargs)) for k, v in args.namedargs.iteritems(): if k not in self._KEYS: raise abstract.WrongKeywordArgs(self._SIGNATURE, args, self.vm, [k]) ret[k] = v return ret def call(self, node, funcv, args): property_args = self._get_args(args) cls = self.to_variable(node) return node, PropertyInstance(self.vm, cls, **property_args).to_variable(node)
def test_signature_del_nonexistent_annotation(self): # def f(): ... sig = function.Signature( name="f", param_names=(), varargs_name=None, kwonly_params=(), kwargs_name=None, defaults={}, annotations={}, ) self.assertRaises(KeyError, sig.del_annotation, "rumpelstiltskin")
def test_signature_kwonly_param_count(self): # def f(*, y=None): ... sig = function.Signature( name="f", param_names=(), varargs_name=None, kwonly_params=("y",), kwargs_name=None, defaults={"y": self._vm.convert.none_type.to_variable(self._node)}, annotations={}, ) self.assertEqual(repr(sig), "def f(*, y = None) -> Any") self.assertEqual(sig.mandatory_param_count(), 0) self.assertEqual(sig.maximum_param_count(), 1)
def test_signature_kwargs_param_count(self): # def f(**kwargs): ... sig = function.Signature( name="f", param_names=(), varargs_name=None, kwonly_params=(), kwargs_name="kwargs", defaults={}, annotations={}, ) self.assertEqual(repr(sig), "def f(**kwargs) -> Any") self.assertEqual(sig.mandatory_param_count(), 0) self.assertIsNone(sig.maximum_param_count())
def test_signature_posarg_only_param_count(self): # def f(x): ... sig = function.Signature( name="f", param_names=("x",), varargs_name=None, kwonly_params=(), kwargs_name=None, defaults={}, annotations={}, ) self.assertEqual(repr(sig), "def f(x) -> Any") self.assertEqual(sig.mandatory_param_count(), 1) self.assertEqual(sig.maximum_param_count(), 1)
def test_signature_has_param(self): # def f(x, *args, y, **kwargs): ... sig = function.Signature( name="f", param_names=("x",), varargs_name="args", kwonly_params={"y"}, kwargs_name="kwargs", defaults={}, annotations={}, ) self.assertEqual(repr(sig), "def f(x, *args, y, **kwargs) -> Any") for param in ("x", "args", "y", "kwargs"): self.assertTrue(sig.has_param(param)) self.assertFalse(sig.has_param("rumpelstiltskin"))
def test_signature_del_return_annotation(self): # def f(x) -> int: ... sig = function.Signature( name="f", param_names=("x",), varargs_name=None, kwonly_params=(), kwargs_name=None, defaults={}, annotations={"x": self._vm.convert.unsolvable, "return": self._vm.convert.unsolvable}, ) sig.del_annotation("return") six.assertCountEqual(self, sig.annotations.keys(), {"x"}) self.assertTrue(sig.has_param_annotations) self.assertFalse(sig.has_return_annotation)
class ClassMethod(abstract.PyTDClass): """Static method decorator.""" # Minimal signature, only used for constructing exceptions. _SIGNATURE = function.Signature("classmethod", ("func", ), None, set(), None, {}, {}, {}) def __init__(self, vm): super(ClassMethod, self).__init__("classmethod", vm.lookup_builtin("__builtin__.classmethod"), vm) self.module = "__builtin__" def call(self, node, funcv, args): if len(args.posargs) != 1: raise abstract.WrongArgCount(self._SIGNATURE, args, self.vm) arg = args.posargs[0] cls = self.to_variable(node) return node, ClassMethodInstance(self.vm, cls, arg).to_variable(node)
def test_signature_annotations_existence(self): # def f(v: "X") -> "Y" sig = function.Signature( name="f", param_names=("v",), varargs_name=None, kwonly_params=(), kwargs_name=None, defaults={}, annotations={}, ) self.assertFalse(sig.has_param_annotations) self.assertFalse(sig.has_return_annotation) sig.set_annotation("v", self._vm.convert.unsolvable) self.assertTrue(sig.has_param_annotations) self.assertFalse(sig.has_return_annotation) sig.set_annotation("return", self._vm.convert.unsolvable) self.assertTrue(sig.has_param_annotations) self.assertTrue(sig.has_return_annotation)
class Super(abstract.PyTDClass): """The super() function. Calling it will create a SuperInstance.""" # Minimal signature, only used for constructing exceptions. _SIGNATURE = function.Signature("super", ("cls", "self"), None, set(), None, {}, {}, {}) def __init__(self, vm): super(Super, self).__init__("super", vm.lookup_builtin("__builtin__.super"), vm) self.module = "__builtin__" 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 test_signature_annotations_existence(self): # def f(v: "X") -> "Y" sig = function.Signature( name="f", param_names=("v", ), varargs_name=None, kwonly_params=(), kwargs_name=None, defaults={}, annotations={}, late_annotations={ "v": annotations_util.LateAnnotation("X", "v", None), "return": annotations_util.LateAnnotation("Y", "return", None) }) self.assertEqual(repr(sig), "def f(v: 'X') -> 'Y'") self.assertFalse(sig.has_param_annotations) self.assertFalse(sig.has_return_annotation) sig.set_annotation("v", self._vm.convert.unsolvable) self.assertTrue(sig.has_param_annotations) self.assertFalse(sig.has_return_annotation) sig.set_annotation("return", self._vm.convert.unsolvable) self.assertTrue(sig.has_param_annotations) self.assertTrue(sig.has_return_annotation)