Skip to content

Commit 06d9a4a

Browse files
authored
Modernize tooling (#37)
* Replace black/isort by ruff * Type all the codebase
1 parent 63f4e38 commit 06d9a4a

File tree

6 files changed

+48
-58
lines changed

6 files changed

+48
-58
lines changed

.github/workflows/build-test-release.yml

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -40,16 +40,13 @@ jobs:
4040
run: hatch run pytest --color=yes
4141

4242
- name: mypy
43-
run: hatch run mypy structlog_gcp
43+
run: hatch run mypy
4444

45-
- name: ruff
46-
run: hatch run ruff check structlog_gcp
45+
- name: lint
46+
run: hatch run ruff check
4747

48-
- name: black
49-
run: hatch run black --check --diff structlog_gcp
50-
51-
- name: isort
52-
run: hatch run isort --check --diff structlog_gcp
48+
- name: format
49+
run: hatch run ruff format --diff
5350

5451
- name: Build
5552
run: hatch build --clean

Makefile

Lines changed: 4 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,13 @@
1-
DIRS = structlog_gcp
2-
3-
all: lint fmt
4-
5-
.PHONY: lint
6-
lint:
7-
$(MAKE) ruff
8-
$(MAKE) mypy
9-
10-
.PHONY: ruff
11-
ruff:
12-
hatch run ruff check $(DIRS)
1+
all: fmt mypy test
132

143
.PHONY: mypy
154
mypy:
16-
hatch run mypy $(DIRS)
5+
hatch run mypy
176

187
.PHONY: fmt
198
fmt:
20-
hatch run black $(DIRS)
21-
hatch run isort $(DIRS)
9+
hatch run ruff format
10+
hatch run ruff check --fix
2211

2312
.PHONY: test
2413
test:

pyproject.toml

Lines changed: 5 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
44

55
[project]
66
name = "structlog-gcp"
7-
description = 'A structlog set of processors to output as Google Cloud Logging format'
7+
description = "A structlog set of processors to output as Google Cloud Logging format"
88
readme = "README.md"
99
requires-python = ">=3.10"
1010
license = "MIT"
@@ -15,9 +15,9 @@ authors = [
1515
classifiers = [
1616
"Development Status :: 4 - Beta",
1717
"Programming Language :: Python",
18-
"Programming Language :: Python :: 3.9",
1918
"Programming Language :: Python :: 3.10",
2019
"Programming Language :: Python :: 3.11",
20+
"Programming Language :: Python :: 3.12",
2121
"Programming Language :: Python :: Implementation :: CPython",
2222
"Programming Language :: Python :: Implementation :: PyPy",
2323
]
@@ -36,9 +36,7 @@ path = "structlog_gcp/__about__.py"
3636

3737
[tool.hatch.envs.default]
3838
dependencies = [
39-
"black",
4039
"ruff",
41-
"isort",
4240
"mypy",
4341
"pytest",
4442
"pytest-cov",
@@ -67,20 +65,9 @@ omit = [
6765
"structlog_gcp/__about__.py",
6866
]
6967

70-
[tool.coverage.report]
71-
exclude_lines = [
72-
"no cov",
73-
"if __name__ == .__main__.:",
74-
"if TYPE_CHECKING:",
75-
]
76-
77-
[tool.isort]
78-
profile = "black"
79-
8068
[tool.mypy]
8169
strict = true
70+
files = ["structlog_gcp", "tests"]
8271

83-
[tool.ruff]
84-
ignore = [
85-
"E501",
86-
]
72+
[tool.ruff.lint]
73+
extend-select = ["I"]

tests/conftest.py

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,18 @@
1+
from typing import Callable, Generator
12
from unittest.mock import patch
23

34
import pytest
45
import structlog
6+
from _pytest.capture import CaptureFixture
7+
from structlog.typing import WrappedLogger
58

69
import structlog_gcp
710

811
from . import fakes
912

1013

1114
@pytest.fixture
12-
def mock_logger_env():
15+
def mock_logger_env() -> Generator[None, None, None]:
1316
with (
1417
patch(
1518
"structlog.processors.CallsiteParameterAdder",
@@ -24,7 +27,7 @@ def mock_logger_env():
2427

2528

2629
@pytest.fixture
27-
def logger(mock_logger_env):
30+
def logger(mock_logger_env: None) -> Generator[WrappedLogger, None, None]:
2831
"""Setup a logger for testing and return it"""
2932

3033
structlog.reset_defaults()
@@ -38,10 +41,10 @@ def logger(mock_logger_env):
3841

3942

4043
@pytest.fixture
41-
def stdout(capsys):
42-
def read():
44+
def stdout(capsys: CaptureFixture[str]) -> Callable[[], str]:
45+
def read() -> str:
4346
output = capsys.readouterr()
4447
assert "" == output.err
4548
return output.out
4649

47-
yield read
50+
return read

tests/fakes.py

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,18 @@
11
"""Fake implementations of structlog processors with side-effects"""
22

3+
from typing import Collection
4+
5+
from structlog.processors import CallsiteParameter
6+
from structlog.typing import EventDict, WrappedLogger
7+
38

49
class CallsiteParameterAdder:
5-
def __init__(self, *args, **kwargs):
10+
def __init__(self, parameters: Collection[CallsiteParameter]) -> None:
611
pass
712

8-
def __call__(self, logger, method_name, event_dict):
13+
def __call__(
14+
self, logger: WrappedLogger, method_name: str, event_dict: EventDict
15+
) -> EventDict:
916
event_dict["pathname"] = "/app/test.py"
1017
event_dict["lineno"] = 42
1118
event_dict["module"] = "test"
@@ -14,15 +21,19 @@ def __call__(self, logger, method_name, event_dict):
1421

1522

1623
class TimeStamper:
17-
def __init__(self, *args, **kwargs):
24+
def __init__(self, fmt: str) -> None:
1825
pass
1926

20-
def __call__(self, logger, method_name, event_dict):
27+
def __call__(
28+
self, logger: WrappedLogger, method_name: str, event_dict: EventDict
29+
) -> EventDict:
2130
event_dict["timestamp"] = "2023-04-01T08:00:00.000000Z"
2231
return event_dict
2332

2433

25-
def format_exc_info(logger, method_name, event_dict):
34+
def format_exc_info(
35+
logger: WrappedLogger, method_name: str, event_dict: EventDict
36+
) -> EventDict:
2637
exc_info = event_dict.pop("exc_info", None)
2738
if exc_info:
2839
event_dict["exception"] = "Traceback blabla"

tests/test_log.py

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,17 @@
11
import datetime
22
import json
3+
from typing import Callable
34
from unittest.mock import patch
45

56
import structlog
7+
from structlog.typing import WrappedLogger
68

79
import structlog_gcp
810

11+
T_stdout = Callable[[], str]
912

10-
def test_normal(stdout, logger):
13+
14+
def test_normal(stdout: T_stdout, logger: WrappedLogger) -> None:
1115
logger.info("test")
1216

1317
msg = json.loads(stdout())
@@ -25,7 +29,7 @@ def test_normal(stdout, logger):
2529
assert msg == expected
2630

2731

28-
def test_error(stdout, logger):
32+
def test_error(stdout: T_stdout, logger: WrappedLogger) -> None:
2933
try:
3034
1 / 0
3135
except ZeroDivisionError:
@@ -60,7 +64,7 @@ def test_error(stdout, logger):
6064
assert msg == expected
6165

6266

63-
def test_service_context_default(stdout, logger):
67+
def test_service_context_default(stdout: T_stdout, logger: WrappedLogger) -> None:
6468
try:
6569
1 / 0
6670
except ZeroDivisionError:
@@ -75,7 +79,7 @@ def test_service_context_default(stdout, logger):
7579

7680

7781
@patch.dict("os.environ", {"K_SERVICE": "test-service", "K_REVISION": "test-version"})
78-
def test_service_context_envvar(stdout, mock_logger_env):
82+
def test_service_context_envvar(stdout: T_stdout, mock_logger_env: None) -> None:
7983
processors = structlog_gcp.build_processors()
8084
structlog.configure(processors=processors)
8185
logger = structlog.get_logger()
@@ -93,7 +97,7 @@ def test_service_context_envvar(stdout, mock_logger_env):
9397
}
9498

9599

96-
def test_service_context_custom(stdout, mock_logger_env):
100+
def test_service_context_custom(stdout: T_stdout, mock_logger_env: None) -> None:
97101
processors = structlog_gcp.build_processors(
98102
service="my-service",
99103
version="deadbeef",
@@ -114,7 +118,7 @@ def test_service_context_custom(stdout, mock_logger_env):
114118
}
115119

116120

117-
def test_extra_labels(stdout, logger):
121+
def test_extra_labels(stdout: T_stdout, logger: WrappedLogger) -> None:
118122
logger.info(
119123
"test",
120124
test1="test1",
@@ -135,7 +139,6 @@ def test_extra_labels(stdout, logger):
135139
"severity": "INFO",
136140
"time": "2023-04-01T08:00:00.000000Z",
137141
"message": "test",
138-
139142
# This should be parsed automatically by Cloud Logging into dedicated keys and saved into a JSON payload.
140143
# See: https://cloud.google.com/logging/docs/structured-logging#special-payload-fields
141144
"test1": "test1",

0 commit comments

Comments
 (0)