socketwrapper 0.1.0__tar.gz → 0.1.1__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.
- {socketwrapper-0.1.0/socketwrapper.egg-info → socketwrapper-0.1.1}/PKG-INFO +8 -1
- {socketwrapper-0.1.0 → socketwrapper-0.1.1}/README.md +7 -0
- {socketwrapper-0.1.0 → socketwrapper-0.1.1}/pyproject.toml +2 -1
- {socketwrapper-0.1.0 → socketwrapper-0.1.1}/socketwrapper/__init__.py +3 -3
- {socketwrapper-0.1.0 → socketwrapper-0.1.1}/socketwrapper/_io.py +1 -1
- {socketwrapper-0.1.0 → socketwrapper-0.1.1}/socketwrapper/_nt.py +38 -12
- {socketwrapper-0.1.0 → socketwrapper-0.1.1}/socketwrapper/_utils.py +2 -2
- {socketwrapper-0.1.0 → socketwrapper-0.1.1/socketwrapper.egg-info}/PKG-INFO +8 -1
- {socketwrapper-0.1.0 → socketwrapper-0.1.1}/socketwrapper.egg-info/zip-safe +1 -1
- {socketwrapper-0.1.0 → socketwrapper-0.1.1}/LICENSE +0 -0
- {socketwrapper-0.1.0 → socketwrapper-0.1.1}/setup.cfg +0 -0
- {socketwrapper-0.1.0 → socketwrapper-0.1.1}/socketwrapper/_varint.py +0 -0
- {socketwrapper-0.1.0 → socketwrapper-0.1.1}/socketwrapper/framing.py +0 -0
- {socketwrapper-0.1.0 → socketwrapper-0.1.1}/socketwrapper/protocols.py +0 -0
- {socketwrapper-0.1.0 → socketwrapper-0.1.1}/socketwrapper/py.typed +0 -0
- {socketwrapper-0.1.0 → socketwrapper-0.1.1}/socketwrapper.egg-info/SOURCES.txt +0 -0
- {socketwrapper-0.1.0 → socketwrapper-0.1.1}/socketwrapper.egg-info/dependency_links.txt +0 -0
- {socketwrapper-0.1.0 → socketwrapper-0.1.1}/socketwrapper.egg-info/requires.txt +0 -0
- {socketwrapper-0.1.0 → socketwrapper-0.1.1}/socketwrapper.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: socketwrapper
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.1
|
|
4
4
|
Summary: high level socket and pipe wrappers
|
|
5
5
|
Author: Felipe A Hernandez
|
|
6
6
|
Author-email: ergoithz@gmail.com
|
|
@@ -109,6 +109,13 @@ uv pip install 'socketwrapper[msgpack]'
|
|
|
109
109
|
|
|
110
110
|
## Changelog
|
|
111
111
|
|
|
112
|
+
### 0.1.1 - 2026.07.03
|
|
113
|
+
|
|
114
|
+
#### Bugfixes
|
|
115
|
+
|
|
116
|
+
- Tighten Windows named pipes permissions.
|
|
117
|
+
- Avoid invalid Windows handles potentially causing descriptor leaks.
|
|
118
|
+
|
|
112
119
|
### 0.1.0 - 2026.01.22
|
|
113
120
|
|
|
114
121
|
#### Breaking
|
|
@@ -54,6 +54,13 @@ uv pip install 'socketwrapper[msgpack]'
|
|
|
54
54
|
|
|
55
55
|
## Changelog
|
|
56
56
|
|
|
57
|
+
### 0.1.1 - 2026.07.03
|
|
58
|
+
|
|
59
|
+
#### Bugfixes
|
|
60
|
+
|
|
61
|
+
- Tighten Windows named pipes permissions.
|
|
62
|
+
- Avoid invalid Windows handles potentially causing descriptor leaks.
|
|
63
|
+
|
|
57
64
|
### 0.1.0 - 2026.01.22
|
|
58
65
|
|
|
59
66
|
#### Breaking
|
|
@@ -5,7 +5,7 @@ build-backend = 'setuptools.build_meta'
|
|
|
5
5
|
[project]
|
|
6
6
|
name = 'socketwrapper'
|
|
7
7
|
description = 'high level socket and pipe wrappers'
|
|
8
|
-
version = '0.1.
|
|
8
|
+
version = '0.1.1'
|
|
9
9
|
requires-python = '>=3.12'
|
|
10
10
|
keywords = ['socket', 'pipe', 'ipc', 'asyncio', 'multiprocessing']
|
|
11
11
|
readme = { file = 'README.md', content-type = 'text/markdown' }
|
|
@@ -139,6 +139,7 @@ ignore = [
|
|
|
139
139
|
# Ignore pylint broken nonsense
|
|
140
140
|
'PLR2004', # declare every single constant as a variable (WTF!)
|
|
141
141
|
'PLR0402', # import namespaces in the same way as properties (WTF!)
|
|
142
|
+
'PLW0717', # too many statements in try/except (WTF!!)
|
|
142
143
|
# Ignore tryceratops nonsense
|
|
143
144
|
'TRY301', # raising inside try/except (WTF!)
|
|
144
145
|
# Just broken
|
|
@@ -320,7 +320,7 @@ class SocketWrapper(_utils.ClosingContext):
|
|
|
320
320
|
|
|
321
321
|
@property
|
|
322
322
|
def inheritable(self) -> bool:
|
|
323
|
-
"""
|
|
323
|
+
"""Whether or not this socket is inheritable by subprocesses.
|
|
324
324
|
|
|
325
325
|
:returns: true if the socket is inheritable by subprocesses.
|
|
326
326
|
|
|
@@ -450,7 +450,7 @@ class MessageWrapper(_utils.ClosingContext, typing_extensions.Generic[R, W, KS])
|
|
|
450
450
|
|
|
451
451
|
@property
|
|
452
452
|
def inheritable(self) -> bool:
|
|
453
|
-
"""
|
|
453
|
+
"""Whether or not this socket is inheritable by subprocesses.
|
|
454
454
|
|
|
455
455
|
:returns: true if the socket is inheritable by subprocesses.
|
|
456
456
|
|
|
@@ -486,7 +486,7 @@ class MessageReader(MessageWrapper[R, typing.Any, KSR], typing_extensions.Generi
|
|
|
486
486
|
|
|
487
487
|
@property
|
|
488
488
|
def _frames(self) -> StreamFrames | None:
|
|
489
|
-
"""
|
|
489
|
+
"""Stream frames function."""
|
|
490
490
|
return self.framing.frames if self._raw._reader.is_stream else None
|
|
491
491
|
|
|
492
492
|
def recv(self, timeout: float | None = None) -> R:
|
|
@@ -95,7 +95,7 @@ class Consumer[Q, R, IO_R]:
|
|
|
95
95
|
|
|
96
96
|
@functools.cached_property
|
|
97
97
|
def selector(self) -> selectors.BaseSelector:
|
|
98
|
-
"""
|
|
98
|
+
"""Selector for class."""
|
|
99
99
|
selector = selectors.DefaultSelector()
|
|
100
100
|
selector.register(self.sock, selectors.EVENT_WRITE if self._writer else selectors.EVENT_READ)
|
|
101
101
|
return selector
|
|
@@ -19,10 +19,18 @@ from . import _utils
|
|
|
19
19
|
|
|
20
20
|
IOBuffer = collections.abc.Buffer | ctypes.Array | ctypes.c_char_p
|
|
21
21
|
|
|
22
|
+
advapi32 = ctypes.windll.advapi32
|
|
22
23
|
kernel32 = ctypes.windll.kernel32
|
|
23
24
|
ntdll = ctypes.windll.ntdll
|
|
24
25
|
winsock2 = ctypes.windll.ws2_32
|
|
25
26
|
|
|
27
|
+
ignored_io_status_block = (ctypes.c_void_p * 2)()
|
|
28
|
+
|
|
29
|
+
PIPE_SEC = b'D:P(D;;GA;;;NU)(A;;GA;;;CO)'
|
|
30
|
+
# D:P - Protected DACL — blocks inherited ACEs
|
|
31
|
+
# (D;;GA;;; - U) - Deny NETWORK (S-1-5-2) all access
|
|
32
|
+
# (A;;GA;;;CO) - Allow Creator Owner (S-1-3-0) all access, resolved to the pipe creator's SID
|
|
33
|
+
|
|
26
34
|
FILE_TYPE_PIPE = 0x03
|
|
27
35
|
WINSOCK_FIONREAD = 0x4004667F
|
|
28
36
|
|
|
@@ -290,7 +298,7 @@ class StreamOperation(OperationBase):
|
|
|
290
298
|
super().__init__(handle)
|
|
291
299
|
self._info = FilePipeLocalInformation()
|
|
292
300
|
self._info_args = (
|
|
293
|
-
self.handle, ctypes.byref(
|
|
301
|
+
self.handle, ctypes.byref(ignored_io_status_block), ctypes.byref(self._info), ctypes.sizeof(self._info),
|
|
294
302
|
FILE_PIPE_LOCAL_INFORMATION,
|
|
295
303
|
)
|
|
296
304
|
|
|
@@ -336,11 +344,22 @@ class StreamOperation(OperationBase):
|
|
|
336
344
|
|
|
337
345
|
def resolve_pipe_handle(fd: int | None = None, handle: int | None = None) -> tuple[int, int, bool, bool, bool]:
|
|
338
346
|
"""Get a valid fd, handle, and whether or not it's a valid pipe."""
|
|
339
|
-
fd =
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
347
|
+
fd, created = (
|
|
348
|
+
(msvcrt.open_osfhandle(handle, os.O_BINARY | os.O_NOINHERIT), True) if fd is None else
|
|
349
|
+
(fd, False)
|
|
350
|
+
)
|
|
351
|
+
try:
|
|
352
|
+
handle = msvcrt.get_osfhandle(fd) if handle is None else handle
|
|
353
|
+
is_overlapped = is_overlapped_file(handle)
|
|
354
|
+
is_named_pipe, is_message = is_message_named_pipe(handle)
|
|
355
|
+
is_pipe = is_named_pipe or kernel32.GetFileType(handle) == FILE_TYPE_PIPE
|
|
356
|
+
|
|
357
|
+
except Exception:
|
|
358
|
+
if created:
|
|
359
|
+
os.close(fd)
|
|
360
|
+
|
|
361
|
+
raise
|
|
362
|
+
|
|
344
363
|
return fd, handle, is_pipe, is_overlapped, is_message
|
|
345
364
|
|
|
346
365
|
|
|
@@ -389,15 +408,19 @@ def is_message_named_pipe(handle: int) -> tuple[bool, bool]:
|
|
|
389
408
|
|
|
390
409
|
def overlapped_pipe() -> tuple[int, int]:
|
|
391
410
|
"""Create overlapped named pipe pair (r,w) and return handlers."""
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
lpSecurityDescriptor=None,
|
|
396
|
-
bInheritHandle=False,
|
|
397
|
-
)
|
|
411
|
+
sd_ptr = ctypes.c_void_p()
|
|
412
|
+
if not advapi32.ConvertStringSecurityDescriptorToSecurityDescriptorA(PIPE_SEC, 1, ctypes.byref(sd_ptr), None):
|
|
413
|
+
raise ctypes.WinError()
|
|
398
414
|
|
|
415
|
+
name = f'\\\\.\\pipe\\iocppipe_{uuid.uuid4().hex}'.encode('ascii')
|
|
399
416
|
rhandle = whandle = -1
|
|
400
417
|
try:
|
|
418
|
+
security = SecurityAttributes(
|
|
419
|
+
nLength=ctypes.sizeof(SecurityAttributes),
|
|
420
|
+
lpSecurityDescriptor=sd_ptr,
|
|
421
|
+
bInheritHandle=False,
|
|
422
|
+
)
|
|
423
|
+
|
|
401
424
|
rhandle = kernel32.CreateNamedPipeA(name, PIPE_INBOUND_OVERLAPPED, 0, 1, BUFFER_SIZE, BUFFER_SIZE, 0,
|
|
402
425
|
ctypes.byref(security))
|
|
403
426
|
if rhandle == -1:
|
|
@@ -417,6 +440,9 @@ def overlapped_pipe() -> tuple[int, int]:
|
|
|
417
440
|
close_handle(handle=whandle)
|
|
418
441
|
raise
|
|
419
442
|
|
|
443
|
+
finally:
|
|
444
|
+
kernel32.LocalFree(sd_ptr)
|
|
445
|
+
|
|
420
446
|
return rhandle, whandle
|
|
421
447
|
|
|
422
448
|
|
|
@@ -174,7 +174,7 @@ class Deadline:
|
|
|
174
174
|
|
|
175
175
|
@property
|
|
176
176
|
def remaining(self) -> float:
|
|
177
|
-
"""
|
|
177
|
+
"""Time left before deadline."""
|
|
178
178
|
return max(0, self.deadline - time.monotonic())
|
|
179
179
|
|
|
180
180
|
def __init__(self, *, deadline: float | None = None, timeout: float = 0, error: str | None = None) -> None:
|
|
@@ -251,7 +251,7 @@ class CrossLock:
|
|
|
251
251
|
|
|
252
252
|
@property
|
|
253
253
|
def locked(self) -> bool:
|
|
254
|
-
"""
|
|
254
|
+
"""Whether lock is acquired or not."""
|
|
255
255
|
return self._lock.locked()
|
|
256
256
|
|
|
257
257
|
def acquire(self, *, timeout: float | None = None) -> bool:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: socketwrapper
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.1
|
|
4
4
|
Summary: high level socket and pipe wrappers
|
|
5
5
|
Author: Felipe A Hernandez
|
|
6
6
|
Author-email: ergoithz@gmail.com
|
|
@@ -109,6 +109,13 @@ uv pip install 'socketwrapper[msgpack]'
|
|
|
109
109
|
|
|
110
110
|
## Changelog
|
|
111
111
|
|
|
112
|
+
### 0.1.1 - 2026.07.03
|
|
113
|
+
|
|
114
|
+
#### Bugfixes
|
|
115
|
+
|
|
116
|
+
- Tighten Windows named pipes permissions.
|
|
117
|
+
- Avoid invalid Windows handles potentially causing descriptor leaks.
|
|
118
|
+
|
|
112
119
|
### 0.1.0 - 2026.01.22
|
|
113
120
|
|
|
114
121
|
#### Breaking
|
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|