amulet-core 2.0.4a1__tar.gz → 2.0.5a1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of amulet-core might be problematic. Click here for more details.

Files changed (105) hide show
  1. {amulet_core-2.0.4a1 → amulet_core-2.0.5a1}/CMakeLists.txt +11 -2
  2. {amulet_core-2.0.4a1/src/amulet_core.egg-info → amulet_core-2.0.5a1}/PKG-INFO +7 -7
  3. amulet_core-2.0.5a1/get_compiler/__init__.py +32 -0
  4. {amulet_core-2.0.4a1 → amulet_core-2.0.5a1}/pyproject.toml +1 -2
  5. {amulet_core-2.0.4a1 → amulet_core-2.0.5a1}/requirements.py +48 -35
  6. {amulet_core-2.0.4a1 → amulet_core-2.0.5a1}/setup.py +3 -38
  7. {amulet_core-2.0.4a1 → amulet_core-2.0.5a1}/src/amulet/core/__init__.py +1 -0
  8. {amulet_core-2.0.4a1 → amulet_core-2.0.5a1}/src/amulet/core/__init__.pyi +1 -1
  9. {amulet_core-2.0.4a1 → amulet_core-2.0.5a1}/src/amulet/core/_amulet_core.py.cpp +1 -0
  10. {amulet_core-2.0.4a1 → amulet_core-2.0.5a1}/src/amulet/core/_amulet_core.pyi +1 -1
  11. {amulet_core-2.0.4a1 → amulet_core-2.0.5a1}/src/amulet/core/_version.py +3 -3
  12. {amulet_core-2.0.4a1 → amulet_core-2.0.5a1}/src/amulet/core/amulet_coreConfig.cmake +2 -0
  13. {amulet_core-2.0.4a1 → amulet_core-2.0.5a1}/src/amulet/core/biome/__init__.pyi +3 -3
  14. {amulet_core-2.0.4a1 → amulet_core-2.0.5a1}/src/amulet/core/block/__init__.pyi +9 -9
  15. {amulet_core-2.0.4a1 → amulet_core-2.0.5a1}/src/amulet/core/block/block.py.cpp +10 -10
  16. {amulet_core-2.0.4a1 → amulet_core-2.0.5a1}/src/amulet/core/block_entity/__init__.pyi +3 -3
  17. {amulet_core-2.0.4a1 → amulet_core-2.0.5a1}/src/amulet/core/chunk/__init__.pyi +1 -1
  18. {amulet_core-2.0.4a1 → amulet_core-2.0.5a1}/src/amulet/core/chunk/component/__init__.pyi +1 -1
  19. {amulet_core-2.0.4a1 → amulet_core-2.0.5a1}/src/amulet/core/chunk/component/block_component.pyi +1 -1
  20. {amulet_core-2.0.4a1 → amulet_core-2.0.5a1}/src/amulet/core/chunk/component/section_array_map.py.cpp +12 -11
  21. {amulet_core-2.0.4a1 → amulet_core-2.0.5a1}/src/amulet/core/chunk/component/section_array_map.pyi +42 -26
  22. {amulet_core-2.0.4a1 → amulet_core-2.0.5a1}/src/amulet/core/entity/__init__.pyi +3 -3
  23. {amulet_core-2.0.4a1 → amulet_core-2.0.5a1}/src/amulet/core/palette/__init__.pyi +1 -1
  24. {amulet_core-2.0.4a1 → amulet_core-2.0.5a1}/src/amulet/core/palette/biome_palette.py.cpp +8 -6
  25. {amulet_core-2.0.4a1 → amulet_core-2.0.5a1}/src/amulet/core/palette/biome_palette.pyi +6 -6
  26. {amulet_core-2.0.4a1 → amulet_core-2.0.5a1}/src/amulet/core/palette/block_palette.py.cpp +8 -6
  27. {amulet_core-2.0.4a1 → amulet_core-2.0.5a1}/src/amulet/core/palette/block_palette.pyi +4 -4
  28. amulet_core-2.0.5a1/src/amulet/core/selection/__init__.pyi +25 -0
  29. amulet_core-2.0.5a1/src/amulet/core/selection/__init_selection.py.cpp +55 -0
  30. {amulet_core-2.0.4a1 → amulet_core-2.0.5a1}/src/amulet/core/selection/box.cpp +43 -3
  31. {amulet_core-2.0.4a1 → amulet_core-2.0.5a1}/src/amulet/core/selection/box.hpp +27 -16
  32. amulet_core-2.0.5a1/src/amulet/core/selection/box.py.cpp +304 -0
  33. {amulet_core-2.0.4a1 → amulet_core-2.0.5a1}/src/amulet/core/selection/box.pyi +20 -10
  34. amulet_core-2.0.4a1/src/amulet/core/selection/group.cpp → amulet_core-2.0.5a1/src/amulet/core/selection/box_group.cpp +35 -26
  35. amulet_core-2.0.5a1/src/amulet/core/selection/box_group.hpp +89 -0
  36. amulet_core-2.0.5a1/src/amulet/core/selection/box_group.py.cpp +303 -0
  37. amulet_core-2.0.4a1/src/amulet/core/selection/group.pyi → amulet_core-2.0.5a1/src/amulet/core/selection/box_group.pyi +34 -33
  38. amulet_core-2.0.5a1/src/amulet/core/selection/cuboid.cpp +458 -0
  39. amulet_core-2.0.5a1/src/amulet/core/selection/cuboid.hpp +41 -0
  40. amulet_core-2.0.5a1/src/amulet/core/selection/cuboid.py.cpp +59 -0
  41. amulet_core-2.0.5a1/src/amulet/core/selection/cuboid.pyi +49 -0
  42. amulet_core-2.0.5a1/src/amulet/core/selection/ellipsoid.cpp +347 -0
  43. amulet_core-2.0.5a1/src/amulet/core/selection/ellipsoid.hpp +42 -0
  44. amulet_core-2.0.5a1/src/amulet/core/selection/ellipsoid.py.cpp +57 -0
  45. amulet_core-2.0.5a1/src/amulet/core/selection/ellipsoid.pyi +47 -0
  46. amulet_core-2.0.5a1/src/amulet/core/selection/shape.cpp +58 -0
  47. amulet_core-2.0.5a1/src/amulet/core/selection/shape.hpp +73 -0
  48. amulet_core-2.0.5a1/src/amulet/core/selection/shape.py.cpp +60 -0
  49. amulet_core-2.0.5a1/src/amulet/core/selection/shape.pyi +56 -0
  50. amulet_core-2.0.5a1/src/amulet/core/selection/shape_group.cpp +142 -0
  51. amulet_core-2.0.5a1/src/amulet/core/selection/shape_group.hpp +73 -0
  52. amulet_core-2.0.5a1/src/amulet/core/selection/shape_group.py.cpp +202 -0
  53. amulet_core-2.0.5a1/src/amulet/core/selection/shape_group.pyi +118 -0
  54. {amulet_core-2.0.4a1 → amulet_core-2.0.5a1}/src/amulet/core/version/__init__.pyi +5 -5
  55. {amulet_core-2.0.4a1 → amulet_core-2.0.5a1/src/amulet_core.egg-info}/PKG-INFO +7 -7
  56. {amulet_core-2.0.4a1 → amulet_core-2.0.5a1}/src/amulet_core.egg-info/SOURCES.txt +21 -3
  57. {amulet_core-2.0.4a1 → amulet_core-2.0.5a1}/src/amulet_core.egg-info/requires.txt +6 -6
  58. amulet_core-2.0.4a1/get_compiler/__init__.py +0 -32
  59. amulet_core-2.0.4a1/src/amulet/core/selection/__init__.pyi +0 -8
  60. amulet_core-2.0.4a1/src/amulet/core/selection/__init_selection.py.cpp +0 -598
  61. amulet_core-2.0.4a1/src/amulet/core/selection/group.hpp +0 -80
  62. {amulet_core-2.0.4a1 → amulet_core-2.0.5a1}/MANIFEST.in +0 -0
  63. {amulet_core-2.0.4a1 → amulet_core-2.0.5a1}/README.md +0 -0
  64. {amulet_core-2.0.4a1 → amulet_core-2.0.5a1}/build_requires.py +0 -0
  65. {amulet_core-2.0.4a1 → amulet_core-2.0.5a1}/get_compiler/CMakeLists.txt +0 -0
  66. {amulet_core-2.0.4a1 → amulet_core-2.0.5a1}/setup.cfg +0 -0
  67. {amulet_core-2.0.4a1 → amulet_core-2.0.5a1}/src/amulet/core/__pyinstaller/__init__.py +0 -0
  68. {amulet_core-2.0.4a1 → amulet_core-2.0.5a1}/src/amulet/core/__pyinstaller/hook-amulet.core.py +0 -0
  69. {amulet_core-2.0.4a1 → amulet_core-2.0.5a1}/src/amulet/core/biome/biome.cpp +0 -0
  70. {amulet_core-2.0.4a1 → amulet_core-2.0.5a1}/src/amulet/core/biome/biome.hpp +0 -0
  71. {amulet_core-2.0.4a1 → amulet_core-2.0.5a1}/src/amulet/core/biome/biome.py.cpp +0 -0
  72. {amulet_core-2.0.4a1 → amulet_core-2.0.5a1}/src/amulet/core/block/block.cpp +0 -0
  73. {amulet_core-2.0.4a1 → amulet_core-2.0.5a1}/src/amulet/core/block/block.hpp +0 -0
  74. {amulet_core-2.0.4a1 → amulet_core-2.0.5a1}/src/amulet/core/block_entity/block_entity.cpp +0 -0
  75. {amulet_core-2.0.4a1 → amulet_core-2.0.5a1}/src/amulet/core/block_entity/block_entity.hpp +0 -0
  76. {amulet_core-2.0.4a1 → amulet_core-2.0.5a1}/src/amulet/core/block_entity/block_entity.py.cpp +0 -0
  77. {amulet_core-2.0.4a1 → amulet_core-2.0.5a1}/src/amulet/core/chunk/chunk.cpp +0 -0
  78. {amulet_core-2.0.4a1 → amulet_core-2.0.5a1}/src/amulet/core/chunk/chunk.hpp +0 -0
  79. {amulet_core-2.0.4a1 → amulet_core-2.0.5a1}/src/amulet/core/chunk/chunk.py.cpp +0 -0
  80. {amulet_core-2.0.4a1 → amulet_core-2.0.5a1}/src/amulet/core/chunk/component/__init_chunk_components.py.cpp +0 -0
  81. {amulet_core-2.0.4a1 → amulet_core-2.0.5a1}/src/amulet/core/chunk/component/biome_3d_component.cpp +0 -0
  82. {amulet_core-2.0.4a1 → amulet_core-2.0.5a1}/src/amulet/core/chunk/component/biome_3d_component.hpp +0 -0
  83. {amulet_core-2.0.4a1 → amulet_core-2.0.5a1}/src/amulet/core/chunk/component/block_component.cpp +0 -0
  84. {amulet_core-2.0.4a1 → amulet_core-2.0.5a1}/src/amulet/core/chunk/component/block_component.hpp +0 -0
  85. {amulet_core-2.0.4a1 → amulet_core-2.0.5a1}/src/amulet/core/chunk/component/block_component.py.cpp +0 -0
  86. {amulet_core-2.0.4a1 → amulet_core-2.0.5a1}/src/amulet/core/chunk/component/block_entity_component.cpp +0 -0
  87. {amulet_core-2.0.4a1 → amulet_core-2.0.5a1}/src/amulet/core/chunk/component/block_entity_component.hpp +0 -0
  88. {amulet_core-2.0.4a1 → amulet_core-2.0.5a1}/src/amulet/core/chunk/component/section_array_map.cpp +0 -0
  89. {amulet_core-2.0.4a1 → amulet_core-2.0.5a1}/src/amulet/core/chunk/component/section_array_map.hpp +0 -0
  90. {amulet_core-2.0.4a1 → amulet_core-2.0.5a1}/src/amulet/core/dll.hpp +0 -0
  91. {amulet_core-2.0.4a1 → amulet_core-2.0.5a1}/src/amulet/core/entity/entity.cpp +0 -0
  92. {amulet_core-2.0.4a1 → amulet_core-2.0.5a1}/src/amulet/core/entity/entity.hpp +0 -0
  93. {amulet_core-2.0.4a1 → amulet_core-2.0.5a1}/src/amulet/core/entity/entity.py.cpp +0 -0
  94. {amulet_core-2.0.4a1 → amulet_core-2.0.5a1}/src/amulet/core/palette/__init_palette.py.cpp +0 -0
  95. {amulet_core-2.0.4a1 → amulet_core-2.0.5a1}/src/amulet/core/palette/biome_palette.cpp +0 -0
  96. {amulet_core-2.0.4a1 → amulet_core-2.0.5a1}/src/amulet/core/palette/biome_palette.hpp +0 -0
  97. {amulet_core-2.0.4a1 → amulet_core-2.0.5a1}/src/amulet/core/palette/block_palette.cpp +0 -0
  98. {amulet_core-2.0.4a1 → amulet_core-2.0.5a1}/src/amulet/core/palette/block_palette.hpp +0 -0
  99. {amulet_core-2.0.4a1 → amulet_core-2.0.5a1}/src/amulet/core/py.typed +0 -0
  100. {amulet_core-2.0.4a1 → amulet_core-2.0.5a1}/src/amulet/core/version/version.cpp +0 -0
  101. {amulet_core-2.0.4a1 → amulet_core-2.0.5a1}/src/amulet/core/version/version.hpp +0 -0
  102. {amulet_core-2.0.4a1 → amulet_core-2.0.5a1}/src/amulet/core/version/version.py.cpp +0 -0
  103. {amulet_core-2.0.4a1 → amulet_core-2.0.5a1}/src/amulet_core.egg-info/dependency_links.txt +0 -0
  104. {amulet_core-2.0.4a1 → amulet_core-2.0.5a1}/src/amulet_core.egg-info/entry_points.txt +0 -0
  105. {amulet_core-2.0.4a1 → amulet_core-2.0.5a1}/src/amulet_core.egg-info/top_level.txt +0 -0
@@ -3,6 +3,7 @@ cmake_minimum_required(VERSION 3.13)
3
3
  project(amulet_core LANGUAGES CXX)
4
4
 
5
5
  set(amulet_core_DIR ${CMAKE_CURRENT_LIST_DIR}/src/amulet/core CACHE PATH "")
6
+ set(BUILD_AMULET_CORE_TESTS OFF CACHE BOOL "Should tests be built?")
6
7
 
7
8
  # Set C++20
8
9
  set(CMAKE_CXX_STANDARD 20)
@@ -15,8 +16,10 @@ if (WIN32)
15
16
  add_definitions(-D_WIN32_WINNT=0x0601)
16
17
  elseif(APPLE)
17
18
  set(CMAKE_OSX_DEPLOYMENT_TARGET "10.15")
18
- else()
19
+ elseif(UNIX)
19
20
  set(CMAKE_POSITION_INDEPENDENT_CODE ON)
21
+ else()
22
+ message( FATAL_ERROR "Unsupported platform. Please submit a pull request to support this platform." )
20
23
  endif()
21
24
 
22
25
  if (MSVC)
@@ -33,6 +36,9 @@ endif()
33
36
  if (NOT TARGET amulet_io)
34
37
  find_package(amulet_io CONFIG REQUIRED)
35
38
  endif()
39
+ if (NOT TARGET amulet_utils)
40
+ find_package(amulet_utils CONFIG REQUIRED)
41
+ endif()
36
42
  if (NOT TARGET amulet_nbt)
37
43
  find_package(amulet_nbt CONFIG REQUIRED)
38
44
  endif()
@@ -49,7 +55,10 @@ list(REMOVE_ITEM HEADERS ${EXTENSION_HEADERS})
49
55
  # Add implementation
50
56
  add_library(amulet_core SHARED)
51
57
  target_compile_definitions(amulet_core PRIVATE ExportAmuletCore)
58
+ target_link_libraries(amulet_core PUBLIC pybind11::module)
59
+ target_link_libraries(amulet_core PUBLIC amulet_pybind11_extensions)
52
60
  target_link_libraries(amulet_core PUBLIC amulet_io)
61
+ target_link_libraries(amulet_core PUBLIC amulet_utils)
53
62
  target_link_libraries(amulet_core PUBLIC amulet_nbt)
54
63
  target_include_directories(amulet_core PUBLIC ${SOURCE_PATH})
55
64
  target_sources(amulet_core PRIVATE ${SOURCES} ${HEADERS})
@@ -84,6 +93,6 @@ endif()
84
93
  install(TARGETS amulet_core DESTINATION ${amulet_core_DIR})
85
94
  install(TARGETS _amulet_core DESTINATION ${AMULET_CORE_EXT_DIR})
86
95
 
87
- if (DEFINED BUILD_AMULET_CORE_TESTS)
96
+ if (BUILD_AMULET_CORE_TESTS)
88
97
  add_subdirectory(tests)
89
98
  endif()
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: amulet-core
3
- Version: 2.0.4a1
3
+ Version: 2.0.5a1
4
4
  Summary: A Python library for reading/writing Minecraft's various save formats.
5
5
  Author: James Clare, Ben Gothard
6
6
  Project-URL: Homepage, https://www.amuletmc.com
@@ -11,12 +11,13 @@ Classifier: Operating System :: OS Independent
11
11
  Requires-Python: >=3.11
12
12
  Description-Content-Type: text/markdown
13
13
  Requires-Dist: amulet-compiler-target==2.0
14
- Requires-Dist: amulet-compiler-version==3.0.0
14
+ Requires-Dist: amulet-compiler-version==4.309027957683952396889703.17
15
15
  Requires-Dist: pybind11==3.0.0
16
- Requires-Dist: amulet-pybind11-extensions~=1.1.0.0a0
16
+ Requires-Dist: amulet-pybind11-extensions~=1.2.0.0a0
17
17
  Requires-Dist: amulet-io~=1.0
18
- Requires-Dist: amulet-zlib~=1.0.1.0a0
19
- Requires-Dist: amulet-nbt~=5.0.1.0a0
18
+ Requires-Dist: amulet-utils~=1.1.3.0a1
19
+ Requires-Dist: amulet-zlib~=1.0.8.0a0
20
+ Requires-Dist: amulet-nbt~=5.0.2.0a0
20
21
  Requires-Dist: numpy~=2.0
21
22
  Provides-Extra: docs
22
23
  Requires-Dist: Sphinx>=1.7.4; extra == "docs"
@@ -27,14 +28,13 @@ Requires-Dist: setuptools>=42; extra == "dev"
27
28
  Requires-Dist: versioneer; extra == "dev"
28
29
  Requires-Dist: packaging; extra == "dev"
29
30
  Requires-Dist: wheel; extra == "dev"
30
- Requires-Dist: amulet_pybind11_extensions~=1.0; extra == "dev"
31
31
  Requires-Dist: pybind11_stubgen>=2.5.4; extra == "dev"
32
32
  Requires-Dist: black>=22.3; extra == "dev"
33
33
  Requires-Dist: isort; extra == "dev"
34
34
  Requires-Dist: autoflake; extra == "dev"
35
35
  Requires-Dist: mypy; extra == "dev"
36
36
  Requires-Dist: types-pyinstaller; extra == "dev"
37
- Requires-Dist: amulet-test-utils~=1.1; extra == "dev"
37
+ Requires-Dist: amulet-test-utils~=1.3; extra == "dev"
38
38
  Dynamic: requires-dist
39
39
 
40
40
  # Amulet Core
@@ -0,0 +1,32 @@
1
+ import os
2
+ import subprocess
3
+ from tempfile import TemporaryDirectory
4
+
5
+
6
+ def main() -> str:
7
+ if subprocess.run(["cmake", "--version"]).returncode:
8
+ raise RuntimeError("Could not find cmake")
9
+
10
+ with TemporaryDirectory() as build_dir:
11
+ # get the compiler id and version
12
+ if subprocess.run(
13
+ ["cmake", "-S", os.path.dirname(__file__), "-B", build_dir]
14
+ ).returncode:
15
+ raise RuntimeError(
16
+ "Could not find a C++ 20 compiler. Do you have a C++ 20 compiler installed?"
17
+ )
18
+
19
+ # Get the compiler variables generated by the cmake file
20
+ with open(os.path.join(build_dir, "compiler_id.txt")) as f:
21
+ compiler_id_str = f.read().strip()
22
+ with open(os.path.join(build_dir, "compiler_version.txt")) as f:
23
+ compiler_version = f.read().strip().split(".", 1)[0]
24
+
25
+ # convert the compiler id to an int so it can be used in a version number
26
+ compiler_id_int = 0
27
+ for b in compiler_id_str.encode("utf-8"):
28
+ compiler_id_int <<= 8
29
+ compiler_id_int += b
30
+
31
+ # combine the compiler id and compiler version into a version number
32
+ return f"==4.{compiler_id_int}.{compiler_version}"
@@ -32,14 +32,13 @@ dev = [
32
32
  "versioneer",
33
33
  "packaging",
34
34
  "wheel",
35
- "amulet_pybind11_extensions~=1.0",
36
35
  "pybind11_stubgen>=2.5.4",
37
36
  "black>=22.3",
38
37
  "isort",
39
38
  "autoflake",
40
39
  "mypy",
41
40
  "types-pyinstaller",
42
- "amulet-test-utils~=1.1",
41
+ "amulet-test-utils~=1.3",
43
42
  ]
44
43
 
45
44
  [project.urls]
@@ -1,14 +1,15 @@
1
1
  import os
2
2
  from packaging.version import Version
3
+ import get_compiler
3
4
 
4
5
  AMULET_COMPILER_TARGET_REQUIREMENT = "==2.0"
5
- AMULET_COMPILER_VERSION_REQUIREMENT = "==3.0.0"
6
6
 
7
7
  PYBIND11_REQUIREMENT = "==3.0.0"
8
- AMULET_PYBIND11_EXTENSIONS_REQUIREMENT = "~=1.1.0.0a0"
8
+ AMULET_PYBIND11_EXTENSIONS_REQUIREMENT = "~=1.2.0.0a0"
9
9
  AMULET_IO_REQUIREMENT = "~=1.0"
10
- AMULET_ZLIB_REQUIREMENT = "~=1.0.1.0a0"
11
- AMULET_NBT_REQUIREMENT = "~=5.0.1.0a0"
10
+ AMULET_UTILS_REQUIREMENT = "~=1.1.3.0a1"
11
+ AMULET_ZLIB_REQUIREMENT = "~=1.0.8.0a0"
12
+ AMULET_NBT_REQUIREMENT = "~=5.0.2.0a0"
12
13
  NUMPY_REQUIREMENT = "~=2.0"
13
14
 
14
15
  if os.environ.get("AMULET_PYBIND11_EXTENSIONS_REQUIREMENT", None):
@@ -19,6 +20,11 @@ if os.environ.get("AMULET_IO_REQUIREMENT", None):
19
20
  f"{AMULET_IO_REQUIREMENT},{os.environ['AMULET_IO_REQUIREMENT']}"
20
21
  )
21
22
 
23
+ if os.environ.get("AMULET_UTILS_REQUIREMENT", None):
24
+ AMULET_UTILS_REQUIREMENT = (
25
+ f"{AMULET_UTILS_REQUIREMENT},{os.environ['AMULET_UTILS_REQUIREMENT']}"
26
+ )
27
+
22
28
  if os.environ.get("AMULET_ZLIB_REQUIREMENT", None):
23
29
  AMULET_ZLIB_REQUIREMENT = (
24
30
  f"{AMULET_ZLIB_REQUIREMENT},{os.environ['AMULET_ZLIB_REQUIREMENT']}"
@@ -41,40 +47,45 @@ def get_specifier_set(version_str: str) -> str:
41
47
  return f"~={version.major}.{version.minor}.{version.micro}.0{''.join(map(str, version.pre or ()))}"
42
48
 
43
49
 
44
- if os.environ.get("AMULET_FREEZE_COMPILER", None):
45
- import get_compiler
46
-
47
- AMULET_COMPILER_VERSION_REQUIREMENT = get_compiler.main()
50
+ AMULET_COMPILER_VERSION_REQUIREMENT = get_compiler.main()
48
51
 
49
- try:
50
- import amulet.pybind11_extensions
51
- except ImportError:
52
- pass
53
- else:
54
- AMULET_PYBIND11_EXTENSIONS_REQUIREMENT = get_specifier_set(
55
- amulet.pybind11_extensions.__version__
56
- )
57
52
 
58
- try:
59
- import amulet.io
60
- except ImportError:
61
- pass
62
- else:
63
- AMULET_IO_REQUIREMENT = get_specifier_set(amulet.io.__version__)
64
-
65
- try:
66
- import amulet.zlib
67
- except ImportError:
68
- pass
69
- else:
70
- AMULET_ZLIB_REQUIREMENT = get_specifier_set(amulet.zlib.__version__)
53
+ try:
54
+ import amulet.pybind11_extensions
55
+ except ImportError:
56
+ pass
57
+ else:
58
+ AMULET_PYBIND11_EXTENSIONS_REQUIREMENT = get_specifier_set(
59
+ amulet.pybind11_extensions.__version__
60
+ )
71
61
 
72
- try:
73
- import amulet.nbt
74
- except ImportError:
75
- pass
76
- else:
77
- AMULET_NBT_REQUIREMENT = get_specifier_set(amulet.nbt.__version__)
62
+ try:
63
+ import amulet.io
64
+ except ImportError:
65
+ pass
66
+ else:
67
+ AMULET_IO_REQUIREMENT = get_specifier_set(amulet.io.__version__)
68
+
69
+ try:
70
+ import amulet.utils
71
+ except ImportError:
72
+ pass
73
+ else:
74
+ AMULET_UTILS_REQUIREMENT = get_specifier_set(amulet.utils.__version__)
75
+
76
+ try:
77
+ import amulet.zlib
78
+ except ImportError:
79
+ pass
80
+ else:
81
+ AMULET_ZLIB_REQUIREMENT = get_specifier_set(amulet.zlib.__version__)
82
+
83
+ try:
84
+ import amulet.nbt
85
+ except ImportError:
86
+ pass
87
+ else:
88
+ AMULET_NBT_REQUIREMENT = get_specifier_set(amulet.nbt.__version__)
78
89
 
79
90
 
80
91
  def get_build_dependencies() -> list:
@@ -83,6 +94,7 @@ def get_build_dependencies() -> list:
83
94
  f"pybind11{PYBIND11_REQUIREMENT}",
84
95
  f"amulet-pybind11-extensions{AMULET_PYBIND11_EXTENSIONS_REQUIREMENT}",
85
96
  f"amulet-io{AMULET_IO_REQUIREMENT}",
97
+ f"amulet-utils{AMULET_UTILS_REQUIREMENT}",
86
98
  f"amulet-zlib{AMULET_ZLIB_REQUIREMENT}",
87
99
  f"amulet-nbt{AMULET_NBT_REQUIREMENT}",
88
100
  ] * (not os.environ.get("AMULET_SKIP_COMPILE", None))
@@ -95,6 +107,7 @@ def get_runtime_dependencies() -> list[str]:
95
107
  f"pybind11{PYBIND11_REQUIREMENT}",
96
108
  f"amulet-pybind11-extensions{AMULET_PYBIND11_EXTENSIONS_REQUIREMENT}",
97
109
  f"amulet-io{AMULET_IO_REQUIREMENT}",
110
+ f"amulet-utils{AMULET_UTILS_REQUIREMENT}",
98
111
  f"amulet-zlib{AMULET_ZLIB_REQUIREMENT}",
99
112
  f"amulet-nbt{AMULET_NBT_REQUIREMENT}",
100
113
  f"numpy{NUMPY_REQUIREMENT}",
@@ -3,25 +3,15 @@ import subprocess
3
3
  import sys
4
4
  from pathlib import Path
5
5
  import platform
6
- import datetime
7
6
  from tempfile import TemporaryDirectory
8
7
 
9
8
  from setuptools import setup, Extension, Command
10
9
  from setuptools.command.build_ext import build_ext
11
10
 
12
- from packaging.version import Version
13
-
14
11
  import versioneer
15
12
 
16
13
  import requirements
17
14
 
18
- if (
19
- os.environ.get("AMULET_FREEZE_COMPILER", None)
20
- and sys.platform == "darwin"
21
- and platform.machine() != "arm64"
22
- ):
23
- raise Exception("The MacOS frozen build must be created on arm64")
24
-
25
15
 
26
16
  def fix_path(path: str) -> str:
27
17
  return os.path.realpath(path).replace(os.sep, "/")
@@ -35,6 +25,7 @@ class CMakeBuild(cmdclass.get("build_ext", build_ext)):
35
25
  import pybind11
36
26
  import amulet.pybind11_extensions
37
27
  import amulet.io
28
+ import amulet.utils
38
29
  import amulet.nbt
39
30
 
40
31
  ext_dir = (
@@ -69,6 +60,7 @@ class CMakeBuild(cmdclass.get("build_ext", build_ext)):
69
60
  f"-Dpybind11_DIR={fix_path(pybind11.get_cmake_dir())}",
70
61
  f"-Damulet_pybind11_extensions_DIR={fix_path(amulet.pybind11_extensions.__path__[0])}",
71
62
  f"-Damulet_io_DIR={fix_path(amulet.io.__path__[0])}",
63
+ f"-Damulet_utils_DIR={fix_path(amulet.utils.__path__[0])}",
72
64
  f"-Damulet_nbt_DIR={fix_path(amulet.nbt.__path__[0])}",
73
65
  f"-Damulet_core_DIR={fix_path(core_src_dir)}",
74
66
  f"-DAMULET_CORE_EXT_DIR={fix_path(ext_dir)}",
@@ -91,35 +83,8 @@ class CMakeBuild(cmdclass.get("build_ext", build_ext)):
91
83
  cmdclass["build_ext"] = CMakeBuild
92
84
 
93
85
 
94
- def _get_version() -> str:
95
- version_str: str = versioneer.get_version()
96
-
97
- if os.environ.get("AMULET_FREEZE_COMPILER", None):
98
- date_format = "%y%m%d%H%M%S"
99
- try:
100
- with open("build/timestamp.txt", "r") as f:
101
- timestamp = datetime.datetime.strptime(f.read(), date_format)
102
- except Exception:
103
- timestamp = datetime.datetime(1, 1, 1)
104
- if datetime.timedelta(minutes=10) < datetime.datetime.now() - timestamp:
105
- timestamp = datetime.datetime.now()
106
- os.makedirs("build", exist_ok=True)
107
- with open("build/timestamp.txt", "w") as f:
108
- f.write(timestamp.strftime(date_format))
109
-
110
- version = Version(version_str)
111
- epoch = f"{version.epoch}!" if version.epoch else ""
112
- release = ".".join(map(str, version.release))
113
- pre = "".join(map(str, version.pre)) if version.is_prerelease else ""
114
- post = f".post{timestamp.strftime(date_format)}"
115
- local = f"+{version.local}" if version.local else ""
116
- version_str = f"{epoch}{release}{pre}{post}{local}"
117
-
118
- return version_str
119
-
120
-
121
86
  setup(
122
- version=_get_version(),
87
+ version=versioneer.get_version(),
123
88
  cmdclass=cmdclass,
124
89
  ext_modules=[Extension("amulet.core._amulet_core", [])]
125
90
  * (not os.environ.get("AMULET_SKIP_COMPILE", None)),
@@ -23,6 +23,7 @@ def _init() -> None:
23
23
  raise RuntimeError(f"Unsupported platform {sys.platform}")
24
24
 
25
25
  # Import dependencies
26
+ import amulet.utils
26
27
  import amulet.zlib
27
28
  import amulet.nbt
28
29
 
@@ -13,7 +13,7 @@ from . import (
13
13
  version,
14
14
  )
15
15
 
16
- __all__ = [
16
+ __all__: list[str] = [
17
17
  "biome",
18
18
  "block",
19
19
  "block_entity",
@@ -17,6 +17,7 @@ void init_chunk(py::module);
17
17
  void init_module(py::module m)
18
18
  {
19
19
  pyext::init_compiler_config(m);
20
+ pyext::check_compatibility(py::module::import("amulet.utils"), m);
20
21
  pyext::check_compatibility(py::module::import("amulet.zlib"), m);
21
22
  pyext::check_compatibility(py::module::import("amulet.nbt"), m);
22
23
 
@@ -2,6 +2,6 @@ from __future__ import annotations
2
2
 
3
3
  import types
4
4
 
5
- __all__ = ["init"]
5
+ __all__: list[str] = ["init"]
6
6
 
7
7
  def init(arg0: types.ModuleType) -> None: ...
@@ -8,11 +8,11 @@ import json
8
8
 
9
9
  version_json = '''
10
10
  {
11
- "date": "2025-07-28T13:06:55+0100",
11
+ "date": "2025-09-17T11:29:24+0100",
12
12
  "dirty": false,
13
13
  "error": null,
14
- "full-revisionid": "9f6478cecb25ca0c0779bb4bf851c1a4ee0771cf",
15
- "version": "2.0.4a1"
14
+ "full-revisionid": "7ed2b2b5421e7cb0691779cf4861faf812f8cee3",
15
+ "version": "2.0.5a1"
16
16
  }
17
17
  ''' # END VERSION_JSON
18
18
 
@@ -3,6 +3,7 @@ if (NOT TARGET amulet_core)
3
3
 
4
4
  find_package(amulet_io CONFIG REQUIRED)
5
5
  find_package(amulet_nbt CONFIG REQUIRED)
6
+ find_package(amulet_utils CONFIG REQUIRED)
6
7
 
7
8
  set(amulet_core_INCLUDE_DIR "${CMAKE_CURRENT_LIST_DIR}/../..")
8
9
  find_library(amulet_core_LIBRARY NAMES amulet_core PATHS "${CMAKE_CURRENT_LIST_DIR}")
@@ -16,6 +17,7 @@ if (NOT TARGET amulet_core)
16
17
  add_library(amulet_core INTERFACE)
17
18
  target_link_libraries(amulet_core INTERFACE amulet_io)
18
19
  target_link_libraries(amulet_core INTERFACE amulet_nbt)
20
+ target_link_libraries(amulet_core INTERFACE amulet_utils)
19
21
  target_link_libraries(amulet_core INTERFACE amulet_core_bin)
20
22
  target_include_directories(amulet_core INTERFACE ${amulet_core_INCLUDE_DIR})
21
23
  endif()
@@ -5,7 +5,7 @@ import typing
5
5
 
6
6
  import amulet.core.version
7
7
 
8
- __all__ = ["Biome"]
8
+ __all__: list[str] = ["Biome"]
9
9
 
10
10
  class Biome(amulet.core.version.PlatformVersionContainer):
11
11
  """
@@ -25,9 +25,9 @@ class Biome(amulet.core.version.PlatformVersionContainer):
25
25
  """
26
26
 
27
27
  @typing.overload
28
- def __eq__(self, arg0: Biome) -> bool: ...
28
+ def __eq__(self, other: Biome) -> bool: ...
29
29
  @typing.overload
30
- def __eq__(self, arg0: typing.Any) -> bool | types.NotImplementedType: ...
30
+ def __eq__(self, other: typing.Any) -> bool | types.NotImplementedType: ...
31
31
  def __ge__(self, arg0: Biome) -> bool: ...
32
32
  def __gt__(self, arg0: Biome) -> bool: ...
33
33
  def __hash__(self) -> int: ...
@@ -7,7 +7,7 @@ import typing
7
7
  import amulet.core.version
8
8
  import amulet.nbt
9
9
 
10
- __all__ = ["Block", "BlockStack"]
10
+ __all__: list[str] = ["Block", "BlockStack"]
11
11
 
12
12
  class Block(amulet.core.version.PlatformVersionContainer):
13
13
  """
@@ -77,9 +77,9 @@ class Block(amulet.core.version.PlatformVersionContainer):
77
77
  """
78
78
 
79
79
  @typing.overload
80
- def __eq__(self, arg0: Block) -> bool: ...
80
+ def __eq__(self, other: Block) -> bool: ...
81
81
  @typing.overload
82
- def __eq__(self, arg0: typing.Any) -> bool | types.NotImplementedType: ...
82
+ def __eq__(self, other: typing.Any) -> bool | types.NotImplementedType: ...
83
83
  def __ge__(self, arg0: Block) -> bool: ...
84
84
  def __gt__(self, arg0: Block) -> bool: ...
85
85
  def __hash__(self) -> int: ...
@@ -216,16 +216,16 @@ class BlockStack:
216
216
  >>> blocks = list(waterlogged_stone)
217
217
  """
218
218
 
219
- def __contains__(self, arg0: typing.Any) -> bool: ...
219
+ def __contains__(self, item: typing.Any) -> bool: ...
220
220
  @typing.overload
221
- def __eq__(self, arg0: BlockStack) -> bool: ...
221
+ def __eq__(self, other: BlockStack) -> bool: ...
222
222
  @typing.overload
223
- def __eq__(self, arg0: typing.Any) -> bool | types.NotImplementedType: ...
223
+ def __eq__(self, other: typing.Any) -> bool | types.NotImplementedType: ...
224
224
  def __ge__(self, arg0: BlockStack) -> bool: ...
225
225
  @typing.overload
226
226
  def __getitem__(self, arg0: typing.SupportsInt) -> Block: ...
227
227
  @typing.overload
228
- def __getitem__(self, arg0: slice) -> list: ...
228
+ def __getitem__(self, item: slice) -> list[Block]: ...
229
229
  def __gt__(self, arg0: BlockStack) -> bool: ...
230
230
  def __hash__(self) -> int: ...
231
231
  def __init__(self, block: Block, *extra_blocks: Block) -> None: ...
@@ -235,10 +235,10 @@ class BlockStack:
235
235
  def __lt__(self, arg0: BlockStack) -> bool: ...
236
236
  def __repr__(self) -> str: ...
237
237
  def __reversed__(self) -> collections.abc.Iterator[Block]: ...
238
- def count(self, value: typing.Any) -> int: ...
238
+ def count(self, value: Block) -> int: ...
239
239
  def index(
240
240
  self,
241
- value: typing.Any,
241
+ value: Block,
242
242
  start: typing.SupportsInt = 0,
243
243
  stop: typing.SupportsInt = 9223372036854775807,
244
244
  ) -> int: ...
@@ -6,8 +6,8 @@
6
6
  #include <memory>
7
7
  #include <span>
8
8
 
9
- #include <amulet/pybind11_extensions/types.hpp>
10
9
  #include <amulet/pybind11_extensions/py_module.hpp>
10
+ #include <amulet/pybind11_extensions/types.hpp>
11
11
 
12
12
  #include <amulet/pybind11_extensions/sequence.hpp>
13
13
 
@@ -278,8 +278,7 @@ void init_block(py::module m_parent)
278
278
  if (index < 0) {
279
279
  throw py::index_error("");
280
280
  }
281
- }
282
- if (index >= self.size()) {
281
+ } else if (index >= self.size()) {
283
282
  throw py::index_error("");
284
283
  }
285
284
  return self.at(index);
@@ -300,13 +299,14 @@ void init_block(py::module m_parent)
300
299
  return Amulet::deserialise<Amulet::BlockStack>(state.cast<std::string>());
301
300
  }));
302
301
 
303
- pyext::collections::def_Sequence_getitem_slice(BlockStack);
304
- pyext::collections::def_Sequence_contains(BlockStack);
305
- pyext::collections::def_Sequence_iter<Amulet::Block>(BlockStack);
306
- pyext::collections::def_Sequence_reversed<Amulet::Block>(BlockStack);
307
- pyext::collections::def_Sequence_index(BlockStack);
308
- pyext::collections::def_Sequence_count(BlockStack);
309
- pyext::collections::register_Sequence(BlockStack);
302
+ using BlockSequence = pyext::collections::Sequence<Amulet::Block>;
303
+ BlockSequence::def_getitem_slice(BlockStack);
304
+ BlockSequence::def_contains(BlockStack);
305
+ BlockSequence::def_iter(BlockStack);
306
+ BlockSequence::def_reversed(BlockStack);
307
+ BlockSequence::def_index(BlockStack);
308
+ BlockSequence::def_count(BlockStack);
309
+ BlockSequence::register_cls(BlockStack);
310
310
 
311
311
  BlockStack.def(py::self == py::self);
312
312
  BlockStack.def(py::self > py::self);
@@ -6,7 +6,7 @@ import typing
6
6
  import amulet.core.version
7
7
  import amulet.nbt
8
8
 
9
- __all__ = ["BlockEntity"]
9
+ __all__: list[str] = ["BlockEntity"]
10
10
 
11
11
  class BlockEntity(amulet.core.version.PlatformVersionContainer):
12
12
  """
@@ -14,9 +14,9 @@ class BlockEntity(amulet.core.version.PlatformVersionContainer):
14
14
  """
15
15
 
16
16
  @typing.overload
17
- def __eq__(self, arg0: BlockEntity) -> bool: ...
17
+ def __eq__(self, other: BlockEntity) -> bool: ...
18
18
  @typing.overload
19
- def __eq__(self, arg0: typing.Any) -> bool | types.NotImplementedType: ...
19
+ def __eq__(self, other: typing.Any) -> bool | types.NotImplementedType: ...
20
20
  def __hash__(self) -> int: ...
21
21
  def __init__(
22
22
  self,
@@ -2,7 +2,7 @@ from __future__ import annotations
2
2
 
3
3
  from . import component
4
4
 
5
- __all__ = [
5
+ __all__: list[str] = [
6
6
  "Chunk",
7
7
  "ChunkDoesNotExist",
8
8
  "ChunkLoadError",
@@ -8,7 +8,7 @@ from amulet.core.chunk.component.section_array_map import IndexArray3D, SectionA
8
8
 
9
9
  from . import block_component, section_array_map
10
10
 
11
- __all__ = [
11
+ __all__: list[str] = [
12
12
  "BlockComponent",
13
13
  "BlockComponentData",
14
14
  "IndexArray3D",
@@ -7,7 +7,7 @@ import amulet.core.chunk.component.section_array_map
7
7
  import amulet.core.palette.block_palette
8
8
  import amulet.core.version
9
9
 
10
- __all__ = ["BlockComponent", "BlockComponentData"]
10
+ __all__: list[str] = ["BlockComponent", "BlockComponentData"]
11
11
 
12
12
  class BlockComponent:
13
13
  ComponentID: typing.ClassVar[str] = "Amulet::BlockComponent"
@@ -221,17 +221,18 @@ py::module init_section_array_map(py::module m_parent)
221
221
  SectionArrayMap.def(
222
222
  "__contains__",
223
223
  &Amulet::SectionArrayMap::contains_section);
224
- pyext::collections::def_Mapping_keys<std::int64_t>(SectionArrayMap);
225
- pyext::collections::def_Mapping_values<pyext::numpy::array_t<std::uint32_t>>(SectionArrayMap);
226
- pyext::collections::def_Mapping_items<std::int64_t, pyext::numpy::array_t<std::uint32_t>>(SectionArrayMap);
227
- pyext::collections::def_Mapping_get<std::int64_t, pyext::numpy::array_t<std::uint32_t>>(SectionArrayMap);
228
- pyext::collections::def_Mapping_eq(SectionArrayMap);
229
- pyext::collections::def_Mapping_hash(SectionArrayMap);
230
- pyext::collections::def_MutableMapping_pop<std::int64_t, pyext::numpy::array_t<std::uint32_t>>(SectionArrayMap);
231
- pyext::collections::def_MutableMapping_popitem<std::int64_t, pyext::numpy::array_t<std::uint32_t>>(SectionArrayMap);
232
- pyext::collections::def_MutableMapping_update(SectionArrayMap);
233
- pyext::collections::def_MutableMapping_setdefault<std::int64_t, pyext::numpy::array_t<std::uint32_t>>(SectionArrayMap);
234
- pyext::collections::register_MutableMapping(SectionArrayMap);
224
+ using SectionMap = pyext::collections::MutableMapping<std::int64_t, pyext::numpy::array_t<std::uint32_t>>;
225
+ SectionMap::def_keys(SectionArrayMap);
226
+ SectionMap::def_values(SectionArrayMap);
227
+ SectionMap::def_items(SectionArrayMap);
228
+ SectionMap::def_get(SectionArrayMap);
229
+ SectionMap::def_eq(SectionArrayMap);
230
+ SectionMap::def_hash(SectionArrayMap);
231
+ SectionMap::def_pop(SectionArrayMap);
232
+ SectionMap::def_popitem(SectionArrayMap);
233
+ SectionMap::def_update(SectionArrayMap);
234
+ SectionMap::def_setdefault(SectionArrayMap);
235
+ SectionMap::register_cls(SectionArrayMap);
235
236
 
236
237
  SectionArrayMap.def(
237
238
  py::pickle(