Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Type annotations / type hints / stub files for mypy #448

Open
MartinThoma opened this issue Oct 14, 2020 · 12 comments
Open

Type annotations / type hints / stub files for mypy #448

MartinThoma opened this issue Oct 14, 2020 · 12 comments
Labels
Milestone

Comments

@MartinThoma
Copy link
Contributor

Are there plans to add type annotations or stub files for mypy?

I've written an article about type annotations if you need one :-)

@rochacbruno
Copy link
Member

@MartinThoma pull requests adding annotations and stubs are very welcome.

@MartinThoma
Copy link
Contributor Author

I see that you're supporting Python 3.6+. Then I would prefer type annotations instead of stub files. I'll prepare something once I have some time :-)

@stale
Copy link

stale bot commented Jun 2, 2022

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@stale stale bot added the wontfix label Jun 2, 2022
@disrupted
Copy link

commenting because this is still a valid and desired request, therefore shouldn't be closed

@stale stale bot removed the wontfix label Jun 2, 2022
@SonGokussj4
Copy link

Still valid even year later. Any progress? I tried to implement some dataclasses with pydantic but faild. Does anyone have a working workaround?

@MartinThoma
Copy link
Contributor Author

I no longer use dynaconf

@rochacbruno
Copy link
Member

I am working on #683 adding type annotations

@FeryET
Copy link

FeryET commented May 13, 2023

Any update on this?

@apowers313
Copy link

Here was my workaround: convert the Dynaconf config into a Pydantic BaseModel. Pydantic does all the validation and defaults and creates a strongly-typed config.

The code is a bit long (but conceptually very simple) because it has to account for all the default Dynaconf fields, so the Gist is here: https://gist.github.com/apowers313/c009991a31195e9e3ee8dc51b989136a

@LukeSavefrogs
Copy link

LukeSavefrogs commented Sep 5, 2023

Yet another workaround inspired by @apowers313 approach:

# -------------- src/package/config/schemas.py -------------- 
import dataclasses
from pathlib import Path

from dynaconf import Dynaconf

@dataclasses.dataclass
class SettingsSchema(Dynaconf):
    myProperty: str
    myCategory: "CategorySettingsSchema"


@dataclasses.dataclass
class CategorySettingsSchema:
    mySecondProperty: int




# -------------- src/package/config/__init__.py -------------- 
from dynaconf import Dynaconf
from package.config.schemas import SettingsSchema

settings: SettingsSchema = Dynaconf(  # pyright: ignore[reportGeneralTypeIssues]
    ...
)

Please note that:

  • this method relies entirely on forcing type casting on the Dynaconf object
  • The line # pyright: ignore[reportGeneralTypeIssues] is needed in order to ignore the PyLance error when trying to cast the Dynaconf object to SettingsSchema.

Pros and cons

Compared to @apowers313 solution this one has the following pros/cons:

PROS:

  • Less verbose
  • Does not need any other dependency installed (dataclasses is shipped with Python)

CONS:

  • Only access the contents of the configuration files (cannot access environment or Dynaconf variables)
  • Provides type hinting only when accessing properties via the dot operator (settings.property.subproperty)

For simpler configurations like mine could be useful.

@apowers313
Copy link

Great idea / example @LukeSavefrogs :)

Note that you can change line 75 of my example from extra="forbid" to extra="allow" and get pretty much the same thing as the dataclass example -- but it won't catch extra fields that have been defined in the config that you weren't expecting (a potential source of errors).

Also, put in the PROS column for Pydantic that it has more validation types (like email addresses, colors, IP addresses, URLs, etc.) and stuff like discriminated unions which could enable different validation requirements for dev / prod. (I also just noticed that it has Settings Management, which might be worth looking into).

I'm really liking the separation of duties of Dynaconf and Pydantic.

@LukeSavefrogs
Copy link

Great idea / example @LukeSavefrogs :)

Note that you can change line 75 of my example from extra="forbid" to extra="allow" and get pretty much the same thing as the dataclass example -- but it won't catch extra fields that have been defined in the config that you weren't expecting (a potential source of errors).

Thank you for your clarification, the only reason why i posted this (very dirty) "workaround" is because i didn't want to install another dependency that I will use only while developing and will be packaged with the final application increasing the bundle size and start times without any improvement for the user.

Also, put in the PROS column for Pydantic that it has more validation types

Sorry for the confusion, the PROS/CONS section was only for the dataclass method, I improved it a bit to make it clearer. 😄

In conclusion, your solution is more complete, but I cannot use it because I cannot afford to install a library for no gain for the end-user, so I had to come up with this 😁

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

7 participants