raams95 opened a new pull request, #40757:
URL: https://github.com/apache/beam/pull/40757

   Fixes #20986
   
   A type hint with a `typing.Protocol` that is not `@runtime_checkable` makes 
the pipeline fail at construction:
   
   ```python
   class HasUpper(typing.Protocol):
     def upper(self) -> str:
       ...
   
   def fn(element: HasUpper) -> str:
     return element.upper()
   
   with beam.Pipeline() as p:
     _ = p | beam.Create(['a', 'b']) | beam.Map(fn)
   ```
   
   ```
   TypeError: Instance and class checks can only be used with 
@runtime_checkable protocols
   ```
   
   `is_consistent_with(str, HasUpper)` calls `issubclass`, through beartype's 
`is_subhint` or directly, and Python raises this error for such a Protocol. 
With `--runtime_type_check` or `--performance_runtime_type_check`, 
`check_constraint` calls `isinstance` on each element and fails the same way. 
So a non-runtime Protocol hint works today only when the input type is exactly 
the same Protocol.
   
   A Protocol is matched structurally, and Beam cannot check that with 
`issubclass` or `isinstance`. With this change, `is_consistent_with` returns 
`True` when the base is such a Protocol, and `check_constraint` skips it, as it 
does for `Any`. For these Protocols, both calls always raised the `TypeError` 
before. The only caller that caught it is the runtime check of a `Union`, which 
counted it as a mismatch, so a runtime check of `Optional[HasUpper]` now also 
passes for a `str`. The element type stays the Protocol, so the coder does not 
change. `@runtime_checkable` Protocols keep the `issubclass`/`isinstance` 
checks that they have today.
   
   Tests:
   - `test_typed_map_protocol_input` in `typed_pipeline_test.py` runs the 
pipeline above.
   - `test_protocol_type_hint` in `typecheck_test.py` runs it with 
`runtime_type_check=True`.
   
   Both fail before the change and pass after it on Python 3.11, 3.12, 3.13 and 
3.14.
   
   Testing:
   - `pytest apache_beam/typehints/typed_pipeline_test.py 
apache_beam/typehints/typecheck_test.py -k protocol` on Python 3.11, 3.12, 3.13 
and 3.14
   - `pytest apache_beam/typehints apache_beam/transforms apache_beam/coders 
apache_beam/pipeline_test.py` on Python 3.12
   - `yapf --diff` and `ruff check` on the changed files
   
   ------------------------
   
   Thank you for your contribution! Follow this checklist to help us 
incorporate your contribution quickly and easily:
   
    - [x] Mention the appropriate issue in your description (for example: 
`addresses #123` or `fixes #456`).
    - [x] Update `CHANGES.md` with noteworthy changes.
    - [ ] If this contribution is large, please file an Apache [Individual 
Contributor License Agreement](https://www.apache.org/licenses/icla.pdf). (Not 
needed, small change.)
   
   See the [Contributor Guide](https://beam.apache.org/contribute) for more 
tips on [how to make review process 
smoother](https://github.com/apache/beam/blob/master/CONTRIBUTING.md#make-the-reviewers-job-easier).
   


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