Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
121 changes: 67 additions & 54 deletions poetry.lock

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,14 @@ description = ""
authors = ["r-spiewak <63987228+r-spiewak@users.noreply.github.com>"]
readme = "README.md"
packages = [{include = "python_template", from = "src"}]
include = ["src/python_template/config/*.yaml"]

[tool.poetry.dependencies]
python = "^3.11"
typer = "^0.12.3"
pandas = "^2.2.2"
pytest-env = "^1.1.5"
pyyaml = "^6.0.2"

[tool.poetry.group.dev.dependencies]
autoflake = "^2.2.1"
Expand All @@ -23,6 +25,7 @@ coverage = "^7.4.1"
pre-commit = "^3.6.1"
pytest-testdox = "^3.1.0"
pytest-mock = "^3.14.0"
types-pyyaml = "^6.0.12.20250516"

[tool.black]
line-length = 79
Expand Down
3 changes: 3 additions & 0 deletions src/python_template/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
"""This is what the module exports."""

from .config import config
3 changes: 3 additions & 0 deletions src/python_template/config/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
"""Expose Config class to module."""

from .load_config import config
1 change: 1 addition & 0 deletions src/python_template/config/defaults.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
debug_prints: true
24 changes: 24 additions & 0 deletions src/python_template/config/load_config.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
"""Contains a class with a config loaded from a file."""

from types import SimpleNamespace

import yaml

from python_template.constants import CONFIG_PATH


def dict_to_namespace(d):
"""Turn a dict into a namespace (so its members can be accessed
with dot notation like for a class)."""
return SimpleNamespace(
**{
k: dict_to_namespace(v) if isinstance(v, dict) else v
for k, v in d.items()
}
)


with open(str(CONFIG_PATH), "r", encoding="utf8") as f:
config_dict = yaml.safe_load(f)

config = dict_to_namespace(config_dict)
6 changes: 6 additions & 0 deletions src/python_template/constants.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
"""This file contains module constants."""

from pathlib import Path

CONFIG_DIR = Path(__file__).parent / "config"
CONFIG_PATH = CONFIG_DIR / "defaults.yaml"
13 changes: 9 additions & 4 deletions src/python_template/logger/logger.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@
from pathlib import Path
from typing import cast

from python_template import config

DEBUG_PRINTS = config.debug_prints


class DebugCategory(IntEnum):
"""Debug category levels for logging, from least to
Expand Down Expand Up @@ -195,10 +199,11 @@ def __init__(
self.logger_filename.parents[0].mkdir(parents=True, exist_ok=True)

logger_key = str(self.logger_filename.absolute().resolve())
print(f"Using logger_key: {logger_key}")
print(
f"Existing keys in _loggers: {list(LoggerMixin._loggers.keys())}"
)
if DEBUG_PRINTS:
print(f"Using logger_key: {logger_key}")
print(
f"Existing keys in _loggers: {list(LoggerMixin._loggers.keys())}"
)
if logger_key in LoggerMixin._loggers:
self.logger: CategoryLogger = LoggerMixin._loggers[logger_key]
if LoggerMixin._debug_enabled:
Expand Down
4 changes: 3 additions & 1 deletion src/python_template/utils/split_args_for_inits.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@
from collections import defaultdict
from typing import Any, get_type_hints

DEBUG_PRINTS = True
from python_template import config

DEBUG_PRINTS = config.debug_prints
LEFTOVERS = "leftovers"


Expand Down
Empty file added tests/test_config/__init__.py
Empty file.
40 changes: 40 additions & 0 deletions tests/test_config/test_load_config.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
"""This file contains tests for the load_config module."""

import types

import yaml

from python_template import config
from python_template.config import load_config
from python_template.constants import CONFIG_PATH


def test_config_file_exists_and_loadable():
"""Test that the default config file exists and can be loaded."""
assert CONFIG_PATH.exists(), "Config file is missing"
with CONFIG_PATH.open("r", encoding="utf8") as f:
data = yaml.safe_load(f)
assert isinstance(data, dict), "Config must be a dictionary"


def test_config_dict_to_namespace_recursive():
"""Test that the namespace returned by load_config goes
recursively into nested dicts."""
one = 1
two = 2
three = 3
sample_dict = {
"a": one,
"b": {"c": two, "d": {"e": three}},
}
ns = load_config.dict_to_namespace(sample_dict)
assert isinstance(ns, types.SimpleNamespace)
assert ns.a == one
assert ns.b.c == two
assert ns.b.d.e == three


def test_loaded_config_is_namespace():
"""Tests that load_config returns a namespace."""
assert isinstance(config, types.SimpleNamespace)
assert hasattr(config, "debug_prints")