You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@flink.apache.org by sj...@apache.org on 2021/05/20 16:15:55 UTC
[flink-statefun] branch master updated: [FLINK-22242][python]
Improve missing attribute error on GeneratedAddressedScopedStorage
This is an automated email from the ASF dual-hosted git repository.
sjwiesman pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/flink-statefun.git
The following commit(s) were added to refs/heads/master by this push:
new a239958 [FLINK-22242][python] Improve missing attribute error on GeneratedAddressedScopedStorage
a239958 is described below
commit a23995878ca12c4f25f08751fad91f1275e1df80
Author: Seth Wiesman <sj...@gmail.com>
AuthorDate: Mon Apr 12 11:32:01 2021 -0500
[FLINK-22242][python] Improve missing attribute error on GeneratedAddressedScopedStorage
This closes #223
---
statefun-sdk-python/statefun/request_reply_v3.py | 2 +-
statefun-sdk-python/statefun/storage.py | 16 +++++++++++++---
statefun-sdk-python/tests/storage_test.py | 10 +++++-----
3 files changed, 19 insertions(+), 9 deletions(-)
diff --git a/statefun-sdk-python/statefun/request_reply_v3.py b/statefun-sdk-python/statefun/request_reply_v3.py
index 3eb258f..fa05253 100644
--- a/statefun-sdk-python/statefun/request_reply_v3.py
+++ b/statefun-sdk-python/statefun/request_reply_v3.py
@@ -209,7 +209,7 @@ class RequestReplyHandler(object):
if not target_fn:
raise ValueError(f"Unable to find a function of type {sdk_address.typename}")
# resolve state
- res = resolve(target_fn.storage_spec, pb_to_function.invocation.state)
+ res = resolve(target_fn.storage_spec, sdk_address.typename, pb_to_function.invocation.state)
if res.missing_specs:
pb_from_function = collect_failure(res.missing_specs)
return pb_from_function.SerializeToString()
diff --git a/statefun-sdk-python/statefun/storage.py b/statefun-sdk-python/statefun/storage.py
index 0eafe94..21a49fe 100644
--- a/statefun-sdk-python/statefun/storage.py
+++ b/statefun-sdk-python/statefun/storage.py
@@ -68,8 +68,13 @@ class Cell(object):
# self.cells: typing.Dict[str, Cell] = {name: Cell(name, tpe, vals[name]) for name, tpe in types.items()}
-def storage_constructor(self, cells: typing.Dict[str, Cell]):
+def storage_constructor(self, cells: typing.Dict[str, Cell], typename: str):
self._cells = cells
+ self._typename = typename
+
+
+def storage_missing_attribute(self, attr):
+ raise AttributeError("'{}' is not a registered ValueSpec for the function '{}'".format(attr, self._typename))
def property_named(name):
@@ -109,7 +114,10 @@ def make_address_storage_spec(specs: typing.List[ValueSpec]) -> StorageSpec:
:param specs: a list of specs as supplied by the user.
:return: a StorageSpec.
"""
- props = {"__init__": storage_constructor, "__slots__": ["_cells"]}
+ props = {
+ "__init__": storage_constructor,
+ "__getattr__": storage_missing_attribute,
+ "__slots__": ["_cells", "_typename"]}
for spec in specs:
if spec.name in props:
raise ValueError("duplicate registered value name: " + spec.name)
@@ -121,11 +129,13 @@ def make_address_storage_spec(specs: typing.List[ValueSpec]) -> StorageSpec:
def resolve(storage: StorageSpec,
+ typename: str,
values: typing.List[ToFunction.PersistedValue]) -> Resolution:
"""
Resolve the registered specs and the actually received values.
:param storage: a storage factory
+ :param typename: the typename of the function under invocation
:param values: the actually received values
:return: a Resolution result, that might have either a list of missing specs
(specs that were defined by the user but didn't arrived from StateFun) or a
@@ -148,5 +158,5 @@ def resolve(storage: StorageSpec,
else:
cells: typing.Dict[str, Cell] = {spec.name: Cell(tpe=spec.type, typed_value=received[spec.name]) for spec in
storage.specs}
- s = storage.make_instance(cells)
+ s = storage.make_instance(cells, typename)
return Resolution(missing_specs=None, storage=s)
diff --git a/statefun-sdk-python/tests/storage_test.py b/statefun-sdk-python/tests/storage_test.py
index 2e99cd2..dd4a9ed 100644
--- a/statefun-sdk-python/tests/storage_test.py
+++ b/statefun-sdk-python/tests/storage_test.py
@@ -39,7 +39,7 @@ class StorageTestCase(unittest.TestCase):
values = [PbPersistedValueLike("a", 1, IntType), PbPersistedValueLike("b", "hello", StringType)]
# resolve spec and values
- resolution = resolve(storage_spec, values)
+ resolution = resolve(storage_spec, "example/func", values)
store = resolution.storage
self.assertEqual(store.a, 1)
@@ -53,7 +53,7 @@ class StorageTestCase(unittest.TestCase):
values = []
# resolve spec and values
- resolution = resolve(storage_spec, values)
+ resolution = resolve(storage_spec, "example/func", values)
self.assertListEqual(resolution.missing_specs, specs)
def test_partial_failed_resolution(self):
@@ -64,7 +64,7 @@ class StorageTestCase(unittest.TestCase):
values = [PbPersistedValueLike("a", 1, IntType)]
# resolve spec and values
- resolution = resolve(storage_spec, values)
+ resolution = resolve(storage_spec, "example/func", values)
self.assertListEqual(resolution.missing_specs, specs[1:])
def test_ignore_unknown(self):
@@ -75,7 +75,7 @@ class StorageTestCase(unittest.TestCase):
values = [PbPersistedValueLike("a", 1, IntType), PbPersistedValueLike("b", "hello", StringType)]
# resolve spec and values
- resolution = resolve(storage_spec, values)
+ resolution = resolve(storage_spec, "example/func", values)
store = resolution.storage
self.assertEqual(store.a, 1)
@@ -157,5 +157,5 @@ def store_from(*args):
else:
vals.append(arg)
storage_spec = make_address_storage_spec(specs)
- resolution = resolve(storage_spec, vals)
+ resolution = resolve(storage_spec, "example/func", vals)
return resolution.storage