Skip to content

The class decorated by @from_file loses its original type hint #62

Description

@OpenGHz

Here is a possible solution:

`
T = TypeVar("T", bound=BaseModel)

def from_file(
loader: Type[FileBaseSettingsSource],
use_field: Optional[str] = None,
required: bool = True,
):
def decorator(cls: Type[T]) -> Type[T]:
if not issubclass(cls, BaseModel):
raise TypeError("@from_file can only be applied to Pydantic models")
if use_field is not None:
if use_field not in cls.model_fields:
raise ValueError(f"Field {use_field} not found in model {cls.name}")
field_annotation = cls.model_fields[use_field].annotation
if not issubclass(field_annotation, (str, Path)):
raise ValueError(
f"Field {use_field} must be a string or Path to be used as file source"
)

    class DynamicSourceSettings(cls, BaseSettings):  # type: ignore
        __arg_source_field__ = use_field
        __arg_source_required__ = required

        @classmethod
        def settings_customise_sources(
            cls,
            settings_cls: Type[BaseSettings],
            init_settings: PydanticBaseSettingsSource,
            env_settings: PydanticBaseSettingsSource,
            dotenv_settings: PydanticBaseSettingsSource,
            file_secret_settings: PydanticBaseSettingsSource,
        ) -> Tuple[PydanticBaseSettingsSource, ...]:
            source = DynamicFileSource(
                settings_cls,
                loader,
                cast(InitSettingsSource, init_settings).init_kwargs,
                required,
                use_field,
            )
            return (source,)

    # Tell the type checker that we are returning the original class (but we are actually returning the inherited class)
    return cast(Type[T], DynamicSourceSettings)

return decorator

`

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions