claudevdm commented on code in PR #41184:
URL: https://github.com/apache/beam/pull/41184#discussion_r4543159975


##########
sdks/python/apache_beam/typehints/decorators.py:
##########
@@ -175,6 +175,25 @@ def _annotation_namespaces(fn):
   return getattr(target, '__globals__', {}), localns
 
 
+def _is_convertible_type_hint(hint):
+  """Whether a resolved annotation converts to a valid Beam type hint.
+
+  A string annotation can resolve to something Beam cannot represent, e.g. a
+  protobuf enum (an ``EnumTypeWrapper`` instance, not a type) used as
+  ``Mapping[str, 'schema_pb2.FeatureType']``, or a typing construct that
+  convert_to_beam_type does not support, such as ``Generator[int]``. The
+  converted hint is validated (rather than the resolved annotation) so that
+  TypeVars, NewTypes and ``type`` aliases, which convert to valid hints, are
+  still resolved.
+  """
+  try:

Review Comment:
   Should this case fall back to `Any` too? It still raises the original enum 
error:
   
   ```python
   import typing
   import apache_beam as beam
   from apache_beam.pvalue import PCollection
   from google.protobuf import descriptor_pb2
   
   class Types(beam.PTransform):
     def expand(self, pcoll: 'PCollection[int]') -> (
         'PCollection[typing.Mapping[str, 
descriptor_pb2.FieldDescriptorProto.Type]]'):
       return pcoll | beam.Map(lambda x: {})
   
   print([1] | Types())
   # TypeError: Value-type parameter to a Mapping hint must be a non-sequence, 
a type, or a TypeConstraint
   ```
   
   I think it's because `convert_to_beam_type` returns `PCollection[...]` and 
`TaggedOutput[...]` unchanged without looking inside, so the check passes, and 
Beam converts the inner type later. The previous commit caught it by checking 
each type argument. Would it work to check the arguments again before 
converting?
   
   ```suggestion
     if hint is None or hint is Ellipsis:
       return True
     origin = get_origin(hint)
     if origin is Literal:
       # Literal arguments are values, not types.
       return True
     args = get_args(hint)
     if origin is typing.Annotated:
       args = args[:1]  # The remaining arguments are metadata.
     for arg in args:
       # A list is a Callable parameter list, e.g. the [int] in
       # Callable[[int], str].
       for inner in (arg if isinstance(arg, list) else [arg]):
         if not _is_convertible_type_hint(inner):
           return False
     try:
   ```



##########
sdks/python/apache_beam/typehints/decorators.py:
##########
@@ -175,6 +175,25 @@ def _annotation_namespaces(fn):
   return getattr(target, '__globals__', {}), localns
 
 
+def _is_convertible_type_hint(hint):
+  """Whether a resolved annotation converts to a valid Beam type hint.
+
+  A string annotation can resolve to something Beam cannot represent, e.g. a
+  protobuf enum (an ``EnumTypeWrapper`` instance, not a type) used as
+  ``Mapping[str, 'schema_pb2.FeatureType']``, or a typing construct that
+  convert_to_beam_type does not support, such as ``Generator[int]``. The
+  converted hint is validated (rather than the resolved annotation) so that
+  TypeVars, NewTypes and ``type`` aliases, which convert to valid hints, are
+  still resolved.
+  """
+  try:
+    validate_composite_type_param(
+        convert_to_beam_type(hint), 'Resolved type annotation')
+  except (TypeError, ValueError):

Review Comment:
   Should a recursive `type` alias fall back to `Any` here as well? It gets 
past this `except`:
   
   ```python
   from __future__ import annotations
   import apache_beam as beam
   
   type JSON = dict[str, JSON] | list[JSON] | str | int | None
   
   def parse(s: str) -> JSON:
     return {}
   
   print([''] | beam.Map(parse))
   # RecursionError: maximum recursion depth exceeded
   ```
   
   `convert_to_beam_type` unwraps the alias, finds the alias again inside, and 
never stops, and `RecursionError` isn't a `TypeError` or `ValueError`. This ran 
before #40625 and already fails on master. Is that something to handle in this 
PR or separately?
   



-- 
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