amulet-core 2.0a7__cp311-cp311-win_amd64.whl → 2.0.1a2.post250529084738__cp311-cp311-win_amd64.whl
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.
- amulet/core/__init__.py +36 -0
- amulet/core/__pyinstaller/hook-amulet.core.py +4 -0
- amulet/core/_amulet_core.cp311-win_amd64.pyd +0 -0
- amulet/core/_amulet_core.pyi +7 -0
- amulet/{_version.py → core/_version.py} +3 -3
- amulet/core/amulet_core.dll +0 -0
- amulet/core/amulet_core.lib +0 -0
- amulet/core/amulet_coreConfig.cmake +18 -0
- amulet/{biome.pyi → core/biome/__init__.pyi} +3 -3
- amulet/core/biome/biome.hpp +53 -0
- amulet/{block.pyi → core/block/__init__.pyi} +25 -26
- amulet/core/block/block.hpp +156 -0
- amulet/{block_entity.pyi → core/block_entity/__init__.pyi} +7 -7
- amulet/core/block_entity/block_entity.hpp +84 -0
- amulet/{errors.py → core/chunk/__init__.pyi} +37 -33
- amulet/core/chunk/chunk.hpp +126 -0
- amulet/core/chunk/component/__init__.pyi +18 -0
- amulet/core/chunk/component/biome_3d_component.hpp +96 -0
- amulet/core/chunk/component/block_component.hpp +101 -0
- amulet/core/chunk/component/block_component.pyi +28 -0
- amulet/core/chunk/component/block_entity_component.hpp +119 -0
- amulet/core/chunk/component/section_array_map.hpp +129 -0
- amulet/{chunk_components.pyi → core/chunk/component/section_array_map.pyi} +4 -24
- amulet/core/dll.hpp +21 -0
- amulet/core/entity/__init__.pyi +105 -0
- amulet/core/entity/entity.hpp +100 -0
- amulet/{palette → core/palette}/__init__.pyi +2 -2
- amulet/core/palette/biome_palette.hpp +65 -0
- amulet/{palette → core/palette}/biome_palette.pyi +8 -8
- amulet/core/palette/block_palette.hpp +71 -0
- amulet/{palette → core/palette}/block_palette.pyi +12 -10
- amulet/core/selection/__init__.pyi +8 -0
- amulet/core/selection/box.hpp +86 -0
- amulet/core/selection/box.pyi +215 -0
- amulet/core/selection/group.hpp +80 -0
- amulet/core/selection/group.pyi +213 -0
- amulet/{version.pyi → core/version/__init__.pyi} +58 -10
- amulet/core/version/version.hpp +204 -0
- {amulet_core-2.0a7.dist-info → amulet_core-2.0.1a2.post250529084738.dist-info}/METADATA +25 -20
- amulet_core-2.0.1a2.post250529084738.dist-info/RECORD +45 -0
- {amulet_core-2.0a7.dist-info → amulet_core-2.0.1a2.post250529084738.dist-info}/WHEEL +1 -1
- amulet_core-2.0.1a2.post250529084738.dist-info/entry_points.txt +2 -0
- amulet/__init__.cp311-win_amd64.pyd +0 -0
- amulet/__init__.py.cpp +0 -43
- amulet/__init__.pyi +0 -28
- amulet/__pyinstaller/hook-amulet.py +0 -4
- amulet/_init.py +0 -26
- amulet/biome.cpp +0 -36
- amulet/biome.hpp +0 -43
- amulet/biome.py.cpp +0 -122
- amulet/block.cpp +0 -435
- amulet/block.hpp +0 -119
- amulet/block.py.cpp +0 -377
- amulet/block_entity.cpp +0 -12
- amulet/block_entity.hpp +0 -56
- amulet/block_entity.py.cpp +0 -115
- amulet/chunk.cpp +0 -16
- amulet/chunk.hpp +0 -99
- amulet/chunk.py.cpp +0 -80
- amulet/chunk.pyi +0 -28
- amulet/chunk_components/biome_3d_component.cpp +0 -5
- amulet/chunk_components/biome_3d_component.hpp +0 -79
- amulet/chunk_components/block_component.cpp +0 -41
- amulet/chunk_components/block_component.hpp +0 -88
- amulet/chunk_components/block_entity_component.cpp +0 -5
- amulet/chunk_components/block_entity_component.hpp +0 -147
- amulet/chunk_components/section_array_map.cpp +0 -129
- amulet/chunk_components/section_array_map.hpp +0 -147
- amulet/collections/eq.py.hpp +0 -37
- amulet/collections/hash.py.hpp +0 -27
- amulet/collections/holder.py.hpp +0 -37
- amulet/collections/iterator.py.hpp +0 -80
- amulet/collections/mapping.py.hpp +0 -199
- amulet/collections/mutable_mapping.py.hpp +0 -226
- amulet/collections/sequence.py.hpp +0 -163
- amulet/collections.pyi +0 -40
- amulet/data_types.py +0 -29
- amulet/entity.py +0 -182
- amulet/game/__init__.py +0 -7
- amulet/game/_game.py +0 -152
- amulet/game/_universal/__init__.py +0 -1
- amulet/game/_universal/_biome.py +0 -17
- amulet/game/_universal/_block.py +0 -47
- amulet/game/_universal/_version.py +0 -68
- amulet/game/abc/__init__.py +0 -22
- amulet/game/abc/_block_specification.py +0 -150
- amulet/game/abc/biome.py +0 -213
- amulet/game/abc/block.py +0 -331
- amulet/game/abc/game_version_container.py +0 -25
- amulet/game/abc/json_interface.py +0 -27
- amulet/game/abc/version.py +0 -44
- amulet/game/bedrock/__init__.py +0 -1
- amulet/game/bedrock/_biome.py +0 -35
- amulet/game/bedrock/_block.py +0 -42
- amulet/game/bedrock/_version.py +0 -165
- amulet/game/java/__init__.py +0 -2
- amulet/game/java/_biome.py +0 -35
- amulet/game/java/_block.py +0 -60
- amulet/game/java/_version.py +0 -176
- amulet/game/translate/__init__.py +0 -12
- amulet/game/translate/_functions/__init__.py +0 -15
- amulet/game/translate/_functions/_code_functions/__init__.py +0 -0
- amulet/game/translate/_functions/_code_functions/_text.py +0 -553
- amulet/game/translate/_functions/_code_functions/banner_pattern.py +0 -67
- amulet/game/translate/_functions/_code_functions/bedrock_chest_connection.py +0 -152
- amulet/game/translate/_functions/_code_functions/bedrock_moving_block_pos.py +0 -88
- amulet/game/translate/_functions/_code_functions/bedrock_sign.py +0 -152
- amulet/game/translate/_functions/_code_functions/bedrock_skull_rotation.py +0 -16
- amulet/game/translate/_functions/_code_functions/custom_name.py +0 -146
- amulet/game/translate/_functions/_frozen.py +0 -66
- amulet/game/translate/_functions/_state.py +0 -54
- amulet/game/translate/_functions/_typing.py +0 -98
- amulet/game/translate/_functions/abc.py +0 -123
- amulet/game/translate/_functions/carry_nbt.py +0 -160
- amulet/game/translate/_functions/carry_properties.py +0 -80
- amulet/game/translate/_functions/code.py +0 -143
- amulet/game/translate/_functions/map_block_name.py +0 -66
- amulet/game/translate/_functions/map_nbt.py +0 -111
- amulet/game/translate/_functions/map_properties.py +0 -93
- amulet/game/translate/_functions/multiblock.py +0 -112
- amulet/game/translate/_functions/new_block.py +0 -42
- amulet/game/translate/_functions/new_entity.py +0 -43
- amulet/game/translate/_functions/new_nbt.py +0 -206
- amulet/game/translate/_functions/new_properties.py +0 -64
- amulet/game/translate/_functions/sequence.py +0 -51
- amulet/game/translate/_functions/walk_input_nbt.py +0 -331
- amulet/game/translate/_translator.py +0 -433
- amulet/img/__init__.py +0 -10
- amulet/img/missing_no.png +0 -0
- amulet/img/missing_pack.png +0 -0
- amulet/img/missing_world.png +0 -0
- amulet/io/binary_reader.hpp +0 -45
- amulet/io/binary_writer.hpp +0 -30
- amulet/item.py +0 -75
- amulet/level/__init__.pyi +0 -23
- amulet/level/_load.py +0 -100
- amulet/level/abc/__init__.py +0 -12
- amulet/level/abc/_chunk_handle.py +0 -335
- amulet/level/abc/_dimension.py +0 -86
- amulet/level/abc/_history/__init__.py +0 -1
- amulet/level/abc/_history/_cache.py +0 -224
- amulet/level/abc/_history/_history_manager.py +0 -291
- amulet/level/abc/_level/__init__.py +0 -5
- amulet/level/abc/_level/_compactable_level.py +0 -10
- amulet/level/abc/_level/_creatable_level.py +0 -28
- amulet/level/abc/_level/_disk_level.py +0 -17
- amulet/level/abc/_level/_level.py +0 -449
- amulet/level/abc/_level/_loadable_level.py +0 -42
- amulet/level/abc/_player_storage.py +0 -7
- amulet/level/abc/_raw_level.py +0 -187
- amulet/level/abc/_registry.py +0 -40
- amulet/level/java/__init__.pyi +0 -16
- amulet/level/java/_chunk_handle.py +0 -17
- amulet/level/java/_dimension.py +0 -20
- amulet/level/java/_level.py +0 -184
- amulet/level/java/_raw/__init__.pyi +0 -15
- amulet/level/java/_raw/_chunk.pyi +0 -23
- amulet/level/java/_raw/_constant.py +0 -9
- amulet/level/java/_raw/_data_pack/__init__.py +0 -2
- amulet/level/java/_raw/_data_pack/data_pack.py +0 -241
- amulet/level/java/_raw/_data_pack/data_pack_manager.py +0 -77
- amulet/level/java/_raw/_dimension.py +0 -86
- amulet/level/java/_raw/_level.py +0 -507
- amulet/level/java/_raw/_typing.py +0 -3
- amulet/level/java/_raw/java_chunk_decode.cpp +0 -531
- amulet/level/java/_raw/java_chunk_decode.hpp +0 -23
- amulet/level/java/_raw/java_chunk_encode.cpp +0 -25
- amulet/level/java/_raw/java_chunk_encode.hpp +0 -23
- amulet/level/java/anvil/__init__.py +0 -2
- amulet/level/java/anvil/_dimension.py +0 -170
- amulet/level/java/anvil/_region.py +0 -421
- amulet/level/java/anvil/_sector_manager.py +0 -223
- amulet/level/java/chunk.pyi +0 -81
- amulet/level/java/chunk_/_chunk.py +0 -260
- amulet/level/java/chunk_/components/inhabited_time.py +0 -12
- amulet/level/java/chunk_/components/last_update.py +0 -12
- amulet/level/java/chunk_/components/legacy_version.py +0 -12
- amulet/level/java/chunk_/components/light_populated.py +0 -12
- amulet/level/java/chunk_/components/named_height_2d.py +0 -37
- amulet/level/java/chunk_/components/status.py +0 -11
- amulet/level/java/chunk_/components/terrain_populated.py +0 -12
- amulet/level/java/chunk_components/data_version_component.cpp +0 -32
- amulet/level/java/chunk_components/data_version_component.hpp +0 -31
- amulet/level/java/chunk_components/java_raw_chunk_component.cpp +0 -56
- amulet/level/java/chunk_components/java_raw_chunk_component.hpp +0 -45
- amulet/level/java/chunk_components.pyi +0 -22
- amulet/level/java/java_chunk.cpp +0 -170
- amulet/level/java/java_chunk.hpp +0 -141
- amulet/level/java/long_array.hpp +0 -175
- amulet/level/java/long_array.pyi +0 -39
- amulet/level/temporary_level/__init__.py +0 -1
- amulet/level/temporary_level/_level.py +0 -16
- amulet/mesh/__init__.py +0 -0
- amulet/mesh/block/__init__.py +0 -1
- amulet/mesh/block/block_mesh.py +0 -369
- amulet/mesh/block/cube.py +0 -149
- amulet/mesh/block/missing_block.py +0 -20
- amulet/mesh/util.py +0 -17
- amulet/palette/biome_palette.hpp +0 -85
- amulet/palette/block_palette.cpp +0 -32
- amulet/palette/block_palette.hpp +0 -93
- amulet/player.py +0 -62
- amulet/pybind11/collections.hpp +0 -118
- amulet/pybind11/numpy.hpp +0 -26
- amulet/pybind11/py_module.hpp +0 -34
- amulet/pybind11/type_hints.hpp +0 -51
- amulet/pybind11/types.hpp +0 -25
- amulet/pybind11/typing.hpp +0 -7
- amulet/resource_pack/__init__.py +0 -62
- amulet/resource_pack/abc/__init__.py +0 -2
- amulet/resource_pack/abc/resource_pack.py +0 -38
- amulet/resource_pack/abc/resource_pack_manager.py +0 -87
- amulet/resource_pack/bedrock/__init__.py +0 -2
- amulet/resource_pack/bedrock/bedrock_vanilla_fix/pack_icon.png +0 -0
- amulet/resource_pack/bedrock/bedrock_vanilla_fix/textures/blocks/grass_carried.png +0 -0
- amulet/resource_pack/bedrock/bedrock_vanilla_fix/textures/blocks/grass_side_carried.png +0 -0
- amulet/resource_pack/bedrock/bedrock_vanilla_fix/textures/blocks/water.png +0 -0
- amulet/resource_pack/bedrock/blockshapes/__init__.py +0 -31
- amulet/resource_pack/bedrock/blockshapes/air.py +0 -35
- amulet/resource_pack/bedrock/blockshapes/base_blockshape.py +0 -29
- amulet/resource_pack/bedrock/blockshapes/bubble_column.py +0 -29
- amulet/resource_pack/bedrock/blockshapes/cake.py +0 -46
- amulet/resource_pack/bedrock/blockshapes/chest.py +0 -54
- amulet/resource_pack/bedrock/blockshapes/comparator.py +0 -51
- amulet/resource_pack/bedrock/blockshapes/cross_texture.py +0 -186
- amulet/resource_pack/bedrock/blockshapes/cross_texture0.py +0 -17
- amulet/resource_pack/bedrock/blockshapes/cross_texture_green.py +0 -16
- amulet/resource_pack/bedrock/blockshapes/cube.py +0 -38
- amulet/resource_pack/bedrock/blockshapes/default.py +0 -14
- amulet/resource_pack/bedrock/blockshapes/door.py +0 -38
- amulet/resource_pack/bedrock/blockshapes/door1.py +0 -14
- amulet/resource_pack/bedrock/blockshapes/door2.py +0 -14
- amulet/resource_pack/bedrock/blockshapes/door3.py +0 -14
- amulet/resource_pack/bedrock/blockshapes/door4.py +0 -14
- amulet/resource_pack/bedrock/blockshapes/door5.py +0 -14
- amulet/resource_pack/bedrock/blockshapes/door6.py +0 -14
- amulet/resource_pack/bedrock/blockshapes/double_plant.py +0 -40
- amulet/resource_pack/bedrock/blockshapes/enchanting_table.py +0 -22
- amulet/resource_pack/bedrock/blockshapes/farmland.py +0 -22
- amulet/resource_pack/bedrock/blockshapes/fence.py +0 -22
- amulet/resource_pack/bedrock/blockshapes/flat.py +0 -55
- amulet/resource_pack/bedrock/blockshapes/flat_wall.py +0 -55
- amulet/resource_pack/bedrock/blockshapes/furnace.py +0 -44
- amulet/resource_pack/bedrock/blockshapes/furnace_lit.py +0 -14
- amulet/resource_pack/bedrock/blockshapes/green_cube.py +0 -39
- amulet/resource_pack/bedrock/blockshapes/ladder.py +0 -36
- amulet/resource_pack/bedrock/blockshapes/lilypad.py +0 -14
- amulet/resource_pack/bedrock/blockshapes/partial_block.py +0 -57
- amulet/resource_pack/bedrock/blockshapes/piston.py +0 -44
- amulet/resource_pack/bedrock/blockshapes/piston_arm.py +0 -72
- amulet/resource_pack/bedrock/blockshapes/portal_frame.py +0 -22
- amulet/resource_pack/bedrock/blockshapes/pressure_plate.py +0 -29
- amulet/resource_pack/bedrock/blockshapes/pumpkin.py +0 -36
- amulet/resource_pack/bedrock/blockshapes/pumpkin_carved.py +0 -14
- amulet/resource_pack/bedrock/blockshapes/pumpkin_lit.py +0 -14
- amulet/resource_pack/bedrock/blockshapes/red_dust.py +0 -14
- amulet/resource_pack/bedrock/blockshapes/repeater.py +0 -53
- amulet/resource_pack/bedrock/blockshapes/slab.py +0 -33
- amulet/resource_pack/bedrock/blockshapes/slab_double.py +0 -15
- amulet/resource_pack/bedrock/blockshapes/tree.py +0 -41
- amulet/resource_pack/bedrock/blockshapes/turtle_egg.py +0 -15
- amulet/resource_pack/bedrock/blockshapes/vine.py +0 -52
- amulet/resource_pack/bedrock/blockshapes/wall.py +0 -22
- amulet/resource_pack/bedrock/blockshapes/water.py +0 -38
- amulet/resource_pack/bedrock/download_resources.py +0 -147
- amulet/resource_pack/bedrock/resource_pack.py +0 -40
- amulet/resource_pack/bedrock/resource_pack_manager.py +0 -361
- amulet/resource_pack/bedrock/sort_blockshapes.py +0 -15
- amulet/resource_pack/java/__init__.py +0 -2
- amulet/resource_pack/java/download_resources.py +0 -212
- amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/banner/banner_black.png +0 -0
- amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/banner/banner_blue.png +0 -0
- amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/banner/banner_brown.png +0 -0
- amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/banner/banner_cyan.png +0 -0
- amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/banner/banner_gray.png +0 -0
- amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/banner/banner_green.png +0 -0
- amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/banner/banner_light_blue.png +0 -0
- amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/banner/banner_light_gray.png +0 -0
- amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/banner/banner_lime.png +0 -0
- amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/banner/banner_magenta.png +0 -0
- amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/banner/banner_orange.png +0 -0
- amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/banner/banner_pink.png +0 -0
- amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/banner/banner_purple.png +0 -0
- amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/banner/banner_red.png +0 -0
- amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/banner/banner_white.png +0 -0
- amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/banner/banner_yellow.png +0 -0
- amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/barrier.png +0 -0
- amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/end_portal.png +0 -0
- amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/grass.png +0 -0
- amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/lava.png +0 -0
- amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/structure_void.png +0 -0
- amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/water.png +0 -0
- amulet/resource_pack/java/java_vanilla_fix/pack.png +0 -0
- amulet/resource_pack/java/resource_pack.py +0 -44
- amulet/resource_pack/java/resource_pack_manager.py +0 -551
- amulet/resource_pack/unknown_resource_pack.py +0 -10
- amulet/selection/__init__.py +0 -2
- amulet/selection/abstract_selection.py +0 -342
- amulet/selection/box.py +0 -852
- amulet/selection/group.py +0 -481
- amulet/utils/__init__.pyi +0 -23
- amulet/utils/call_spec/__init__.py +0 -24
- amulet/utils/call_spec/_call_spec.py +0 -257
- amulet/utils/comment_json.py +0 -188
- amulet/utils/format_utils.py +0 -41
- amulet/utils/generator.py +0 -18
- amulet/utils/matrix.py +0 -243
- amulet/utils/numpy.hpp +0 -36
- amulet/utils/numpy.pyi +0 -11
- amulet/utils/numpy_helpers.py +0 -19
- amulet/utils/shareable_lock.py +0 -335
- amulet/utils/signal/__init__.py +0 -10
- amulet/utils/signal/_signal.py +0 -228
- amulet/utils/task_manager.py +0 -235
- amulet/utils/typed_property.py +0 -111
- amulet/utils/weakref.py +0 -70
- amulet/utils/world_utils.py +0 -102
- amulet/version.cpp +0 -136
- amulet/version.hpp +0 -142
- amulet/version.py.cpp +0 -281
- amulet_core-2.0a7.dist-info/RECORD +0 -295
- amulet_core-2.0a7.dist-info/entry_points.txt +0 -2
- /amulet/{__pyinstaller → core/__pyinstaller}/__init__.py +0 -0
- /amulet/{py.typed → core/py.typed} +0 -0
- {amulet_core-2.0a7.dist-info → amulet_core-2.0.1a2.post250529084738.dist-info}/top_level.txt +0 -0
amulet/utils/signal/_signal.py
DELETED
|
@@ -1,228 +0,0 @@
|
|
|
1
|
-
from __future__ import annotations
|
|
2
|
-
|
|
3
|
-
import logging
|
|
4
|
-
from typing import (
|
|
5
|
-
Callable,
|
|
6
|
-
Any,
|
|
7
|
-
overload,
|
|
8
|
-
Protocol,
|
|
9
|
-
TYPE_CHECKING,
|
|
10
|
-
TypeVarTuple,
|
|
11
|
-
Generic,
|
|
12
|
-
)
|
|
13
|
-
from collections.abc import Sequence
|
|
14
|
-
from weakref import WeakMethod
|
|
15
|
-
from inspect import ismethod
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
if TYPE_CHECKING:
|
|
19
|
-
import PySide6.QtCore # type: ignore # noqa
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
CallArgs = TypeVarTuple("CallArgs")
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
class SignalInstance(Protocol[*CallArgs]):
|
|
26
|
-
def connect(
|
|
27
|
-
self,
|
|
28
|
-
slot: Callable[[*CallArgs], None] | SignalInstance[*CallArgs] | None,
|
|
29
|
-
type: PySide6.QtCore.Qt.ConnectionType | None = ...,
|
|
30
|
-
) -> None: ...
|
|
31
|
-
|
|
32
|
-
def disconnect(
|
|
33
|
-
self,
|
|
34
|
-
slot: Callable[[*CallArgs], None] | SignalInstance[*CallArgs] | None = None,
|
|
35
|
-
) -> None: ...
|
|
36
|
-
|
|
37
|
-
def emit(self, *args: *CallArgs) -> None: ...
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
_signal_instance_constructor: SignalInstanceConstructor | None = None
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
# TODO: https://github.com/python/typing/issues/1216
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
def create_signal_instance(
|
|
47
|
-
*types: type, instance: Any, name: str = "", arguments: Sequence[str] = ()
|
|
48
|
-
) -> SignalInstance[*CallArgs]:
|
|
49
|
-
"""Create a new signal instance"""
|
|
50
|
-
if _signal_instance_constructor is None:
|
|
51
|
-
set_signal_instance_constructor(get_fallback_signal_instance_constructor())
|
|
52
|
-
assert _signal_instance_constructor is not None
|
|
53
|
-
return _signal_instance_constructor(
|
|
54
|
-
types=types,
|
|
55
|
-
name=name,
|
|
56
|
-
arguments=arguments,
|
|
57
|
-
instance=instance,
|
|
58
|
-
)
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
SignalInstanceCacheName = "_SignalCache"
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
def _get_signal_instances(instance: Any) -> dict[Signal, SignalInstance]:
|
|
65
|
-
signal_instances: dict[Any, SignalInstance]
|
|
66
|
-
try:
|
|
67
|
-
signal_instances = getattr(instance, SignalInstanceCacheName)
|
|
68
|
-
except AttributeError:
|
|
69
|
-
signal_instances = {}
|
|
70
|
-
setattr(instance, SignalInstanceCacheName, signal_instances)
|
|
71
|
-
return signal_instances
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
class Signal(Generic[*CallArgs]):
|
|
75
|
-
def __init__(self, *types: type, name: str = "", arguments: Sequence[str] = ()):
|
|
76
|
-
self._types = types
|
|
77
|
-
self._name = name
|
|
78
|
-
self._arguments = arguments
|
|
79
|
-
|
|
80
|
-
@overload
|
|
81
|
-
def __get__(self, instance: None, owner: Any | None) -> Signal[*CallArgs]: ...
|
|
82
|
-
|
|
83
|
-
@overload
|
|
84
|
-
def __get__(
|
|
85
|
-
self, instance: Any, owner: Any | None
|
|
86
|
-
) -> SignalInstance[*CallArgs]: ...
|
|
87
|
-
|
|
88
|
-
def __get__(self, instance: Any, owner: Any) -> Any:
|
|
89
|
-
if instance is None:
|
|
90
|
-
return self
|
|
91
|
-
signal_instances = _get_signal_instances(instance)
|
|
92
|
-
if self not in signal_instances:
|
|
93
|
-
signal_instances[self] = create_signal_instance(
|
|
94
|
-
*self._types,
|
|
95
|
-
name=self._name,
|
|
96
|
-
arguments=self._arguments,
|
|
97
|
-
instance=instance,
|
|
98
|
-
)
|
|
99
|
-
return signal_instances[self]
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
class SignalInstanceConstructor(Protocol[*CallArgs]):
|
|
103
|
-
def __call__(
|
|
104
|
-
self,
|
|
105
|
-
*,
|
|
106
|
-
types: tuple[type, ...],
|
|
107
|
-
name: str,
|
|
108
|
-
arguments: Sequence[str],
|
|
109
|
-
instance: Any,
|
|
110
|
-
) -> SignalInstance[*CallArgs]: ...
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
def set_signal_instance_constructor(constructor: SignalInstanceConstructor) -> None:
|
|
114
|
-
global _signal_instance_constructor
|
|
115
|
-
if _signal_instance_constructor is not None:
|
|
116
|
-
raise RuntimeError("Signal instance constructor has already been set.")
|
|
117
|
-
_signal_instance_constructor = constructor
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
def get_fallback_signal_instance_constructor() -> SignalInstanceConstructor:
|
|
121
|
-
class FallbackSignalInstance(SignalInstance[*CallArgs]):
|
|
122
|
-
_callbacks: set[
|
|
123
|
-
Callable[[*CallArgs], None]
|
|
124
|
-
| WeakMethod[Callable[[*CallArgs], None]]
|
|
125
|
-
| FallbackSignalInstance[*CallArgs]
|
|
126
|
-
]
|
|
127
|
-
|
|
128
|
-
def __init__(self, *types: type):
|
|
129
|
-
self._types = types
|
|
130
|
-
self._callbacks = set()
|
|
131
|
-
|
|
132
|
-
@staticmethod
|
|
133
|
-
def _wrap_slot(
|
|
134
|
-
slot: Callable[[*CallArgs], None] | SignalInstance[*CallArgs] | None
|
|
135
|
-
) -> (
|
|
136
|
-
Callable[[*CallArgs], None]
|
|
137
|
-
| WeakMethod[Callable[[*CallArgs], None]]
|
|
138
|
-
| FallbackSignalInstance[*CallArgs]
|
|
139
|
-
):
|
|
140
|
-
if ismethod(slot):
|
|
141
|
-
return WeakMethod(slot) # type: ignore
|
|
142
|
-
elif isinstance(slot, FallbackSignalInstance) or callable(slot):
|
|
143
|
-
return slot # type: ignore
|
|
144
|
-
else:
|
|
145
|
-
raise RuntimeError(f"{slot} is not a supported slot type.")
|
|
146
|
-
|
|
147
|
-
def connect(
|
|
148
|
-
self,
|
|
149
|
-
slot: Callable[[*CallArgs], None] | SignalInstance[*CallArgs] | None,
|
|
150
|
-
type: PySide6.QtCore.Qt.ConnectionType | None = None,
|
|
151
|
-
) -> None:
|
|
152
|
-
if type is not None:
|
|
153
|
-
logging.warning(
|
|
154
|
-
"FallbackSignalInstance does not support custom connection types. Using DirectConnection"
|
|
155
|
-
)
|
|
156
|
-
self._callbacks.add(self._wrap_slot(slot))
|
|
157
|
-
|
|
158
|
-
def disconnect(
|
|
159
|
-
self,
|
|
160
|
-
slot: Callable[[*CallArgs], None] | SignalInstance[*CallArgs] | None = None,
|
|
161
|
-
) -> None:
|
|
162
|
-
self._callbacks.remove(self._wrap_slot(slot))
|
|
163
|
-
|
|
164
|
-
def emit(self, *args: *CallArgs) -> None:
|
|
165
|
-
if len(args) != len(self._types):
|
|
166
|
-
raise TypeError(
|
|
167
|
-
f"SignalInstance{self._types}.emit expected {len(self._types)} argument(s), {len(args)} given."
|
|
168
|
-
)
|
|
169
|
-
for slot in self._callbacks:
|
|
170
|
-
try:
|
|
171
|
-
if isinstance(slot, FallbackSignalInstance):
|
|
172
|
-
slot.emit(*args) # type: ignore
|
|
173
|
-
elif isinstance(slot, WeakMethod):
|
|
174
|
-
method = slot()
|
|
175
|
-
if method is not None:
|
|
176
|
-
method(*args)
|
|
177
|
-
else:
|
|
178
|
-
slot(*args)
|
|
179
|
-
except Exception as e:
|
|
180
|
-
logging.error(e)
|
|
181
|
-
|
|
182
|
-
def fallback_signal_instance_constructor(
|
|
183
|
-
*,
|
|
184
|
-
types: tuple[type, ...],
|
|
185
|
-
name: str,
|
|
186
|
-
arguments: Sequence[str],
|
|
187
|
-
instance: Any,
|
|
188
|
-
) -> FallbackSignalInstance[*CallArgs]:
|
|
189
|
-
return FallbackSignalInstance(*types)
|
|
190
|
-
|
|
191
|
-
return fallback_signal_instance_constructor
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
def get_pyside6_signal_instance_constructor() -> SignalInstanceConstructor:
|
|
195
|
-
try:
|
|
196
|
-
from PySide6.QtCore import (
|
|
197
|
-
QObject,
|
|
198
|
-
Signal as PySide6_Signal,
|
|
199
|
-
SignalInstance as PySide6_SignalInstance,
|
|
200
|
-
)
|
|
201
|
-
except ImportError as e:
|
|
202
|
-
raise ImportError("Could not import PySide6") from e
|
|
203
|
-
|
|
204
|
-
QObjectCacheName = "_QObjectCache"
|
|
205
|
-
|
|
206
|
-
def pyside6_signal_instance_constructor(
|
|
207
|
-
*,
|
|
208
|
-
types: tuple[type, ...],
|
|
209
|
-
name: str,
|
|
210
|
-
arguments: Sequence[str],
|
|
211
|
-
instance: Any,
|
|
212
|
-
) -> PySide6_SignalInstance:
|
|
213
|
-
if isinstance(instance, QObject):
|
|
214
|
-
return PySide6_Signal(
|
|
215
|
-
*types, name=name, arguments=list(arguments) if arguments else None
|
|
216
|
-
).__get__(instance, QObject)
|
|
217
|
-
else:
|
|
218
|
-
signal_instances = _get_signal_instances(instance)
|
|
219
|
-
if QObjectCacheName not in signal_instances:
|
|
220
|
-
signal_instances[QObjectCacheName] = QObject() # type: ignore
|
|
221
|
-
obj = signal_instances[QObjectCacheName] # type: ignore
|
|
222
|
-
if not isinstance(obj, QObject):
|
|
223
|
-
raise RuntimeError
|
|
224
|
-
return PySide6_Signal(*types, name=name, arguments=arguments).__get__(
|
|
225
|
-
obj, QObject
|
|
226
|
-
)
|
|
227
|
-
|
|
228
|
-
return pyside6_signal_instance_constructor # type: ignore
|
amulet/utils/task_manager.py
DELETED
|
@@ -1,235 +0,0 @@
|
|
|
1
|
-
from __future__ import annotations
|
|
2
|
-
|
|
3
|
-
from typing import Generic, TypeVar, Callable
|
|
4
|
-
from abc import ABC, abstractmethod
|
|
5
|
-
|
|
6
|
-
from .signal import Signal, SignalInstance
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
T = TypeVar("T")
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
class TaskCancelled(Exception):
|
|
13
|
-
"""Exception to be raised by the callee when a task is cancelled.
|
|
14
|
-
|
|
15
|
-
The callee may define a custom return instead of using this.
|
|
16
|
-
"""
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
class AbstractCancelManager(ABC):
|
|
20
|
-
@abstractmethod
|
|
21
|
-
def cancel(self) -> None:
|
|
22
|
-
"""Request the operation be canceled.
|
|
23
|
-
|
|
24
|
-
It is down to the operation to implement support for this.
|
|
25
|
-
"""
|
|
26
|
-
raise NotImplementedError
|
|
27
|
-
|
|
28
|
-
@abstractmethod
|
|
29
|
-
def is_cancel_requested(self) -> bool:
|
|
30
|
-
"""Has cancel been called to signal that the operation should be canceled."""
|
|
31
|
-
raise NotImplementedError
|
|
32
|
-
|
|
33
|
-
@abstractmethod
|
|
34
|
-
def register_on_cancel(self, callback: Callable[[], None]) -> None:
|
|
35
|
-
"""Register a function to get called when :meth:`cancel` is called."""
|
|
36
|
-
raise NotImplementedError
|
|
37
|
-
|
|
38
|
-
@abstractmethod
|
|
39
|
-
def unregister_on_cancel(self, callback: Callable[[], None]) -> None:
|
|
40
|
-
"""Unregister a registered function from being called when :meth:`cancel` is called."""
|
|
41
|
-
raise NotImplementedError
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
class VoidCancelManager(AbstractCancelManager):
|
|
45
|
-
def cancel(self) -> None:
|
|
46
|
-
pass
|
|
47
|
-
|
|
48
|
-
def is_cancel_requested(self) -> bool:
|
|
49
|
-
return False
|
|
50
|
-
|
|
51
|
-
def register_on_cancel(self, callback: Callable[[], None]) -> None:
|
|
52
|
-
pass
|
|
53
|
-
|
|
54
|
-
def unregister_on_cancel(self, callback: Callable[[], None]) -> None:
|
|
55
|
-
pass
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
class Pointer(Generic[T]):
|
|
59
|
-
value: T
|
|
60
|
-
|
|
61
|
-
def __init__(self, value: T) -> None:
|
|
62
|
-
self.value = value
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
class _CancelManager(AbstractCancelManager):
|
|
66
|
-
def __init__(
|
|
67
|
-
self,
|
|
68
|
-
cancelled: Pointer[bool],
|
|
69
|
-
cancel_signal: SignalInstance[()],
|
|
70
|
-
) -> None:
|
|
71
|
-
self._cancelled = cancelled
|
|
72
|
-
self._on_cancel = cancel_signal
|
|
73
|
-
|
|
74
|
-
def cancel(self) -> None:
|
|
75
|
-
self._cancelled.value = True
|
|
76
|
-
self._on_cancel.emit()
|
|
77
|
-
|
|
78
|
-
def is_cancel_requested(self) -> bool:
|
|
79
|
-
return self._cancelled.value
|
|
80
|
-
|
|
81
|
-
def register_on_cancel(self, callback: Callable[[], None]) -> None:
|
|
82
|
-
self._on_cancel.connect(callback)
|
|
83
|
-
|
|
84
|
-
def unregister_on_cancel(self, callback: Callable[[], None]) -> None:
|
|
85
|
-
self._on_cancel.disconnect(callback)
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
class CancelManager(_CancelManager):
|
|
89
|
-
_cancel_signal = Signal[()]()
|
|
90
|
-
|
|
91
|
-
def __init__(self) -> None:
|
|
92
|
-
super().__init__(
|
|
93
|
-
Pointer[bool](False),
|
|
94
|
-
self._cancel_signal,
|
|
95
|
-
)
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
class AbstractProgressManager(ABC):
|
|
99
|
-
@abstractmethod
|
|
100
|
-
def update_progress(self, progress: float) -> None:
|
|
101
|
-
"""Notify the caller of the updated progress.
|
|
102
|
-
|
|
103
|
-
:param progress: The new progress to relay to the caller. 0.0-1.0
|
|
104
|
-
"""
|
|
105
|
-
raise NotImplementedError
|
|
106
|
-
|
|
107
|
-
@abstractmethod
|
|
108
|
-
def update_progress_text(self, text: str) -> None:
|
|
109
|
-
"""Notify the caller of the updated progress.
|
|
110
|
-
|
|
111
|
-
:param text: The new message to relay to the caller.
|
|
112
|
-
"""
|
|
113
|
-
raise NotImplementedError
|
|
114
|
-
|
|
115
|
-
@abstractmethod
|
|
116
|
-
def get_child(
|
|
117
|
-
self, progress_min: float, progress_max: float
|
|
118
|
-
) -> AbstractProgressManager:
|
|
119
|
-
"""Get a child ExecutionContext.
|
|
120
|
-
|
|
121
|
-
If calling multiple functions, this allows segmenting the reported time.
|
|
122
|
-
|
|
123
|
-
:param progress_min: The minimum progress for the child to use 0.0-1.0
|
|
124
|
-
:param progress_max: The maximum progress for the child to use 0.0-1.0
|
|
125
|
-
:return: A new ExecutionContext
|
|
126
|
-
"""
|
|
127
|
-
raise NotImplementedError
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
class VoidProgressManager(AbstractProgressManager):
|
|
131
|
-
def update_progress(self, progress: float) -> None:
|
|
132
|
-
pass
|
|
133
|
-
|
|
134
|
-
def update_progress_text(self, text: str) -> None:
|
|
135
|
-
pass
|
|
136
|
-
|
|
137
|
-
def get_child(
|
|
138
|
-
self, progress_min: float, progress_max: float
|
|
139
|
-
) -> VoidProgressManager:
|
|
140
|
-
return self
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
class _ProgressManager(AbstractProgressManager):
|
|
144
|
-
def __init__(
|
|
145
|
-
self,
|
|
146
|
-
progress_change: SignalInstance[float],
|
|
147
|
-
progress_text_change: SignalInstance[str],
|
|
148
|
-
progress_min: float,
|
|
149
|
-
progress_max: float,
|
|
150
|
-
) -> None:
|
|
151
|
-
self._progress_change = progress_change
|
|
152
|
-
self._progress_text_change = progress_text_change
|
|
153
|
-
assert 0.0 <= progress_min <= progress_max <= 1.0
|
|
154
|
-
self._progress_min = progress_min
|
|
155
|
-
self._progress_delta = progress_max - progress_min
|
|
156
|
-
|
|
157
|
-
def update_progress(self, progress: float) -> None:
|
|
158
|
-
assert 0.0 <= progress <= 1.0
|
|
159
|
-
self._progress_change.emit(self._progress_min + progress * self._progress_delta)
|
|
160
|
-
|
|
161
|
-
def update_progress_text(self, text: str) -> None:
|
|
162
|
-
self._progress_text_change.emit(text)
|
|
163
|
-
|
|
164
|
-
def get_child(self, progress_min: float, progress_max: float) -> _ProgressManager:
|
|
165
|
-
assert 0.0 <= progress_min <= progress_max <= 1.0
|
|
166
|
-
return _ProgressManager(
|
|
167
|
-
self._progress_change,
|
|
168
|
-
self._progress_text_change,
|
|
169
|
-
self._progress_min + progress_min * self._progress_delta,
|
|
170
|
-
self._progress_min + progress_max * self._progress_delta,
|
|
171
|
-
)
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
class ProgressManager(_ProgressManager):
|
|
175
|
-
progress_change = Signal[float](float)
|
|
176
|
-
progress_text_change = Signal[str](str)
|
|
177
|
-
|
|
178
|
-
def __init__(self) -> None:
|
|
179
|
-
super().__init__(
|
|
180
|
-
self.progress_change,
|
|
181
|
-
self.progress_text_change,
|
|
182
|
-
0.0,
|
|
183
|
-
1.0,
|
|
184
|
-
)
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
class AbstractTaskManager(AbstractCancelManager, AbstractProgressManager, ABC):
|
|
188
|
-
pass
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
class VoidTaskManager(VoidCancelManager, VoidProgressManager, AbstractTaskManager):
|
|
192
|
-
"""An empty Execution Context that ignores all calls."""
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
class _TaskManager(CancelManager, ProgressManager, AbstractTaskManager):
|
|
196
|
-
def __init__(
|
|
197
|
-
self,
|
|
198
|
-
cancelled: Pointer[bool],
|
|
199
|
-
cancel_signal: SignalInstance[()],
|
|
200
|
-
progress_change: SignalInstance[float],
|
|
201
|
-
progress_text_change: SignalInstance[str],
|
|
202
|
-
progress_min: float,
|
|
203
|
-
progress_max: float,
|
|
204
|
-
) -> None:
|
|
205
|
-
_CancelManager.__init__(self, cancelled, cancel_signal)
|
|
206
|
-
_ProgressManager.__init__(
|
|
207
|
-
self,
|
|
208
|
-
progress_change,
|
|
209
|
-
progress_text_change,
|
|
210
|
-
progress_min,
|
|
211
|
-
progress_max,
|
|
212
|
-
)
|
|
213
|
-
|
|
214
|
-
def get_child(self, progress_min: float, progress_max: float) -> _TaskManager:
|
|
215
|
-
assert 0.0 <= progress_min <= progress_max <= 1.0
|
|
216
|
-
return _TaskManager(
|
|
217
|
-
self._cancelled,
|
|
218
|
-
self._on_cancel,
|
|
219
|
-
self._progress_change,
|
|
220
|
-
self._progress_text_change,
|
|
221
|
-
self._progress_min + progress_min * self._progress_delta,
|
|
222
|
-
self._progress_min + progress_max * self._progress_delta,
|
|
223
|
-
)
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
class TaskManager(_TaskManager):
|
|
227
|
-
def __init__(self) -> None:
|
|
228
|
-
super().__init__(
|
|
229
|
-
Pointer[bool](False),
|
|
230
|
-
self._cancel_signal,
|
|
231
|
-
self.progress_change,
|
|
232
|
-
self.progress_text_change,
|
|
233
|
-
0.0,
|
|
234
|
-
1.0,
|
|
235
|
-
)
|
amulet/utils/typed_property.py
DELETED
|
@@ -1,111 +0,0 @@
|
|
|
1
|
-
from __future__ import annotations
|
|
2
|
-
from typing import TypeVar, Any, Generic, Callable, overload
|
|
3
|
-
|
|
4
|
-
GetT = TypeVar("GetT")
|
|
5
|
-
SetT = TypeVar("SetT")
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
class TypedProperty(Generic[GetT, SetT]):
|
|
9
|
-
"""
|
|
10
|
-
Type hinting with the vanilla property does not support having a different type on the setter.
|
|
11
|
-
See https://github.com/python/mypy/issues/3004
|
|
12
|
-
This is a custom property implementation that supports independently typing the getter and setter to appease mypy.
|
|
13
|
-
|
|
14
|
-
Note that the getter, setter and deleter return the method they were given and not a property instance.
|
|
15
|
-
This was to appease mypy complaining about overriding variables.
|
|
16
|
-
This has a side effect that a setter can be used as a setter or the method
|
|
17
|
-
|
|
18
|
-
>>> class MyClass:
|
|
19
|
-
>>> def __init__(self) -> None:
|
|
20
|
-
>>> self._value = 1
|
|
21
|
-
>>>
|
|
22
|
-
>>> @TypedProperty[int, int | float]
|
|
23
|
-
>>> def value(self) -> int:
|
|
24
|
-
>>> return self._value
|
|
25
|
-
>>>
|
|
26
|
-
>>> @value.setter
|
|
27
|
-
>>> def set_value(self, val: int | float) -> None:
|
|
28
|
-
>>> self._value = int(val)
|
|
29
|
-
>>>
|
|
30
|
-
>>> @value.deleter
|
|
31
|
-
>>> def del_value(self) -> None:
|
|
32
|
-
>>> del self._value
|
|
33
|
-
>>>
|
|
34
|
-
>>>
|
|
35
|
-
>>> inst = MyClass()
|
|
36
|
-
>>> assert inst.value == 1
|
|
37
|
-
>>> inst.value = 2
|
|
38
|
-
>>> assert inst.value == 2
|
|
39
|
-
>>> inst.set_value(3)
|
|
40
|
-
>>> assert inst.value == 3
|
|
41
|
-
>>> del inst.value
|
|
42
|
-
>>> try:
|
|
43
|
-
>>> inst.value
|
|
44
|
-
>>> except AttributeError:
|
|
45
|
-
>>> pass
|
|
46
|
-
>>> else:
|
|
47
|
-
>>> raise Exception
|
|
48
|
-
>>> inst.value = 4
|
|
49
|
-
>>> assert inst.value == 4
|
|
50
|
-
|
|
51
|
-
If you want the original methods to be private then just prefix them with an underscore.
|
|
52
|
-
"""
|
|
53
|
-
|
|
54
|
-
fget: Callable[[Any], GetT] | None
|
|
55
|
-
fset: Callable[[Any, SetT], None] | None
|
|
56
|
-
fdel: Callable[[Any], None] | None
|
|
57
|
-
|
|
58
|
-
def __init__(
|
|
59
|
-
self,
|
|
60
|
-
fget: Callable[[Any], GetT] | None = None,
|
|
61
|
-
fset: Callable[[Any, SetT], None] | None = None,
|
|
62
|
-
fdel: Callable[[Any], None] | None = None,
|
|
63
|
-
doc: str | None = None,
|
|
64
|
-
) -> None:
|
|
65
|
-
self.fget = fget
|
|
66
|
-
self.fset = fset
|
|
67
|
-
self.fdel = fdel
|
|
68
|
-
if doc is None and fget is not None:
|
|
69
|
-
doc = fget.__doc__
|
|
70
|
-
self.__doc__ = doc
|
|
71
|
-
self._name = ""
|
|
72
|
-
|
|
73
|
-
def __set_name__(self, owner: Any, name: str) -> None:
|
|
74
|
-
self._name = name
|
|
75
|
-
|
|
76
|
-
@overload
|
|
77
|
-
def __get__(self, obj: None, objtype: None) -> TypedProperty[GetT, SetT]: ...
|
|
78
|
-
|
|
79
|
-
@overload
|
|
80
|
-
def __get__(self, obj: object, objtype: type[object]) -> GetT: ...
|
|
81
|
-
|
|
82
|
-
def __get__(
|
|
83
|
-
self, obj: Any, objtype: Any = None
|
|
84
|
-
) -> GetT | TypedProperty[GetT, SetT]:
|
|
85
|
-
if obj is None:
|
|
86
|
-
return self
|
|
87
|
-
if self.fget is None:
|
|
88
|
-
raise AttributeError(f"property '{self._name}' has no getter")
|
|
89
|
-
return self.fget(obj)
|
|
90
|
-
|
|
91
|
-
def __set__(self, obj: Any, value: SetT) -> None:
|
|
92
|
-
if self.fset is None:
|
|
93
|
-
raise AttributeError(f"property '{self._name}' has no setter")
|
|
94
|
-
self.fset(obj, value)
|
|
95
|
-
|
|
96
|
-
def __delete__(self, obj: Any) -> None:
|
|
97
|
-
if self.fdel is None:
|
|
98
|
-
raise AttributeError(f"property '{self._name}' has no deleter")
|
|
99
|
-
self.fdel(obj)
|
|
100
|
-
|
|
101
|
-
def getter(self, fget: Callable[[Any], GetT]) -> Callable[[Any], GetT]:
|
|
102
|
-
self.fget = fget
|
|
103
|
-
return fget
|
|
104
|
-
|
|
105
|
-
def setter(self, fset: Callable[[Any, SetT], None]) -> Callable[[Any, SetT], None]:
|
|
106
|
-
self.fset = fset
|
|
107
|
-
return fset
|
|
108
|
-
|
|
109
|
-
def deleter(self, fdel: Callable[[Any], None]) -> Callable[[Any], None]:
|
|
110
|
-
self.fdel = fdel
|
|
111
|
-
return fdel
|
amulet/utils/weakref.py
DELETED
|
@@ -1,70 +0,0 @@
|
|
|
1
|
-
"""Extension to the builtin weakref module."""
|
|
2
|
-
|
|
3
|
-
from __future__ import annotations
|
|
4
|
-
from typing import Any, TypeVar, Generic, Callable, final
|
|
5
|
-
from weakref import WeakMethod as _WeakMethod, ReferenceType as _ReferenceType
|
|
6
|
-
|
|
7
|
-
T = TypeVar("T")
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
# Classes have an __del__ method to run code at object destruction.
|
|
11
|
-
# This is usually sufficient if the object gets deleted before the interpreter exits.
|
|
12
|
-
# In some cases global variables are set to None causing the __del__ to fail if run after interpreter shutdown.
|
|
13
|
-
# I have noticed this while debugging.
|
|
14
|
-
#
|
|
15
|
-
# In the following example when debugging sys is None when __del__ is called after interpreter shutdown.
|
|
16
|
-
#
|
|
17
|
-
# >>> import sys
|
|
18
|
-
# >>>
|
|
19
|
-
# >>> class Cls:
|
|
20
|
-
# >>> def __init__(self) -> None:
|
|
21
|
-
# >>> self._sys_modules = sys.modules
|
|
22
|
-
# >>> print(self._sys_modules)
|
|
23
|
-
# >>>
|
|
24
|
-
# >>> def __del__(self) -> None:
|
|
25
|
-
# >>> print(self._sys_modules)
|
|
26
|
-
# >>> print(sys)
|
|
27
|
-
# >>>
|
|
28
|
-
# >>> t = Cls()
|
|
29
|
-
#
|
|
30
|
-
# weakref.finalize takes care of this. It can be manually called in the __del__ method if the object is garbage
|
|
31
|
-
# collected before interpreter shutdown or automatically run at interpreter exit. It can only be called once.
|
|
32
|
-
# It must be given a weak method otherwise the instance will be kept alive until interpreter exit.
|
|
33
|
-
# weakref.WeakMethod is not directly callable so CallableWeakMethod is implemented to allow this.
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
@final
|
|
37
|
-
class CallableWeakMethod(_WeakMethod):
|
|
38
|
-
"""
|
|
39
|
-
A wrapper around WeakMethod that makes the method directly callable.
|
|
40
|
-
If the method no longer exists, this does nothing.
|
|
41
|
-
"""
|
|
42
|
-
|
|
43
|
-
def __call__(self, *args: Any, **kwargs: Any) -> Any:
|
|
44
|
-
meth = super().__call__()
|
|
45
|
-
if meth is not None:
|
|
46
|
-
return meth(*args, **kwargs)
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
@final
|
|
50
|
-
class DetachableWeakRef(Generic[T]):
|
|
51
|
-
"""A weak reference that can be detached by the creator before the object is deleted."""
|
|
52
|
-
|
|
53
|
-
_ref: Callable[[], T | None]
|
|
54
|
-
|
|
55
|
-
@classmethod
|
|
56
|
-
def new(cls, obj: T) -> tuple[DetachableWeakRef[T], Callable[[], None]]:
|
|
57
|
-
"""Get a new weak reference and a callable to detach the object.
|
|
58
|
-
Once called the reference will always return None.
|
|
59
|
-
"""
|
|
60
|
-
self = cls(obj)
|
|
61
|
-
return self, self._detach
|
|
62
|
-
|
|
63
|
-
def __init__(self, obj: T) -> None:
|
|
64
|
-
self._ref = _ReferenceType(obj)
|
|
65
|
-
|
|
66
|
-
def __call__(self) -> T | None:
|
|
67
|
-
return self._ref()
|
|
68
|
-
|
|
69
|
-
def _detach(self) -> None:
|
|
70
|
-
self._ref = lambda: None
|