Skip to content

Commit cc49b7c

Browse files
committed
chore: Add encoding="utf8" everywhere
1 parent c7bfe4b commit cc49b7c

9 files changed

Lines changed: 64 additions & 45 deletions

File tree

src/griffe/_internal/cli.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ def __call__(self, *args: Any, **kwargs: Any) -> None: # noqa: ARG002
5959

6060
def _print_data(data: str, output_file: str | IO | None) -> None:
6161
if isinstance(output_file, str):
62-
with open(output_file, "w") as fd: # noqa: PTH123
62+
with open(output_file, "w", encoding="utf8") as fd: # noqa: PTH123
6363
print(data, file=fd)
6464
else:
6565
if output_file is None:

src/griffe/_internal/finder.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -485,7 +485,7 @@ def _handle_editable_module(path: Path) -> list[_SP]:
485485
# Support for how 'setuptools' writes these files:
486486
# example line: `MAPPING = {'griffe': '/media/data/dev/griffe/src/griffe', 'briffe': '/media/data/dev/griffe/src/briffe'}`.
487487
# with annotation: `MAPPING: dict[str, str] = {...}`.
488-
parsed_module = ast.parse(path.read_text())
488+
parsed_module = ast.parse(path.read_text(encoding="utf8"))
489489
for node in parsed_module.body:
490490
if isinstance(node, ast.Assign):
491491
target = node.targets[0]
@@ -499,7 +499,7 @@ def _handle_editable_module(path: Path) -> list[_SP]:
499499
# Support for how 'meson-python' writes these files:
500500
# example line: `install({'package', 'module1'}, '/media/data/dev/griffe/build/cp311', ["path"], False)`.
501501
# Compiled modules then found in the cp311 folder, under src/package.
502-
parsed_module = ast.parse(path.read_text())
502+
parsed_module = ast.parse(path.read_text(encoding="utf8"))
503503
for node in parsed_module.body:
504504
if (
505505
isinstance(node, ast.Expr)

src/griffe/_internal/git.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,14 @@ def _normalize(value: str) -> str:
3434

3535

3636
def _git(*args: str, check: bool = True) -> str:
37-
process = subprocess.run(["git", *args], check=False, text=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
37+
process = subprocess.run(
38+
["git", *args],
39+
check=False,
40+
text=True,
41+
stdout=subprocess.PIPE,
42+
stderr=subprocess.STDOUT,
43+
encoding="utf8",
44+
)
3845
if check and process.returncode != 0:
3946
raise GitError(process.stdout.strip())
4047
return process.stdout.strip()

src/griffe/_internal/tests.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ def temporary_pyfile(code: str, *, module_name: str = "module") -> Iterator[tupl
6464
"""
6565
with tempfile.TemporaryDirectory(prefix=_TMPDIR_PREFIX) as tmpdir:
6666
tmpfile = Path(tmpdir) / f"{module_name}.py"
67-
tmpfile.write_text(dedent(code))
67+
tmpfile.write_text(dedent(code), encoding="utf8")
6868
yield module_name, tmpfile
6969

7070

@@ -108,7 +108,7 @@ def temporary_pypackage(
108108
current_path = package_path
109109
for part in Path(module_name).parts:
110110
if part.endswith((".py", ".pyi")):
111-
current_path.joinpath(part).write_text(dedent(module_contents))
111+
current_path.joinpath(part).write_text(dedent(module_contents), encoding="utf8")
112112
else:
113113
current_path /= part
114114
current_path.mkdir(**mkdir_kwargs)

tests/test_encoders.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,7 @@ def test_json_schema() -> None:
165165
module = loader.load("griffe")
166166
loader.resolve_aliases()
167167
data = json.loads(module.as_json(full=True))
168-
with open("docs/schema.json") as f: # noqa: PTH123
168+
with open("docs/schema.json", encoding="utf8") as f: # noqa: PTH123
169169
schema = json.load(f)
170170
validate(data, schema)
171171

@@ -186,7 +186,7 @@ def func[**P, T, *R](arg: T, *args: P.args, **kwargs: P.kwargs) -> tuple[*R]: pa
186186
""",
187187
) as module:
188188
data = json.loads(module.as_json(full=True))
189-
with open("docs/schema.json") as f: # noqa: PTH123
189+
with open("docs/schema.json", encoding="utf8") as f: # noqa: PTH123
190190
schema = json.load(f)
191191
validate(data, schema)
192192

@@ -206,6 +206,6 @@ def func[**P, T, *R](arg: T, *args: P.args, **kwargs: P.kwargs) -> tuple[*R]: pa
206206
""",
207207
) as module:
208208
data = json.loads(module.as_json(full=True))
209-
with open("docs/schema.json") as f: # noqa: PTH123
209+
with open("docs/schema.json", encoding="utf8") as f: # noqa: PTH123
210210
schema = json.load(f)
211211
validate(data, schema)

tests/test_finder.py

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,8 @@ def test_find_pkg_style_namespace_packages(statement: str) -> None:
6464
temporary_pypackage("namespace/package1") as tmp_package1,
6565
temporary_pypackage("namespace/package2") as tmp_package2,
6666
):
67-
tmp_package1.path.parent.joinpath("__init__.py").write_text(statement)
68-
tmp_package2.path.parent.joinpath("__init__.py").write_text(statement)
67+
tmp_package1.path.parent.joinpath("__init__.py").write_text(statement, encoding="utf8")
68+
tmp_package2.path.parent.joinpath("__init__.py").write_text(statement, encoding="utf8")
6969
finder = ModuleFinder(search_paths=[tmp_package1.tmpdir, tmp_package2.tmpdir])
7070
_, package = finder.find_spec("namespace")
7171
assert package.name == "namespace"
@@ -91,6 +91,7 @@ def test_pth_file_handling(tmp_path: Path) -> None:
9191
tests
9292
""",
9393
),
94+
encoding="utf8",
9495
)
9596
paths = [sp.path for sp in _handle_pth_file(pth_file)]
9697
assert paths == [Path("tests")]
@@ -110,6 +111,7 @@ def test_pth_file_handling_with_semi_colon(tmp_path: Path) -> None:
110111
import thing; import\tthing; /doesnotexist; tests
111112
""",
112113
),
114+
encoding="utf8",
113115
)
114116
paths = [sp.path for sp in _handle_pth_file(pth_file)]
115117
assert paths == [Path("tests")]
@@ -123,7 +125,7 @@ def test_editables_file_handling(tmp_path: Path, editable_file_name: str) -> Non
123125
tmp_path: Pytest fixture.
124126
"""
125127
pth_file = tmp_path / editable_file_name
126-
pth_file.write_text("hello\nF.map_module('griffe', 'src/griffe/__init__.py')")
128+
pth_file.write_text("hello\nF.map_module('griffe', 'src/griffe/__init__.py')", encoding="utf8")
127129
paths = [sp.path for sp in _handle_editable_module(pth_file)]
128130
assert paths == [Path("src")]
129131

@@ -137,7 +139,7 @@ def test_setuptools_file_handling(tmp_path: Path, annotation: str) -> None:
137139
annotation: The type annotation of the MAPPING variable.
138140
"""
139141
pth_file = tmp_path / "__editable__whatever.py"
140-
pth_file.write_text(f"hello\nMAPPING{annotation} = {{'griffe': 'src/griffe'}}")
142+
pth_file.write_text(f"hello\nMAPPING{annotation} = {{'griffe': 'src/griffe'}}", encoding="utf8")
141143
paths = [sp.path for sp in _handle_editable_module(pth_file)]
142144
assert paths == [Path("src")]
143145

@@ -155,6 +157,7 @@ def test_setuptools_file_handling_multiple_paths(tmp_path: Path, annotation: str
155157
"hello=1\n"
156158
f"MAPPING{annotation} = {{\n'griffe':\n 'src1/griffe', 'briffe':'src2/briffe'}}\n"
157159
"def printer():\n print(hello)",
160+
encoding="utf8",
158161
)
159162
paths = [sp.path for sp in _handle_editable_module(pth_file)]
160163
assert paths == [Path("src1"), Path("src2")]
@@ -169,6 +172,7 @@ def test_scikit_build_core_file_handling(tmp_path: Path) -> None:
169172
pth_file = tmp_path / "_whatever_editable.py"
170173
pth_file.write_text(
171174
"hello=1\ninstall({'whatever': '/path/to/whatever'}, {'whatever.else': '/else'}, None, False, True)",
175+
encoding="utf8",
172176
)
173177
# The second dict is not handled: scikit-build-core puts these files
174178
# in a location that Griffe won't be able to discover anyway
@@ -188,6 +192,7 @@ def test_meson_python_file_handling(tmp_path: Path) -> None:
188192
pth_file.write_text(
189193
# The path in argument 2 suffixed with src must exist, so we pass `.`.
190194
"hello=1\ninstall({'griffe', 'hello'}, '.', ['/tmp/ninja'], False)",
195+
encoding="utf8",
191196
)
192197
search_paths = _handle_editable_module(pth_file)
193198
assert all(sp.always_scan_for == "griffe" for sp in search_paths)

tests/test_loader.py

Lines changed: 27 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,9 @@ def test_recursive_wildcard_expansion() -> None:
4141
mod_a = mod_a_dir / "__init__.py"
4242
mod_b = mod_b_dir / "__init__.py"
4343
mod_c = mod_b_dir / "mod_c.py"
44-
mod_c.write_text("CONST_X = 'X'\nCONST_Y = 'Y'")
45-
mod_b.write_text("from .mod_c import *")
46-
mod_a.write_text("from .mod_b import *")
44+
mod_c.write_text("CONST_X = 'X'\nCONST_Y = 'Y'", encoding="utf8")
45+
mod_b.write_text("from .mod_c import *", encoding="utf8")
46+
mod_a.write_text("from .mod_b import *", encoding="utf8")
4747

4848
loader = GriffeLoader(search_paths=[tmp_package.tmpdir])
4949
package = loader.load(tmp_package.name)
@@ -69,9 +69,9 @@ def test_dont_shortcut_alias_chain_after_expanding_wildcards() -> None:
6969
mod_b = tmp_package.path / "mod_b.py"
7070
mod_c = tmp_package.path / "mod_c.py"
7171

72-
mod_a.write_text("from package.mod_b import *\nclass Child(Base): ...\n")
73-
mod_b.write_text("from package.mod_c import Base\n__all__ = ['Base']\n")
74-
mod_c.write_text("class Base: ...\n")
72+
mod_a.write_text("from package.mod_b import *\nclass Child(Base): ...\n", encoding="utf8")
73+
mod_b.write_text("from package.mod_c import Base\n__all__ = ['Base']\n", encoding="utf8")
74+
mod_c.write_text("class Base: ...\n", encoding="utf8")
7575

7676
loader = GriffeLoader(search_paths=[tmp_package.tmpdir])
7777
package = loader.load(tmp_package.name)
@@ -90,8 +90,8 @@ def test_dont_overwrite_lower_member_when_expanding_wildcard() -> None:
9090
mod_a = tmp_package.path / "mod_a.py"
9191
mod_b = tmp_package.path / "mod_b.py"
9292

93-
mod_a.write_text("overwritten = 0\nfrom package.mod_b import *\nnot_overwritten = 0\n")
94-
mod_b.write_text("overwritten = 1\nnot_overwritten = 1\n")
93+
mod_a.write_text("overwritten = 0\nfrom package.mod_b import *\nnot_overwritten = 0\n", encoding="utf8")
94+
mod_b.write_text("overwritten = 1\nnot_overwritten = 1\n", encoding="utf8")
9595

9696
loader = GriffeLoader(search_paths=[tmp_package.tmpdir])
9797
package = loader.load(tmp_package.name)
@@ -129,9 +129,10 @@ def __init__(self, watch_paths: List[str], debug: bool) -> None:
129129
debug: if true, print details about all events to stderr
130130
"""
131131
'''
132-
tmp_package.path.joinpath("_rust_notify.pyi").write_text(dedent(code))
132+
tmp_package.path.joinpath("_rust_notify.pyi").write_text(dedent(code), encoding="utf8")
133133
tmp_package.path.joinpath("__init__.py").write_text(
134134
"from ._rust_notify import RustNotify\n__all__ = ['RustNotify']",
135+
encoding="utf8",
135136
)
136137
loader = GriffeLoader(search_paths=[tmp_package.tmpdir])
137138
package = loader.load(tmp_package.name)
@@ -160,6 +161,7 @@ def function2(self, arg1=2.2):
160161
pass
161162
""",
162163
),
164+
encoding="utf8",
163165
)
164166
tmp_package.path.joinpath("mod.pyi").write_text(
165167
dedent(
@@ -179,6 +181,7 @@ def function1(self, arg1: bytes) -> Sequence[bytes]: ...
179181
def function2(self, arg1: float) -> float: ...
180182
""",
181183
),
184+
encoding="utf8",
182185
)
183186
loader = GriffeLoader(search_paths=[tmp_package.tmpdir])
184187
package = loader.load(tmp_package.name)
@@ -215,8 +218,8 @@ def function2(self, arg1: float) -> float: ...
215218
def test_overwrite_module_with_attribute() -> None:
216219
"""Check we are able to overwrite a module with an attribute."""
217220
with temporary_pypackage("package", ["mod.py"]) as tmp_package:
218-
tmp_package.path.joinpath("mod.py").write_text("mod: list = [0, 1, 2]")
219-
tmp_package.path.joinpath("__init__.py").write_text("from package.mod import *")
221+
tmp_package.path.joinpath("mod.py").write_text("mod: list = [0, 1, 2]", encoding="utf8")
222+
tmp_package.path.joinpath("__init__.py").write_text("from package.mod import *", encoding="utf8")
220223
loader = GriffeLoader(search_paths=[tmp_package.tmpdir])
221224
loader.load(tmp_package.name)
222225
loader.resolve_aliases()
@@ -229,8 +232,8 @@ def test_load_package_from_both_py_and_pyi_files() -> None:
229232
`__init__.pyi` (not so uncommon).
230233
"""
231234
with temporary_pypackage("package", ["__init__.py", "__init__.pyi"]) as tmp_package:
232-
tmp_package.path.joinpath("__init__.py").write_text("globals()['f'] = lambda x: str(x)")
233-
tmp_package.path.joinpath("__init__.pyi").write_text("def f(x: int) -> str: ...")
235+
tmp_package.path.joinpath("__init__.py").write_text("globals()['f'] = lambda x: str(x)", encoding="utf8")
236+
tmp_package.path.joinpath("__init__.pyi").write_text("def f(x: int) -> str: ...", encoding="utf8")
234237

235238
loader = GriffeLoader(search_paths=[tmp_package.tmpdir])
236239
package = loader.load(tmp_package.name)
@@ -245,8 +248,8 @@ def test_load_single_module_from_both_py_and_pyi_files() -> None:
245248
"""
246249
with temporary_pypackage("just_a_folder", ["mod.py", "mod.pyi"]) as tmp_folder:
247250
tmp_folder.path.joinpath("__init__.py").unlink()
248-
tmp_folder.path.joinpath("mod.py").write_text("globals()['f'] = lambda x: str(x)")
249-
tmp_folder.path.joinpath("mod.pyi").write_text("def f(x: int) -> str: ...")
251+
tmp_folder.path.joinpath("mod.py").write_text("globals()['f'] = lambda x: str(x)", encoding="utf8")
252+
tmp_folder.path.joinpath("mod.pyi").write_text("def f(x: int) -> str: ...", encoding="utf8")
250253

251254
loader = GriffeLoader(search_paths=[tmp_folder.path])
252255
package = loader.load("mod")
@@ -261,8 +264,11 @@ def test_unsupported_item_in_all(caplog: pytest.LogCaptureFixture) -> None:
261264
"""
262265
item_name = "XXX"
263266
with temporary_pypackage("package", ["mod.py"]) as tmp_folder:
264-
tmp_folder.path.joinpath("__init__.py").write_text(f"from .mod import {item_name}\n__all__ = [{item_name}]")
265-
tmp_folder.path.joinpath("mod.py").write_text(f"class {item_name}: ...")
267+
tmp_folder.path.joinpath("__init__.py").write_text(
268+
f"from .mod import {item_name}\n__all__ = [{item_name}]",
269+
encoding="utf8",
270+
)
271+
tmp_folder.path.joinpath("mod.py").write_text(f"class {item_name}: ...", encoding="utf8")
266272
loader = GriffeLoader(search_paths=[tmp_folder.tmpdir])
267273
loader.expand_exports(loader.load("package")) # type: ignore[arg-type]
268274
assert any(item_name in record.message and record.levelname == "WARNING" for record in caplog.records)
@@ -384,17 +390,17 @@ def test_loading_stubs_only_packages(tmp_path: Path, namespace: bool) -> None:
384390
package = package_parent / "package"
385391
package.mkdir()
386392
if not namespace:
387-
package.joinpath("__init__.py").write_text("a: int = 0")
388-
package.joinpath("module.py").write_text("a: int = 0")
393+
package.joinpath("__init__.py").write_text("a: int = 0", encoding="utf8")
394+
package.joinpath("module.py").write_text("a: int = 0", encoding="utf8")
389395

390396
# Create stubs.
391397
stubs_parent = tmp_path / "stubs_parent"
392398
stubs_parent.mkdir()
393399
stubs = stubs_parent / "package-stubs"
394400
stubs.mkdir()
395401
if not namespace:
396-
stubs.joinpath("__init__.pyi").write_text("b: int")
397-
stubs.joinpath("module.pyi").write_text("b: int")
402+
stubs.joinpath("__init__.pyi").write_text("b: int", encoding="utf8")
403+
stubs.joinpath("module.pyi").write_text("b: int", encoding="utf8")
398404

399405
# Exposing stubs first, to make sure order doesn't matter.
400406
loader = GriffeLoader(search_paths=[stubs_parent, package_parent])

tests/test_models.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -65,8 +65,8 @@ def test_handle_aliases_chain_in_has_docstrings() -> None:
6565
with temporary_pypackage("package", ["mod_a.py", "mod_b.py"]) as tmp_package:
6666
mod_a = tmp_package.path / "mod_a.py"
6767
mod_b = tmp_package.path / "mod_b.py"
68-
mod_a.write_text("from .mod_b import someobj")
69-
mod_b.write_text("from somelib import someobj")
68+
mod_a.write_text("from .mod_b import someobj", encoding="utf8")
69+
mod_b.write_text("from somelib import someobj", encoding="utf8")
7070

7171
loader = GriffeLoader(search_paths=[tmp_package.tmpdir])
7272
package = loader.load(tmp_package.name)
@@ -80,8 +80,8 @@ def test_has_docstrings_does_not_trigger_alias_resolution() -> None:
8080
with temporary_pypackage("package", ["mod_a.py", "mod_b.py"]) as tmp_package:
8181
mod_a = tmp_package.path / "mod_a.py"
8282
mod_b = tmp_package.path / "mod_b.py"
83-
mod_a.write_text("from .mod_b import someobj")
84-
mod_b.write_text("from somelib import someobj")
83+
mod_a.write_text("from .mod_b import someobj", encoding="utf8")
84+
mod_b.write_text("from somelib import someobj", encoding="utf8")
8585

8686
loader = GriffeLoader(search_paths=[tmp_package.tmpdir])
8787
package = loader.load(tmp_package.name)

tests/test_visitor.py

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
def test_not_defined_at_runtime() -> None:
2121
"""Assert that objects not defined at runtime are not added to wildcards expansions."""
2222
with temporary_pypackage("package", ["module_a.py", "module_b.py", "module_c.py"]) as tmp_package:
23-
tmp_package.path.joinpath("__init__.py").write_text("from package.module_a import *")
23+
tmp_package.path.joinpath("__init__.py").write_text("from package.module_a import *", encoding="utf8")
2424
tmp_package.path.joinpath("module_a.py").write_text(
2525
dedent(
2626
"""
@@ -36,9 +36,10 @@ def test_not_defined_at_runtime() -> None:
3636
from package.module_c import TYPE_C
3737
""",
3838
),
39+
encoding="utf8",
3940
)
40-
tmp_package.path.joinpath("module_b.py").write_text("CONST_B = 'hi'\nTYPE_B = str")
41-
tmp_package.path.joinpath("module_c.py").write_text("CONST_C = 'ho'\nTYPE_C = str")
41+
tmp_package.path.joinpath("module_b.py").write_text("CONST_B = 'hi'\nTYPE_B = str", encoding="utf8")
42+
tmp_package.path.joinpath("module_c.py").write_text("CONST_C = 'ho'\nTYPE_C = str", encoding="utf8")
4243
loader = GriffeLoader(search_paths=[tmp_package.tmpdir])
4344
package = loader.load(tmp_package.name)
4445
loader.resolve_aliases()
@@ -208,9 +209,9 @@ def test_parse_complex__all__assignments(statements: str) -> None:
208209
statements: Parametrized text containing `__all__` [augmented] assignments.
209210
"""
210211
with temporary_pypackage("package", ["moda.py", "modb.py", "modc.py"]) as tmp_package:
211-
tmp_package.path.joinpath("moda.py").write_text("CONST_A = 1\n\n__all__ = ['CONST_A']")
212-
tmp_package.path.joinpath("modb.py").write_text("CONST_B = 1\n\n__all__ = ['CONST_B']")
213-
tmp_package.path.joinpath("modc.py").write_text("CONST_C = 2\n\n__all__ = ['CONST_C']")
212+
tmp_package.path.joinpath("moda.py").write_text("CONST_A = 1\n\n__all__ = ['CONST_A']", encoding="utf8")
213+
tmp_package.path.joinpath("modb.py").write_text("CONST_B = 1\n\n__all__ = ['CONST_B']", encoding="utf8")
214+
tmp_package.path.joinpath("modc.py").write_text("CONST_C = 2\n\n__all__ = ['CONST_C']", encoding="utf8")
214215
code = """
215216
from package.moda import *
216217
from package.moda import __all__ as moda_all
@@ -221,7 +222,7 @@ def test_parse_complex__all__assignments(statements: str) -> None:
221222
222223
CONST_INIT = 0
223224
"""
224-
tmp_package.path.joinpath("__init__.py").write_text(dedent(code) + dedent(statements))
225+
tmp_package.path.joinpath("__init__.py").write_text(dedent(code) + dedent(statements), encoding="utf8")
225226

226227
loader = GriffeLoader(search_paths=[tmp_package.tmpdir])
227228
package = loader.load(tmp_package.name)

0 commit comments

Comments
 (0)