robertwb commented on code in PR #29169:
URL: https://github.com/apache/beam/pull/29169#discussion_r1376941324


##########
sdks/python/apache_beam/yaml/yaml_mapping.py:
##########
@@ -75,28 +79,86 @@ def __setstate__(self, state):
     self.__dict__.update(state)
 
 
+def py_value_to_js_dict(py_value):
+  if ((isinstance(py_value, tuple) and hasattr(py_value, '_asdict')) or
+      isinstance(py_value, beam.Row)):
+    py_value = py_value._asdict()
+  if isinstance(py_value, dict):
+    return {key: py_value_to_js_dict(value) for key, value in py_value.items()}
+  elif not isinstance(py_value, str) and isinstance(py_value, Iterable):
+    return [py_value_to_js_dict(value) for value in list(py_value)]
+  else:
+    return py_value
+
+
 # TODO(yaml) Consider adding optional language version parameter to support
 #  ECMAScript 5 and 6
 def _expand_javascript_mapping_func(
     original_fields, expression=None, callable=None, path=None, name=None):
+
+  js_array_type = (
+      base.PyJsArray,
+      base.PyJsArrayBuffer,
+      base.PyJsInt8Array,
+      base.PyJsUint8Array,
+      base.PyJsUint8ClampedArray,
+      base.PyJsInt16Array,
+      base.PyJsUint16Array,
+      base.PyJsInt32Array,
+      base.PyJsUint32Array,
+      base.PyJsFloat32Array,
+      base.PyJsFloat64Array)
+
+  def _js_object_to_py_object(obj):
+    if isinstance(obj, (base.PyJsNumber, base.PyJsString, base.PyJsBoolean)):
+      return base.to_python(obj)
+    elif isinstance(obj, js_array_type):
+      return [_js_object_to_py_object(value) for value in obj.to_list()]
+    elif isinstance(obj, jsdate.PyJsDate):
+      return obj.to_utc_dt()
+    elif isinstance(obj, (base.PyJsNull, base.PyJsUndefined)):
+      return None
+    elif isinstance(obj, base.PyJsError):
+      raise RuntimeError(obj['message'])
+    elif isinstance(obj, base.PyJsObject):
+      return {
+          key: _js_object_to_py_object(value['value'])
+          for (key, value) in obj.own.items()
+      }
+    elif isinstance(obj, base.JsObjectWrapper):
+      return _js_object_to_py_object(obj._obj)
+
+    return obj
+
   if expression:
-    args = ', '.join(original_fields)
-    js_func = f'function fn({args}) {{return ({expression})}}'
-    js_callable = _CustomJsObjectWrapper(js2py.eval_js(js_func))
-    return lambda __row__: js_callable(*__row__._asdict().values())
+    source = '\n'.join(['function(row) {'] + [

Review Comment:
   OK, this is somewhere where you are going to want to do something like 
__row__ in case they have a field named row. 



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to