🐛 Fix: 修复 dotenv 配置项为 None 将会跳过赋值 (#2143)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Ju4tCode <42488585+yanyongyu@users.noreply.github.com>
This commit is contained in:
eya46 2023-07-04 10:45:55 +08:00 committed by GitHub
parent c40b95f3e9
commit 0033d7c686
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 16 additions and 5 deletions

View File

@ -17,6 +17,7 @@ from ipaddress import IPv4Address
from typing import TYPE_CHECKING, Any, Set, Dict, Tuple, Union, Mapping, Optional from typing import TYPE_CHECKING, Any, Set, Dict, Tuple, Union, Mapping, Optional
from pydantic.utils import deep_update from pydantic.utils import deep_update
from pydantic.fields import Undefined, UndefinedType
from pydantic import Extra, Field, BaseSettings, IPvAnyAddress from pydantic import Extra, Field, BaseSettings, IPvAnyAddress
from pydantic.env_settings import ( from pydantic.env_settings import (
DotenvType, DotenvType,
@ -44,19 +45,22 @@ class CustomEnvSettings(EnvSettingsSource):
env_vars = {**env_file_vars, **env_vars} env_vars = {**env_file_vars, **env_vars}
for field in settings.__fields__.values(): for field in settings.__fields__.values():
env_val: Optional[str] = None env_val: Union[str, None, UndefinedType] = Undefined
for env_name in field.field_info.extra["env_names"]: for env_name in field.field_info.extra["env_names"]:
env_val = env_vars.get(env_name) env_val = env_vars.get(env_name, Undefined)
if env_name in env_file_vars: if env_name in env_file_vars:
del env_file_vars[env_name] del env_file_vars[env_name]
if env_val is not None: if env_val is not Undefined:
break break
is_complex, allow_parse_failure = self.field_is_complex(field) is_complex, allow_parse_failure = self.field_is_complex(field)
if is_complex: if is_complex:
if env_val is None: if isinstance(env_val, UndefinedType):
# field is complex but no value found so far, try explode_env_vars
if env_val_built := self.explode_env_vars(field, env_vars): if env_val_built := self.explode_env_vars(field, env_vars):
d[field.alias] = env_val_built d[field.alias] = env_val_built
elif env_val is None:
d[field.alias] = env_val
else: else:
# field is complex and there's a value # field is complex and there's a value
# decode that as JSON, then add explode_env_vars # decode that as JSON, then add explode_env_vars
@ -74,7 +78,7 @@ class CustomEnvSettings(EnvSettingsSource):
) )
else: else:
d[field.alias] = env_val d[field.alias] = env_val
elif env_val is not None: elif not isinstance(env_val, UndefinedType):
# simplest case, field is not complex # simplest case, field is not complex
# we only need to add the value if it was found # we only need to add the value if it was found
d[field.alias] = env_val d[field.alias] = env_val

View File

@ -1,6 +1,8 @@
LOG_LEVEL=TRACE LOG_LEVEL=TRACE
NICKNAME=["test"] NICKNAME=["test"]
SUPERUSERS=["test", "fake:faketest"] SUPERUSERS=["test", "fake:faketest"]
API_TIMEOUT
SIMPLE_NONE
COMMON_OVERRIDE=new COMMON_OVERRIDE=new
CONFIG_FROM_ENV= CONFIG_FROM_ENV=
CONFIG_OVERRIDE=old CONFIG_OVERRIDE=old

View File

@ -20,6 +20,11 @@ async def test_init():
assert env == "test" assert env == "test"
config = nonebot.get_driver().config config = nonebot.get_driver().config
assert config.nickname == {"test"}
assert config.superusers == {"test", "fake:faketest"}
assert config.api_timeout is None
assert config.simple_none is None
assert config.config_from_env == {"test": "test"} assert config.config_from_env == {"test": "test"}
assert config.config_override == "new" assert config.config_override == "new"
assert config.config_from_init == "init" assert config.config_from_init == "init"