def PyModule_GetName(space, w_mod): """ Return module's __name__ value. If the module does not provide one, or if it is not a string, SystemError is raised and NULL is returned. """ # NOTE: this version of the code works only because w_mod.w_name is # a wrapped string object attached to w_mod; so it makes a # PyStringObject that will live as long as the module itself, # and returns a "char *" inside this PyStringObject. if not isinstance(w_mod, Module): raise oefmt(space.w_SystemError, "PyModule_GetName(): not a module") from pypy.module.cpyext.bytesobject import PyString_AsString return PyString_AsString(space, as_pyobj(space, w_mod.w_name))
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