diff --git a/sdk/python/kfp/compiler/compiler_test.py b/sdk/python/kfp/compiler/compiler_test.py index c6926f1a96f..42649752bbc 100644 --- a/sdk/python/kfp/compiler/compiler_test.py +++ b/sdk/python/kfp/compiler/compiler_test.py @@ -572,9 +572,8 @@ def my_pipeline(text: bool): # pylint: disable=import-outside-toplevel,unused-import,import-error,redefined-outer-name,reimported class V2NamespaceAliasTest(unittest.TestCase): - """Test that imports of both modules and objects are aliased - (e.g. all import path variants work). - """ + """Test that imports of both modules and objects are aliased (e.g. all + import path variants work).""" # Note: The DeprecationWarning is only raised on the first import where # the kfp.v2 module is loaded. Due to the way we run tests in CI/CD, we cannot ensure that the kfp.v2 module will first be loaded in these tests, diff --git a/sdk/python/kfp/components/component_factory.py b/sdk/python/kfp/components/component_factory.py index 0a533a95cd1..5033ea421dc 100644 --- a/sdk/python/kfp/components/component_factory.py +++ b/sdk/python/kfp/components/component_factory.py @@ -127,15 +127,9 @@ def _annotation_to_type_struct(annotation): else: type_name = str(annotation.__name__) - # TODO: remove the hack once drop Python 3.6 support. - # In Python 3.6+, typing.Dict, typing.List are not instance of type. - if type_annotations.get_short_type_name( - str(annotation)) in ['List', 'Dict']: - type_name = str(annotation) - elif hasattr( annotation, '__forward_arg__' - ): # Handling typing.ForwardRef('Type_name') (the name was _ForwardRef in python 3.5-3.6) + ): # Handling typing.ForwardRef('Type_name') type_name = str(annotation.__forward_arg__) else: type_name = str(annotation) diff --git a/sdk/python/kfp/components/structures.py b/sdk/python/kfp/components/structures.py index e52fe9d5233..14fe3b0e4a1 100644 --- a/sdk/python/kfp/components/structures.py +++ b/sdk/python/kfp/components/structures.py @@ -305,8 +305,6 @@ class ComponentSpec(BaseModel): implementation: The implementation of the component. Either an executor (container, importer) or a DAG consists of other components. """ - # TODO(ji-yaqi): Update to OrderedDict for inputs and outputs once we drop - # Python 3.6 support name: str description: Optional[str] = None inputs: Optional[Dict[str, InputSpec]] = None diff --git a/sdk/python/kfp/components/v1_modelbase.py b/sdk/python/kfp/components/v1_modelbase.py index 0091aff7ea8..c20017bb4e6 100644 --- a/sdk/python/kfp/components/v1_modelbase.py +++ b/sdk/python/kfp/components/v1_modelbase.py @@ -67,10 +67,7 @@ def verify_object_against_type(x: Any, typ: Type[T]) -> T: raise TypeError( 'Error: None object is incompatible with type {}'.format(typ)) - #assert isinstance(x, typ.__origin__) - generic_type = typ.__origin__ or getattr( - typ, '__extra__', None - ) #In python <3.7 typing.List.__origin__ == None; Python 3.7 has working __origin__, but no __extra__ TODO: Remove the __extra__ once we move to Python 3.7 + generic_type = typ.__origin__ if generic_type in [ list, List, abc.Sequence, abc.MutableSequence, Sequence, MutableSequence @@ -79,7 +76,7 @@ def verify_object_against_type(x: Any, typ: Type[T]) -> T: raise TypeError( 'Error: Object "{}" is incompatible with type "{}"'.format( x, typ)) - # In Python <3.7 Mapping.__args__ is None. + # In Python 3.9 typ.__args__ does not exist when the generic type does not have subscripts type_args = typ.__args__ if getattr( typ, '__args__', None) is not None else (Any, Any) @@ -96,7 +93,7 @@ def verify_object_against_type(x: Any, typ: Type[T]) -> T: raise TypeError( 'Error: Object "{}" is incompatible with type "{}"'.format( x, typ)) - # In Python <3.7 Mapping.__args__ is None. + # In Python 3.9 typ.__args__ does not exist when the generic type does not have subscripts type_args = typ.__args__ if getattr( typ, '__args__', None) is not None else (Any, Any) @@ -157,9 +154,7 @@ def parse_object_from_struct_based_on_type(struct: Any, typ: Type[T]) -> T: possible_types = list(getattr(typ, '__args__', [Any])) #if type(None) in possible_types and struct is None: #Shortcut for Optional[] tests. Can be removed, but the exceptions will be more noisy. # return None - #Hack for Python <3.7 which for some reason "simplifies" Union[bool, int, ...] to just Union[int, ...] - if int in possible_types: - possible_types = possible_types + [bool] + for possible_type in possible_types: try: obj = parse_object_from_struct_based_on_type( @@ -194,10 +189,7 @@ def parse_object_from_struct_based_on_type(struct: Any, typ: Type[T]) -> T: 'Error: None structure is incompatible with type {}'.format( typ)) - #assert isinstance(x, typ.__origin__) - generic_type = typ.__origin__ or getattr( - typ, '__extra__', None - ) #In python <3.7 typing.List.__origin__ == None; Python 3.7 has working __origin__, but no __extra__ TODO: Remove the __extra__ once we move to Python 3.7 + generic_type = typ.__origin__ if generic_type in [ list, List, abc.Sequence, abc.MutableSequence, Sequence, MutableSequence @@ -206,7 +198,7 @@ def parse_object_from_struct_based_on_type(struct: Any, typ: Type[T]) -> T: raise TypeError( 'Error: Structure "{}" is incompatible with type "{}" - it does not have list type.' .format(struct, typ)) - # In Python <3.7 Mapping.__args__ is None. + # In Python 3.9 typ.__args__ does not exist when the generic type does not have subscripts type_args = typ.__args__ if getattr( typ, '__args__', None) is not None else (Any, Any) @@ -219,12 +211,12 @@ def parse_object_from_struct_based_on_type(struct: Any, typ: Type[T]) -> T: elif generic_type in [ dict, Dict, abc.Mapping, abc.MutableMapping, Mapping, MutableMapping, OrderedDict - ]: #in Python <3.7 there is a difference between abc.Mapping and typing.Mapping + ]: if not isinstance(struct, generic_type): raise TypeError( 'Error: Structure "{}" is incompatible with type "{}" - it does not have dict type.' .format(struct, typ)) - # In Python <3.7 Mapping.__args__ is None. + # In Python 3.9 typ.__args__ does not exist when the generic type does not have subscripts type_args = typ.__args__ if getattr( typ, '__args__', None) is not None else (Any, Any)