Releases: ionite34/einspect
Releases · ionite34/einspect
v0.5.6
Adds
View.swap()
This is like
View.move_from()
, but swaps data from the target view from the supplied viewable object
from einspect import view
view("dog").swap("cat")
print("dog", "cat")
# cat dog
view(max).swap(min)
print(min(1, 2, 3), max(1, 2, 3))
# 3 1
Full Changelog: v0.5.5...v0.5.6
v0.5.5
Added
- Implement sort() for TupleView and StrView
This sorts the tuple or string in-place, like
list.sort
, and accepts optionalkey
andreverse
arguments.
from einspect import view
s = "a1b2c3"
view(s).sort()
print(s)
>> 123abc
from einspect import view
t = (3, 1, 4, 2)
view(t).sort()
print(t)
>> (1, 2, 3, 4)
Fixes
- Add 2 missing
__all__
declarations inapi
andtypes
by @ionite34 in #42 - Change README heading phrasing, update lock file by @ionite34 in #43
- Switch from yanked version of sphinx-autodoc-typehints by @ionite34 in #44
Full Changelog: v0.5.4...v0.5.5
v0.5.4
Added
- CFunctionView
- PyCFunctionObject
These are essentially for support of builtin functions.
from einspect import view
v = view(abs)
print(v.ml.ml_name)
>> b'abs'
v <<= print
abs("hello")
>> hello
Fixes
FunctionView.version
naming fromfunc_version
Full Changelog: v0.5.3...v0.5.4
v0.5.3
Added
- PyFunctionObject and FunctionView
@struct
class PyFunctionObject(PyObject[FunctionType, None, None]):
globals: ptr[PyObject]
builtins: ptr[PyObject]
name: ptr[PyObject]
qualname: ptr[PyObject]
code: ptr[PyObject] # A code object, the __code__ attribute
defaults: ptr[PyObject] # NULL or a tuple
kwdefaults: ptr[PyObject] # NULL or a dict
closure: ptr[PyObject] # NULL or a tuple of cell objects
func_doc: ptr[PyObject] # The __doc__ attribute, can be anything
func_dict: ptr[PyObject] # The __dict__ attribute, a dict or NULL
func_weakreflist: ptr[PyObject] # List of weak references
func_module: ptr[PyObject] # The __module__ attribute, can be anything
func_annotations: ptr[PyObject] # Annotations, a dict or NULL
vectorcall: vectorcallfunc
func_version: Annotated[int, c_uint32]
So you can now do stuff like
from einspect import view
def func():
assert "__builtins__" not in globals()
return some_undefined_thing
v = view(func)
with v.unsafe():
v.globals = {"some_undefined_thing": 123}
print(func())
>> 123
Full Changelog: v0.5.2...v0.5.3
v0.5.2.post1
v0.5.2
Added
- py_unicode and instance dict compatibility for Python 3.12 definitions
- bumped higher python bound in pyproject.toml to support Python 3.12
Full Changelog: v0.5.1...v0.5.2
v0.5.1
Added
- Formatting for SetView.info
from einspect import view
s = {1, 2, 3}
print(view(s).info())
PySetObject (at 0x7f70e22f5ac0):
ob_refcnt: Py_ssize_t = 2
ob_type: *PyTypeObject = &[set]
fill: Py_ssize_t = 3
used: Py_ssize_t = 3
mask: Py_ssize_t = 7
table: *SetEntry = &[{ key = &[NULL], hash = 0 }]
hash: Py_hash_t = -1
finger: Py_ssize_t = 0
smalltable: Array[SetEntry] = [
{ key = &[NULL], hash = 0 },
{ key = &[1], hash = 1 },
{ key = &[2], hash = 2 },
{ key = &[3], hash = 3 },
{ key = &[NULL], hash = 0 },
{ key = &[NULL], hash = 0 },
{ key = &[NULL], hash = 0 },
{ key = &[NULL], hash = 0 }
]
weakreflist: *PyObject = &[<weakref at 0x7f70e230dd10; to 'set' at 0x7f70e22f5ac0>]
Full Changelog: v0.5.0...v0.5.1
v0.5.0
New
einspect.view
now supports subtypes. The additional instance dictionary is supported to be moved duringView.move_from
orView.move_to
from einspect import view
class Num(int):
pass
print(view(10))
# IntView(<PyLongObject at 0x101786a60>)
print(view(Num(10)))
# IntView[Num](<PyLongObject at 0x1006e7440>)
- Memory moves now no longer require an unsafe context if it can be performed safely.
- If safe moving is not possible (target size exceeds allocated memory for the object) an UnsafeError is raised.
from einspect import view
x = 900
view(x) << 50
ls = [1, 2]
view(ls) << [3, 4, 5]
tup = (1, 2)
view(tup) << (1, 2)
Changes
einspect.view
DeprecationWarning for non-concrete types is removed.View.move_from
no longer makes a deep-copy ofother
, this was originally added to prevent member references from being dropped but hindered features like connected instance dictionary pointers from working.- Such, the target of a move will receive most heap-allocated pointers of the source. For example, moved lists will share the original
ob_item
array
from einspect import view, unsafe
ls = []
x = [3, 4]
with unsafe():
view(ls) << x
print(ls) # [3, 4]
# Updating x will now affect ls as well
x[0] = "hi"
print(ls) # ['hi', 4]
- However, this only applies to pointers referring to allocations off the object struct, other attributes are still statically moved. For example, calling
x.clear()
will deallocate theob_item
array ofx
and set it as aNULL
pointer. Butls
still has anob_size
of 2, and will try to access itsob_item
pointer to get elements.
from einspect import view, unsafe
ls = []
x = [3, 4]
with unsafe():
view(ls) << x
x.clear()
print(ls) # Segmentation fault (likely)
- To revert to original behavior,
deepcopy
can be called explicitly
from copy import deepcopy
from einspect import view, unsafe
ls = []
x = [3, 4]
with unsafe():
view(ls) << deepcopy(x)
x.clear()
print(ls) # [3, 4]
- PyObject and subclasses can now be provided 1 positional argument to invoke
from_object
behavior:
from einspect.structs import PyObject, PyTypeObject
obj = PyObject("foo")
# equivalent to
obj = PyObject.from_object("foo")
- Manual struct creation can still be done with kwargs. This mode will also now invoke the relevant
_PyObject_New
,_PyObject_NewVar
, or_PyObject_GC_NewVar
C APIs to correctly initialize GC linked lists and allocate the object using free-lists, matching the interpreter’s native handling of new objects.
from einspect.structs import PyObject, PyTypeObject
obj = PyObject(
ob_refcnt=1,
ob_type=PyTypeObject(object).as_ref(),
)
Full Changelog: v0.4.10...v0.5.0
v0.5.0a1
New
einspect.view
now supports subtypes. The additional instance dictionary is supported to be moved duringView.move_from
orView.move_to
from einspect import view
class Num(int):
pass
print(view(10))
# IntView(<PyLongObject at 0x101786a60>)
print(view(Num(10)))
# IntView[Num](<PyLongObject at 0x1006e7440>)
- Memory moves now no longer require an unsafe context if it can be performed safely.
- If safe moving is not possible (target size exceeds allocated memory for the object) an UnsafeError is raised.
from einspect import view
x = 900
view(x) << 50
ls = [1, 2]
view(ls) << [3, 4, 5]
tup = (1, 2)
view(tup) << (1, 2)
Changes
einspect.view
DeprecationWarning for non-concrete types is removed.View.move_from
no longer makes a deep-copy ofother
, this was originally added to prevent member references from being dropped but hindered features like connected instance dictionary pointers from working.- Such, the target of a move will receive most heap-allocated pointers of the source. For example, moved lists will share the original
ob_item
array
from einspect import view, unsafe
ls = []
x = [3, 4]
with unsafe():
view(ls) << x
print(ls) # [3, 4]
# Updating x will now affect ls as well
x[0] = "hi"
print(ls) # ['hi', 4]
- However, this only applies to pointers referring to allocations off the object struct, other attributes are still statically moved. For example, calling
x.clear()
will deallocate theob_item
array ofx
and set it as aNULL
pointer. Butls
still has anob_size
of 2, and will try to access itsob_item
pointer to get elements.
from einspect import view, unsafe
ls = []
x = [3, 4]
with unsafe():
view(ls) << x
x.clear()
print(ls) # Segmentation fault (likely)
- To revert to original behavior,
deepcopy
can be called explicitly
from copy import deepcopy
from einspect import view, unsafe
ls = []
x = [3, 4]
with unsafe():
view(ls) << deepcopy(x)
x.clear()
print(ls) # [3, 4]
What's Changed
- Implement formatting for
MappingProxyView.info
by @ionite34 in #30 - Add tests for MappingProxyView info formatting by @ionite34 in #32
- Add subclass support for Views, safe memory moves no longer requires unsafe context by @ionite34 in #33
Full Changelog: v0.4.10...v0.5.0a1
v0.4.10
Adds
- PyObject
instance_dict
method - View
instance_dict
property
Fixes
- Formatting for
StrView.info
will now resolve additional values fields likewstr
Improvements
- Test coverage
Full Changelog: v0.4.9...v0.4.10