Add an implicit-pkg-path-as-logger-name test
A bit of test driven dev to anticipate support of `.log.get_logger()` usage such that it can be called from arbitrary sub-modules, themselves embedded in arbitrary sub-pkgs, of some project; the when not provided, the `sub_name` passed to the `Logger.getChild(<sub_name>)` will be set as the sub-pkg path "down to" the calling module. IOW if you call something like, `log = tractor.log.get_logger(pkg_name='mypylib')` from some `submod.py` in a project-dir that looks like, mypylib/ mod.py subpkg/ submod.py <- calling module the `log: StackLevelAdapter` child-`Logger` instance will have a `.name: str = 'mypylib.subpkg'`, discluding the `submod` part since this already rendered as the `{filename}` header in `log.LOG_FORMAT`. Previously similar behaviour would be obtained by passing `get_logger(name=__name__)` in the calling module and so much so it motivated me to make this the default, presuming we can introspect for the info. Impl deats, - duplicated a `load_module_from_path()` from `modden` to load the `testdir` rendered py project dir from its path. |_should prolly factor it down to this lib anyway bc we're going to need it for hot code reload? (well that and `watchfiles` Bp) - in each of `mod.py` and `submod.py` render the `get_logger()` code sin `name`, expecting the (coming shortly) implicit introspection feat to do this. - do `.name` and `.parent` checks against expected sub-logger values from `StackLevelAdapter.logger.getChildren()`.log_sys_testing
parent
b4bacbc766
commit
093ad02beb
|
@ -2,16 +2,29 @@
|
||||||
`tractor.log`-wrapping unit tests.
|
`tractor.log`-wrapping unit tests.
|
||||||
|
|
||||||
'''
|
'''
|
||||||
|
import importlib
|
||||||
|
from pathlib import Path
|
||||||
|
import shutil
|
||||||
|
import sys
|
||||||
|
from types import ModuleType
|
||||||
|
|
||||||
|
import pytest
|
||||||
import tractor
|
import tractor
|
||||||
|
|
||||||
|
|
||||||
def test_root_pkg_not_duplicated():
|
def test_root_pkg_not_duplicated_in_logger_name():
|
||||||
|
'''
|
||||||
|
When both `_root_name` and `name` are passed and they have
|
||||||
|
a common `<root_name>.< >` prefix, ensure that it is not
|
||||||
|
duplicated in the child's `StackLevelAdapter.name: str`.
|
||||||
|
|
||||||
|
'''
|
||||||
project_name: str = 'pylib'
|
project_name: str = 'pylib'
|
||||||
pkg_path: str = 'pylib.subpkg.mod'
|
pkg_path: str = 'pylib.subpkg.mod'
|
||||||
|
|
||||||
log = tractor.log.get_logger(
|
proj_log = tractor.log.get_logger(
|
||||||
_root_name=project_name,
|
_root_name=project_name,
|
||||||
|
mk_sublog=False,
|
||||||
)
|
)
|
||||||
|
|
||||||
sublog = tractor.log.get_logger(
|
sublog = tractor.log.get_logger(
|
||||||
|
@ -19,11 +32,111 @@ def test_root_pkg_not_duplicated():
|
||||||
name=pkg_path,
|
name=pkg_path,
|
||||||
)
|
)
|
||||||
|
|
||||||
assert log is not sublog
|
assert proj_log is not sublog
|
||||||
assert sublog.name.count(log.name) == 1
|
assert sublog.name.count(proj_log.name) == 1
|
||||||
assert 'mod' not in sublog.name
|
assert 'mod' not in sublog.name
|
||||||
|
|
||||||
|
|
||||||
|
# ?TODO, move this into internal libs?
|
||||||
|
# -[ ] we already use it in `modden.config._pymod` as well
|
||||||
|
def load_module_from_path(
|
||||||
|
path: Path,
|
||||||
|
module_name: str|None = None,
|
||||||
|
) -> ModuleType:
|
||||||
|
'''
|
||||||
|
Taken from SO,
|
||||||
|
https://stackoverflow.com/a/67208147
|
||||||
|
|
||||||
|
which is based on stdlib docs,
|
||||||
|
https://docs.python.org/3/library/importlib.html#importing-a-source-file-directly
|
||||||
|
|
||||||
|
'''
|
||||||
|
module_name = module_name or path.stem
|
||||||
|
spec = importlib.util.spec_from_file_location(
|
||||||
|
module_name,
|
||||||
|
str(path),
|
||||||
|
)
|
||||||
|
module = importlib.util.module_from_spec(spec)
|
||||||
|
sys.modules[module_name] = module
|
||||||
|
spec.loader.exec_module(module)
|
||||||
|
return module
|
||||||
|
|
||||||
|
|
||||||
|
def test_implicit_mod_name_applied_for_child(
|
||||||
|
testdir: pytest.Pytester,
|
||||||
|
):
|
||||||
|
'''
|
||||||
|
Verify that when `.log.get_logger(pkg_name='pylib')` is called
|
||||||
|
from a given sub-mod from within the `pylib` pkg-path, we
|
||||||
|
implicitly set the equiv of `name=__name__` from the caller's
|
||||||
|
module.
|
||||||
|
|
||||||
|
'''
|
||||||
|
proj_name: str = 'snakelib'
|
||||||
|
mod_code: str = (
|
||||||
|
f'import tractor\n'
|
||||||
|
f'\n'
|
||||||
|
f'log = tractor.log.get_logger(_root_name="{proj_name}")\n'
|
||||||
|
)
|
||||||
|
|
||||||
|
# create a sub-module for each pkg layer
|
||||||
|
_lib = testdir.mkpydir(proj_name)
|
||||||
|
pkg: Path = Path(_lib)
|
||||||
|
subpkg: Path = pkg / 'subpkg'
|
||||||
|
subpkg.mkdir()
|
||||||
|
|
||||||
|
pkgmod: Path = subpkg / "__init__.py"
|
||||||
|
pkgmod.touch()
|
||||||
|
|
||||||
|
_submod: Path = testdir.makepyfile(
|
||||||
|
_mod=mod_code,
|
||||||
|
)
|
||||||
|
|
||||||
|
pkg_mod = pkg / 'mod.py'
|
||||||
|
pkg_subpkg_submod = subpkg / 'submod.py'
|
||||||
|
shutil.copyfile(
|
||||||
|
_submod,
|
||||||
|
pkg_mod,
|
||||||
|
)
|
||||||
|
shutil.copyfile(
|
||||||
|
_submod,
|
||||||
|
pkg_subpkg_submod,
|
||||||
|
)
|
||||||
|
testdir.chdir()
|
||||||
|
|
||||||
|
# XXX NOTE, once the "top level" pkg mod has been
|
||||||
|
# imported, we can then use `import` syntax to
|
||||||
|
# import it's sub-pkgs and modules.
|
||||||
|
pkgmod = load_module_from_path(
|
||||||
|
Path(pkg / '__init__.py'),
|
||||||
|
module_name=proj_name,
|
||||||
|
)
|
||||||
|
pkg_root_log = tractor.log.get_logger(
|
||||||
|
_root_name=proj_name,
|
||||||
|
mk_sublog=False,
|
||||||
|
)
|
||||||
|
assert pkg_root_log.name == proj_name
|
||||||
|
assert not pkg_root_log.logger.getChildren()
|
||||||
|
|
||||||
|
from snakelib import mod
|
||||||
|
assert mod.log.name == proj_name
|
||||||
|
|
||||||
|
from snakelib.subpkg import submod
|
||||||
|
assert (
|
||||||
|
submod.log.name
|
||||||
|
==
|
||||||
|
submod.__package__ # ?TODO, use this in `.get_logger()` instead?
|
||||||
|
==
|
||||||
|
f'{proj_name}.subpkg'
|
||||||
|
)
|
||||||
|
|
||||||
|
sub_logs = pkg_root_log.logger.getChildren()
|
||||||
|
assert len(sub_logs) == 1 # only one nested sub-pkg module
|
||||||
|
assert submod.log.logger in sub_logs
|
||||||
|
|
||||||
|
# breakpoint()
|
||||||
|
|
||||||
|
|
||||||
# TODO, moar tests against existing feats:
|
# TODO, moar tests against existing feats:
|
||||||
# ------ - ------
|
# ------ - ------
|
||||||
# - [ ] color settings?
|
# - [ ] color settings?
|
||||||
|
|
Loading…
Reference in New Issue