Skip to content

Commit 9f6db68

Browse files
committed
Fixing up CI and mutations
1 parent 09235ae commit 9f6db68

5 files changed

Lines changed: 31 additions & 30 deletions

File tree

.github/workflows/pytest.yaml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,10 @@ jobs:
1212
runs-on: ${{ matrix.os }}
1313
strategy:
1414
matrix:
15-
os: [ubuntu-latest, macos-latest, windows-latest]
15+
# pytest-forked does not work on windows and we currently use it for isolation
16+
# of logging configs as logging.dictConfig has a setting to not disable old loggers
17+
# but, does seem to trample old handlers, filters and formatters
18+
os: [ubuntu-latest, macos-latest]
1619
python-version: ["3.9", "3.10", "3.11", "pypy3.9", "pypy3.10"]
1720
exclude:
1821
- os: macos-latest

annotated_logger/__init__.py

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -87,12 +87,12 @@ class AnnotatedClass(Protocol[C_co]):
8787
Annotations = dict[str, Any]
8888

8989

90-
DEFAULT_LOGGING_CONFIG = { # pragma: no mutate
90+
DEFAULT_LOGGING_CONFIG = {
9191
"version": 1,
92-
"disable_existing_loggers": False,
92+
"disable_existing_loggers": False, # pragma: no mutate
9393
"filters": {
9494
"annotated_filter": {
95-
"annotated_filter": True,
95+
"annotated_filter": True, # pragma: no mutate
9696
}
9797
},
9898
"handlers": {
@@ -104,19 +104,19 @@ class AnnotatedClass(Protocol[C_co]):
104104
},
105105
"formatters": {
106106
"annotated_formatter": {
107-
"class": "pythonjsonlogger.jsonlogger.JsonFormatter",
107+
"class": "pythonjsonlogger.jsonlogger.JsonFormatter", # pragma: no mutate
108108
# Note that this format string uses `time` and `level` which are
109109
# set by the renamer plugin. Because the handler is using the
110110
# annotated_filter the plugings will be run and the fields will be renamed
111-
"format": "{created} {levelname} {name} {message}",
111+
"format": "{created} {levelname} {name} {message}", # pragma: no mutate
112112
"style": "{",
113113
},
114114
},
115115
"loggers": {
116116
"annotated_logger": {
117117
"level": "DEBUG",
118118
"handlers": ["annotated_handler"],
119-
"propagate": False,
119+
"propagate": False, # pragma: no mutate
120120
},
121121
},
122122
}
@@ -337,7 +337,6 @@ def __init__( # noqa: PLR0913
337337
log_level: int = logging.INFO,
338338
name: str = "annotated_logger",
339339
config: dict[str, Any] | Literal[False] | None = None,
340-
# TODO: boolean for correlation_id and then auto generate it
341340
) -> None:
342341
"""Store the settings.
343342

annotated_logger/mocks.py

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -106,18 +106,14 @@ def _check_record_matches(
106106
record: logging.LogRecord,
107107
) -> list[str]:
108108
differences = []
109-
if "levelname" in record.__dict__:
110-
level = record.levelname
111-
elif "level" in record.__dict__:
112-
level = record.level # pyright: ignore[reportAttributeAccessIssue]
113-
# If you have removed levelname and levelno and didn't add level... good luck
114-
else:
115-
level = {
116-
logging.DEBUG: "DEBUG",
117-
logging.INFO: "INFO",
118-
logging.WARNING: "WARNING",
119-
logging.ERROR: "ERROR",
120-
}[record.levelno]
109+
# `levelname` is often renamed. But, `levelno` shouldn't be touched as often
110+
# So, don't try to guess what the level name is, just use the levelno.
111+
level = {
112+
logging.DEBUG: "DEBUG",
113+
logging.INFO: "INFO",
114+
logging.WARNING: "WARNING",
115+
logging.ERROR: "ERROR",
116+
}[record.levelno]
121117
actual = {
122118
"level": level,
123119
"msg": record.msg,

example/logging_config.py

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -40,11 +40,11 @@
4040
# But, if you want to do that you are likely better off
4141
# using a filter not associated with an AnnotatedLogger
4242
# like the `logging_config.logger_filter_parens` below
43-
"annotations": {"decorated": False},
43+
"annotations": {"config_based_filter": True},
4444
},
4545
"logging_config.logger_filter_parens": {
4646
"()": AnnotatedFilter,
47-
"annotations": {"decorated": False},
47+
"annotations": {"decorated": False, "class_based_filter": True},
4848
"class_annotations": {},
4949
"runtime_annotations": {"custom_runtime": lambda _record: True},
5050
"plugins": [BasePlugin()],
@@ -80,10 +80,9 @@
8080
"formatters": {
8181
"logging_config.annotated_formatter": {
8282
"class": "pythonjsonlogger.jsonlogger.JsonFormatter",
83-
# Note that this format string uses `time` and `level` which are
84-
# set by the renamer plugin. Because the handler is using the
85-
# annotated_filter the plugings will be run and the fields will be renamed
86-
# This also pulls the `runtime` annotation to a specific place in the log
83+
# Note that this format string uses `time` which is set by the renamer
84+
# plugin. It also has `lvl` which is there strictly to test our fallback
85+
# to using `levelno` in the mocks to determine level.
8786
"format": "{time} {lvl} {name} {runtime} {message}",
8887
"style": "{",
8988
},
@@ -92,7 +91,7 @@
9291
"style": "{",
9392
},
9493
"logging_config.long_formatter": {
95-
"format": "{level} Long message, may be split {message}",
94+
"format": "{lvl} Long message, may be split {message}",
9695
# 3.12 added support for defaults in dict configs
9796
# With that we can add the format and defaults below
9897
# for a more realistic example. Not all of the messages
@@ -143,7 +142,7 @@ def runtime(_record: logging.LogRecord) -> str:
143142
annotated_logger = AnnotatedLogger(
144143
annotations={"hostname": "my-host"},
145144
runtime_annotations={"runtime": runtime},
146-
plugins=[RenamerPlugin(time="created", level="levelname")],
145+
plugins=[RenamerPlugin(time="created", lvl="levelname")],
147146
log_level=logging.DEBUG,
148147
max_length=200,
149148
name="annotated_logger.logging_config",

test/test_logging_config.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,12 @@ def test_base_logging(self, annotated_logger_mock):
2222
annotated_logger_mock.assert_logged(
2323
level,
2424
f"this is {level}",
25-
present={"decorated": False},
26-
absent=["weird"],
25+
present={
26+
"decorated": False,
27+
"config_based_filter": True,
28+
"class_based_filter": True,
29+
},
30+
absent=["weird", "hostname"],
2731
)
2832

2933
def test_annotated_logging(self, annotated_logger_mock: AnnotatedLogMock):

0 commit comments

Comments
 (0)