omlish 0.0.0.dev444__py3-none-any.whl → 0.0.0.dev445__py3-none-any.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 omlish might be problematic. Click here for more details.

omlish/__about__.py CHANGED
@@ -1,5 +1,5 @@
1
- __version__ = '0.0.0.dev444'
2
- __revision__ = 'ce3fb695bf149775254b152cc6a5a761e3f5bb90'
1
+ __version__ = '0.0.0.dev445'
2
+ __revision__ = '68ca679313e2d1b22ba7545fe7f27bb938535ac3'
3
3
 
4
4
 
5
5
  #
@@ -185,6 +185,8 @@ class SetuptoolsBase:
185
185
 
186
186
 
187
187
  class Setuptools(SetuptoolsBase):
188
+ cexts = True
189
+
188
190
  find_packages = {
189
191
  'include': [Project.name, f'{Project.name}.*'],
190
192
  'exclude': [*SetuptoolsBase.find_packages['exclude']],
@@ -0,0 +1,101 @@
1
+ // @omlish-cext
2
+ #include <atomic>
3
+
4
+ #define PY_SSIZE_T_CLEAN
5
+ #define Py_BUILD_CORE 1
6
+ #include "Python.h"
7
+ #include "internal/pycore_frame.h"
8
+ #undef Py_BUILD_CORE
9
+
10
+ #if PY_VERSION_HEX < 0x030D0000
11
+ # error "This extension requires CPython 3.13+"
12
+ #endif
13
+
14
+ //
15
+
16
+ #define _MODULE_NAME "_capture"
17
+ #define _PACKAGE_NAME "omlish.lang.imports"
18
+ #define _MODULE_FULL_NAME _PACKAGE_NAME "." _MODULE_NAME
19
+
20
+ //
21
+
22
+ static PyObject *
23
+ _set_frame_builtins(PyObject *self, PyObject *args)
24
+ {
25
+ PyObject *frame_obj;
26
+ PyObject *old_builtins;
27
+ PyObject *new_builtins;
28
+
29
+ if (!PyArg_ParseTuple(
30
+ args, "OO!O!",
31
+ &frame_obj,
32
+ &PyDict_Type, &old_builtins,
33
+ &PyDict_Type, &new_builtins
34
+ )) {
35
+ return NULL;
36
+ }
37
+
38
+ if (!PyFrame_Check(frame_obj)) {
39
+ PyErr_SetString(PyExc_TypeError, "first argument must be a frame object");
40
+ return NULL;
41
+ }
42
+
43
+ PyFrameObject *frame = (PyFrameObject *)frame_obj;
44
+ _PyInterpreterFrame *iframe = frame->f_frame;
45
+
46
+ if (!iframe) {
47
+ PyErr_SetString(PyExc_ValueError, "frame has no underlying interpreter frame");
48
+ return NULL;
49
+ }
50
+
51
+ std::atomic_ref<PyObject*> builtins_ref(iframe->f_builtins);
52
+ PyObject* expected = old_builtins;
53
+ bool success = builtins_ref.compare_exchange_strong(
54
+ expected,
55
+ new_builtins,
56
+ std::memory_order_acq_rel,
57
+ std::memory_order_acquire
58
+ );
59
+
60
+ if (success) {
61
+ Py_RETURN_TRUE;
62
+ } else {
63
+ Py_RETURN_FALSE;
64
+ }
65
+ }
66
+
67
+ //
68
+
69
+ PyDoc_STRVAR(capture_doc, _MODULE_NAME);
70
+
71
+ static PyMethodDef capture_methods[] = {
72
+ {"_set_frame_builtins", _set_frame_builtins, METH_VARARGS, "_set_frame_builtins"},
73
+ {NULL, NULL, 0, NULL}
74
+ };
75
+
76
+ static struct PyModuleDef_Slot capture_slots[] = {
77
+ {Py_mod_gil, Py_MOD_GIL_NOT_USED},
78
+ {Py_mod_multiple_interpreters, Py_MOD_MULTIPLE_INTERPRETERS_SUPPORTED},
79
+ {0, NULL}
80
+ };
81
+
82
+ static struct PyModuleDef capture_module = {
83
+ .m_base = PyModuleDef_HEAD_INIT,
84
+ .m_name = _MODULE_NAME,
85
+ .m_doc = capture_doc,
86
+ .m_size = 0,
87
+ .m_methods = capture_methods,
88
+ .m_slots = capture_slots,
89
+ .m_traverse = NULL,
90
+ .m_clear = NULL,
91
+ .m_free = NULL,
92
+ };
93
+
94
+ extern "C" {
95
+
96
+ PyMODINIT_FUNC PyInit__capture(void)
97
+ {
98
+ return PyModuleDef_Init(&capture_module);
99
+ }
100
+
101
+ }
@@ -235,10 +235,31 @@ class _ImportCaptureHook:
235
235
 
236
236
  return module.module_obj
237
237
 
238
- # @abc.abstractmethod
238
+ @ta.final
239
+ @contextlib.contextmanager
239
240
  def hook_context(
240
241
  self,
241
242
  mod_globals: ta.MutableMapping[str, ta.Any], # noqa
243
+ ) -> ta.Iterator[None]:
244
+ if self._MOD_SELF_ATTR in mod_globals:
245
+ raise ImportCaptureErrors.HookError
246
+
247
+ mod_globals[self._MOD_SELF_ATTR] = self
248
+
249
+ try:
250
+ with self._hook_context(mod_globals):
251
+ yield
252
+
253
+ finally:
254
+ if mod_globals[self._MOD_SELF_ATTR] is not self:
255
+ raise ImportCaptureErrors.HookError
256
+
257
+ del mod_globals[self._MOD_SELF_ATTR]
258
+
259
+ # @abc.abstractmethod
260
+ def _hook_context(
261
+ self,
262
+ mod_globals: ta.MutableMapping[str, ta.Any], # noqa
242
263
  ) -> ta.ContextManager[None]:
243
264
  raise NotImplementedError
244
265
 
@@ -333,7 +354,10 @@ class _ImportCaptureHook:
333
354
  )
334
355
 
335
356
 
336
- class _AbstractBuiltinImportCaptureHook(_ImportCaptureHook):
357
+ #
358
+
359
+
360
+ class _AbstractBuiltinsImportCaptureHook(_ImportCaptureHook):
337
361
  def _new_import(
338
362
  self,
339
363
  old_import,
@@ -366,38 +390,28 @@ class _AbstractBuiltinImportCaptureHook(_ImportCaptureHook):
366
390
  )
367
391
 
368
392
 
369
- class _UnsafeGlobalBuiltinImportCaptureHook(_AbstractBuiltinImportCaptureHook):
393
+ class _UnsafeGlobalBuiltinsImportCaptureHook(_AbstractBuiltinsImportCaptureHook):
370
394
  @contextlib.contextmanager
371
- def hook_context(
395
+ def _hook_context(
372
396
  self,
373
397
  mod_globals: ta.MutableMapping[str, ta.Any], # noqa
374
398
  ) -> ta.Iterator[None]:
375
- if self._MOD_SELF_ATTR in mod_globals:
376
- raise ImportCaptureErrors.HookError
377
-
378
- #
379
-
380
399
  old_import = builtins.__import__
381
400
  new_import = functools.partial(self._new_import, old_import)
382
401
 
383
- mod_globals[self._MOD_SELF_ATTR] = self
384
402
  builtins.__import__ = new_import
385
403
 
386
404
  try:
387
405
  yield
388
406
 
389
407
  finally:
390
- if not (
391
- mod_globals[self._MOD_SELF_ATTR] is self and
392
- builtins.__import__ is new_import
393
- ):
408
+ if builtins.__import__ is not new_import:
394
409
  raise ImportCaptureErrors.HookError
395
410
 
396
- del mod_globals[self._MOD_SELF_ATTR]
397
411
  builtins.__import__ = old_import
398
412
 
399
413
 
400
- class _SomewhatThreadSafeGlobalBuiltinImportCaptureHook(_AbstractBuiltinImportCaptureHook):
414
+ class _SomewhatThreadSafeGlobalBuiltinsImportCaptureHook(_AbstractBuiltinsImportCaptureHook):
401
415
  class _AlreadyPatchedError(Exception):
402
416
  pass
403
417
 
@@ -411,23 +425,23 @@ class _SomewhatThreadSafeGlobalBuiltinImportCaptureHook(_AbstractBuiltinImportCa
411
425
  self.__uninstalled = False
412
426
 
413
427
  @classmethod
414
- def _add_hook(cls, mod_globals, new_import) -> '_SomewhatThreadSafeGlobalBuiltinImportCaptureHook._Patch':
428
+ def _add_hook(cls, mod_globals, new_import) -> '_SomewhatThreadSafeGlobalBuiltinsImportCaptureHook._Patch':
415
429
  gi = id(mod_globals)
416
430
  for _ in range(1_000):
417
431
  try:
418
432
  with cls.__lock:
419
433
  x: ta.Any = builtins.__import__
420
- p: _SomewhatThreadSafeGlobalBuiltinImportCaptureHook._Patch
434
+ p: _SomewhatThreadSafeGlobalBuiltinsImportCaptureHook._Patch
421
435
  if x.__class__ is cls:
422
436
  p = x
423
437
  if p.__uninstalled: # noqa
424
- raise _SomewhatThreadSafeGlobalBuiltinImportCaptureHook._AlreadyPatchedError # noqa
438
+ raise _SomewhatThreadSafeGlobalBuiltinsImportCaptureHook._AlreadyPatchedError # noqa
425
439
  else:
426
440
  p = cls(x)
427
441
  builtins.__import__ = p
428
442
  p.__hooks[gi] = (mod_globals, new_import)
429
443
  return p
430
- except _SomewhatThreadSafeGlobalBuiltinImportCaptureHook._AlreadyPatchedError:
444
+ except _SomewhatThreadSafeGlobalBuiltinsImportCaptureHook._AlreadyPatchedError:
431
445
  pass
432
446
  raise ImportCaptureErrors.HookError('Failed to install builtins hook')
433
447
 
@@ -480,17 +494,11 @@ class _SomewhatThreadSafeGlobalBuiltinImportCaptureHook(_AbstractBuiltinImportCa
480
494
  )
481
495
 
482
496
  @contextlib.contextmanager
483
- def hook_context(
497
+ def _hook_context(
484
498
  self,
485
499
  mod_globals: ta.MutableMapping[str, ta.Any], # noqa
486
500
  ) -> ta.Iterator[None]:
487
- if self._MOD_SELF_ATTR in mod_globals:
488
- raise ImportCaptureErrors.HookError
489
-
490
- #
491
-
492
- mod_globals[self._MOD_SELF_ATTR] = self
493
- patch = _SomewhatThreadSafeGlobalBuiltinImportCaptureHook._Patch._add_hook(mod_globals, self._new_import) # noqa
501
+ patch = _SomewhatThreadSafeGlobalBuiltinsImportCaptureHook._Patch._add_hook(mod_globals, self._new_import) # noqa
494
502
 
495
503
  try:
496
504
  yield
@@ -498,12 +506,18 @@ class _SomewhatThreadSafeGlobalBuiltinImportCaptureHook(_AbstractBuiltinImportCa
498
506
  finally:
499
507
  patch._remove_hook(mod_globals) # noqa
500
508
 
501
- if mod_globals[self._MOD_SELF_ATTR] is not self:
502
- raise ImportCaptureErrors.HookError
503
- del mod_globals[self._MOD_SELF_ATTR]
509
+
510
+ #
511
+
512
+
513
+ _capture: ta.Any = None
514
+ try:
515
+ from . import _capture # type: ignore
516
+ except ImportError:
517
+ pass
504
518
 
505
519
 
506
- class _FrameBuiltinImportCaptureHook(_AbstractBuiltinImportCaptureHook):
520
+ class _FrameBuiltinsImportCaptureHook(_AbstractBuiltinsImportCaptureHook):
507
521
  def __init__(
508
522
  self,
509
523
  *,
@@ -519,41 +533,35 @@ class _FrameBuiltinImportCaptureHook(_AbstractBuiltinImportCaptureHook):
519
533
  cls,
520
534
  frame: types.FrameType,
521
535
  new_builtins: dict[str, ta.Any],
522
- ) -> None:
523
- # FIXME: cext...
524
- frame.f_builtins = new_builtins # type: ignore[misc] # noqa
536
+ ) -> bool:
537
+ return _capture._set_frame_builtins(frame, frame.f_builtins, new_builtins) # noqa
525
538
 
526
539
  @contextlib.contextmanager
527
- def hook_context(
540
+ def _hook_context(
528
541
  self,
529
542
  mod_globals: ta.MutableMapping[str, ta.Any], # noqa
530
543
  ) -> ta.Iterator[None]:
531
- if self._MOD_SELF_ATTR in mod_globals:
532
- raise ImportCaptureErrors.HookError
533
-
534
- #
535
-
536
544
  old_builtins = self._frame.f_builtins
537
545
  old_import = old_builtins['__import__']
538
546
  new_import = functools.partial(self._new_import, old_import)
539
547
 
540
- mod_globals[self._MOD_SELF_ATTR] = self
541
548
  new_builtins = dict(old_builtins)
542
549
  new_builtins['__import__'] = new_import
543
- self._set_frame_builtins(self._frame, new_builtins)
550
+ if not self._set_frame_builtins(self._frame, new_builtins):
551
+ raise ImportCaptureErrors.HookError
544
552
 
545
553
  try:
546
554
  yield
547
555
 
548
556
  finally:
549
- if not (
550
- mod_globals[self._MOD_SELF_ATTR] is self and
551
- self._frame.f_builtins is new_builtins
552
- ):
557
+ if self._frame.f_builtins is not new_builtins:
553
558
  raise ImportCaptureErrors.HookError
554
559
 
555
- del mod_globals[self._MOD_SELF_ATTR]
556
- self._set_frame_builtins(self._frame, old_builtins)
560
+ if not self._set_frame_builtins(self._frame, old_builtins):
561
+ raise ImportCaptureErrors.HookError
562
+
563
+
564
+ #
557
565
 
558
566
 
559
567
  def _new_import_capture_hook(
@@ -566,14 +574,10 @@ def _new_import_capture_hook(
566
574
  if frame is None or frame.f_globals is not mod_globals:
567
575
  raise ImportCaptureError("Can't find importing frame")
568
576
 
569
- # return _FrameBuiltinImportCaptureHook(
570
- # _frame=frame,
571
- # **kwargs,
572
- # )
573
-
574
- # return _UnsafeGlobalBuiltinImportCaptureHook(**kwargs)
577
+ if _capture is not None:
578
+ return _FrameBuiltinsImportCaptureHook(_frame=frame, **kwargs)
575
579
 
576
- return _SomewhatThreadSafeGlobalBuiltinImportCaptureHook(**kwargs)
580
+ return _SomewhatThreadSafeGlobalBuiltinsImportCaptureHook(**kwargs)
577
581
 
578
582
 
579
583
  ##
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: omlish
3
- Version: 0.0.0.dev444
3
+ Version: 0.0.0.dev445
4
4
  Summary: omlish
5
5
  Author: wrmsr
6
6
  License-Expression: BSD-3-Clause
@@ -1,5 +1,5 @@
1
1
  omlish/.omlish-manifests.json,sha256=FLw7xkPiSXuImZgqSP8BwrEib2R1doSzUPLUkc-QUIA,8410
2
- omlish/__about__.py,sha256=D7D4UxsfklmK-zdp6Wwtzw06_4DWmvYn98lqDSM6AsY,3595
2
+ omlish/__about__.py,sha256=l_CYKLoqEfq6eAr9gqXrD5Kc9h73YjDaqtcp7Jsos90,3613
3
3
  omlish/__init__.py,sha256=SsyiITTuK0v74XpKV8dqNaCmjOlan1JZKrHQv5rWKPA,253
4
4
  omlish/c3.py,sha256=ZNIMl1kwg3qdei4DiUrJPQe5M81S1e76N-GuNSwLBAE,8683
5
5
  omlish/cached.py,sha256=MLap_p0rdGoDIMVhXVHm1tsbcWobJF0OanoodV03Ju8,542
@@ -447,7 +447,8 @@ omlish/lang/classes/restrict.py,sha256=xHLIK20MQ_jJPQ7JVzMNhyN4Xc4eLBgrcxqDnTbeK
447
447
  omlish/lang/classes/simple.py,sha256=3AJSs-plVg2flq4SC6I39LxP0nBaB241puv3D5YCP5I,2973
448
448
  omlish/lang/classes/virtual.py,sha256=J4y-uiv1RaP2rfFeptXqQ1a4MRek0TMlAFFraO_lzhs,3397
449
449
  omlish/lang/imports/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
450
- omlish/lang/imports/capture.py,sha256=Q6UUKKolgovpo3IabWV8fTRmuNffJj5jwsT-cyJzVQM,21859
450
+ omlish/lang/imports/_capture.cc,sha256=jAKW9pOV3ER4Vzd-aywmAeOxbv-b_jNdaxAaVdxfueg,2261
451
+ omlish/lang/imports/capture.py,sha256=38jP4ydXgiryz77wZ-52GuPQi2fXUiBYZSzoTuQSLdw,21706
451
452
  omlish/lang/imports/conditional.py,sha256=R-E47QD95mMonPImWlrde3rnJrFKCCkYz71c94W05sc,1006
452
453
  omlish/lang/imports/lazy.py,sha256=Eefs9hkj5surMdwgxX_Q3BOqPcox10v0sKT5rKIQknc,808
453
454
  omlish/lang/imports/proxy.py,sha256=wlXJrl1GiXQ-t5cO_aJLqp1mr_Erl4oMk4uySkkK7bg,6516
@@ -819,9 +820,9 @@ omlish/typedvalues/marshal.py,sha256=AtBz7Jq-BfW8vwM7HSxSpR85JAXmxK2T0xDblmm1HI0
819
820
  omlish/typedvalues/of_.py,sha256=UXkxSj504WI2UrFlqdZJbu2hyDwBhL7XVrc2qdR02GQ,1309
820
821
  omlish/typedvalues/reflect.py,sha256=PAvKW6T4cW7u--iX80w3HWwZUS3SmIZ2_lQjT65uAyk,1026
821
822
  omlish/typedvalues/values.py,sha256=ym46I-q2QJ_6l4UlERqv3yj87R-kp8nCKMRph0xQ3UA,1307
822
- omlish-0.0.0.dev444.dist-info/licenses/LICENSE,sha256=B_hVtavaA8zCYDW99DYdcpDLKz1n3BBRjZrcbv8uG8c,1451
823
- omlish-0.0.0.dev444.dist-info/METADATA,sha256=2yqL9SPGq9kDHq7xgB2IHEl5pXuPVFwl_8_Fu8i_zJ4,19003
824
- omlish-0.0.0.dev444.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
825
- omlish-0.0.0.dev444.dist-info/entry_points.txt,sha256=Lt84WvRZJskWCAS7xnQGZIeVWksprtUHj0llrvVmod8,35
826
- omlish-0.0.0.dev444.dist-info/top_level.txt,sha256=pePsKdLu7DvtUiecdYXJ78iO80uDNmBlqe-8hOzOmfs,7
827
- omlish-0.0.0.dev444.dist-info/RECORD,,
823
+ omlish-0.0.0.dev445.dist-info/licenses/LICENSE,sha256=B_hVtavaA8zCYDW99DYdcpDLKz1n3BBRjZrcbv8uG8c,1451
824
+ omlish-0.0.0.dev445.dist-info/METADATA,sha256=agRgaRokAzMENgsipDKwsg8FjW0uO6bc6kgfzwkTZ-8,19003
825
+ omlish-0.0.0.dev445.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
826
+ omlish-0.0.0.dev445.dist-info/entry_points.txt,sha256=Lt84WvRZJskWCAS7xnQGZIeVWksprtUHj0llrvVmod8,35
827
+ omlish-0.0.0.dev445.dist-info/top_level.txt,sha256=pePsKdLu7DvtUiecdYXJ78iO80uDNmBlqe-8hOzOmfs,7
828
+ omlish-0.0.0.dev445.dist-info/RECORD,,