Skip to content

Commit 375626b

Browse files
committed
Reorganize to match current Java codebase
1 parent 64b41f6 commit 375626b

11 files changed

Lines changed: 96 additions & 58 deletions

File tree

src/appose/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -218,7 +218,7 @@ def task_listener(event):
218218

219219
from .builder import Builder
220220
from .environment import Environment
221-
from .types import NDArray, SharedMemory # noqa: F401
221+
from .shm import NDArray, SharedMemory # noqa: F401
222222

223223

224224
def base(directory: Path) -> Builder:
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@
3535

3636
from pathlib import Path
3737

38-
from .environment import Environment
38+
from ..environment import Environment
3939

4040

4141
class Builder:

src/appose/environment.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@
3636
import os
3737
from pathlib import Path
3838

39-
from .filepath import find_exe
39+
from .util.filepath import find_exe
4040
from .service import Service
4141

4242

src/appose/python_worker.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,8 @@
5050

5151
# NB: Avoid relative imports so that this script can be run standalone.
5252
from appose.service import RequestType, ResponseType
53-
from appose.types import Args, _set_worker, decode, encode
53+
from appose.util import types
54+
from appose.util.types import Args, decode, encode
5455

5556

5657
class Task:
@@ -200,7 +201,7 @@ def __init__(self):
200201
self.exports: dict[str, Any] = {}
201202

202203
# Flag this process as a worker, not a service.
203-
_set_worker(True)
204+
types._worker_mode = True
204205

205206
def run(self) -> None:
206207
"""

src/appose/service.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@
4141
from typing import Any, Callable
4242
from uuid import uuid4
4343

44-
from .types import Args, decode, encode
44+
from .util.types import Args, decode, encode
4545

4646

4747
class Service:
@@ -55,7 +55,7 @@ class Service:
5555
_service_count: int = 0
5656

5757
def __init__(self, cwd: str | Path, args: list[str]) -> None:
58-
self._cwd: str | Path = cwd
58+
self._cwd: Path = Path(cwd)
5959
self._args: list[str] = args[:]
6060
self._tasks: dict[str, "Task"] = {}
6161
self._service_id: int = Service._service_count
Lines changed: 2 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -33,13 +33,11 @@
3333

3434
from __future__ import annotations
3535

36-
import json
3736
import re
3837
from math import ceil, prod
3938
from multiprocessing import resource_tracker, shared_memory
40-
from typing import Any
4139

42-
Args = dict[str, Any]
40+
from .util import types
4341

4442

4543
class SharedMemory(shared_memory.SharedMemory):
@@ -70,7 +68,7 @@ def __init__(self, name: str = None, create: bool = False, rsize: int = 0):
7068
super().__init__(name=name, create=create, size=rsize)
7169
self.rsize: int = rsize
7270
self._unlink_on_dispose: bool = create
73-
if _is_worker:
71+
if types._worker_mode:
7472
# HACK: Remove this shared memory block from the resource_tracker,
7573
# which would otherwise want to clean up shared memory blocks
7674
# after all known references are done using them.
@@ -141,14 +139,6 @@ def __exit__(self, exc_type, exc_value, exc_tb) -> None:
141139
self.dispose()
142140

143141

144-
def encode(data: Args) -> str:
145-
return json.dumps(data, cls=_ApposeJSONEncoder, separators=(",", ":"))
146-
147-
148-
def decode(the_json: str) -> Args:
149-
return json.loads(the_json, object_hook=_appose_object_hook)
150-
151-
152142
class NDArray:
153143
"""
154144
Data structure for a multi-dimensional array.
@@ -204,46 +194,9 @@ def __exit__(self, exc_type, exc_value, exc_tb) -> None:
204194
self.shm.dispose()
205195

206196

207-
class _ApposeJSONEncoder(json.JSONEncoder):
208-
def default(self, obj):
209-
if isinstance(obj, SharedMemory):
210-
return {
211-
"appose_type": "shm",
212-
"name": obj.name,
213-
"rsize": obj.rsize,
214-
}
215-
if isinstance(obj, NDArray):
216-
return {
217-
"appose_type": "ndarray",
218-
"dtype": obj.dtype,
219-
"shape": obj.shape,
220-
"shm": obj.shm,
221-
}
222-
return super().default(obj)
223-
224-
225-
def _appose_object_hook(obj: dict):
226-
atype = obj.get("appose_type")
227-
if atype == "shm":
228-
# Attach to existing shared memory block.
229-
return SharedMemory(name=(obj["name"]), rsize=(obj["rsize"]))
230-
elif atype == "ndarray":
231-
return NDArray(obj["dtype"], obj["shape"], obj["shm"])
232-
else:
233-
return obj
234-
235-
236197
def _bytes_per_element(dtype: str) -> int | float:
237198
try:
238199
bits = int(re.sub("[^0-9]", "", dtype))
239200
except ValueError:
240201
raise ValueError(f"Invalid dtype: {dtype}")
241202
return bits / 8
242-
243-
244-
_is_worker = False
245-
246-
247-
def _set_worker(value: bool) -> None:
248-
global _is_worker
249-
_is_worker = value

src/appose/util/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
pass

src/appose/util/types.py

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
###
2+
# #%L
3+
# Appose: multi-language interprocess cooperation with shared memory.
4+
# %%
5+
# Copyright (C) 2023 - 2025 Appose developers.
6+
# %%
7+
# Redistribution and use in source and binary forms, with or without
8+
# modification, are permitted provided that the following conditions are met:
9+
#
10+
# 1. Redistributions of source code must retain the above copyright notice,
11+
# this list of conditions and the following disclaimer.
12+
# 2. Redistributions in binary form must reproduce the above copyright notice,
13+
# this list of conditions and the following disclaimer in the documentation
14+
# and/or other materials provided with the distribution.
15+
#
16+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17+
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18+
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19+
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
20+
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21+
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22+
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23+
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24+
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25+
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26+
# POSSIBILITY OF SUCH DAMAGE.
27+
# #L%
28+
###
29+
30+
"""
31+
TODO
32+
"""
33+
34+
from __future__ import annotations
35+
36+
import json
37+
from typing import Any
38+
39+
from ..shm import NDArray, SharedMemory
40+
41+
Args = dict[str, Any]
42+
43+
# Flag indicating whether this process is running as an Appose worker.
44+
# Set to True by python_worker.Worker.__init__().
45+
_worker_mode = False
46+
47+
48+
def encode(data: Args) -> str:
49+
return json.dumps(data, cls=_ApposeJSONEncoder, separators=(",", ":"))
50+
51+
52+
def decode(the_json: str) -> Args:
53+
return json.loads(the_json, object_hook=_appose_object_hook)
54+
55+
56+
class _ApposeJSONEncoder(json.JSONEncoder):
57+
def default(self, obj):
58+
if isinstance(obj, SharedMemory):
59+
return {
60+
"appose_type": "shm",
61+
"name": obj.name,
62+
"rsize": obj.rsize,
63+
}
64+
if isinstance(obj, NDArray):
65+
return {
66+
"appose_type": "ndarray",
67+
"dtype": obj.dtype,
68+
"shape": obj.shape,
69+
"shm": obj.shm,
70+
}
71+
return super().default(obj)
72+
73+
74+
def _appose_object_hook(obj: dict):
75+
atype = obj.get("appose_type")
76+
if atype == "shm":
77+
# Attach to existing shared memory block.
78+
return SharedMemory(name=(obj["name"]), rsize=(obj["rsize"]))
79+
elif atype == "ndarray":
80+
return NDArray(obj["dtype"], obj["shape"], obj["shm"])
81+
else:
82+
return obj

0 commit comments

Comments
 (0)