struct: replace sys.getrefcount with a cleaner method

This commit is contained in:
Shiz 2021-06-24 12:45:48 +02:00
parent 3055156ef5
commit 727e89e051
1 changed files with 17 additions and 5 deletions

View File

@ -19,6 +19,16 @@ from ..core.expr import VarExpr, VarSource
T = TypeVar('T')
class StructProxy:
def __init__(self):
self._sx_fields_ = {}
def __getattr__(self, name: str) -> VarExpr:
e = VarExpr(name)
self._sx_fields_[name].append(e)
return e
class StructType(G[T], Type[T]):
__slots__ = ('fields', 'cls', 'partial', 'union', 'generics', 'bound')
@ -222,21 +232,23 @@ class Struct:
localns.update({g.name: g for g in generics})
# Evaluate annotations into fields
proxy = StructProxy()
localns['self'] = proxy
fields = {}
refs: Mapping[str, VarExpr] = {}
for name, (globalns, value) in annots.items():
val = eval(value, globalns, localns)
if isinstance(val, Annotated):
val = next(v for v in val.__metadata__ if isinstance(v, Type))
fields[name] = val
localns[name] = refs[name] = VarExpr(name)
proxy._sx_fields_[name] = []
del localns
for name, r in refs.items():
count = sys.getrefcount(r) - 4 # cursed
for name, exprs in proxy._sx_fields_.items():
count = len(exprs)
if count:
fields[name] = VarSource(fields[name], count)
r._sx_resolve_(fields[name])
for e in exprs:
e._sx_resolve_(fields[name])
cls._sx_type_ = StructType(fields, cls, generics=generics, bound=bound, **kwargs)