Skip to content

Commit 6c022ed

Browse files
typed: @typed deco + base.new TypeError message update
1 parent 2e61e28 commit 6c022ed

2 files changed

Lines changed: 30 additions & 3 deletions

File tree

modeled/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,8 @@
8282
from .property import *
8383
mproperty = property
8484

85+
from .typed import typed
86+
8587
from .cfunc import *
8688
mcfunc = cfunc
8789
mcarg = cfunc.arg

modeled/typed.py

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,10 @@
2323

2424
__all__ = ['base']
2525

26-
from moretools import cached
26+
from inspect import getfullargspec, isclass
27+
28+
from decorator import decorator
29+
from moretools import cached, qualname
2730

2831
from .base import base
2932

@@ -77,5 +80,27 @@ def new(self, value, func):
7780
return value
7881
raise TypeError(
7982
"%s.new.func() must return an instance of '%s', not '%s'"
80-
% (type(self).__name__, self.mtype.__name__,
81-
type(value).__name__))
83+
% (qualname(type(self)), qualname(self.mtype),
84+
qualname(type(value))))
85+
86+
87+
def typed(func):
88+
spec = getfullargspec(func)
89+
90+
def typed(func, *args, **kwargs):
91+
iargs = iter(args)
92+
args = []
93+
for name, value in zip(spec.args, iargs):
94+
mtype = wrapper.mtypes.get(name)
95+
if isclass(mtype) and not isinstance(value, mtype):
96+
value = mtype(value)
97+
args.append(value)
98+
result = func(*args, **kwargs)
99+
mtype = wrapper.mtypes.get('return')
100+
if isclass(mtype) and not isinstance(result, mtype):
101+
result = mtype(result)
102+
return result
103+
104+
wrapper = decorator(typed, func)
105+
wrapper.mtypes = spec.annotations
106+
return wrapper

0 commit comments

Comments
 (0)