示例#1
0
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)
示例#2
0
    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)))
示例#3
0
 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
示例#4
0
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)
示例#5
0
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))
示例#6
0
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
示例#7
0
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)
示例#8
0
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)
示例#9
0
文件: typeobject.py 项目: fhalde/pypy
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)
示例#10
0
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
示例#11
0
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)
示例#12
0
文件: methodobject.py 项目: Mu-L/pypy
 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
示例#13
0
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)
示例#14
0
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)
示例#15
0
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
示例#16
0
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
示例#17
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
示例#18
0
    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)
示例#19
0
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)
示例#20
0
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]
示例#21
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)
示例#22
0
文件: typeobject.py 项目: fhalde/pypy
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)
示例#23
0
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)
示例#24
0
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)
示例#25
0
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
示例#26
0
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
示例#27
0
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)
示例#28
0
def _get_w_obj(space, c_obj):
    return from_ref(space, cts.cast('PyObject*', c_obj._as_ptr()))
示例#29
0
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)
示例#30
0
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)