def type_attach(space, py_obj, w_obj, w_userdata=None): '''Fills a newly allocated py_obj from the w_obj If it is a datetime.time or datetime.datetime, it may have tzinfo ''' state = space.fromcache(State) # cannot raise here, so just crash assert len(state.datetimeAPI) > 0 if state.datetimeAPI[0].c_TimeType == py_obj.c_ob_type: py_datetime = rffi.cast(PyDateTime_Time, py_obj) w_tzinfo = space.getattr(w_obj, space.newtext('tzinfo')) if space.is_none(w_tzinfo): py_datetime.c_hastzinfo = cts.cast('unsigned char', 0) py_datetime.c_tzinfo = lltype.nullptr(PyObject.TO) else: py_datetime.c_hastzinfo = cts.cast('unsigned char', 1) py_datetime.c_tzinfo = make_ref(space, w_tzinfo) elif state.datetimeAPI[0].c_DateTimeType == py_obj.c_ob_type: # For now this is exactly the same structure as PyDateTime_Time py_datetime = rffi.cast(PyDateTime_DateTime, py_obj) w_tzinfo = space.getattr(w_obj, space.newtext('tzinfo')) if space.is_none(w_tzinfo): py_datetime.c_hastzinfo = cts.cast('unsigned char', 0) py_datetime.c_tzinfo = lltype.nullptr(PyObject.TO) else: py_datetime.c_hastzinfo = cts.cast('unsigned char', 1) py_datetime.c_tzinfo = make_ref(space, w_tzinfo)
def __init__(self, space, pto): bases_w = space.fixedview(from_ref(space, pto.c_tp_bases)) dict_w = {} add_operators(space, dict_w, pto) convert_method_defs(space, dict_w, pto.c_tp_methods, self) convert_getset_defs(space, dict_w, pto.c_tp_getset, self) convert_member_defs(space, dict_w, pto.c_tp_members, self) name = rffi.charp2str(cts.cast('char*', pto.c_tp_name)) flag_heaptype = pto.c_tp_flags & Py_TPFLAGS_HEAPTYPE if flag_heaptype: minsize = rffi.sizeof(PyHeapTypeObject.TO) else: minsize = rffi.sizeof(PyObject.TO) new_layout = (pto.c_tp_basicsize > minsize or pto.c_tp_itemsize > 0) W_TypeObject.__init__(self, space, name, bases_w or [space.w_object], dict_w, force_new_layout=new_layout, is_heaptype=flag_heaptype) self.flag_cpytype = True # if a sequence or a mapping, then set the flag to force it if pto.c_tp_as_sequence and pto.c_tp_as_sequence.c_sq_item: self.flag_map_or_seq = 'S' elif (pto.c_tp_as_mapping and pto.c_tp_as_mapping.c_mp_subscript and not (pto.c_tp_as_sequence and pto.c_tp_as_sequence.c_sq_slice)): self.flag_map_or_seq = 'M' if pto.c_tp_doc: self.w_doc = space.newtext( rffi.charp2str(cts.cast('char*', pto.c_tp_doc)))
def releasebuffer(self): if self.pyobj: if self.needs_decref: if self.releasebufferproc: func_target = rffi.cast(releasebufferproc, self.releasebufferproc) with lltype.scoped_alloc(Py_buffer) as pybuf: pybuf.c_buf = self.ptr pybuf.c_len = self.size pybuf.c_ndim = cts.cast('int', self.ndim) pybuf.c_shape = cts.cast('Py_ssize_t*', pybuf.c__shape) pybuf.c_strides = cts.cast('Py_ssize_t*', pybuf.c__strides) for i in range(self.ndim): pybuf.c_shape[i] = self.shape[i] pybuf.c_strides[i] = self.strides[i] if self.format: pybuf.c_format = rffi.str2charp(self.format) else: pybuf.c_format = rffi.str2charp("B") generic_cpy_call(self.space, func_target, self.pyobj, pybuf) decref(self.space, self.pyobj) self.pyobj = lltype.nullptr(PyObject.TO) else: #do not call twice return
def timedeltatype_attach(space, py_obj, w_obj, w_userdata=None): "Fills a newly allocated py_obj from the w_obj" py_delta = rffi.cast(PyDateTime_Delta, py_obj) days = space.int_w(space.getattr(w_obj, space.newtext('days'))) py_delta.c_days = cts.cast('int', days) seconds = space.int_w(space.getattr(w_obj, space.newtext('seconds'))) py_delta.c_seconds = cts.cast('int', seconds) microseconds = space.int_w(space.getattr(w_obj, space.newtext('microseconds'))) py_delta.c_microseconds = cts.cast('int', microseconds)
def init_descr(space, py_obj, w_type, name): """Initialises the common fields in a PyDescrObject Arguments: py_obj: PyObject* pointer to a PyDescrObject w_type: W_TypeObject c_name: char* """ py_descr = cts.cast('PyDescrObject*', py_obj) py_descr.c_d_type = cts.cast('PyTypeObject*', make_ref(space, w_type)) py_descr.c_d_name = make_ref(space, space.newtext(name))
def make_GetSet(space, getsetprop): py_getsetdef = lltype.malloc(PyGetSetDef, flavor='raw') doc = getsetprop.doc if doc: py_getsetdef.c_doc = rffi.str2charp(doc) else: py_getsetdef.c_doc = rffi.cast(rffi.CCHARP, 0) py_getsetdef.c_name = rffi.str2charp(getsetprop.getname(space)) # XXX FIXME - actually assign these !!! py_getsetdef.c_get = cts.cast('getter', 0) py_getsetdef.c_set = cts.cast('setter', 0) py_getsetdef.c_closure = cts.cast('void*', 0) return py_getsetdef
def type_attach(space, py_obj, w_obj, w_userdata=None): '''Fills a newly allocated py_obj from the w_obj ''' if space.type(w_obj).name == 'date': # No tzinfo return py_datetime = rffi.cast(PyDateTime_Time, py_obj) w_tzinfo = space.getattr(w_obj, space.newtext('tzinfo')) if space.is_none(w_tzinfo): py_datetime.c_hastzinfo = cts.cast('unsigned char', 0) py_datetime.c_tzinfo = lltype.nullptr(PyObject.TO) else: py_datetime.c_hastzinfo = cts.cast('unsigned char', 1) py_datetime.c_tzinfo = make_ref(space, w_tzinfo)
def add_operators(space, dict_w, pto): from pypy.module.cpyext.object import PyObject_HashNotImplemented hash_not_impl = PyObject_HashNotImplemented.api_func.get_llhelper(space) for method_name, slot_names, wrapper_func, wrapper_func_kwds, doc in slotdefs_for_wrappers: if method_name in dict_w: continue offset = [rffi.offsetof(lltype.typeOf(pto).TO, slot_names[0])] if len(slot_names) == 1: func = getattr(pto, slot_names[0]) if slot_names[0] == 'c_tp_hash': if hash_not_impl == func: # special case for tp_hash == PyObject_HashNotImplemented dict_w[method_name] = space.w_None continue else: assert len(slot_names) == 2 struct = getattr(pto, slot_names[0]) if not struct: continue offset.append(rffi.offsetof(lltype.typeOf(struct).TO, slot_names[1])) func = getattr(struct, slot_names[1]) func_voidp = rffi.cast(rffi.VOIDP, func) if not func: continue if wrapper_func is None and wrapper_func_kwds is None: continue w_obj = W_PyCWrapperObject(space, pto, method_name, wrapper_func, wrapper_func_kwds, doc, func_voidp, offset=offset) dict_w[method_name] = w_obj if pto.c_tp_doc: dict_w['__doc__'] = space.newtext( rffi.charp2str(cts.cast('char*', pto.c_tp_doc))) if pto.c_tp_new: add_tp_new_wrapper(space, dict_w, pto)
def add_operators(space, dict_w, pto): # XXX support PyObject_HashNotImplemented for method_name, slot_names, wrapper_func, wrapper_func_kwds, doc in slotdefs_for_wrappers: if method_name in dict_w: continue offset = [rffi.offsetof(lltype.typeOf(pto).TO, slot_names[0])] if len(slot_names) == 1: func = getattr(pto, slot_names[0]) else: assert len(slot_names) == 2 struct = getattr(pto, slot_names[0]) if not struct: continue offset.append( rffi.offsetof(lltype.typeOf(struct).TO, slot_names[1])) func = getattr(struct, slot_names[1]) func_voidp = rffi.cast(rffi.VOIDP, func) if not func: continue if wrapper_func is None and wrapper_func_kwds is None: continue w_obj = W_PyCWrapperObject(space, pto, method_name, wrapper_func, wrapper_func_kwds, doc, func_voidp, offset=offset) dict_w[method_name] = w_obj if pto.c_tp_doc: dict_w['__doc__'] = space.newtext( rffi.charp2str(cts.cast('char*', pto.c_tp_doc))) if pto.c_tp_new: add_tp_new_wrapper(space, dict_w, pto)
def memberdescr_realize(space, obj): # XXX NOT TESTED When is this ever called? member = cts.cast('PyMemberDef*', obj) w_type = from_ref(space, rffi.cast(PyObject, obj.c_ob_type)) w_obj = space.allocate_instance(W_MemberDescr, w_type) w_obj.__init__(member, w_type) track_reference(space, obj, w_obj) return w_obj
def memberdescr_attach(space, py_obj, w_obj, w_userdata=None): """ Fills a newly allocated PyMemberDescrObject with the given W_MemberDescr object. The values must not be modified. """ py_memberdescr = cts.cast('PyMemberDescrObject*', py_obj) assert isinstance(w_obj, W_MemberDescr) py_memberdescr.c_d_member = w_obj.member init_descr(space, py_obj, w_obj.w_type, w_obj.name)
def descr_get_doc(self, space): py_obj = make_ref(space, self) py_methoddescr = cts.cast('PyWrapperDescrObject*', py_obj) if py_methoddescr.c_d_base and py_methoddescr.c_d_base.c_doc: doc = rffi.charp2str(py_methoddescr.c_d_base.c_doc) else: doc = self.doc if doc: return space.newtext(doc) return space.w_None
def is_allowed_to_leak(space, obj): from pypy.module.cpyext.methodobject import W_PyCFunctionObject try: w_obj = from_ref(space, cts.cast('PyObject*', obj._as_ptr())) except: return False if isinstance(w_obj, W_PyCFunctionObject): return True # It's OK to "leak" some interned strings: if the pyobj is created by # the test, but the w_obj is referred to from elsewhere. return is_interned_string(space, w_obj)
def attach_legacy_methods(space, pymethods, w_obj, modname=None): """ pymethods is passed as a void*, but it is expected to be a PyMethodDef[]. Wrap its items into the proper cpyext.W_*Function objects, and attach them to w_obj (which can be either a module or a type). """ pymethods = cpyts.cast('PyMethodDef*', pymethods) dict_w = {} convert_method_defs(space, dict_w, pymethods, None, w_obj, modname) for key, w_func in dict_w.items(): space.setattr(w_obj, space.newtext(key), w_func)
def type_realize(space, py_obj): pto = rffi.cast(PyTypeObjectPtr, py_obj) assert pto.c_tp_flags & Py_TPFLAGS_READY == 0 assert pto.c_tp_flags & Py_TPFLAGS_READYING == 0 pto.c_tp_flags |= Py_TPFLAGS_READYING try: w_obj = _type_realize(space, py_obj) finally: name = rffi.charp2str(cts.cast('char*', pto.c_tp_name)) pto.c_tp_flags &= ~Py_TPFLAGS_READYING pto.c_tp_flags |= Py_TPFLAGS_READY return w_obj
def _readify(space, py_obj, value): maxchar = 0 for c in value: if ord(c) > maxchar: maxchar = ord(c) if maxchar > MAX_UNICODE: raise oefmt( space.w_ValueError, "Character U+%d is not in range [U+0000; U+10ffff]", maxchar) if maxchar < 256: ucs1_data = rffi.str2charp( unicode_encode_latin_1(value, len(value), errors='strict')) set_data(py_obj, cts.cast('void*', ucs1_data)) set_kind(py_obj, _1BYTE_KIND) set_len(py_obj, get_wsize(py_obj)) if maxchar < 128: set_ascii(py_obj, 1) set_utf8(py_obj, cts.cast('char*', get_data(py_obj))) set_utf8_len(py_obj, get_wsize(py_obj)) else: set_ascii(py_obj, 0) set_utf8(py_obj, cts.cast('char *', 0)) set_utf8_len(py_obj, 0) elif maxchar < 65536: # XXX: assumes that sizeof(wchar_t) == 4 ucs2_str = unicode_encode_utf_16_helper(value, len(value), errors='strict', byteorder=runicode.BYTEORDER) ucs2_data = cts.cast('Py_UCS2 *', rffi.str2charp(ucs2_str)) set_data(py_obj, cts.cast('void*', ucs2_data)) set_len(py_obj, get_wsize(py_obj)) set_kind(py_obj, _2BYTE_KIND) set_utf8(py_obj, cts.cast('char *', 0)) set_utf8_len(py_obj, 0) else: # XXX: assumes that sizeof(wchar_t) == 4 if not get_wbuffer(py_obj): # Copy unicode buffer set_wbuffer(py_obj, rffi.unicode2wcharp(value)) set_wsize(py_obj, len(value)) ucs4_data = get_wbuffer(py_obj) set_data(py_obj, cts.cast('void*', ucs4_data)) set_len(py_obj, get_wsize(py_obj)) set_kind(py_obj, _4BYTE_KIND) set_utf8(py_obj, cts.cast('char *', 0)) set_utf8_len(py_obj, 0) set_ready(py_obj, 1) return 0
def PyMemoryView_FromMemory(space, mem, size, flags): """Expose a raw memory area as a view of contiguous bytes. flags can be PyBUF_READ or PyBUF_WRITE. view->format is set to "B" (unsigned bytes). The memoryview has complete buffer information. """ readonly = int(widen(flags) == PyBUF_WRITE) view = CPyBuffer(space, cts.cast('void*', mem), size, None, readonly=readonly) w_mview = W_MemoryView(view) return w_mview
def __init__(self, space, pto): bases_w = space.fixedview(from_ref(space, pto.c_tp_bases)) dict_w = {} name = rffi.charp2str(cts.cast('char*', pto.c_tp_name)) add_operators(space, self, dict_w, pto, name) convert_method_defs(space, dict_w, pto.c_tp_methods, self) convert_getset_defs(space, dict_w, pto.c_tp_getset, self) convert_member_defs(space, dict_w, pto.c_tp_members, self) w_dict = from_ref(space, pto.c_tp_dict) if w_dict is not None: dictkeys_w = space.listview(w_dict) for w_key in dictkeys_w: key = space.text_w(w_key) dict_w[key] = space.getitem(w_dict, w_key) flag_heaptype = pto.c_tp_flags & Py_TPFLAGS_HEAPTYPE if flag_heaptype: minsize = rffi.sizeof(PyHeapTypeObject.TO) else: minsize = rffi.sizeof(PyObject.TO) new_layout = (pto.c_tp_basicsize > minsize or pto.c_tp_itemsize > 0) self.flag_cpytype = True W_TypeObject.__init__(self, space, name, bases_w or [space.w_object], dict_w, force_new_layout=new_layout, is_heaptype=flag_heaptype) # if a sequence or a mapping, then set the flag to force it if pto.c_tp_as_sequence and pto.c_tp_as_sequence.c_sq_item: self.flag_map_or_seq = 'S' elif pto.c_tp_as_mapping and pto.c_tp_as_mapping.c_mp_subscript: self.flag_map_or_seq = 'M' if pto.c_tp_doc: rawdoc = rffi.charp2str(cts.cast('char*', pto.c_tp_doc)) self.w_doc = space.newtext_or_none(extract_doc(rawdoc, name)) self.text_signature = extract_txtsig(rawdoc, name)
def getsetdescr_attach(space, py_obj, w_obj, w_userdata=None): """ Fills a newly allocated PyGetSetDescrObject with the given W_GetSetPropertyEx object. The values must not be modified. """ py_getsetdescr = cts.cast('PyGetSetDescrObject*', py_obj) if isinstance(w_obj, GetSetProperty): py_getsetdef = make_GetSet(space, w_obj) assert space.isinstance_w(w_userdata, space.w_type) w_obj = W_GetSetPropertyEx(py_getsetdef, w_userdata) # now w_obj.getset is py_getsetdef, which was freshly allocated # XXX how is this ever released? assert isinstance(w_obj, W_GetSetPropertyEx) py_getsetdescr.c_d_getset = w_obj.getset init_descr(space, py_obj, w_obj.w_type, w_obj.name)
def PyUnicode_FromKindAndData(space, kind, data, size): if size < 0: raise oefmt(space.w_ValueError, "size must be positive") data = cts.cast('char *', data) kind = widen(kind) if kind == _1BYTE_KIND: value = rffi.charpsize2str(data, size) w_res = latin_1_decode(space, value, w_final=space.w_False) elif kind == _2BYTE_KIND: value = rffi.charpsize2str(data, 2 * size) w_res = utf_16_decode(space, value, w_final=space.w_False) elif kind == _4BYTE_KIND: value = rffi.charpsize2str(data, 4 * size) w_res = utf_32_decode(space, value, w_final=space.w_False) else: raise oefmt(space.w_SystemError, "invalid kind") return space.unpackiterable(w_res)[0]
def add_operators(space, dict_w, pto): from pypy.module.cpyext.object import PyObject_HashNotImplemented hash_not_impl = llslot(space, PyObject_HashNotImplemented) for method_name, slot_names, wrapper_class, doc in slotdefs_for_wrappers: if method_name in dict_w: continue offset = [rffi.offsetof(lltype.typeOf(pto).TO, slot_names[0])] if len(slot_names) == 1: func = getattr(pto, slot_names[0]) if slot_names[0] == 'c_tp_hash': # two special cases where __hash__ is explicitly set to None # (which leads to an unhashable type): # 1) tp_hash == PyObject_HashNotImplemented # 2) tp_hash == NULL and either of tp_compare or tp_richcompare are not NULL if hash_not_impl == func or (not func and (pto.c_tp_compare or pto.c_tp_richcompare)): dict_w[method_name] = space.w_None continue else: assert len(slot_names) == 2 struct = getattr(pto, slot_names[0]) if not struct: continue offset.append( rffi.offsetof(lltype.typeOf(struct).TO, slot_names[1])) func = getattr(struct, slot_names[1]) func_voidp = rffi.cast(rffi.VOIDP, func) if not func: continue if wrapper_class is None: continue assert issubclass(wrapper_class, W_PyCWrapperObject) w_obj = wrapper_class(space, pto, method_name, doc, func_voidp, offset=offset[:]) dict_w[method_name] = w_obj if pto.c_tp_doc: dict_w['__doc__'] = space.newtext( rffi.charp2str(cts.cast('char*', pto.c_tp_doc))) if pto.c_tp_new: add_tp_new_wrapper(space, dict_w, pto)
def finish_type_1(space, pto): """ Sets up tp_bases, necessary before creating the interpreter type. """ base = pto.c_tp_base base_pyo = rffi.cast(PyObject, pto.c_tp_base) if base and not base.c_tp_flags & Py_TPFLAGS_READY: name = rffi.charp2str(cts.cast('char*', base.c_tp_name)) type_realize(space, base_pyo) if base and not pto.c_ob_type: # will be filled later pto.c_ob_type = base.c_ob_type if not pto.c_tp_bases: if not base: bases = space.newtuple([]) else: bases = space.newtuple([from_ref(space, base_pyo)]) pto.c_tp_bases = make_ref(space, bases)
def finish_type_1(space, pto, bases_w=None): """ Sets up tp_bases, necessary before creating the interpreter type. """ base = pto.c_tp_base base_pyo = rffi.cast(PyObject, pto.c_tp_base) if base and not base.c_tp_flags & Py_TPFLAGS_READY: name = rffi.charp2str(cts.cast('char*', base.c_tp_name)) type_realize(space, base_pyo) if base and not pto.c_ob_type: # will be filled later pto.c_ob_type = base.c_ob_type if not pto.c_tp_bases: if bases_w is None: if not base: bases_w = [] else: bases_w = [from_ref(space, base_pyo)] is_heaptype = bool(pto.c_tp_flags & Py_TPFLAGS_HEAPTYPE) pto.c_tp_bases = make_ref(space, space.newtuple(bases_w), immortal=not is_heaptype)
def from_ref(space, ref): """ Finds the interpreter object corresponding to the given reference. If the object is not yet realized (see bytesobject.py), creates it. """ assert is_pyobj(ref) if not ref: return None w_obj = rawrefcount.to_obj(W_Root, ref) if w_obj is not None: if w_obj is not w_marker_deallocating: return w_obj type_name = rffi.charp2str(cts.cast('char*', ref.c_ob_type.c_tp_name)) fatalerror( "*** Invalid usage of a dying CPython object ***\n" "\n" "cpyext, the emulation layer, detected that while it is calling\n" "an object's tp_dealloc, the C code calls back a function that\n" "tries to recreate the PyPy version of the object. Usually it\n" "means that tp_dealloc calls some general PyXxx() API. It is\n" "a dangerous and potentially buggy thing to do: even in CPython\n" "the PyXxx() function could, in theory, cause a reference to the\n" "object to be taken and stored somewhere, for an amount of time\n" "exceeding tp_dealloc itself. Afterwards, the object will be\n" "freed, making that reference point to garbage.\n" ">>> PyPy could contain some workaround to still work if\n" "you are lucky, but it is not done so far; better fix the bug in\n" "the CPython extension.\n" ">>> This object is of type '%s'" % (type_name, )) # This reference is not yet a real interpreter object. # Realize it. ref_type = rffi.cast(PyObject, ref.c_ob_type) if ref_type == ref: # recursion! raise InvalidPointerException(str(ref)) w_type = from_ref(space, ref_type) assert isinstance(w_type, W_TypeObject) return get_typedescr(w_type.layout.typedef).realize(space, ref)
def type_attach(space, py_obj, w_type, w_userdata=None): """ Fills a newly allocated PyTypeObject from an existing type. """ assert isinstance(w_type, W_TypeObject) pto = rffi.cast(PyTypeObjectPtr, py_obj) typedescr = get_typedescr(w_type.layout.typedef) if space.is_w(w_type, space.w_bytes): pto.c_tp_itemsize = 1 elif space.is_w(w_type, space.w_tuple): pto.c_tp_itemsize = rffi.sizeof(PyObject) # buffer protocol setup_buffer_procs(space, w_type, pto) state = space.fromcache(State) pto.c_tp_free = state.C.PyObject_Free pto.c_tp_alloc = state.C.PyType_GenericAlloc builder = state.builder if ((pto.c_tp_flags & Py_TPFLAGS_HEAPTYPE) != 0 and builder.cpyext_type_init is None): # this ^^^ is not None only during startup of cpyext. At that # point we might get into troubles by doing make_ref() when # things are not initialized yet. So in this case, simply use # str2charp() and "leak" the string. w_typename = space.getattr(w_type, space.newtext('__name__')) heaptype = cts.cast('PyHeapTypeObject*', pto) heaptype.c_ht_name = make_ref(space, w_typename) from pypy.module.cpyext.bytesobject import PyString_AsString pto.c_tp_name = cts.cast('const char *', PyString_AsString(space, heaptype.c_ht_name)) else: pto.c_tp_name = cts.cast('const char*', rffi.str2charp(w_type.name)) # uninitialized fields: # c_tp_print # XXX implement # c_tp_compare and more? w_base = best_base(space, w_type.bases_w) pto.c_tp_base = rffi.cast(PyTypeObjectPtr, make_ref(space, w_base)) # dealloc if space.gettypeobject(w_type.layout.typedef) is w_type: # only for the exact type, like 'space.w_tuple' or 'space.w_list' pto.c_tp_dealloc = typedescr.get_dealloc(space) else: # for all subtypes, use base's dealloc (requires sorting in attach_all) pto.c_tp_dealloc = pto.c_tp_base.c_tp_dealloc if not pto.c_tp_dealloc: # strange, but happens (ABCMeta) pto.c_tp_dealloc = state.C._PyPy_subtype_dealloc if builder.cpyext_type_init is not None: builder.cpyext_type_init.append((pto, w_type)) else: finish_type_1(space, pto, w_type.bases_w) finish_type_2(space, pto, w_type) pto.c_tp_basicsize = rffi.sizeof(typedescr.basestruct) if pto.c_tp_base: if pto.c_tp_base.c_tp_basicsize > pto.c_tp_basicsize: pto.c_tp_basicsize = pto.c_tp_base.c_tp_basicsize if pto.c_tp_itemsize < pto.c_tp_base.c_tp_itemsize: pto.c_tp_itemsize = pto.c_tp_base.c_tp_itemsize if w_type.is_heaptype(): update_all_slots(space, w_type, pto) else: update_all_slots_builtin(space, w_type, pto) # XXX generlize this pattern for various slot functions implemented in C if space.is_w(w_type, space.w_tuple): pto.c_tp_new = state.C.tuple_new if not pto.c_tp_new: base_object_pyo = make_ref(space, space.w_object) base_object_pto = rffi.cast(PyTypeObjectPtr, base_object_pyo) flags = rffi.cast(lltype.Signed, pto.c_tp_flags) if pto.c_tp_base != base_object_pto or flags & Py_TPFLAGS_HEAPTYPE: pto.c_tp_new = pto.c_tp_base.c_tp_new decref(space, base_object_pyo) pto.c_tp_flags |= Py_TPFLAGS_READY return pto
def methoddescr_attach(space, py_obj, w_obj, w_userdata=None): py_methoddescr = cts.cast('PyMethodDescrObject*', py_obj) # XXX assign to d_dname, d_type? assert isinstance(w_obj, W_PyCFunctionObject) py_methoddescr.c_d_method = w_obj.ml
def methoddescr_attach(space, py_obj, w_obj, w_userdata=None): py_methoddescr = cts.cast('PyMethodDescrObject*', py_obj) assert isinstance(w_obj, W_PyCFunctionObject) py_methoddescr.c_d_method = w_obj.ml init_descr(space, py_obj, w_obj.w_objclass, w_obj.name)
def _get_w_obj(space, c_obj): return from_ref(space, cts.cast('PyObject*', c_obj._as_ptr()))
def gi_attach(space, py_obj, w_obj, w_userdata=None): assert isinstance(w_obj, GeneratorIterator) cts.cast('PyGenObject*', py_obj).c_gi_code = as_pyobj(space, w_obj.pycode)
def descr_dealloc(space, py_obj): from pypy.module.cpyext.object import _dealloc py_descr = cts.cast('PyDescrObject*', py_obj) decref(space, py_descr.c_d_type) decref(space, py_descr.c_d_name) _dealloc(space, py_obj)