Skip to main content

Extended Inspect - view and modify memory structs of runtime objects.

Project description

einspect

Build codecov

Extended Inspect for CPython

Provides simple and robust ways to view and modify the base memory structures of Python objects at runtime.

Note: The below examples show interactions with a TupleView, but applies much the same way generically for many of the specialized View subtypes that are dynamically returned by the view function. If no specific view is implemented, the base View will be used which represents limited interactions on the assumption of PyObject struct parts.

from einspect import view

print(view((1, 2)))
print(view([1, 2]))
print(view("hello"))
print(view(256))
print(view(object()))
TupleView[tuple](<PyTupleObject at 0x100f19a00>)
ListView[list](<PyListObject at 0x10124f800>)
StrView[str](<PyUnicodeObject at 0x100f12ab0>)
IntView[int](<PyLongObject at 0x102058920>)
View[object](<PyObject at 0x100ea08a0>)

1. Viewing python object struct attributes

State information of the underlying PyTupleObject struct can be accessed through the view's attributes.

print(v.ref_count)  # ob_refcnt
print(v.type)       # ob_type
print(v.size)       # ob_size
print(v.items)      # ob_item
4
<class 'tuple'>
3
<einspect.structs.c_long_Array_3 object at 0x105038ed0>

2. Writing to view attributes

Writing to these attributes will affect the underlying object of the view.

Note that most memory-unsafe attribute modifications require entering an unsafe context manager with View.unsafe()

with v.unsafe():
    v.size -= 1

print(obj)

(1, 2)

Since items is an array of integer pointers to python objects, they can be replaced by id() addresses to modify index items in the tuple.

from einspect import view

tup = (100, 200)

with view(tup).unsafe() as v:
    s = "dog"
    v.item[0] = id(s)

print(tup)
('dog', 200)

>> Process finished with exit code 139 (interrupted by signal 11: SIGSEGV)

So here we did set the item at index 0 with our new item, the string "dog", but this also caused a segmentation fault. Note that the act of setting an item in containers like tuples and lists "steals" a reference to the object, even if we only supplied the address pointer.

To make this safe, we will have to manually increment a ref-count before the new item is assigned. To do this we can either create a view of our new item, and increment its ref_count += 1, or use the apis from einspect.api, which are pre-typed implementations of ctypes.pythonapi methods.

from einspect import view
from einspect.api import Py

tup = (100, 200)

with view(tup).unsafe() as v:
    a = "bird"
    Py.IncRef(a)
    v.item[0] = id(a)
    
    b = "kitten"
    Py.IncRef(b)
    v.item[1] = id(b)

print(tup)

('bird', 'kitten')

🎉 No more seg-faults, and we just successfully set both items in an otherwise immutable tuple.

To make the above routine easier, you can access an abstraction by simply indexing the view.

from einspect import view

tup = ("a", "b", "c")

v = view(tup)
v[0] = 123
v[1] = "hm"
v[2] = "🤔"

print(tup)

(123, 'hm', '🤔')

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

einspect-0.2.1.tar.gz (16.0 kB view details)

Uploaded Source

Built Distribution

einspect-0.2.1-py3-none-any.whl (21.6 kB view details)

Uploaded Python 3

File details

Details for the file einspect-0.2.1.tar.gz.

File metadata

  • Download URL: einspect-0.2.1.tar.gz
  • Upload date:
  • Size: 16.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/1.3.0 CPython/3.11.1 Linux/5.15.0-1024-azure

File hashes

Hashes for einspect-0.2.1.tar.gz
Algorithm Hash digest
SHA256 d878da3e9c8434afadc2e2f0e39a89a6c19c386c355c46aeefeca4216ddcf030
MD5 64b5786b566f0af938fb308a5fd093c5
BLAKE2b-256 9701eb8eef4bb178e670ec451c0b23bc0592a669cb7670773167eaccb93ba6c6

See more details on using hashes here.

File details

Details for the file einspect-0.2.1-py3-none-any.whl.

File metadata

  • Download URL: einspect-0.2.1-py3-none-any.whl
  • Upload date:
  • Size: 21.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/1.3.0 CPython/3.11.1 Linux/5.15.0-1024-azure

File hashes

Hashes for einspect-0.2.1-py3-none-any.whl
Algorithm Hash digest
SHA256 fcdc3d5c6f720bd2d43a7fc9d5aed06f4753e8a48fb73bf65810b2a248ecc48e
MD5 03bbe392bd1b243d7747b281e3178c98
BLAKE2b-256 fb29123157874a55f717db9b11c548f635b5d3b738c6be437da0df959c4ca35c

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page