Skip to content

Commit a5edb7d

Browse files
committed
remove einspect
1 parent fa29953 commit a5edb7d

File tree

4 files changed

+224
-147
lines changed

4 files changed

+224
-147
lines changed

mlir/extras/ast/py_type.py

Lines changed: 222 additions & 144 deletions
Original file line numberDiff line numberDiff line change
@@ -1,154 +1,232 @@
1-
from __future__ import annotations
2-
1+
import sys
32
from ctypes import (
3+
POINTER,
4+
PYFUNCTYPE,
5+
Structure,
6+
_Pointer,
47
c_char,
58
c_char_p,
9+
c_int,
10+
c_ssize_t,
611
c_uint,
12+
c_uint16,
13+
c_uint32,
14+
c_uint8,
715
c_ulong,
16+
c_void_p,
17+
cast,
818
pointer,
19+
py_object,
920
)
10-
from typing import TypeVar
11-
12-
from einspect.structs.include.descrobject_h import PyGetSetDef, PyMemberDef
13-
from einspect.structs.include.methodobject_h import PyMethodDef
14-
from einspect.structs.include.object_h import (
15-
destructor,
16-
getattrfunc,
17-
setattrfunc,
18-
PyAsyncMethods,
19-
reprfunc,
20-
PyNumberMethods,
21-
PySequenceMethods,
22-
PyMappingMethods,
23-
hashfunc,
24-
ternaryfunc,
25-
getattrofunc,
26-
setattrofunc,
27-
PyBufferProcs,
28-
traverseproc,
29-
inquiry,
30-
richcmpfunc,
31-
getiterfunc,
32-
iternextfunc,
33-
descrgetfunc,
34-
descrsetfunc,
35-
initproc,
36-
allocfunc,
37-
newfunc,
38-
freefunc,
39-
vectorcallfunc,
40-
)
41-
from einspect.structs.py_object import PyObject, PyVarObject
42-
from einspect.types import ptr
43-
from typing_extensions import Annotated, Self
44-
45-
__all__ = ("PyTypeObject",)
46-
47-
_T = TypeVar("_T")
48-
49-
DEFAULT = object()
50-
51-
52-
# noinspection PyPep8Naming
53-
class PyTypeObject(PyVarObject[_T, None, None]):
54-
"""
55-
Defines a PyTypeObject Structure.
56-
57-
https://github.com/python/cpython/blob/3.11/Doc/includes/typestruct.h
58-
59-
..
60-
source: Include/cpython/object.h (struct _typeobject)
61-
"""
62-
63-
tp_name: Annotated[bytes, c_char_p]
64-
# For allocation
65-
tp_basicsize: int
66-
tp_itemsize: int
67-
# Methods to implement standard operations
68-
tp_dealloc: destructor
69-
tp_vectorcall_offset: int
70-
tp_getattr: getattrfunc
71-
tp_setattr: setattrfunc
72-
# formerly known as tp_compare (Python 2) or tp_reserved (Python 3)
73-
tp_as_async: ptr[PyAsyncMethods]
74-
75-
tp_repr: reprfunc
76-
77-
# Method suites for standard classes
78-
tp_as_number: ptr[PyNumberMethods]
79-
tp_as_sequence: ptr[PySequenceMethods]
80-
tp_as_mapping: ptr[PyMappingMethods]
81-
82-
# More standard operations (here for binary compatibility)
83-
tp_hash: hashfunc
84-
tp_call: ternaryfunc
85-
tp_str: reprfunc
86-
tp_getattro: getattrofunc
87-
tp_setattro: setattrofunc
88-
89-
# Functions to access object as input/output buffer
90-
tp_as_buffer: ptr[PyBufferProcs]
91-
92-
# Flags to define presence of optional/expanded features
93-
tp_flags: Annotated[int, c_ulong]
94-
95-
tp_doc: Annotated[bytes, c_char_p] # Documentation string
96-
97-
# Assigned meaning in release 2.0
98-
# call function for all accessible objects
99-
tp_traverse: traverseproc
100-
101-
tp_clear: inquiry # delete references to contained objects
102-
103-
# Assigned meaning in release 2.1
104-
# rich comparisons
105-
tp_richcompare: richcmpfunc
106-
107-
tp_weaklistoffset: int # weak reference enabler
108-
109-
# Iterators
110-
tp_iter: getiterfunc
111-
tp_iternext: iternextfunc
112-
113-
# Attribute descriptor and subclassing stuff
114-
tp_methods: ptr[PyMethodDef]
115-
tp_members: ptr[PyMemberDef]
116-
tp_getset: ptr[PyGetSetDef]
117-
118-
# Strong reference on a heap type, borrowed reference on a static type
119-
tp_base: pointer[Self]
120-
tp_dict: ptr[PyObject]
121-
tp_descr_get: descrgetfunc
122-
tp_descr_set: descrsetfunc
123-
tp_dictoffset: int
124-
tp_init: initproc
125-
tp_alloc: allocfunc
126-
tp_new: newfunc
127-
tp_free: freefunc # Low-level free-memory routine
128-
tp_is_gc: inquiry # For PyObject_IS_GC
129-
tp_bases: ptr[PyObject]
130-
tp_mro: ptr[PyObject] # method resolution order
131-
tp_cache: ptr[PyObject]
132-
tp_subclasses: ptr[PyObject] # for static builtin types this is an index
133-
tp_weaklist: ptr[PyObject]
134-
tp_del: destructor
135-
136-
# Type attribute cache version tag. Added in version 2.6
137-
tp_version_tag: Annotated[int, c_uint]
138-
139-
tp_finalize: destructor
140-
tp_vectorcall: vectorcallfunc
141-
142-
# bitset of which type-watchers care about this type
143-
tp_watched: c_char
144-
145-
146-
# https://github.com/python/cpython/blob/809aa9a682fc865f7502e7421da0a74d204aab6d/Objects/typevarobject.c#L29
147-
class PyTypeVarObject(PyVarObject[_T, None, None]):
148-
name: ptr[PyObject]
149-
# not sure why but this is the only thing that works but that's fine because it's the only thing we need
150-
bound: ptr[PyObject]
21+
from typing import get_origin, _SpecialForm, _GenericAlias
22+
23+
24+
_SelfPtr = object()
25+
26+
27+
@_SpecialForm
28+
def Self(self, parameters):
29+
raise TypeError(f"{self} is not subscriptable")
30+
31+
32+
class _Ptr(_Pointer):
33+
def __new__(cls, *args, **kwargs):
34+
return pointer(*args, **kwargs)
35+
36+
def __class_getitem__(cls, item):
37+
"""Return a `ctypes.POINTER` of the given type."""
38+
# For ptr[Self], return a special object
39+
if item is Self:
40+
return _SelfPtr
41+
42+
# Get base of generic alias
43+
# noinspection PyUnresolvedReferences, PyProtectedMember
44+
if isinstance(item, _GenericAlias):
45+
item = get_origin(item)
46+
47+
try:
48+
return POINTER(item)
49+
except TypeError as e:
50+
raise TypeError(f"{e} (During POINTER({item}))") from e
51+
52+
53+
def address(obj) -> int:
54+
source = py_object(obj)
55+
addr = c_void_p.from_buffer(source).value
56+
if addr is None:
57+
raise ValueError("address: NULL object") # pragma: no cover
58+
return addr
59+
60+
61+
# https://github.com/python/cpython/blob/3.11/Include/object.h#L196-L227
62+
unaryfunc = PYFUNCTYPE(py_object, py_object)
63+
binaryfunc = PYFUNCTYPE(py_object, py_object, py_object)
64+
ternaryfunc = PYFUNCTYPE(py_object, py_object, py_object, py_object)
65+
inquiry = PYFUNCTYPE(c_int, py_object)
66+
lenfunc = PYFUNCTYPE(c_ssize_t, py_object)
67+
ssizeargfunc = PYFUNCTYPE(py_object, py_object, c_ssize_t)
68+
ssizessizeargfunc = PYFUNCTYPE(py_object, py_object, c_ssize_t, c_ssize_t)
69+
ssizeobjargproc = PYFUNCTYPE(c_int, py_object, c_ssize_t, py_object)
70+
ssizessizeobjargproc = PYFUNCTYPE(c_int, py_object, c_ssize_t, c_ssize_t, py_object)
71+
objobjargproc = PYFUNCTYPE(c_int, py_object, py_object, py_object)
72+
73+
objobjproc = PYFUNCTYPE(c_int, py_object, py_object)
74+
visitproc = PYFUNCTYPE(c_int, py_object, c_void_p)
75+
traverseproc = PYFUNCTYPE(c_int, py_object, visitproc, c_void_p)
76+
77+
freefunc = PYFUNCTYPE(None, c_void_p)
78+
destructor = PYFUNCTYPE(None, py_object)
79+
getattrfunc = PYFUNCTYPE(py_object, py_object, c_char_p)
80+
getattrofunc = PYFUNCTYPE(py_object, py_object, py_object)
81+
setattrfunc = PYFUNCTYPE(c_int, py_object, c_char_p, py_object)
82+
setattrofunc = PYFUNCTYPE(c_int, py_object, py_object, py_object)
83+
reprfunc = PYFUNCTYPE(py_object, py_object)
84+
hashfunc = PYFUNCTYPE(c_ssize_t, py_object)
85+
richcmpfunc = PYFUNCTYPE(py_object, py_object, py_object, c_int)
86+
getiterfunc = PYFUNCTYPE(py_object, py_object)
87+
iternextfunc = PYFUNCTYPE(py_object, py_object)
88+
89+
descrgetfunc = PYFUNCTYPE(py_object, py_object, py_object, py_object)
90+
descrsetfunc = PYFUNCTYPE(c_int, py_object, py_object, py_object)
91+
initproc = PYFUNCTYPE(c_int, py_object, py_object, py_object)
92+
newfunc = PYFUNCTYPE(py_object, py_object, py_object, py_object)
93+
allocfunc = PYFUNCTYPE(py_object, py_object, c_ssize_t)
94+
95+
# PyObject *(*vectorcallfunc)(PyObject *callable, PyObject *const *args, size_t nargsf, PyObject *kwnames)
96+
vectorcallfunc = PYFUNCTYPE(py_object, py_object, _Ptr[py_object], c_ssize_t, py_object)
97+
# PySendResult (*sendfunc)(PyObject *iter, PyObject *value, PyObject **result)
98+
sendfunc = PYFUNCTYPE(c_int, py_object, py_object, _Ptr[py_object])
99+
100+
101+
def _is_gil_enabled():
102+
try:
103+
return sys._is_gil_enabled()
104+
except:
105+
return True
106+
107+
108+
if _is_gil_enabled():
109+
_py_object_fields = [
110+
("ob_refcnt", c_ssize_t),
111+
("ob_type", _Ptr[py_object]),
112+
]
113+
else:
114+
# https://github.com/python/cpython/blob/main/Include/object.h#L168
115+
_py_object_fields = [
116+
("ob_tid", c_ssize_t),
117+
("ob_flags", c_uint16),
118+
# https://github.com/python/cpython/blob/main/Include/cpython/pylock.h#L29
119+
("ob_mutex", c_uint8),
120+
("ob_gc_bits", c_uint8),
121+
("ob_ref_local", c_uint32),
122+
("ob_ref_shared", c_ssize_t),
123+
("ob_type", _Ptr[py_object]),
124+
]
125+
126+
127+
class PyObject(Structure):
128+
_fields_ = _py_object_fields
129+
130+
def as_ref(self) -> _Ptr[Self]:
131+
"""Return a pointer to the Structure."""
132+
return pointer(self) # type: ignore
133+
134+
def into_object(self):
135+
"""Cast the PyObject into a Python object."""
136+
py_obj = cast(self.as_ref(), py_object)
137+
return py_obj.value
138+
139+
140+
# https://github.com/python/cpython/blob/3.11/Doc/includes/typestruct.h
141+
class PyTypeObject(Structure):
142+
_fields_ = _py_object_fields + [
143+
("ob_size", c_ssize_t),
144+
("tp_name", c_char_p),
145+
("tp_basicsize", c_ssize_t),
146+
("tp_itemsize", c_ssize_t),
147+
("tp_dealloc", destructor),
148+
("tp_vectorcall_offset", c_ssize_t),
149+
("tp_getattr", getattrfunc),
150+
("tp_setattr", setattrfunc),
151+
# ("tp_as_async", _Ptr[PyAsyncMethods]),
152+
("tp_as_async", _Ptr[PyObject]),
153+
("tp_repr", reprfunc),
154+
# ("tp_as_number", _Ptr[PyNumberMethods]),
155+
("tp_as_number", _Ptr[PyObject]),
156+
# ("tp_as_sequence", _Ptr[PySequenceMethods]),
157+
("tp_as_sequence", _Ptr[PyObject]),
158+
# ("tp_as_mapping", _Ptr[PyMappingMethods]),
159+
("tp_as_mapping", _Ptr[PyObject]),
160+
("tp_hash", hashfunc),
161+
("tp_call", ternaryfunc),
162+
("tp_str", reprfunc),
163+
("tp_getattro", getattrofunc),
164+
("tp_setattro", setattrofunc),
165+
# ("tp_as_buffer", _Ptr[PyBufferProcs]),
166+
("tp_as_buffer", _Ptr[PyObject]),
167+
("tp_flags", c_ulong),
168+
("tp_doc", c_char_p),
169+
("tp_traverse", traverseproc),
170+
("tp_clear", inquiry),
171+
("tp_richcompare", richcmpfunc),
172+
("tp_weaklistoffset", c_ssize_t),
173+
("tp_iter", getiterfunc),
174+
("tp_iternext", iternextfunc),
175+
("tp_methods", _Ptr[PyObject]),
176+
("tp_members", _Ptr[PyObject]),
177+
("tp_getset", _Ptr[PyObject]),
178+
# ("tp_base", _Ptr[PyTypeObject]),
179+
("tp_base", _Ptr[PyObject]),
180+
("tp_dict", _Ptr[PyObject]),
181+
("tp_descr_get", descrgetfunc),
182+
("tp_descr_set", descrsetfunc),
183+
("tp_dictoffset", c_ssize_t),
184+
("tp_init", initproc),
185+
("tp_alloc", allocfunc),
186+
("tp_new", newfunc),
187+
("tp_free", freefunc),
188+
("tp_is_gc", inquiry),
189+
("tp_bases", _Ptr[PyObject]),
190+
("tp_mro", _Ptr[PyObject]),
191+
("tp_cache", _Ptr[PyObject]),
192+
("tp_subclasses", _Ptr[PyObject]),
193+
("tp_weaklist", _Ptr[PyObject]),
194+
("tp_del", destructor),
195+
("tp_version_tag", c_uint),
196+
("tp_finalize", descrsetfunc),
197+
("tp_vectorcall", vectorcallfunc),
198+
("tp_watched", c_char),
199+
]
200+
201+
@classmethod
202+
def from_object(cls, obj) -> Self:
203+
"""Create a PyObject from an object."""
204+
return cls.from_address(address(obj))
205+
206+
207+
class PyTypeVarObject(Structure):
208+
_fields_ = _py_object_fields + [
209+
("ob_size", c_ssize_t),
210+
("name", _Ptr[PyObject]),
211+
# not sure why but this is the only thing that works but that's fine because it's the only thing we need
212+
("bound", _Ptr[PyObject]),
213+
]
214+
215+
@classmethod
216+
def from_object(cls, obj) -> Self:
217+
"""Create a PyObject from an object."""
218+
return cls.from_address(address(obj))
151219

152220

153221
if __name__ == "__main__":
154-
print(PyTypeObject.from_object(type(3.14)))
222+
# for k, v in PyObject._fields_:
223+
# print(f"('{k}', {v.__name__}),")
224+
# for k, v in PyVarObject._fields_:
225+
# print(f"('{k}', {v.__name__}),")
226+
# for k, v in PyTypeObject._fields_:
227+
# print(f"('{k}', {v.__name__}),")
228+
print(PyTypeObject.from_object(type(3.14)).tp_name)
229+
print(PyTypeObject.from_object(type(3.14)).tp_base)
230+
print(PyTypeObject.from_object(type(3.14)).ob_type)
231+
for k, v in PyTypeVarObject._fields_:
232+
print(f"('{k}', {v.__name__}),")

mlir/extras/dialects/ext/func.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -308,7 +308,7 @@ def __getitem__(self, item):
308308
generics = copy.deepcopy(self.generics)
309309
for i, t in enumerate(generics):
310310
if sys.version_info >= (3, 12):
311-
type_var_bound = PyTypeVarObject.try_from(t).bound
311+
type_var_bound = PyTypeVarObject.from_object(t).bound
312312
else:
313313
type_var_bound = t.__bound__
314314
if type_var_bound:

requirements.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
PyYAML>=5.4.0
22
bytecode @ git+https://github.com/MatthieuDartiailh/[email protected]
33
cloudpickle>=3.0.0
4-
einspect @ git+https://github.com/makslevental/einspect@makslevental/bump-py.3.13
54
numpy>=1.19.5, <=2.1.2

0 commit comments

Comments
 (0)