-
-
Notifications
You must be signed in to change notification settings - Fork 1.9k
Add stubs for django-environ #14573
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
base: main
Are you sure you want to change the base?
Add stubs for django-environ #14573
Changes from all commits
a7151c6
40c0da3
a08916e
f090e9f
11da833
5b5a7bb
88ae28a
e0977d6
fe8b2f4
73b4012
1326a7a
f8a7a38
076c8e2
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
from __future__ import annotations | ||
|
||
from typing import Union | ||
from typing_extensions import TypedDict, assert_type | ||
|
||
import environ | ||
|
||
env = environ.Env() | ||
|
||
assert_type(env.parse_value("just-a-value123", None), str) | ||
|
||
# builtin types | ||
assert_type(env.parse_value("string", str), str) | ||
assert_type(env.parse_value("TRUE", bool), bool) | ||
assert_type(env.parse_value("2000", int), int) | ||
assert_type(env.parse_value("-500.01", float), float) | ||
assert_type(env.parse_value("first,second,", list), list[str]) | ||
assert_type(env.parse_value("(first,second)", tuple), tuple[str, ...]) | ||
assert_type(env.parse_value("a=first,b=second", dict), dict[str, str]) | ||
|
||
|
||
# cast list values (first list element is used) | ||
assert_type(env.parse_value("20.5,-0.2", [str]), list[str]) | ||
assert_type(env.parse_value("20.5,-0.2", [bool]), list[bool]) | ||
assert_type(env.parse_value("20.5,-0.2", [int]), list[int]) | ||
assert_type(env.parse_value("20.5,-0.2", [float]), list[float]) | ||
|
||
# cast tuple values (first tuple element is used) | ||
assert_type(env.parse_value("(20.5,-0.2)", (str,)), tuple[str, ...]) | ||
assert_type(env.parse_value("(20.5,-0.2)", (bool,)), tuple[bool, ...]) | ||
assert_type(env.parse_value("(20.5,-0.2)", (int,)), tuple[int, ...]) | ||
assert_type(env.parse_value("(20.5,-0.2)", (float,)), tuple[float, ...]) | ||
|
||
# cast dict values | ||
assert_type(env.parse_value("0=TRUE,99=FALSE", {}), dict[str, str]) | ||
assert_type(env.parse_value("0=TRUE,99=FALSE", {"cast": {}}), dict[str, Union[str, object]]) | ||
assert_type(env.parse_value("0=TRUE,99=FALSE", {"value": bool}), dict[str, bool]) | ||
assert_type(env.parse_value("0=TRUE,99=FALSE", {"value": bool, "cast": {}}), dict[str, Union[bool, object]]) | ||
assert_type(env.parse_value("0=TRUE,99=FALSE", {"key": int}), dict[int, str]) | ||
assert_type(env.parse_value("0=TRUE,99=FALSE", {"key": int, "cast": {}}), dict[int, Union[str, object]]) | ||
assert_type(env.parse_value("0=TRUE,99=FALSE", {"key": int, "value": bool}), dict[int, bool]) | ||
assert_type(env.parse_value("0=TRUE,99=FALSE", {"key": int, "value": bool, "cast": {}}), dict[int, Union[bool, object]]) | ||
|
||
|
||
# custom cast functions | ||
def cast_float(x: str) -> float: | ||
return float(x) | ||
|
||
|
||
assert_type(env.parse_value("20.5", cast_float), float) | ||
|
||
|
||
class Person(TypedDict): | ||
first_name: str | ||
last_name: str | ||
age: int | ||
|
||
|
||
def cast_person(v: str) -> Person: | ||
parts = v.split(",") | ||
return {"first_name": parts[0], "last_name": parts[1], "age": int(parts[2])} | ||
Comment on lines
+59
to
+61
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No need to include a runtime implementation since these tests aren't executed (we only check how they type check). I think this case is also redundant with custom cast function case above |
||
|
||
|
||
assert_type(env.parse_value("Bob,Riveira,30", cast_person), Person) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
version = "0.12.*" | ||
upstream_repository = "https://github.com/joke2k/django-environ" |
Original file line number | Diff line number | Diff line change | ||
---|---|---|---|---|
@@ -0,0 +1,13 @@ | ||||
from typing import Final | ||||
|
||||
from .compat import DJANGO_POSTGRES as DJANGO_POSTGRES, PYMEMCACHE_DRIVER as PYMEMCACHE_DRIVER, REDIS_DRIVER as REDIS_DRIVER | ||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. These are indirectly re-exported from
Suggested change
|
||||
from .environ import * | ||||
|
||||
__copyright__: Final[str] | ||||
__version__: Final[str] | ||||
__license__: Final[str] | ||||
__author_email__: Final[str] | ||||
__maintainer__: Final[str] | ||||
__maintainer_email__: Final[str] | ||||
__url__: Final[str] | ||||
__description__: Final[str] |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
from typing import Final | ||
|
||
# reexports ImproperlyConfigured from django.core.exceptions if available | ||
class ImproperlyConfigured(Exception): ... | ||
EmCeeEs marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
def choose_rediscache_driver() -> str: ... | ||
def choose_postgres_driver() -> str: ... | ||
def choose_pymemcache_driver() -> str: ... | ||
|
||
REDIS_DRIVER: Final[str] | ||
DJANGO_POSTGRES: Final[str] | ||
PYMEMCACHE_DRIVER: Final[str] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the inferred type for this case should ideally be
dict[str, str]
. Inferringdict[str, object]
makes this awkward to use for end users, since you can't use the values in the dictionary without casting them or using a type narrowing construct