Skip to content

Commit

Permalink
feature(loader): Removed __yaml_files__ and __yaml_reload__.
Browse files Browse the repository at this point in the history
Removed tests concerning their use.
Moved ``CreateYamlSettings`` to ``settings.py`` and validators to ``loader.py``.
Added ``util.py``.
  • Loading branch information
acederberg committed Jul 16, 2024
1 parent 9794b6f commit 6a78363
Show file tree
Hide file tree
Showing 5 changed files with 255 additions and 275 deletions.
92 changes: 48 additions & 44 deletions tests/test_basic.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,33 +35,35 @@ def create_settings(reload: Any | None = None, files: Any | None = None) -> Any:
"Settings",
(BaseYamlSettings,),
{
"__yaml_reload__": reload or False,
"__yaml_files__": files or set(file_dummies),
"model_config": YamlSettingsConfigDict(
yaml_reload=reload if reload is not None else False,
yaml_files=files or set(file_dummies),
)
},
)

Settings = create_settings()
yaml_settings = CreateYamlSettings(Settings)
yaml_settings()

assert not yaml_settings.reload, "Should not reload."
assert not yaml_settings.settings_cls.model_config.get(
"yaml_reload"
), "Should not reload."

# Malform a file.
bad: Path = Settings.__yaml_files__.pop()
bad: Path = Settings.model_config["yaml_files"].pop()
with bad.open("w") as file:
yaml.dump([], file)

# # NOTE: Loading should not be an error as the files should not be reloaded.
# NOTE: Loading should not be an error as the files should not be reloaded.
yaml_settings()
#
# # NOTE: Test reloading with bad file.
# # This could be called without the args as mutation is visible
# # to fn.
Settings = create_settings(reload=False)
yaml_settings = CreateYamlSettings(Settings)

# NOTE: Test reloading with bad file.
# This could be called without the args as mutation is visible
# to fn.
Settings = create_settings(reload=False)
with pytest.raises(ValueError) as err:
yaml_settings()
yaml_settings = CreateYamlSettings(Settings)

assert bad.as_posix() in str(err.value), "Missing required path in message."

Expand All @@ -71,37 +73,37 @@ def create_settings(reload: Any | None = None, files: Any | None = None) -> Any:
yaml_settings()

def from_model_config(
self, **kwargs: Any
self, *, load: bool = False, **kwargs: Any
) -> tuple[CreateYamlSettings, type[BaseYamlSettings]]:
Settings = type(
"Settings",
(BaseYamlSettings,),
{"model_config": YamlSettingsConfigDict(**kwargs)}, # type: ignore
)
return CreateYamlSettings(Settings), Settings

def test_dunders_have_priority(self) -> None:
init_reload = True
foo_bar: Path = Path("foo-bar.yaml")
yaml_settings, Settings = self.from_model_config(
yaml_files={foo_bar},
yaml_reload=init_reload,
)

default = DEFAULT_YAML_FILE_CONFIG_DICT
assert yaml_settings.files == {foo_bar: default}
assert yaml_settings.reload == init_reload

final_files: set[Path] = {Path("spam-eggs.yaml")}
OverwriteSettings = type(
"OverwriteSettings",
(Settings,),
{"__yaml_files__": final_files},
)
yaml_settings = CreateYamlSettings(OverwriteSettings)

assert yaml_settings.files == {Path("spam-eggs.yaml"): default}
assert yaml_settings.reload == init_reload
return CreateYamlSettings(Settings, load=load), Settings

# def test_dunders_have_priority(self) -> None:
# init_reload = True
# foo_bar: Path = Path("foo-bar.yaml")
# yaml_settings, Settings = self.from_model_config(
# yaml_files={foo_bar},
# yaml_reload=init_reload,
# )
#
# default = DEFAULT_YAML_FILE_CONFIG_DICT
# assert yaml_settings.files == {foo_bar: default}
# assert yaml_settings.reload == init_reload
#
# final_files: set[Path] = {Path("spam-eggs.yaml")}
# OverwriteSettings = type(
# "OverwriteSettings",
# (Settings,),
# {"__yaml_files__": final_files},
# )
# yaml_settings = CreateYamlSettings(OverwriteSettings)
#
# assert yaml_settings.files == {Path("spam-eggs.yaml"): default}
# assert yaml_settings.reload == init_reload

@pytest.mark.parametrize(
"yaml_files",
Expand All @@ -114,10 +116,12 @@ def test_dunders_have_priority(self) -> None:
def test_hydration_yaml_files(self, yaml_files: Any) -> None:
make, _ = self.from_model_config(yaml_files=yaml_files)

assert len(make.files) == 1, "Exactly one file."
assert isinstance(make.files, dict), "Files should hydrate to a ``dict``."
assert len(make.yaml_files_configs) == 1, "Exactly one file."
assert isinstance(
make.yaml_files_configs, dict
), "Files should hydrate to a ``dict``."
assert (
foo := make.files.get(Path("foo.yaml"))
foo := make.yaml_files_configs.get(Path("foo.yaml"))
), "An entry should exist under key ``Path('foo.yaml')``."
assert isinstance(foo, dict), "`foo` must be a dictionary."
assert foo.get("required"), "Required is always ``True`` by default."
Expand All @@ -133,7 +137,7 @@ def test_yaml_not_required(self) -> None:
),
},
)
if not make.files.get(Path("foo.yaml")):
if not make.yaml_files_configs.get(Path("foo.yaml")):
raise ValueError
make.load()

Expand Down Expand Up @@ -161,7 +165,7 @@ def test_envvar(self, tmp_path: pathlib.Path) -> None:
)
}
)
assert set(make.files.keys()) == {path_default}
assert set(make.yaml_files_configs.keys()) == {path_default}

class SettingsModel(BaseModel):
whatever: Annotated[str, Field(default="whatever")]
Expand All @@ -183,7 +187,7 @@ class Settings(SettingsModel, _Settings): ... # type: ignore
with mock.patch.dict(os.environ, {"FOO_PATH": str(path_other)}, clear=True):
filepath_resolved = resolve_filepaths(
path_default,
make.files[path_default],
make.yaml_files_configs[path_default],
)
assert filepath_resolved == path_other

Expand All @@ -194,7 +198,7 @@ class Settings(SettingsModel, _Settings): ... # type: ignore
with mock.patch.dict(os.environ, {"FOO_PATH": ""}, clear=True):
filepath_resolved = resolve_filepaths(
path_default,
make.files[path_default],
make.yaml_files_configs[path_default],
)
assert filepath_resolved == path_default

Expand Down
Loading

0 comments on commit 6a78363

Please sign in to comment.