From f26d5df15f50f7431f629bd466b501ea0c81acef Mon Sep 17 00:00:00 2001 From: Nick Craig-Wood Date: Sat, 16 Feb 2019 13:12:30 +0000 Subject: [PATCH] Fix initialisation of function, staticmethod and classmethod __dict__ Add test files for function, staticmethod and classmethod Fixes #56 --- py/classmethod.go | 4 +- py/function.go | 5 +- py/staticmethod.go | 4 +- py/tests/classmethod.py | 19 ++++++ py/tests/function.py | 130 +++++++++++++++++++++++++++++++++++++++ py/tests/staticmethod.py | 18 ++++++ 6 files changed, 174 insertions(+), 6 deletions(-) create mode 100644 py/tests/classmethod.py create mode 100644 py/tests/function.py create mode 100644 py/tests/staticmethod.py diff --git a/py/classmethod.go b/py/classmethod.go index 731184e4..8b6fbf8b 100644 --- a/py/classmethod.go +++ b/py/classmethod.go @@ -44,7 +44,9 @@ func (c *ClassMethod) GetDict() StringDict { // ClassMethodNew func ClassMethodNew(metatype *Type, args Tuple, kwargs StringDict) (res Object, err error) { - c := &ClassMethod{} + c := &ClassMethod{ + Dict: make(StringDict), + } err = UnpackTuple(args, kwargs, "classmethod", 1, 1, &c.Callable) if err != nil { return nil, err diff --git a/py/function.go b/py/function.go index 673c93d4..28eace5d 100644 --- a/py/function.go +++ b/py/function.go @@ -84,6 +84,7 @@ func NewFunction(code *Code, globals StringDict, qualname string) *Function { Name: code.Name, Doc: doc, Module: module, + Dict: make(StringDict), } } @@ -193,10 +194,6 @@ func init() { f.Dict = dict return nil }, - Fdel: func(self Object) error { - self.(*Function).Dict = nil - return nil - }, } FunctionType.Dict["__name__"] = &Property{ Fget: func(self Object) (Object, error) { diff --git a/py/staticmethod.go b/py/staticmethod.go index 939c8cff..0ca07438 100644 --- a/py/staticmethod.go +++ b/py/staticmethod.go @@ -41,7 +41,9 @@ func (c *StaticMethod) GetDict() StringDict { // StaticMethodNew func StaticMethodNew(metatype *Type, args Tuple, kwargs StringDict) (res Object, err error) { - c := &StaticMethod{} + c := &StaticMethod{ + Dict: make(StringDict), + } err = UnpackTuple(args, kwargs, "staticmethod", 1, 1, &c.Callable) if err != nil { return nil, err diff --git a/py/tests/classmethod.py b/py/tests/classmethod.py new file mode 100644 index 00000000..db4a5ca6 --- /dev/null +++ b/py/tests/classmethod.py @@ -0,0 +1,19 @@ +# Copyright 2019 The go-python Authors. All rights reserved. +# Use of this source code is governed by a BSD-style +# license that can be found in the LICENSE file. + +doc="classmethod" + +class A: + @classmethod + def fn(cls, p): + assert cls is A + return p+1 + +a = A() +assert a.fn(1) == 2 + +a.x = 3 +assert a.x == 3 + +doc="finished" diff --git a/py/tests/function.py b/py/tests/function.py new file mode 100644 index 00000000..ba05142d --- /dev/null +++ b/py/tests/function.py @@ -0,0 +1,130 @@ +# Copyright 2019 The go-python Authors. All rights reserved. +# Use of this source code is governed by a BSD-style +# license that can be found in the LICENSE file. + +doc="function" + +def fn(p): + "docstring" + return p+1 + +assert fn(1) == 2 + +# FIXME this doesn't work yet +#assert fn.__doc__ == "docstring" +#fn.__doc__ = "hello" +#assert fn.__doc__ == "hello" + +assert str(type(fn)) == "" + +fn.x = 3 +assert fn.x == 3 + +def f2(p): + return p+2 + +doc="check __code__" +fn.__code__ = f2.__code__ +assert fn(1) == 3 +try: + fn.__code__ = "bad" +except TypeError: + pass +else: + assert False, "TypeError not raised" + +doc="check __defaults__" +def f3(p=2): + return p +assert f3.__defaults__ == (2,) +assert f3() == 2 +f3.__defaults__ = (10,) +assert f3() == 10 +assert f3.__defaults__ == (10,) +try: + f3.__defaults__ = "bad" +except TypeError: + pass +else: + assert False, "TypeError not raised" +del f3.__defaults__ +assert f3.__defaults__ == None or f3.__defaults__ == () + +doc="check __kwdefaults__" +def f4(*, b=2): + return b +assert f4.__kwdefaults__ == {"b":2} +assert f4() == 2 +f4.__kwdefaults__ = {"b":10} +assert f4() == 10 +assert f4.__kwdefaults__ == {"b":10} +try: + f4.__kwdefaults__ = "bad" +except TypeError: + pass +else: + assert False, "TypeError not raised" +del f4.__kwdefaults__ +assert f4.__kwdefaults__ == None or f4.__kwdefaults__ == {} + +doc="check __annotations__" +def f5(a: "potato") -> "sausage": + pass +assert f5.__annotations__ == {'a': 'potato', 'return': 'sausage'} +f5.__annotations__ = {'a': 'potato', 'return': 'SAUSAGE'} +assert f5.__annotations__ == {'a': 'potato', 'return': 'SAUSAGE'} +try: + f5.__annotations__ = "bad" +except TypeError: + pass +else: + assert False, "TypeError not raised" +del f5.__annotations__ +assert f5.__annotations__ == None or f5.__annotations__ == {} + +doc="check __dict__" +def f6(): + pass +assert f6.__dict__ == {} +f6.__dict__ = {'a': 'potato'} +assert f6.__dict__ == {'a': 'potato'} +try: + f6.__dict__ = "bad" +except TypeError: + pass +else: + assert False, "TypeError not raised" +try: + del f6.__dict__ +except (TypeError, AttributeError): + pass +else: + assert False, "Error not raised" + +doc="check __name__" +def f7(): + pass +assert f7.__name__ == "f7" +f7.__name__ = "new_name" +assert f7.__name__ == "new_name" +try: + f7.__name__ = 1 +except TypeError: + pass +else: + assert False, "TypeError not raised" + +doc="check __qualname__" +def f8(): + pass +assert f8.__qualname__ == "f8" +f8.__qualname__ = "new_qualname" +assert f8.__qualname__ == "new_qualname" +try: + f8.__qualname__ = 1 +except TypeError: + pass +else: + assert False, "TypeError not raised" + +doc="finished" diff --git a/py/tests/staticmethod.py b/py/tests/staticmethod.py new file mode 100644 index 00000000..f93aa757 --- /dev/null +++ b/py/tests/staticmethod.py @@ -0,0 +1,18 @@ +# Copyright 2019 The go-python Authors. All rights reserved. +# Use of this source code is governed by a BSD-style +# license that can be found in the LICENSE file. + +doc="staticmethod" + +class A: + @staticmethod + def fn(p): + return p+1 + +a = A() +assert a.fn(1) == 2 + +a.x = 3 +assert a.x == 3 + +doc="finished" pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy