简体   繁体   中英

Python type hinting (for return type) not working for classes vs subclasses?

The code:

So I have super simple code files as follows:

First, my schema definition file: schema.py

from pydantic import BaseModel


class BaseSchema(BaseModel):

    user_type: UserTypeEnum
    configuration_type: ConfigurationTypeEnum


class UserDataSchema(BaseSchema):

    user_type: UserTypeEnum.NORMAL
    configuration_type: ConfigurationTypeEnum.NORMAL

    user_name: str
    user_age: int

Second, I have a class definition file, say class_file.py

class AnotherServiceClass(BaseClient):

    @property
    def client_name(self):
        return 'another_service_class'

    def get_call(self, schema_identifier_param: str) -> BaseSchema:
        url = 'some/url/constructed'
        return self.get(url)

And then I have a file that calls the above class's function: caller_function.py

def get_data_from_another_service(
    user_name: str,
    schema_identifier_param: str
) -> UserDataSchema:
    another_service_instance = AnotherServiceClass(
        user_name=user_name
    )
    return another_service_instance.get_call(schema_identifier_param)

The problem:

Here, the AnotherServiceClass.get_call function in class_file.py is a generic function that can return any type of schema that is a child of BaseSchema ; therefore the -> BaseSchema: .

And the get_data_from_another_service function in caller_function.py file knows that it should always get UserDataSchema . This is because of the specific value passed in schema_identifier_param parameter.

The problem is, I still get type hinting errors in get_data_from_another_service function; saying that AnotherServiceClass.get_call returns BaseSchema , but I am then returning UserDataSchema .

Since UserDataSchema inherits BaseSchema , shouldn't it be a valid return type?

I have also tried defining the AnotherServiceClass.get_call 's return type as:
get_call(self, schema_identifier_param: str) -> Type[BaseSchema]:
but it does not help.

What am I doing wrong?

And the get_data_from_another_service function in caller_function.py file knows that it should always get UserDataSchema. This is because of the specific value passed in schema_identifier_param parameter.

This is where it gets wrong. Python does not know your convention that "the specific value passed in schema_identifier_param" results in UserDataSchema always being returned. And you can not easily explain this in type hints system. So what Python is saying is roughly "I do not see why get_data_from_another_service will return UserDataSchema". And Python is absolutely right in this.

(Moreover, your code also does not guarantee this in any way. You return something that is returned by some url, so you have to rely on remote server behavior to make it always return UserDataSchema. This is very very fragile.)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM