Skip to content

Commit 6c28992

Browse files
Improve build tools and update pymctranslate (#18)
* Improve build tools * Fix mypy warnings
1 parent 4d6483f commit 6c28992

File tree

9 files changed

+86
-82
lines changed

9 files changed

+86
-82
lines changed

build_requires.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
# mypy: disable-error-code=no-redef
2+
13
from typing import Union, Mapping
24

35
from setuptools import build_meta

mypy.ini

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,13 @@ disallow_untyped_defs = True
33
check_untyped_defs = True
44
warn_return_any = True
55
python_version = 3.12
6+
explicit_package_bases = True
67
mypy_path = $MYPY_CONFIG_FILE_DIR/src,$MYPY_CONFIG_FILE_DIR/tests
7-
packages = amulet,test_amulet_game
8+
files =
9+
src,
10+
tests,
11+
tools,
12+
get_compiler,
13+
build_requires.py,
14+
requirements.py,
15+
setup.py

pyproject.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,9 @@ classifiers = [
2323
[project.optional-dependencies]
2424
dev = [
2525
"setuptools>=42",
26+
"types-setuptools",
2627
"versioneer",
28+
"types-versioneer",
2729
"packaging",
2830
"wheel",
2931
"pybind11_stubgen>=2.5.4",

setup.py

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import gzip
99
import pickle
1010
from tempfile import TemporaryDirectory
11+
from typing import TypeAlias, TYPE_CHECKING
1112

1213
from setuptools import setup, Extension, Command
1314
from setuptools.command.build import build
@@ -18,15 +19,20 @@
1819
import requirements
1920

2021

21-
def fix_path(path: str) -> str:
22+
def fix_path(path: str | os.PathLike[str]) -> str:
2223
return os.path.realpath(path).replace(os.sep, "/")
2324

2425

2526
cmdclass: dict[str, type[Command]] = versioneer.get_cmdclass()
2627

28+
if TYPE_CHECKING:
29+
BuildExt: TypeAlias = build_ext
30+
else:
31+
BuildExt = cmdclass.get("build_ext", build_ext)
2732

28-
class CMakeBuild(cmdclass.get("build_ext", build_ext)):
29-
def build_extension(self, ext):
33+
34+
class CMakeBuild(BuildExt):
35+
def build_extension(self, ext: Extension) -> None:
3036
import pybind11
3137
import amulet.pybind11_extensions
3238
import amulet.io
@@ -88,18 +94,19 @@ def build_extension(self, ext):
8894

8995

9096
class MinifyJSON(Command):
91-
def initialize_options(self):
97+
def initialize_options(self) -> None:
9298
self.editable_mode = False
93-
self.build_lib = None
99+
self.build_lib: str | None = None
94100

95-
def finalize_options(self):
101+
def finalize_options(self) -> None:
96102
self.set_undefined_options("build_py", ("build_lib", "build_lib"))
97103

98-
def run(self):
104+
def run(self) -> None:
99105
# This is rather janky but it is a stop-gap until the whole library can be ported to C++
100106
if self.editable_mode:
101107
src_dir = os.path.abspath("src")
102108
else:
109+
assert self.build_lib is not None
103110
src_dir = self.build_lib
104111

105112
sys.path.append(src_dir)
@@ -150,7 +157,7 @@ def run(self):
150157
cmdclass.get("build", build).sub_commands.append(("minify_json", None))
151158

152159

153-
cmdclass["build_ext"] = CMakeBuild
160+
cmdclass["build_ext"] = CMakeBuild # type: ignore
154161

155162

156163
setup(

src/amulet/game/abc/__init__.pyi

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -60,8 +60,8 @@ __all__: list[str] = [
6060
"load_json_block_spec",
6161
"version",
6262
]
63-
JSONCompatible: (
64-
typing._UnionGenericAlias
65-
) # value = typing.Union[str, int, float, bool, NoneType, ForwardRef('JSONList'), ForwardRef('JSONDict')]
66-
JSONDict: typing.TypeAlias = dict[str, "JSONCompatible"]
67-
JSONList: typing.TypeAlias = list["JSONCompatible"]
63+
JSONCompatible: typing.TypeAlias = typing.Union[
64+
str, int, float, bool, None, JSONList, JSONDict
65+
]
66+
JSONDict: typing.TypeAlias = dict[str, JSONCompatible]
67+
JSONList: typing.TypeAlias = list[JSONCompatible]

src/amulet/game/translate/_functions/walk_input_nbt.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -274,7 +274,7 @@ def run(self, src: SrcData, state: StateData, dst: DstData) -> None:
274274
else:
275275
raise TypeError
276276

277-
for i, value in enumerate(tag):
277+
for i, arr_value in enumerate(tag):
278278
if self._index is not None and i in self._index:
279279
outer_name, outer_type, path = nbt_path
280280
new_path = path + ((i, nested_dtype),)

submodules/PyMCTranslate

tools/cmake_generate.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ def fix_path(path: str) -> str:
1919
RootDir = fix_path(os.path.dirname(os.path.dirname(__file__)))
2020

2121

22-
def main():
22+
def main() -> None:
2323
platform_args = []
2424
if sys.platform == "win32":
2525
platform_args.extend(["-G", "Visual Studio 17 2022"])

tools/generate_pybind_stubs.py

Lines changed: 50 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -7,16 +7,28 @@
77
import pybind11_stubgen
88
from pybind11_stubgen.structs import Identifier
99
from pybind11_stubgen.parser.mixins.filter import FilterClassMembers
10-
from pybind11_stubgen import main as pybind11_stubgen_main
10+
11+
12+
ForwardRefPattern = re.compile(r"ForwardRef\('(?P<variable>[a-zA-Z_][a-zA-Z0-9_]*)'\)")
13+
14+
QuotePattern = re.compile(r"'(?P<variable>[a-zA-Z_][a-zA-Z0-9_]*)'")
15+
16+
17+
def fix_value(value: str) -> str:
18+
value = value.replace("NoneType", "None")
19+
value = ForwardRefPattern.sub(lambda match: match.group("variable"), value)
20+
value = QuotePattern.sub(lambda match: match.group("variable"), value)
21+
return value
22+
1123

1224
UnionPattern = re.compile(
13-
r"^(?P<variable>[a-zA-Z_][a-zA-Z0-9_]*): types\.UnionType\s*#\s*value = (?P<value>.*)$",
25+
r"^(?P<variable>[a-zA-Z_][a-zA-Z0-9_]*): (types\.UnionType|typing\._UnionGenericAlias)\s*#\s*value = (?P<value>.*)$",
1426
flags=re.MULTILINE,
1527
)
1628

1729

18-
def union_sub_func(match: re.Match) -> str:
19-
return f'{match.group("variable")}: typing.TypeAlias = {match.group("value")}'
30+
def union_sub_func(match: re.Match[str]) -> str:
31+
return f'{match.group("variable")}: typing.TypeAlias = {fix_value(match.group("value"))}'
2032

2133

2234
ClassVarUnionPattern = re.compile(
@@ -26,7 +38,7 @@ def union_sub_func(match: re.Match) -> str:
2638

2739

2840
def class_var_union_sub_func(match: re.Match) -> str:
29-
return f'{match.group("variable")}: typing.ClassVar[typing.TypeAlias] = {match.group("value")}'
41+
return f'{match.group("variable")}: typing.TypeAlias = {fix_value(match.group("value"))}'
3042

3143

3244
VersionPattern = re.compile(r"(?P<var>[a-zA-Z0-9_].*): str = '.*?'")
@@ -36,13 +48,20 @@ def str_sub_func(match: re.Match) -> str:
3648
return f"{match.group('var')}: str"
3749

3850

51+
CompilerConfigPattern = re.compile(r"compiler_config: dict.*")
52+
53+
54+
def compiler_config_sub_func(match: re.Match) -> str:
55+
return "compiler_config: dict"
56+
57+
3958
EqPattern = re.compile(
4059
r"(?P<indent>[ \t]+)def __eq__\(self, arg0: (?P<other>[a-zA-Z1-9.]+)\) -> (?P<return>[a-zA-Z1-9.]+):"
4160
r"(?P<ellipsis_docstring>\s*((\.\.\.)|(\"\"\"(.|\n)*?\"\"\")))"
4261
)
4362

4463

45-
def eq_sub_func(match: re.Match) -> str:
64+
def eq_sub_func(match: re.Match[str]) -> str:
4665
"""
4766
if one - add @overload and overloaded signature
4867
@@ -80,7 +99,7 @@ def eq_sub_func(match: re.Match) -> str:
8099

81100

82101
def generic_alias_sub_func(match: re.Match) -> str:
83-
return f"{match.group('variable')}: typing.TypeAlias = {match.group('value')}"
102+
return f'{match.group("variable")}: typing.TypeAlias = {fix_value(match.group("value"))}'
84103

85104

86105
def get_module_path(name: str) -> str:
@@ -95,72 +114,37 @@ def get_package_dir(name: str) -> str:
95114
return os.path.realpath(os.path.dirname(get_module_path(name)))
96115

97116

98-
def patch_stubgen():
117+
def patch_stubgen() -> None:
118+
class_member_blacklist: set[Identifier] = FilterClassMembers._FilterClassMembers__class_member_blacklist # type: ignore
119+
attribute_blacklist: set[Identifier] = FilterClassMembers._FilterClassMembers__attribute_blacklist # type: ignore
120+
99121
# Is there a better way to add items to the blacklist?
100122
# Pybind11
101-
FilterClassMembers._FilterClassMembers__class_member_blacklist.add(
102-
Identifier("_pybind11_conduit_v1_")
103-
)
123+
class_member_blacklist.add(Identifier("_pybind11_conduit_v1_"))
104124
# Python
105-
FilterClassMembers._FilterClassMembers__class_member_blacklist.add(
106-
Identifier("__new__")
107-
)
108-
FilterClassMembers._FilterClassMembers__class_member_blacklist.add(
109-
Identifier("__subclasshook__")
110-
)
125+
class_member_blacklist.add(Identifier("__new__"))
126+
class_member_blacklist.add(Identifier("__subclasshook__"))
111127
# Pickle
112-
FilterClassMembers._FilterClassMembers__class_member_blacklist.add(
113-
Identifier("__getnewargs__")
114-
)
115-
FilterClassMembers._FilterClassMembers__class_member_blacklist.add(
116-
Identifier("__getstate__")
117-
)
118-
FilterClassMembers._FilterClassMembers__class_member_blacklist.add(
119-
Identifier("__setstate__")
120-
)
128+
class_member_blacklist.add(Identifier("__getnewargs__"))
129+
class_member_blacklist.add(Identifier("__getstate__"))
130+
class_member_blacklist.add(Identifier("__setstate__"))
121131
# ABC
122-
FilterClassMembers._FilterClassMembers__attribute_blacklist.add(
123-
Identifier("__abstractmethods__")
124-
)
125-
FilterClassMembers._FilterClassMembers__attribute_blacklist.add(
126-
Identifier("__orig_bases__")
127-
)
128-
FilterClassMembers._FilterClassMembers__attribute_blacklist.add(
129-
Identifier("__parameters__")
130-
)
131-
FilterClassMembers._FilterClassMembers__attribute_blacklist.add(
132-
Identifier("_abc_impl")
133-
)
132+
attribute_blacklist.add(Identifier("__abstractmethods__"))
133+
attribute_blacklist.add(Identifier("__orig_bases__"))
134+
attribute_blacklist.add(Identifier("__parameters__"))
135+
attribute_blacklist.add(Identifier("_abc_impl"))
134136
# Protocol
135-
FilterClassMembers._FilterClassMembers__attribute_blacklist.add(
136-
Identifier("__protocol_attrs__")
137-
)
138-
FilterClassMembers._FilterClassMembers__attribute_blacklist.add(
139-
Identifier("__non_callable_proto_members__")
140-
)
141-
FilterClassMembers._FilterClassMembers__attribute_blacklist.add(
142-
Identifier("_is_protocol")
143-
)
144-
FilterClassMembers._FilterClassMembers__attribute_blacklist.add(
145-
Identifier("_is_runtime_protocol")
146-
)
137+
attribute_blacklist.add(Identifier("__protocol_attrs__"))
138+
attribute_blacklist.add(Identifier("__non_callable_proto_members__"))
139+
attribute_blacklist.add(Identifier("_is_protocol"))
140+
attribute_blacklist.add(Identifier("_is_runtime_protocol"))
147141
# dataclass
148-
FilterClassMembers._FilterClassMembers__attribute_blacklist.add(
149-
Identifier("__dataclass_fields__")
150-
)
151-
FilterClassMembers._FilterClassMembers__attribute_blacklist.add(
152-
Identifier("__dataclass_params__")
153-
)
154-
FilterClassMembers._FilterClassMembers__attribute_blacklist.add(
155-
Identifier("__match_args__")
156-
)
142+
attribute_blacklist.add(Identifier("__dataclass_fields__"))
143+
attribute_blacklist.add(Identifier("__dataclass_params__"))
144+
attribute_blacklist.add(Identifier("__match_args__"))
157145
# Buffer protocol
158-
FilterClassMembers._FilterClassMembers__class_member_blacklist.add(
159-
Identifier("__buffer__")
160-
)
161-
FilterClassMembers._FilterClassMembers__class_member_blacklist.add(
162-
Identifier("__release_buffer__")
163-
)
146+
class_member_blacklist.add(Identifier("__buffer__"))
147+
class_member_blacklist.add(Identifier("__release_buffer__"))
164148

165149

166150
def main() -> None:
@@ -236,6 +220,7 @@ def main() -> None:
236220
pyi = UnionPattern.sub(union_sub_func, pyi)
237221
pyi = ClassVarUnionPattern.sub(class_var_union_sub_func, pyi)
238222
pyi = VersionPattern.sub(str_sub_func, pyi)
223+
pyi = CompilerConfigPattern.sub(compiler_config_sub_func, pyi)
239224
pyi = GenericAliasPattern.sub(generic_alias_sub_func, pyi)
240225
pyi = pyi.replace(
241226
"__hash__: typing.ClassVar[None] = None",

0 commit comments

Comments
 (0)