From 7f849eb49a9971eb810f51a7753a94100f99f008 Mon Sep 17 00:00:00 2001 From: Joey Tran Date: Fri, 20 Sep 2024 10:04:50 -0400 Subject: [PATCH 1/5] Add test case --- sdks/python/apache_beam/typehints/typehints_test.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/sdks/python/apache_beam/typehints/typehints_test.py b/sdks/python/apache_beam/typehints/typehints_test.py index c395893a23ba..99c369aacf29 100644 --- a/sdks/python/apache_beam/typehints/typehints_test.py +++ b/sdks/python/apache_beam/typehints/typehints_test.py @@ -166,6 +166,14 @@ def test_any_compatibility(self): self.assertCompatible(object, typehints.Any) self.assertCompatible(typehints.Any, object) + def test_int_float_complex_compatibility(self): + self.assertCompatible(int, float) + self.assertCompatible(int, complex) + self.assertCompatible(float, complex) + self.assertNotCompatible(float, int) + self.assertNotCompatible(complex, int) + self.assertNotCompatible(complex, float) + def test_repr(self): self.assertEqual('Any', repr(typehints.Any)) From 4661b14017f78625d32d089a46d3b9815da70832 Mon Sep 17 00:00:00 2001 From: Joey Tran Date: Fri, 20 Sep 2024 10:09:15 -0400 Subject: [PATCH 2/5] reverse ordering of test --- sdks/python/apache_beam/typehints/typehints_test.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/sdks/python/apache_beam/typehints/typehints_test.py b/sdks/python/apache_beam/typehints/typehints_test.py index 99c369aacf29..e40231da6d49 100644 --- a/sdks/python/apache_beam/typehints/typehints_test.py +++ b/sdks/python/apache_beam/typehints/typehints_test.py @@ -167,12 +167,12 @@ def test_any_compatibility(self): self.assertCompatible(typehints.Any, object) def test_int_float_complex_compatibility(self): - self.assertCompatible(int, float) - self.assertCompatible(int, complex) - self.assertCompatible(float, complex) - self.assertNotCompatible(float, int) - self.assertNotCompatible(complex, int) - self.assertNotCompatible(complex, float) + self.assertCompatible(float, int) + self.assertCompatible(complex, int) + self.assertCompatible(complex, float) + self.assertNotCompatible(int, float) + self.assertNotCompatible(int, complex) + self.assertNotCompatible(float, complex) def test_repr(self): self.assertEqual('Any', repr(typehints.Any)) From 52b86c52a297fb4650b25ded6a0f7c85251d338c Mon Sep 17 00:00:00 2001 From: Joey Tran Date: Fri, 20 Sep 2024 10:11:29 -0400 Subject: [PATCH 3/5] Update is_consistent_with --- sdks/python/apache_beam/typehints/typehints.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/sdks/python/apache_beam/typehints/typehints.py b/sdks/python/apache_beam/typehints/typehints.py index b368f0abdf3d..912cb78dc095 100644 --- a/sdks/python/apache_beam/typehints/typehints.py +++ b/sdks/python/apache_beam/typehints/typehints.py @@ -1309,6 +1309,12 @@ def is_consistent_with(sub, base): return True if isinstance(sub, AnyTypeConstraint) or isinstance(base, AnyTypeConstraint): return True + # Per PEP484, ints are considered floats and complexes and + # floats are considered complexes. + if sub is int and base in (float, complex): + return True + if sub is float and base is complex: + return True sub = normalize(sub, none_as_type=True) base = normalize(base, none_as_type=True) if isinstance(sub, UnionConstraint): From ad55edc32491b29c027f19e5fc98f1da370dc066 Mon Sep 17 00:00:00 2001 From: Joey Tran Date: Fri, 20 Sep 2024 10:48:07 -0400 Subject: [PATCH 4/5] Update failing unit test to use str instead of int --- sdks/python/apache_beam/transforms/ptransform_test.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sdks/python/apache_beam/transforms/ptransform_test.py b/sdks/python/apache_beam/transforms/ptransform_test.py index a51d5cd83d26..2fdec14651f1 100644 --- a/sdks/python/apache_beam/transforms/ptransform_test.py +++ b/sdks/python/apache_beam/transforms/ptransform_test.py @@ -1495,17 +1495,17 @@ def test_filter_does_not_type_check_using_type_hints_decorator(self): def more_than_half(a): return a > 0.50 - # Func above was hinted to only take a float, yet an int will be passed. + # Func above was hinted to only take a float, yet a str will be passed. with self.assertRaises(typehints.TypeCheckError) as e: ( self.p - | 'Ints' >> beam.Create([1, 2, 3, 4]).with_output_types(int) + | 'Ints' >> beam.Create(['1', '2', '3', '4']).with_output_types(str) | 'Half' >> beam.Filter(more_than_half)) self.assertStartswith( e.exception.args[0], "Type hint violation for 'Half': " - "requires {} but got {} for a".format(float, int)) + "requires {} but got {} for a".format(float, str)) def test_filter_type_checks_using_type_hints_decorator(self): @with_input_types(b=int) From 22ce9feddb9dd8f4be77f819c35d7665f4fda14e Mon Sep 17 00:00:00 2001 From: Joey Tran Date: Fri, 20 Sep 2024 16:53:47 -0400 Subject: [PATCH 5/5] update a couple more tests --- .../apache_beam/typehints/typed_pipeline_test.py | 10 +++++----- sdks/python/apache_beam/typehints/typehints_test.py | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/sdks/python/apache_beam/typehints/typed_pipeline_test.py b/sdks/python/apache_beam/typehints/typed_pipeline_test.py index 9cb3fcdbb91d..72aed46f5e78 100644 --- a/sdks/python/apache_beam/typehints/typed_pipeline_test.py +++ b/sdks/python/apache_beam/typehints/typed_pipeline_test.py @@ -422,7 +422,7 @@ def test_typed_ptransform_fn_conflicting_hints(self): # In this case, both MyMap and its contained ParDo have separate type # checks (that disagree with each other). @beam.ptransform_fn - @typehints.with_input_types(int) + @typehints.with_input_types(str) def MyMap(pcoll): def fn(element: float): yield element @@ -430,11 +430,11 @@ def fn(element: float): return pcoll | beam.ParDo(fn) with self.assertRaisesRegex(typehints.TypeCheckError, - r'ParDo.*requires.*float.*got.*int'): - _ = [1, 2, 3] | MyMap() + r'ParDo.*requires.*float.*got.*str'): + _ = ['1', '2', '3'] | MyMap() with self.assertRaisesRegex(typehints.TypeCheckError, - r'MyMap.*expected.*int.*got.*str'): - _ = ['a'] | MyMap() + r'MyMap.*expected.*str.*got.*bytes'): + _ = [b'a'] | MyMap() def test_typed_dofn_string_literals(self): class MyDoFn(beam.DoFn): diff --git a/sdks/python/apache_beam/typehints/typehints_test.py b/sdks/python/apache_beam/typehints/typehints_test.py index e40231da6d49..843c1498cac5 100644 --- a/sdks/python/apache_beam/typehints/typehints_test.py +++ b/sdks/python/apache_beam/typehints/typehints_test.py @@ -226,7 +226,7 @@ def test_union_hint_compatibility(self): typehints.Union[int, str], typehints.Union[str, typehints.Union[int, str]]) - self.assertNotCompatible( + self.assertCompatible( typehints.Union[float, bool], typehints.Union[int, bool]) self.assertNotCompatible( typehints.Union[bool, str], typehints.Union[float, bool, int])