Fixes for $protkey protfunc implementation

This commit is contained in:
Griatch 2021-09-12 19:51:08 +02:00
parent cb5830bbc5
commit 4db1a1e2e0
2 changed files with 39 additions and 17 deletions

View file

@ -44,7 +44,22 @@ def protfunc_callable_protkey(*args, **kwargs):
return "" return ""
prototype = kwargs.get("prototype", {}) prototype = kwargs.get("prototype", {})
prot_value = prototype[args[0]] fieldname = args[0]
prot_value = None
if fieldname in prototype:
prot_value = prototype[fieldname]
else:
# check if it's an attribute
for attrtuple in prototype.get('attrs', []):
if attrtuple[0] == fieldname:
prot_value = attrtuple[1]
break
else:
raise AttributeError(f"{fieldname} not found in prototype\n{prototype}\n"
"(neither as prototype-field or as an Attribute")
if callable(prot_value):
raise RuntimeError(f"Error in prototype\n{prototype}\n$protkey can only reference static "
f"values/attributes (found {prot_value})")
try: try:
return funcparser.funcparser_callable_eval(prot_value, **kwargs) return funcparser.funcparser_callable_eval(prot_value, **kwargs)
except funcparser.ParsingError: except funcparser.ParsingError:

View file

@ -937,41 +937,45 @@ def spawn(*prototypes, caller=None, **kwargs):
"key", "key",
"Spawned-{}".format(hashlib.md5(bytes(str(time.time()), "utf-8")).hexdigest()[:6]), "Spawned-{}".format(hashlib.md5(bytes(str(time.time()), "utf-8")).hexdigest()[:6]),
) )
create_kwargs["db_key"] = init_spawn_value(val, str, caller=caller) create_kwargs["db_key"] = init_spawn_value(val, str, caller=caller, prototype=prototype)
val = prot.pop("location", None) val = prot.pop("location", None)
create_kwargs["db_location"] = init_spawn_value(val, value_to_obj, caller=caller) create_kwargs["db_location"] = init_spawn_value(
val, value_to_obj, caller=caller, prototype=prototype)
val = prot.pop("home", None) val = prot.pop("home", None)
if val: if val:
create_kwargs["db_home"] = init_spawn_value(val, value_to_obj, caller=caller) create_kwargs["db_home"] = init_spawn_value(val, value_to_obj, caller=caller,
prototype=prototype)
else: else:
try: try:
create_kwargs["db_home"] = init_spawn_value( create_kwargs["db_home"] = init_spawn_value(
settings.DEFAULT_HOME, value_to_obj, caller=caller) settings.DEFAULT_HOME, value_to_obj, caller=caller, prototype=prototype)
except ObjectDB.DoesNotExist: except ObjectDB.DoesNotExist:
# settings.DEFAULT_HOME not existing is common for unittests # settings.DEFAULT_HOME not existing is common for unittests
pass pass
val = prot.pop("destination", None) val = prot.pop("destination", None)
create_kwargs["db_destination"] = init_spawn_value(val, value_to_obj, caller=caller) create_kwargs["db_destination"] = init_spawn_value(val, value_to_obj, caller=caller,
prototype=prototype)
val = prot.pop("typeclass", settings.BASE_OBJECT_TYPECLASS) val = prot.pop("typeclass", settings.BASE_OBJECT_TYPECLASS)
create_kwargs["db_typeclass_path"] = init_spawn_value(val, str, caller=caller) create_kwargs["db_typeclass_path"] = init_spawn_value(val, str, caller=caller,
prototype=prototype)
# extract calls to handlers # extract calls to handlers
val = prot.pop("permissions", []) val = prot.pop("permissions", [])
permission_string = init_spawn_value(val, make_iter, caller=caller) permission_string = init_spawn_value(val, make_iter, caller=caller, prototype=prototype)
val = prot.pop("locks", "") val = prot.pop("locks", "")
lock_string = init_spawn_value(val, str, caller=caller) lock_string = init_spawn_value(val, str, caller=caller, prototype=prototype)
val = prot.pop("aliases", []) val = prot.pop("aliases", [])
alias_string = init_spawn_value(val, make_iter, caller=caller) alias_string = init_spawn_value(val, make_iter, caller=caller, prototype=prototype)
val = prot.pop("tags", []) val = prot.pop("tags", [])
tags = [] tags = []
for (tag, category, *data) in val: for (tag, category, *data) in val:
tags.append((init_spawn_value(tag, str, caller=caller), category, data[0] tags.append((init_spawn_value(tag, str, caller=caller, prototype=prototype),
if data else None)) category, data[0] if data else None))
prototype_key = prototype.get("prototype_key", None) prototype_key = prototype.get("prototype_key", None)
if prototype_key: if prototype_key:
@ -979,11 +983,12 @@ def spawn(*prototypes, caller=None, **kwargs):
tags.append((prototype_key, PROTOTYPE_TAG_CATEGORY)) tags.append((prototype_key, PROTOTYPE_TAG_CATEGORY))
val = prot.pop("exec", "") val = prot.pop("exec", "")
execs = init_spawn_value(val, make_iter, caller=caller) execs = init_spawn_value(val, make_iter, caller=caller, prototype=prototype)
# extract ndb assignments # extract ndb assignments
nattributes = dict( nattributes = dict(
(key.split("_", 1)[1], init_spawn_value(val, value_to_obj, caller=caller)) (key.split("_", 1)[1], init_spawn_value(val, value_to_obj, caller=caller,
prototype=prototype))
for key, val in prot.items() for key, val in prot.items()
if key.startswith("ndb_") if key.startswith("ndb_")
) )
@ -992,8 +997,9 @@ def spawn(*prototypes, caller=None, **kwargs):
val = make_iter(prot.pop("attrs", [])) val = make_iter(prot.pop("attrs", []))
attributes = [] attributes = []
for (attrname, value, *rest) in val: for (attrname, value, *rest) in val:
attributes.append((attrname, init_spawn_value(value, caller=caller), attributes.append(
rest[0] if rest else None, rest[1] if len(rest) > 1 else None)) (attrname, init_spawn_value(value, caller=caller, prototype=prototype),
rest[0] if rest else None, rest[1] if len(rest) > 1 else None))
simple_attributes = [] simple_attributes = []
for key, value in ( for key, value in (
@ -1004,7 +1010,8 @@ def spawn(*prototypes, caller=None, **kwargs):
continue continue
else: else:
simple_attributes.append( simple_attributes.append(
(key, init_spawn_value(value, value_to_obj_or_any, caller=caller), None, None) (key, init_spawn_value(value, value_to_obj_or_any, caller=caller,
prototype=prototype), None, None)
) )
attributes = attributes + simple_attributes attributes = attributes + simple_attributes