amulet-anvil 1.0.0a0__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.
Files changed (35) hide show
  1. amulet_anvil-1.0.0a0/CMakeLists.txt +98 -0
  2. amulet_anvil-1.0.0a0/MANIFEST.in +8 -0
  3. amulet_anvil-1.0.0a0/PKG-INFO +37 -0
  4. amulet_anvil-1.0.0a0/README.md +3 -0
  5. amulet_anvil-1.0.0a0/build_requires.py +24 -0
  6. amulet_anvil-1.0.0a0/pyproject.toml +70 -0
  7. amulet_anvil-1.0.0a0/requirements.py +120 -0
  8. amulet_anvil-1.0.0a0/setup.cfg +4 -0
  9. amulet_anvil-1.0.0a0/setup.py +128 -0
  10. amulet_anvil-1.0.0a0/src/amulet/anvil/__init__.py +39 -0
  11. amulet_anvil-1.0.0a0/src/amulet/anvil/__init__.pyi +28 -0
  12. amulet_anvil-1.0.0a0/src/amulet/anvil/__pyinstaller/__init__.py +2 -0
  13. amulet_anvil-1.0.0a0/src/amulet/anvil/__pyinstaller/hook-amulet.anvil.py +4 -0
  14. amulet_anvil-1.0.0a0/src/amulet/anvil/_amulet_anvil.py.cpp +36 -0
  15. amulet_anvil-1.0.0a0/src/amulet/anvil/_amulet_anvil.pyi +7 -0
  16. amulet_anvil-1.0.0a0/src/amulet/anvil/_version.py +21 -0
  17. amulet_anvil-1.0.0a0/src/amulet/anvil/amulet_anvilConfig.cmake +23 -0
  18. amulet_anvil-1.0.0a0/src/amulet/anvil/dimension.cpp +428 -0
  19. amulet_anvil-1.0.0a0/src/amulet/anvil/dimension.hpp +349 -0
  20. amulet_anvil-1.0.0a0/src/amulet/anvil/dimension.py.cpp +271 -0
  21. amulet_anvil-1.0.0a0/src/amulet/anvil/dimension.pyi +248 -0
  22. amulet_anvil-1.0.0a0/src/amulet/anvil/dll.hpp +21 -0
  23. amulet_anvil-1.0.0a0/src/amulet/anvil/py.typed +0 -0
  24. amulet_anvil-1.0.0a0/src/amulet/anvil/region.cpp +682 -0
  25. amulet_anvil-1.0.0a0/src/amulet/anvil/region.hpp +300 -0
  26. amulet_anvil-1.0.0a0/src/amulet/anvil/region.py.cpp +188 -0
  27. amulet_anvil-1.0.0a0/src/amulet/anvil/region.pyi +168 -0
  28. amulet_anvil-1.0.0a0/src/amulet/anvil/sector_manager.cpp +165 -0
  29. amulet_anvil-1.0.0a0/src/amulet/anvil/sector_manager.hpp +95 -0
  30. amulet_anvil-1.0.0a0/src/amulet_anvil.egg-info/PKG-INFO +37 -0
  31. amulet_anvil-1.0.0a0/src/amulet_anvil.egg-info/SOURCES.txt +33 -0
  32. amulet_anvil-1.0.0a0/src/amulet_anvil.egg-info/dependency_links.txt +1 -0
  33. amulet_anvil-1.0.0a0/src/amulet_anvil.egg-info/entry_points.txt +2 -0
  34. amulet_anvil-1.0.0a0/src/amulet_anvil.egg-info/requires.txt +21 -0
  35. amulet_anvil-1.0.0a0/src/amulet_anvil.egg-info/top_level.txt +1 -0
@@ -0,0 +1,98 @@
1
+ cmake_minimum_required(VERSION 3.13)
2
+
3
+ project(amulet_anvil LANGUAGES CXX)
4
+
5
+ # Set C++20
6
+ set(CMAKE_CXX_STANDARD 20)
7
+ set(CMAKE_CXX_STANDARD_REQUIRED ON)
8
+ set(CMAKE_CXX_EXTENSIONS OFF)
9
+
10
+ # Set platform variables
11
+ if (WIN32)
12
+ # set windows 7 as the minimum version
13
+ add_definitions(-D_WIN32_WINNT=0x0601)
14
+ elseif(APPLE)
15
+ set(CMAKE_OSX_DEPLOYMENT_TARGET "10.15")
16
+ else()
17
+ set(CMAKE_POSITION_INDEPENDENT_CODE ON)
18
+ endif()
19
+
20
+ if (MSVC)
21
+ add_definitions("/MP")
22
+ endif()
23
+
24
+ include(FetchContent)
25
+
26
+ # Add lz4
27
+ FetchContent_Declare(
28
+ lz4
29
+ GIT_REPOSITORY https://github.com/lz4/lz4.git
30
+ GIT_TAG ebb370ca83af193212df4dcbadcc5d87bc0de2f0
31
+ )
32
+ FetchContent_MakeAvailable(lz4)
33
+ set(LZ4_BUILD_CLI OFF)
34
+ add_subdirectory(${lz4_SOURCE_DIR}/build/cmake)
35
+
36
+ # Add pybind11
37
+ find_package(pybind11 CONFIG REQUIRED)
38
+
39
+ # Add Amulet libraries
40
+ find_package(amulet_pybind11_extensions CONFIG REQUIRED)
41
+ find_package(amulet_nbt CONFIG REQUIRED)
42
+ find_package(amulet_core CONFIG REQUIRED)
43
+ find_package(amulet_utils CONFIG REQUIRED)
44
+ find_package(amulet_zlib CONFIG REQUIRED)
45
+
46
+ # Find C++ files
47
+ file(REAL_PATH src SOURCE_PATH)
48
+ file(GLOB_RECURSE EXTENSION_SOURCES LIST_DIRECTORIES false ${SOURCE_PATH}/amulet/*.py.cpp)
49
+ file(GLOB_RECURSE EXTENSION_HEADERS LIST_DIRECTORIES false ${SOURCE_PATH}/amulet/*.py.hpp)
50
+ file(GLOB_RECURSE SOURCES LIST_DIRECTORIES false ${SOURCE_PATH}/amulet/*.cpp)
51
+ file(GLOB_RECURSE HEADERS LIST_DIRECTORIES false ${SOURCE_PATH}/amulet/*.hpp)
52
+ list(REMOVE_ITEM SOURCES ${EXTENSION_SOURCES})
53
+ list(REMOVE_ITEM HEADERS ${EXTENSION_HEADERS})
54
+
55
+ # Add implementation
56
+ add_library(amulet_anvil SHARED)
57
+ target_compile_definitions(amulet_anvil PRIVATE ExportAmuletAnvil)
58
+ target_link_libraries( amulet_anvil PRIVATE lz4_static )
59
+ target_link_libraries( amulet_anvil PRIVATE amulet_zlib )
60
+ target_link_libraries( amulet_anvil PUBLIC amulet_nbt )
61
+ target_link_libraries( amulet_anvil PUBLIC amulet_core )
62
+ target_link_libraries( amulet_anvil PUBLIC amulet_utils )
63
+ target_include_directories(amulet_anvil PUBLIC ${SOURCE_PATH})
64
+ target_sources(amulet_anvil PRIVATE ${SOURCES} ${HEADERS})
65
+ foreach(FILE ${SOURCES} ${HEADERS})
66
+ file(RELATIVE_PATH REL_PATH ${SOURCE_PATH} ${FILE})
67
+ get_filename_component(GROUP ${REL_PATH} DIRECTORY)
68
+ string(REPLACE "/" "\\" GROUP ${GROUP})
69
+ source_group(${GROUP} FILES ${FILE})
70
+ endforeach()
71
+
72
+ # Add python extension
73
+ pybind11_add_module(_amulet_anvil)
74
+ target_link_libraries( _amulet_anvil PRIVATE amulet_pybind11_extensions )
75
+ target_link_libraries( _amulet_anvil PRIVATE amulet_anvil )
76
+ target_compile_definitions(_amulet_anvil PRIVATE PYBIND11_DETAILED_ERROR_MESSAGES)
77
+ target_compile_definitions(_amulet_anvil PRIVATE PYBIND11_VERSION="${pybind11_VERSION}")
78
+ target_compile_definitions(_amulet_anvil PRIVATE COMPILER_ID="${CMAKE_CXX_COMPILER_ID}")
79
+ target_compile_definitions(_amulet_anvil PRIVATE COMPILER_VERSION="${CMAKE_CXX_COMPILER_VERSION}")
80
+ target_sources(_amulet_anvil PRIVATE ${EXTENSION_SOURCES} ${EXTENSION_HEADERS})
81
+ foreach(FILE ${EXTENSION_SOURCES} ${EXTENSION_HEADERS})
82
+ file(RELATIVE_PATH REL_PATH ${SOURCE_PATH} ${FILE})
83
+ get_filename_component(GROUP ${REL_PATH} DIRECTORY)
84
+ string(REPLACE "/" "\\" GROUP ${GROUP})
85
+ source_group(${GROUP} FILES ${FILE})
86
+ endforeach()
87
+
88
+ if(NOT DEFINED AMULET_ANVIL_EXT_DIR)
89
+ set(AMULET_ANVIL_EXT_DIR ${amulet_anvil_DIR})
90
+ endif()
91
+
92
+ # Install
93
+ install(TARGETS amulet_anvil DESTINATION ${amulet_anvil_DIR})
94
+ install(TARGETS _amulet_anvil DESTINATION ${AMULET_ANVIL_EXT_DIR})
95
+
96
+ if (DEFINED BUILD_AMULET_ANVIL_TESTS)
97
+ add_subdirectory(tests)
98
+ endif()
@@ -0,0 +1,8 @@
1
+ include build_requires.py
2
+ include requirements.py
3
+
4
+ recursive-include src/amulet *.cpp *.hpp *Config.cmake
5
+
6
+ include CMakeLists.txt
7
+
8
+ prune tests
@@ -0,0 +1,37 @@
1
+ Metadata-Version: 2.4
2
+ Name: amulet-anvil
3
+ Version: 1.0.0a0
4
+ Summary: A C++ library with Python wrapper for the Minecraft Anvil format.
5
+ Author: James Clare
6
+ Project-URL: Homepage, https://www.amuletmc.com
7
+ Project-URL: Repository, https://github.com/Amulet-Team/Amulet-Anvil
8
+ Project-URL: Issues, https://github.com/Amulet-Team/Amulet-Anvil/issues
9
+ Classifier: Programming Language :: Python :: 3
10
+ Classifier: Operating System :: OS Independent
11
+ Requires-Python: >=3.11
12
+ Description-Content-Type: text/markdown
13
+ Requires-Dist: pybind11==2.13.6
14
+ Requires-Dist: amulet-compiler-target==1.0
15
+ Requires-Dist: amulet-compiler-version==3.0.0
16
+ Requires-Dist: amulet-zlib~=1.0.0.0a1
17
+ Requires-Dist: amulet-nbt~=5.0.0.0a1
18
+ Requires-Dist: amulet-core~=2.0.2.0a1
19
+ Requires-Dist: amulet-utils~=1.1.0.0a2
20
+ Provides-Extra: dev
21
+ Requires-Dist: setuptools>=42; extra == "dev"
22
+ Requires-Dist: versioneer; extra == "dev"
23
+ Requires-Dist: packaging; extra == "dev"
24
+ Requires-Dist: wheel; extra == "dev"
25
+ Requires-Dist: amulet_pybind11_extensions~=1.0; extra == "dev"
26
+ Requires-Dist: pybind11_stubgen>=2.5.4; extra == "dev"
27
+ Requires-Dist: black>=22.3; extra == "dev"
28
+ Requires-Dist: isort; extra == "dev"
29
+ Requires-Dist: autoflake; extra == "dev"
30
+ Requires-Dist: mypy; extra == "dev"
31
+ Requires-Dist: types-pyinstaller; extra == "dev"
32
+ Requires-Dist: amulet-test-utils~=1.1; extra == "dev"
33
+ Dynamic: requires-dist
34
+
35
+ # Amulet Anvil
36
+
37
+ A C++ library with Python wrapper for the Minecraft Anvil format.
@@ -0,0 +1,3 @@
1
+ # Amulet Anvil
2
+
3
+ A C++ library with Python wrapper for the Minecraft Anvil format.
@@ -0,0 +1,24 @@
1
+ from typing import Union, Mapping
2
+ import requirements
3
+
4
+ from setuptools import build_meta
5
+ from setuptools.build_meta import *
6
+
7
+
8
+ def get_requires_for_build_wheel(
9
+ config_settings: Union[Mapping[str, Union[str, list[str], None]], None] = None,
10
+ ) -> list[str]:
11
+ return [
12
+ *build_meta.get_requires_for_build_wheel(config_settings),
13
+ "wheel",
14
+ *requirements.get_build_dependencies(),
15
+ ]
16
+
17
+
18
+ def get_requires_for_build_editable(
19
+ config_settings: Union[Mapping[str, Union[str, list[str], None]], None] = None,
20
+ ) -> list[str]:
21
+ return [
22
+ *build_meta.get_requires_for_build_editable(config_settings),
23
+ *requirements.get_build_dependencies(),
24
+ ]
@@ -0,0 +1,70 @@
1
+ [build-system]
2
+ requires = [
3
+ "setuptools>=42",
4
+ "versioneer",
5
+ "packaging",
6
+ "amulet-compiler-version@git+https://github.com/Amulet-Team/Amulet-Compiler-Version.git@3.0"
7
+ ]
8
+ build-backend = "build_requires"
9
+ backend-path = [""]
10
+
11
+ [project]
12
+ name = "amulet-anvil"
13
+ authors = [
14
+ {name = "James Clare"},
15
+ ]
16
+ description = "A C++ library with Python wrapper for the Minecraft Anvil format."
17
+ dynamic = ["version", "readme", "dependencies"]
18
+ requires-python = ">=3.11"
19
+ classifiers = [
20
+ "Programming Language :: Python :: 3",
21
+ "Operating System :: OS Independent",
22
+ ]
23
+
24
+ [project.optional-dependencies]
25
+ dev = [
26
+ "setuptools>=42",
27
+ "versioneer",
28
+ "packaging",
29
+ "wheel",
30
+ "amulet_pybind11_extensions~=1.0",
31
+ "pybind11_stubgen>=2.5.4",
32
+ "black>=22.3",
33
+ "isort",
34
+ "autoflake",
35
+ "mypy",
36
+ "types-pyinstaller",
37
+ "amulet-test-utils~=1.1",
38
+ ]
39
+
40
+ [project.urls]
41
+ Homepage = "https://www.amuletmc.com"
42
+ Repository = "https://github.com/Amulet-Team/Amulet-Anvil"
43
+ Issues = "https://github.com/Amulet-Team/Amulet-Anvil/issues"
44
+
45
+ [tool.setuptools]
46
+ include-package-data = false
47
+
48
+ [tool.setuptools.package-data]
49
+ "*" = [
50
+ "*Config.cmake",
51
+ "**/*.hpp",
52
+ "**/*.dll",
53
+ "**/*.so",
54
+ "**/*.dylib",
55
+ "**/*.lib"
56
+ ]
57
+
58
+ [tool.setuptools.dynamic]
59
+ readme = {file = ["README.md"], content-type = "text/markdown"}
60
+
61
+ [project.entry-points.pyinstaller40]
62
+ hook-dirs = "amulet.anvil.__pyinstaller:get_hook_dirs"
63
+
64
+ [tool.versioneer]
65
+ VCS = "git"
66
+ style = "pep440"
67
+ versionfile_source = "src/amulet/anvil/_version.py"
68
+ versionfile_build = "amulet/anvil/_version.py"
69
+ tag_prefix = ""
70
+ parentdir_prefix = "amulet-anvil-"
@@ -0,0 +1,120 @@
1
+ import os
2
+ import amulet_compiler_version
3
+ from packaging.version import Version
4
+
5
+ AMULET_COMPILER_TARGET_REQUIREMENT = "==1.0"
6
+ AMULET_COMPILER_VERSION_REQUIREMENT = "==3.0.0"
7
+
8
+ PYBIND11_REQUIREMENT = "==2.13.6"
9
+ AMULET_PYBIND11_EXTENSIONS_REQUIREMENT = "~=1.0"
10
+
11
+ AMULET_IO_REQUIREMENT = "~=1.0"
12
+ # AMULET_ZLIB_REQUIREMENT = "~=1.0"
13
+ AMULET_ZLIB_REQUIREMENT = "~=1.0.0.0a1"
14
+ # AMULET_NBT_REQUIREMENT = "~=5.0"
15
+ AMULET_NBT_REQUIREMENT = "~=5.0.0.0a1"
16
+ # AMULET_CORE_REQUIREMENT = "~=2.0"
17
+ AMULET_CORE_REQUIREMENT = "~=2.0.2.0a1"
18
+ # AMULET_UTILS_REQUIREMENT = "~=1.1"
19
+ AMULET_UTILS_REQUIREMENT = "~=1.1.0.0a2"
20
+
21
+
22
+ if os.environ.get("AMULET_IO_REQUIREMENT", None):
23
+ AMULET_IO_REQUIREMENT = (
24
+ f"{AMULET_IO_REQUIREMENT},{os.environ['AMULET_IO_REQUIREMENT']}"
25
+ )
26
+
27
+ if os.environ.get("AMULET_ZLIB_REQUIREMENT", None):
28
+ AMULET_ZLIB_REQUIREMENT = (
29
+ f"{AMULET_ZLIB_REQUIREMENT},{os.environ['AMULET_ZLIB_REQUIREMENT']}"
30
+ )
31
+
32
+ if os.environ.get("AMULET_NBT_REQUIREMENT", None):
33
+ AMULET_NBT_REQUIREMENT = (
34
+ f"{AMULET_NBT_REQUIREMENT},{os.environ['AMULET_NBT_REQUIREMENT']}"
35
+ )
36
+
37
+ if os.environ.get("AMULET_CORE_REQUIREMENT", None):
38
+ AMULET_CORE_REQUIREMENT = (
39
+ f"{AMULET_CORE_REQUIREMENT},{os.environ['AMULET_CORE_REQUIREMENT']}"
40
+ )
41
+
42
+ if os.environ.get("AMULET_UTILS_REQUIREMENT", None):
43
+ AMULET_UTILS_REQUIREMENT = (
44
+ f"{AMULET_UTILS_REQUIREMENT},{os.environ['AMULET_UTILS_REQUIREMENT']}"
45
+ )
46
+
47
+
48
+ def get_specifier_set(version_str: str) -> str:
49
+ """
50
+ version_str: The PEP 440 version number of the library.
51
+ """
52
+ version = Version(version_str)
53
+ if version.epoch != 0 or version.is_devrelease or version.is_postrelease:
54
+ raise RuntimeError(f"Unsupported version format. {version_str}")
55
+
56
+ return f"~={version.major}.{version.minor}.{version.micro}.0{''.join(map(str, version.pre or ()))}"
57
+
58
+
59
+ if os.environ.get("AMULET_FREEZE_COMPILER", None):
60
+ AMULET_COMPILER_VERSION_REQUIREMENT = f"=={amulet_compiler_version.__version__}"
61
+
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.zlib
71
+ except ImportError:
72
+ pass
73
+ else:
74
+ AMULET_ZLIB_REQUIREMENT = get_specifier_set(amulet.zlib.__version__)
75
+
76
+ try:
77
+ import amulet.nbt
78
+ except ImportError:
79
+ pass
80
+ else:
81
+ AMULET_NBT_REQUIREMENT = get_specifier_set(amulet.nbt.__version__)
82
+
83
+ try:
84
+ import amulet.core
85
+ except ImportError:
86
+ pass
87
+ else:
88
+ AMULET_CORE_REQUIREMENT = get_specifier_set(amulet.core.__version__)
89
+
90
+ try:
91
+ import amulet.utils
92
+ except ImportError:
93
+ pass
94
+ else:
95
+ AMULET_UTILS_REQUIREMENT = get_specifier_set(amulet.utils.__version__)
96
+
97
+
98
+ def get_build_dependencies() -> list:
99
+ return [
100
+ f"pybind11{PYBIND11_REQUIREMENT}",
101
+ f"amulet_pybind11_extensions{AMULET_PYBIND11_EXTENSIONS_REQUIREMENT}",
102
+ f"amulet-compiler-version{AMULET_COMPILER_VERSION_REQUIREMENT}",
103
+ f"amulet_io{AMULET_IO_REQUIREMENT}",
104
+ f"amulet-zlib{AMULET_ZLIB_REQUIREMENT}",
105
+ f"amulet-nbt{AMULET_NBT_REQUIREMENT}",
106
+ f"amulet-core{AMULET_CORE_REQUIREMENT}",
107
+ f"amulet-utils{AMULET_UTILS_REQUIREMENT}",
108
+ ]
109
+
110
+
111
+ def get_runtime_dependencies() -> list[str]:
112
+ return [
113
+ f"pybind11{PYBIND11_REQUIREMENT}",
114
+ f"amulet-compiler-target{AMULET_COMPILER_TARGET_REQUIREMENT}",
115
+ f"amulet-compiler-version{AMULET_COMPILER_VERSION_REQUIREMENT}",
116
+ f"amulet-zlib{AMULET_ZLIB_REQUIREMENT}",
117
+ f"amulet-nbt{AMULET_NBT_REQUIREMENT}",
118
+ f"amulet-core{AMULET_CORE_REQUIREMENT}",
119
+ f"amulet-utils{AMULET_UTILS_REQUIREMENT}",
120
+ ]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,128 @@
1
+ import os
2
+ import subprocess
3
+ import sys
4
+ from pathlib import Path
5
+ import platform
6
+ import datetime
7
+
8
+ from setuptools import setup, Extension, Command
9
+ from setuptools.command.build_ext import build_ext
10
+
11
+ from packaging.version import Version
12
+
13
+ import versioneer
14
+
15
+ import requirements
16
+
17
+ if (
18
+ os.environ.get("AMULET_FREEZE_COMPILER", None)
19
+ and sys.platform == "darwin"
20
+ and platform.machine() != "arm64"
21
+ ):
22
+ raise Exception("The MacOS frozen build must be created on arm64")
23
+
24
+
25
+ def fix_path(path: str) -> str:
26
+ return os.path.realpath(path).replace(os.sep, "/")
27
+
28
+
29
+ cmdclass: dict[str, type[Command]] = versioneer.get_cmdclass()
30
+
31
+
32
+ class CMakeBuild(cmdclass.get("build_ext", build_ext)):
33
+ def build_extension(self, ext):
34
+ import pybind11
35
+ import amulet.pybind11_extensions
36
+ import amulet.io
37
+ import amulet.nbt
38
+ import amulet.core
39
+ import amulet.utils
40
+ import amulet.zlib
41
+
42
+ ext_dir = (
43
+ (Path.cwd() / self.get_ext_fullpath("")).parent.resolve()
44
+ / "amulet"
45
+ / "anvil"
46
+ )
47
+ anvil_src_dir = (
48
+ Path.cwd() / "src" / "amulet" / "anvil" if self.editable_mode else ext_dir
49
+ )
50
+
51
+ platform_args = []
52
+ if sys.platform == "win32":
53
+ platform_args.extend(["-G", "Visual Studio 17 2022"])
54
+ if sys.maxsize > 2**32:
55
+ platform_args.extend(["-A", "x64"])
56
+ else:
57
+ platform_args.extend(["-A", "Win32"])
58
+ platform_args.extend(["-T", "v143"])
59
+ elif sys.platform == "darwin":
60
+ if platform.machine() == "arm64":
61
+ platform_args.append("-DCMAKE_OSX_ARCHITECTURES=x86_64;arm64")
62
+
63
+ if subprocess.run(
64
+ [
65
+ "cmake",
66
+ *platform_args,
67
+ f"-DPYTHON_EXECUTABLE={sys.executable}",
68
+ f"-Dpybind11_DIR={pybind11.get_cmake_dir().replace(os.sep, '/')}",
69
+ f"-Damulet_pybind11_extensions_DIR={fix_path(amulet.pybind11_extensions.__path__[0])}",
70
+ f"-Damulet_io_DIR={fix_path(amulet.io.__path__[0])}",
71
+ f"-Damulet_nbt_DIR={fix_path(amulet.nbt.__path__[0])}",
72
+ f"-Damulet_core_DIR={fix_path(amulet.core.__path__[0])}",
73
+ f"-Damulet_utils_DIR={fix_path(amulet.utils.__path__[0])}",
74
+ f"-Damulet_zlib_DIR={fix_path(amulet.zlib.__path__[0])}",
75
+ f"-Damulet_anvil_DIR={fix_path(anvil_src_dir)}",
76
+ f"-DAMULET_ANVIL_EXT_DIR={fix_path(ext_dir)}",
77
+ f"-DCMAKE_INSTALL_PREFIX=install",
78
+ "-B",
79
+ "build",
80
+ ]
81
+ ).returncode:
82
+ raise RuntimeError("Error configuring amulet_anvil")
83
+ if subprocess.run(
84
+ ["cmake", "--build", "build", "--config", "Release"]
85
+ ).returncode:
86
+ raise RuntimeError("Error installing amulet_anvil")
87
+ if subprocess.run(
88
+ ["cmake", "--install", "build", "--config", "Release"]
89
+ ).returncode:
90
+ raise RuntimeError("Error installing amulet_anvil")
91
+
92
+
93
+ cmdclass["build_ext"] = CMakeBuild
94
+
95
+
96
+ def _get_version() -> str:
97
+ version_str: str = versioneer.get_version()
98
+
99
+ if os.environ.get("AMULET_FREEZE_COMPILER", None):
100
+ date_format = "%y%m%d%H%M%S"
101
+ try:
102
+ with open("build/timestamp.txt", "r") as f:
103
+ timestamp = datetime.datetime.strptime(f.read(), date_format)
104
+ except Exception:
105
+ timestamp = datetime.datetime(1, 1, 1)
106
+ if datetime.timedelta(minutes=10) < datetime.datetime.now() - timestamp:
107
+ timestamp = datetime.datetime.now()
108
+ os.makedirs("build", exist_ok=True)
109
+ with open("build/timestamp.txt", "w") as f:
110
+ f.write(timestamp.strftime(date_format))
111
+
112
+ version = Version(version_str)
113
+ epoch = f"{version.epoch}!" if version.epoch else ""
114
+ release = ".".join(map(str, version.release))
115
+ pre = "".join(map(str, version.pre)) if version.is_prerelease else ""
116
+ post = f".post{timestamp.strftime(date_format)}"
117
+ local = f"+{version.local}" if version.local else ""
118
+ version_str = f"{epoch}{release}{pre}{post}{local}"
119
+
120
+ return version_str
121
+
122
+
123
+ setup(
124
+ version=_get_version(),
125
+ cmdclass=cmdclass,
126
+ ext_modules=[Extension("amulet.anvil._amulet_anvil", [])],
127
+ install_requires=requirements.get_runtime_dependencies(),
128
+ )
@@ -0,0 +1,39 @@
1
+ import logging
2
+
3
+ from . import _version
4
+
5
+ __version__ = _version.get_versions()["version"]
6
+
7
+ # init a default logger
8
+ logging.basicConfig(level=logging.INFO, format="%(levelname)s - %(message)s")
9
+
10
+
11
+ def _init() -> None:
12
+ import os
13
+ import sys
14
+ import ctypes
15
+
16
+ if sys.platform == "win32":
17
+ lib_path = os.path.join(os.path.dirname(__file__), "amulet_anvil.dll")
18
+ elif sys.platform == "darwin":
19
+ lib_path = os.path.join(os.path.dirname(__file__), "libamulet_anvil.dylib")
20
+ elif sys.platform == "linux":
21
+ lib_path = os.path.join(os.path.dirname(__file__), "libamulet_anvil.so")
22
+ else:
23
+ raise RuntimeError(f"Unsupported platform {sys.platform}")
24
+
25
+ # Import dependencies
26
+ import amulet.nbt
27
+ import amulet.core
28
+ import amulet.utils
29
+ import amulet.zlib
30
+
31
+ # Load the shared library
32
+ ctypes.cdll.LoadLibrary(lib_path)
33
+
34
+ from ._amulet_anvil import init
35
+
36
+ init(sys.modules[__name__])
37
+
38
+
39
+ _init()
@@ -0,0 +1,28 @@
1
+ from __future__ import annotations
2
+
3
+ import logging as logging
4
+ import typing
5
+
6
+ import amulet.nbt
7
+ from amulet.anvil.dimension import AnvilDimension, AnvilDimensionLayer
8
+ from amulet.anvil.region import AnvilRegion, RegionDoesNotExist
9
+
10
+ from . import _amulet_anvil, _version, dimension, region
11
+
12
+ __all__ = [
13
+ "AnvilDimension",
14
+ "AnvilDimensionLayer",
15
+ "AnvilRegion",
16
+ "RawChunkType",
17
+ "RegionDoesNotExist",
18
+ "compiler_config",
19
+ "dimension",
20
+ "logging",
21
+ "region",
22
+ ]
23
+
24
+ def _init() -> None: ...
25
+
26
+ RawChunkType: typing.TypeAlias = dict[str, amulet.nbt.NamedTag]
27
+ __version__: str
28
+ compiler_config: dict
@@ -0,0 +1,2 @@
1
+ def get_hook_dirs() -> list[str]:
2
+ return __path__
@@ -0,0 +1,4 @@
1
+ from PyInstaller.utils.hooks import collect_data_files, collect_submodules
2
+
3
+ hiddenimports = collect_submodules("amulet.anvil")
4
+ datas = collect_data_files("amulet.anvil")
@@ -0,0 +1,36 @@
1
+ #include <pybind11/pybind11.h>
2
+
3
+ #include <amulet/pybind11_extensions/compatibility.hpp>
4
+ #include <amulet/pybind11_extensions/py_module.hpp>
5
+
6
+ namespace py = pybind11;
7
+ namespace pyext = Amulet::pybind11_extensions;
8
+
9
+ py::module init_anvil_region(py::module);
10
+ py::module init_anvil_dimension(py::module);
11
+
12
+ void init_module(py::module m)
13
+ {
14
+ pyext::init_compiler_config(m);
15
+ pyext::check_compatibility(py::module::import("amulet.zlib"), m);
16
+ pyext::check_compatibility(py::module::import("amulet.nbt"), m);
17
+ pyext::check_compatibility(py::module::import("amulet.core"), m);
18
+ pyext::check_compatibility(py::module::import("amulet.utils"), m);
19
+
20
+ auto region = init_anvil_region(m);
21
+ auto dimension = init_anvil_dimension(m);
22
+
23
+ m.attr("AnvilRegion") = region.attr("AnvilRegion");
24
+ m.attr("RegionDoesNotExist") = region.attr("RegionDoesNotExist");
25
+ m.attr("AnvilDimensionLayer") = dimension.attr("AnvilDimensionLayer");
26
+ m.attr("AnvilDimension") = dimension.attr("AnvilDimension");
27
+ m.attr("RawChunkType") = dimension.attr("RawChunkType");
28
+ }
29
+
30
+ PYBIND11_MODULE(_amulet_anvil, m)
31
+ {
32
+ py::options options;
33
+ options.disable_function_signatures();
34
+ m.def("init", &init_module, py::doc("init(arg0: types.ModuleType) -> None"));
35
+ options.enable_function_signatures();
36
+ }
@@ -0,0 +1,7 @@
1
+ from __future__ import annotations
2
+
3
+ import types
4
+
5
+ __all__ = ["init"]
6
+
7
+ def init(arg0: types.ModuleType) -> None: ...
@@ -0,0 +1,21 @@
1
+
2
+ # This file was generated by 'versioneer.py' (0.29) from
3
+ # revision-control system data, or from the parent directory name of an
4
+ # unpacked source archive. Distribution tarballs contain a pre-generated copy
5
+ # of this file.
6
+
7
+ import json
8
+
9
+ version_json = '''
10
+ {
11
+ "date": "2025-06-12T11:19:40+0100",
12
+ "dirty": false,
13
+ "error": null,
14
+ "full-revisionid": "cfc71a65525a11eac462c9642380915a9622278b",
15
+ "version": "1.0.0a0"
16
+ }
17
+ ''' # END VERSION_JSON
18
+
19
+
20
+ def get_versions():
21
+ return json.loads(version_json)
@@ -0,0 +1,23 @@
1
+ if (NOT TARGET amulet_anvil)
2
+ message(STATUS "Finding amulet_anvil")
3
+
4
+ find_package(amulet_nbt CONFIG REQUIRED)
5
+ find_package(amulet_core CONFIG REQUIRED)
6
+ find_package(amulet_utils CONFIG REQUIRED)
7
+
8
+ set(amulet_anvil_INCLUDE_DIR "${CMAKE_CURRENT_LIST_DIR}/../..")
9
+ find_library(amulet_anvil_LIBRARY NAMES amulet_anvil PATHS "${CMAKE_CURRENT_LIST_DIR}")
10
+ message(STATUS "amulet_anvil_LIBRARY: ${amulet_anvil_LIBRARY}")
11
+
12
+ add_library(amulet_anvil_bin SHARED IMPORTED)
13
+ set_target_properties(amulet_anvil_bin PROPERTIES
14
+ IMPORTED_IMPLIB "${amulet_anvil_LIBRARY}"
15
+ )
16
+
17
+ add_library(amulet_anvil INTERFACE)
18
+ target_link_libraries(amulet_anvil INTERFACE amulet_nbt)
19
+ target_link_libraries(amulet_anvil INTERFACE amulet_core)
20
+ target_link_libraries(amulet_anvil INTERFACE amulet_utils)
21
+ target_link_libraries(amulet_anvil INTERFACE amulet_anvil_bin)
22
+ target_include_directories(amulet_anvil INTERFACE ${amulet_anvil_INCLUDE_DIR})
23
+ endif()