Пример #1
0
def _PySet_NextEntry(space, w_set, ppos, pkey, phash):
    if w_set is None or not PyAnySet_Check(space, w_set):
        PyErr_BadInternalCall(space)
        return -1
    if not pkey:
        PyErr_BadInternalCall(space)
        return -1
    pos = ppos[0]
    py_obj = as_pyobj(space, w_set)
    py_set = rffi.cast(PySetObject, py_obj)
    if pos == 0:
        # Store the current item list in the PySetObject.
        # w_keys must use the object strategy in order to keep the keys alive
        w_keys = space.newlist(space.listview(w_set))
        w_keys.switch_to_object_strategy()
        oldlist = py_set.c__tmplist
        py_set.c__tmplist = create_ref(space, w_keys)
        incref(space, py_set.c__tmplist)
        decref(space, oldlist)
    else:
        if not py_set.c__tmplist:
            # pos should have been 0, cannot fail so return 0
            return 0
        w_keys = from_ref(space, py_set.c__tmplist)
    ppos[0] += 1
    if pos >= space.len_w(w_keys):
        decref(space, py_set.c__tmplist)
        py_set.c__tmplist = lltype.nullptr(PyObject.TO)
        return 0
    w_key = space.listview(w_keys)[pos]
    pkey[0] = as_pyobj(space, w_key)
    if phash:
        phash[0] = space.hash_w(w_key)
    return 1
Пример #2
0
    def __init__(self, space, ptr, size, w_obj, format='B', shape=None,
                 strides=None, ndim=1, itemsize=1, readonly=True,
                 needs_decref=False,
                 releasebufferproc=rffi.cast(rffi.VOIDP, 0)):
        self.space = space
        self.ptr = ptr
        self.size = size
        self.w_obj = w_obj  # kept alive
        self.pyobj = as_pyobj(space, w_obj)
        self.format = format
        self.ndim = ndim
        self.itemsize = itemsize

        # cf. Objects/memoryobject.c:init_shape_strides()
        if ndim == 0:
            self.shape = []
            self.strides = []
        elif ndim == 1:
            if shape is None:
                self.shape = [size // itemsize]
            else:
                self.shape = shape
            if strides is None:
                self.strides = [itemsize]
            else:
                self.strides = strides
        else:
            assert len(shape) == ndim
            self.shape = shape
            # XXX: missing init_strides_from_shape
            self.strides = strides
        self.readonly = readonly
        self.needs_decref = needs_decref
        self.releasebufferproc = releasebufferproc
Пример #3
0
def _type_realize(space, py_obj):
    """
    Creates an interpreter type from a PyTypeObject structure.
    """
    # missing:
    # inheriting tp_as_* slots
    # unsupported:
    # tp_mro, tp_subclasses
    py_type = rffi.cast(PyTypeObjectPtr, py_obj)

    if not py_type.c_tp_base:
        # borrowed reference, but w_object is unlikely to disappear
        base = as_pyobj(space, space.w_object)
        py_type.c_tp_base = rffi.cast(PyTypeObjectPtr, base)

    finish_type_1(space, py_type)

    w_metatype = from_ref(space, rffi.cast(PyObject, py_type.c_ob_type))

    w_obj = space.allocate_instance(W_PyCTypeObject, w_metatype)
    track_reference(space, py_obj, w_obj)
    w_obj.__init__(space, py_type)
    w_obj.ready()

    finish_type_2(space, py_type, w_obj)

    return w_obj
Пример #4
0
    def __init__(self,
                 space,
                 ptr,
                 size,
                 w_obj,
                 format='B',
                 shape=None,
                 strides=None,
                 ndim=1,
                 itemsize=1,
                 readonly=True,
                 needs_decref=False,
                 releasebufferproc=rffi.cast(rffi.VOIDP, 0)):
        self.space = space
        self.ptr = ptr
        self.size = size
        self.w_obj = w_obj  # kept alive
        self.pyobj = as_pyobj(space, w_obj)
        self.format = format
        self.ndim = ndim
        self.itemsize = itemsize

        if not shape:
            self.shape = [size]
        else:
            self.shape = shape
        if not strides:
            self.strides = [1]
        else:
            self.strides = strides
        self.readonly = readonly
        self.needs_decref = needs_decref
        self.releasebufferproc = releasebufferproc
Пример #5
0
 def call(self, space, w_self, w_args, w_kw):
     func_to_call = self.func
     if self.offset:
         pto = as_pyobj(space, self.w_objclass)
         # make ptr the equivalent of this, using the offsets
         #func_to_call = rffi.cast(rffi.VOIDP, ptr.c_tp_as_number.c_nb_multiply)
         if pto:
             cptr = rffi.cast(rffi.CCHARP, pto)
             for o in self.offset:
                 ptr = rffi.cast(rffi.VOIDPP, rffi.ptradd(cptr, o))[0]
                 cptr = rffi.cast(rffi.CCHARP, ptr)
             func_to_call = rffi.cast(rffi.VOIDP, cptr)
         else:
             # Should never happen, assert to get a traceback
             assert False, "failed to convert w_type %s to PyObject" % str(
                                                           self.w_objclass)
     assert func_to_call
     if self.wrapper_func is None:
         assert self.wrapper_func_kwds is not None
         return self.wrapper_func_kwds(space, w_self, w_args, func_to_call,
                                       w_kw)
     if space.is_true(w_kw):
         raise oefmt(space.w_TypeError,
                     "wrapper %s doesn't take any keyword arguments",
                     self.method_name)
     return self.wrapper_func(space, w_self, w_args, func_to_call)
Пример #6
0
 def call(self, space, w_self, w_args, w_kw):
     func_to_call = self.func
     if self.offset:
         pto = as_pyobj(space, self.w_objclass)
         # make ptr the equivalent of this, using the offsets
         #func_to_call = rffi.cast(rffi.VOIDP, ptr.c_tp_as_number.c_nb_multiply)
         if pto:
             cptr = rffi.cast(rffi.CCHARP, pto)
             for o in self.offset:
                 ptr = rffi.cast(rffi.VOIDPP, rffi.ptradd(cptr, o))[0]
                 cptr = rffi.cast(rffi.CCHARP, ptr)
             func_to_call = rffi.cast(rffi.VOIDP, cptr)
         else:
             # Should never happen, assert to get a traceback
             assert False, "failed to convert w_type %s to PyObject" % str(
                                                           self.w_objclass)
     assert func_to_call
     if self.wrapper_func is None:
         assert self.wrapper_func_kwds is not None
         return self.wrapper_func_kwds(space, w_self, w_args, func_to_call,
                                       w_kw)
     if space.is_true(w_kw):
         raise oefmt(space.w_TypeError,
                     "wrapper %s doesn't take any keyword arguments",
                     self.method_name)
     return self.wrapper_func(space, w_self, w_args, func_to_call)
Пример #7
0
def PySequence_ITEM(space, w_obj, i):
    """Return the ith element of o or NULL on failure. Macro form of
    PySequence_GetItem() but without checking that
    PySequence_Check(o)() is true and without adjustment for negative
    indices.

    This function used an int type for i. This might require
    changes in your code for properly supporting 64-bit systems."""
    # XXX we should call Py*_GET_ITEM() instead of Py*_GetItem()
    # from here, but we cannot because we are also called from
    # PySequence_GetItem()
    py_obj = as_pyobj(space, w_obj)
    if isinstance(w_obj, tupleobject.W_TupleObject):
        from pypy.module.cpyext.tupleobject import PyTuple_GetItem
        py_res = PyTuple_GetItem(space, py_obj, i)
        incref(space, py_res)
        keepalive_until_here(w_obj)
        return py_res
    if isinstance(w_obj, W_ListObject):
        from pypy.module.cpyext.listobject import PyList_GetItem
        py_res = PyList_GetItem(space, py_obj, i)
        incref(space, py_res)
        keepalive_until_here(w_obj)
        return py_res

    as_sequence = py_obj.c_ob_type.c_tp_as_sequence
    if not as_sequence or not as_sequence.c_sq_item:
        raise oefmt(space.w_TypeError, "'%T' object does not support indexing",
                    w_obj)
    ret = generic_cpy_call(space, as_sequence.c_sq_item, w_obj, i)
    return make_ref(space, ret)
Пример #8
0
def _type_realize(space, py_obj):
    """
    Creates an interpreter type from a PyTypeObject structure.
    """
    # missing:
    # inheriting tp_as_* slots
    # unsupported:
    # tp_mro, tp_subclasses
    py_type = rffi.cast(PyTypeObjectPtr, py_obj)

    if not py_type.c_tp_base:
        # borrowed reference, but w_object is unlikely to disappear
        base = as_pyobj(space, space.w_object)
        py_type.c_tp_base = rffi.cast(PyTypeObjectPtr, base)

    finish_type_1(space, py_type)

    w_metatype = from_ref(space, rffi.cast(PyObject, py_type.c_ob_type))

    w_obj = space.allocate_instance(W_PyCTypeObject, w_metatype)
    track_reference(space, py_obj, w_obj)
    w_obj.__init__(space, py_type)
    w_obj.ready()

    finish_type_2(space, py_type, w_obj)

    return w_obj
Пример #9
0
def create_module_from_def_and_spec(space, moddef, w_spec, name):
    moddef = rffi.cast(PyModuleDef, moddef)
    if moddef.c_m_size < 0:
        raise oefmt(
            space.w_SystemError,
            "module %s: m_size may not be negative for multi-phase "
            "initialization", name)
    createf = lltype.nullptr(rffi.VOIDP.TO)
    has_execution_slots = False
    cur_slot = rffi.cast(rffi.CArrayPtr(PyModuleDef_Slot), moddef.c_m_slots)
    if cur_slot:
        while True:
            slot = rffi.cast(lltype.Signed, cur_slot[0].c_slot)
            if slot == 0:
                break
            elif slot == 1:
                if createf:
                    raise oefmt(space.w_SystemError,
                                "module %s has multiple create slots", name)
                createf = cur_slot[0].c_value
            elif slot < 0 or slot > 2:
                raise oefmt(space.w_SystemError,
                            "module %s uses unknown slot ID %d", name, slot)
            else:
                has_execution_slots = True
            cur_slot = rffi.ptradd(cur_slot, 1)
    if createf:
        createf = rffi.cast(createfunctype, createf)
        w_mod = generic_cpy_call(space, createf, w_spec, moddef)
    else:
        w_mod = Module(space, space.newtext(name))
    if isinstance(w_mod, Module):
        mod = rffi.cast(PyModuleObject, as_pyobj(space, w_mod))
        #mod.c_md_state = None
        mod.c_md_def = moddef
    else:
        if moddef.c_m_size > 0 or moddef.c_m_traverse or moddef.c_m_clear or \
           moddef.c_m_free:
            raise oefmt(
                space.w_SystemError,
                "module %s is not a module object, but requests "
                "module state", name)
        if has_execution_slots:
            raise oefmt(
                space.w_SystemError,
                "module %s specifies execution slots, but did not "
                "create a ModuleType instance", name)
    dict_w = {}
    convert_method_defs(space, dict_w, moddef.c_m_methods, None, w_mod, name)
    for key, w_value in dict_w.items():
        space.setattr(w_mod, space.newtext(key), w_value)
    if moddef.c_m_doc:
        doc = rffi.charp2str(rffi.cast(rffi.CCHARP, moddef.c_m_doc))
        space.setattr(w_mod, space.newtext('__doc__'), space.newtext(doc))
    return w_mod
Пример #10
0
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))
Пример #11
0
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))
Пример #12
0
def _type_realize(space, py_obj):
    """
    Creates an interpreter type from a PyTypeObject structure.
    """
    # missing:
    # unsupported:
    # tp_mro, tp_subclasses
    py_type = rffi.cast(PyTypeObjectPtr, py_obj)

    if not py_type.c_tp_base:
        # borrowed reference, but w_object is unlikely to disappear
        base = as_pyobj(space, space.w_object)
        py_type.c_tp_base = rffi.cast(PyTypeObjectPtr, base)

    finish_type_1(space, py_type)

    if py_type.c_ob_type:
        w_metatype = from_ref(space, rffi.cast(PyObject, py_type.c_ob_type))
    else:
        # Somehow the tp_base type is created with no ob_type, notably
        # PyString_Type and PyBaseString_Type
        # While this is a hack, cpython does it as well.
        w_metatype = space.w_type

    w_obj = rawrefcount.to_obj(W_PyCTypeObject, py_obj)
    if w_obj is None:
        w_obj = space.allocate_instance(W_PyCTypeObject, w_metatype)
        track_reference(space, py_obj, w_obj)
    # __init__ wraps all slotdefs functions from py_type via add_operators
    w_obj.__init__(space, py_type)
    w_obj.ready()

    finish_type_2(space, py_type, w_obj)
    base = py_type.c_tp_base
    if base:
        # XXX refactor - parts of this are done in finish_type_2 -> inherit_slots
        if not py_type.c_tp_as_number:
            py_type.c_tp_as_number = base.c_tp_as_number
            py_type.c_tp_flags |= base.c_tp_flags & Py_TPFLAGS_CHECKTYPES
            py_type.c_tp_flags |= base.c_tp_flags & Py_TPFLAGS_HAVE_INPLACEOPS
        if not py_type.c_tp_as_sequence:
            py_type.c_tp_as_sequence = base.c_tp_as_sequence
            py_type.c_tp_flags |= base.c_tp_flags & Py_TPFLAGS_HAVE_INPLACEOPS
        if not py_type.c_tp_as_mapping:
            py_type.c_tp_as_mapping = base.c_tp_as_mapping
        #if not py_type.c_tp_as_buffer: py_type.c_tp_as_buffer = base.c_tp_as_buffer

    return w_obj
Пример #13
0
def _type_realize(space, py_obj):
    """
    Creates an interpreter type from a PyTypeObject structure.
    """
    # missing:
    # unsupported:
    # tp_mro, tp_subclasses
    py_type = rffi.cast(PyTypeObjectPtr, py_obj)

    if not py_type.c_tp_base:
        # borrowed reference, but w_object is unlikely to disappear
        base = as_pyobj(space, space.w_object)
        py_type.c_tp_base = rffi.cast(PyTypeObjectPtr, base)

    finish_type_1(space, py_type)

    if py_type.c_ob_type:
        w_metatype = from_ref(space, rffi.cast(PyObject, py_type.c_ob_type))
    else:
        # Somehow the tp_base type is created with no ob_type, notably
        # PyString_Type and PyBaseString_Type
        # While this is a hack, cpython does it as well.
        w_metatype = space.w_type

    w_obj = space.allocate_instance(W_PyCTypeObject, w_metatype)
    track_reference(space, py_obj, w_obj)
    # __init__ wraps all slotdefs functions from py_type via add_operators
    w_obj.__init__(space, py_type)
    w_obj.ready()

    finish_type_2(space, py_type, w_obj)
    base = py_type.c_tp_base
    if base:
        # XXX refactor - parts of this are done in finish_type_2 -> inherit_slots
        if not py_type.c_tp_as_number:
            py_type.c_tp_as_number = base.c_tp_as_number
            py_type.c_tp_flags |= base.c_tp_flags & Py_TPFLAGS_CHECKTYPES
            py_type.c_tp_flags |= base.c_tp_flags & Py_TPFLAGS_HAVE_INPLACEOPS
        if not py_type.c_tp_as_sequence:
            py_type.c_tp_as_sequence = base.c_tp_as_sequence
            py_type.c_tp_flags |= base.c_tp_flags & Py_TPFLAGS_HAVE_INPLACEOPS
        if not py_type.c_tp_as_mapping: py_type.c_tp_as_mapping = base.c_tp_as_mapping
        #if not py_type.c_tp_as_buffer: py_type.c_tp_as_buffer = base.c_tp_as_buffer

    return w_obj
Пример #14
0
def dict_attach(space, py_obj, w_obj, w_userdata=None):
    """
    Fills a newly allocated PyDictObject with the given dict object.
    """
    py_dict = rffi.cast(PyDictObject, py_obj)
    py_dict.c__tmpkeys = lltype.nullptr(PyObject.TO)
    # Problems: if this dict is a typedict, we may have unbound GetSetProperty
    # functions in the dict. The corresponding PyGetSetDescrObject must be
    # bound to a class, but the actual w_type will be unavailable later on.
    # Solution: use the w_userdata argument when assigning a PyTypeObject's
    # tp_dict slot to pass a w_type in, and force creation of the pair here
    if not space.is_w(w_userdata, space.gettypefor(GetSetProperty)):
        # do not do this for type dict of GetSetProperty, that would recurse
        w_vals = space.call_method(space.w_dict, "values", w_obj)
        vals = space.listview(w_vals)
        for w_v in vals:
            if isinstance(w_v, GetSetProperty):
                pyobj = as_pyobj(space, w_v, w_userdata)
Пример #15
0
 def get_func_to_call(self):
     func_to_call = self.func
     if self.offset:
         pto = as_pyobj(self.space, self.w_objclass)
         # make ptr the equivalent of this, using the offsets
         #func_to_call = rffi.cast(rffi.VOIDP, ptr.c_tp_as_number.c_nb_multiply)
         if pto:
             cptr = rffi.cast(rffi.CCHARP, pto)
             for o in self.offset:
                 ptr = rffi.cast(rffi.VOIDPP, rffi.ptradd(cptr, o))[0]
                 cptr = rffi.cast(rffi.CCHARP, ptr)
             func_to_call = rffi.cast(rffi.VOIDP, cptr)
         else:
             # Should never happen, assert to get a traceback
             assert False, "failed to convert w_type %s to PyObject" % str(
                 self.w_objclass)
     assert func_to_call
     return func_to_call
Пример #16
0
def PySequence_Fast_ITEMS(space, w_obj):
    """Return the underlying array of PyObject pointers.  Assumes that o was returned
    by PySequence_Fast() and o is not NULL.

    Note, if a list gets resized, the reallocation may relocate the items array.
    So, only use the underlying array pointer in contexts where the sequence
    cannot change.
    """
    if isinstance(w_obj, W_ListObject):
        cpy_strategy = space.fromcache(CPyListStrategy)
        if w_obj.strategy is cpy_strategy:
            return w_obj.get_raw_items()  # asserts it's a cpyext strategy
    elif isinstance(w_obj, tupleobject.W_TupleObject):
        from pypy.module.cpyext.tupleobject import PyTupleObject
        py_obj = as_pyobj(space, w_obj)
        py_tuple = rffi.cast(PyTupleObject, py_obj)
        return rffi.cast(PyObjectP, py_tuple.c_ob_item)
    raise oefmt(
        space.w_TypeError,
        "PySequence_Fast_ITEMS called but object is not the result of "
        "PySequence_Fast")
Пример #17
0
def PyModule_Create2(space, module, api_version):
    """Create a new module object, given the definition in module, assuming the
    API version module_api_version.  If that version does not match the version
    of the running interpreter, a RuntimeWarning is emitted.

    Most uses of this function should be using PyModule_Create()
    instead; only use this if you are sure you need it."""

    modname = rffi.charp2str(rffi.cast(rffi.CCHARP, module.c_m_name))
    if module.c_m_doc:
        doc = rffi.charp2str(rffi.cast(rffi.CCHARP, module.c_m_doc))
    else:
        doc = None
    methods = module.c_m_methods

    state = space.fromcache(State)
    f_name, f_path = state.package_context
    if f_name is not None:
        modname = f_name
    w_mod = Module(space, space.newtext(modname))
    py_mod = rffi.cast(PyModuleObject, as_pyobj(space, w_mod))
    py_mod.c_md_def = module
    state.package_context = None, None

    if f_path is not None:
        dict_w = {'__file__': space.newfilename(f_path)}
    else:
        dict_w = {}
    convert_method_defs(space, dict_w, methods, None, w_mod, modname)
    for key, w_value in dict_w.items():
        space.setattr(w_mod, space.newtext(key), w_value)
    if doc:
        space.setattr(w_mod, space.newtext("__doc__"), space.newtext(doc))

    if module.c_m_size > 0:
        py_mod.c_md_state = lltype.malloc(rffi.VOIDP.TO,
                                          module.c_m_size,
                                          flavor='raw',
                                          zero=True)
    return w_mod
Пример #18
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)
Пример #19
0
def PyDict_Next(space, w_dict, ppos, pkey, pvalue):
    """Iterate over all key-value pairs in the dictionary p.  The
    Py_ssize_t referred to by ppos must be initialized to 0
    prior to the first call to this function to start the iteration; the
    function returns true for each pair in the dictionary, and false once all
    pairs have been reported.  The parameters pkey and pvalue should either
    point to PyObject* variables that will be filled in with each key
    and value, respectively, or may be NULL.  Any references returned through
    them are borrowed.  ppos should not be altered during iteration. Its
    value represents offsets within the internal dictionary structure, and
    since the structure is sparse, the offsets are not consecutive.

    For example:

    PyObject *key, *value;
    Py_ssize_t pos = 0;

    while (PyDict_Next(self->dict, &pos, &key, &value)) {
        /* do something interesting with the values... */
        ...
    }

    The dictionary p should not be mutated during iteration.  It is safe
    (since Python 2.1) to modify the values but not the keys as you iterate
    over the dictionary, the keys must not change.
    For example:

    PyObject *key, *value;
    Py_ssize_t pos = 0;

    while (PyDict_Next(self->dict, &pos, &key, &value)) {
        int i = PyInt_AS_LONG(value) + 1;
        PyObject *o = PyInt_FromLong(i);
        if (o == NULL)
            return -1;
        if (PyDict_SetItem(self->dict, key, o) < 0) {
            Py_DECREF(o);
            return -1;
        }
        Py_DECREF(o);
    }"""

    if w_dict is None:
        return 0
    if not space.isinstance_w(w_dict, space.w_dict):
        return 0
    pos = ppos[0]
    py_obj = as_pyobj(space, w_dict)
    py_dict = rffi.cast(PyDictObject, py_obj)
    if pos == 0:
        # Store the current keys in the PyDictObject.
        from pypy.objspace.std.listobject import W_ListObject
        decref(space, py_dict.c__tmpkeys)
        w_keys = space.call_method(space.w_dict, "keys", w_dict)
        # w_keys must use the object strategy in order to keep the keys alive
        if not isinstance(w_keys, W_ListObject):
            return 0  # XXX should not call keys() above
        w_keys.switch_to_object_strategy()
        py_dict.c__tmpkeys = create_ref(space, w_keys)
        incref(space, py_dict.c__tmpkeys)
    else:
        if not py_dict.c__tmpkeys:
            # pos should have been 0, cannot fail so return 0
            return 0
        w_keys = from_ref(space, py_dict.c__tmpkeys)
    ppos[0] += 1
    if pos >= space.len_w(w_keys):
        decref(space, py_dict.c__tmpkeys)
        py_dict.c__tmpkeys = lltype.nullptr(PyObject.TO)
        return 0
    w_key = space.listview(w_keys)[pos]  # fast iff w_keys uses object strat
    w_value = space.getitem(w_dict, w_key)
    if pkey:
        pkey[0] = as_pyobj(space, w_key)
    if pvalue:
        pvalue[0] = as_pyobj(space, w_value)
    return 1
Пример #20
0
def PyDict_Next(space, w_dict, ppos, pkey, pvalue):
    """Iterate over all key-value pairs in the dictionary p.  The
    Py_ssize_t referred to by ppos must be initialized to 0
    prior to the first call to this function to start the iteration; the
    function returns true for each pair in the dictionary, and false once all
    pairs have been reported.  The parameters pkey and pvalue should either
    point to PyObject* variables that will be filled in with each key
    and value, respectively, or may be NULL.  Any references returned through
    them are borrowed.  ppos should not be altered during iteration. Its
    value represents offsets within the internal dictionary structure, and
    since the structure is sparse, the offsets are not consecutive.

    For example:

    PyObject *key, *value;
    Py_ssize_t pos = 0;

    while (PyDict_Next(self->dict, &pos, &key, &value)) {
        /* do something interesting with the values... */
        ...
    }

    The dictionary p should not be mutated during iteration.  It is safe
    (since Python 2.1) to modify the values of the keys as you iterate over the
    dictionary, but only so long as the set of keys does not change.  For
    example:

    PyObject *key, *value;
    Py_ssize_t pos = 0;

    while (PyDict_Next(self->dict, &pos, &key, &value)) {
        int i = PyInt_AS_LONG(value) + 1;
        PyObject *o = PyInt_FromLong(i);
        if (o == NULL)
            return -1;
        if (PyDict_SetItem(self->dict, key, o) < 0) {
            Py_DECREF(o);
            return -1;
        }
        Py_DECREF(o);
    }"""
    if w_dict is None:
        return 0

    # XXX XXX PyDict_Next is not efficient. Storing an iterator would probably
    # work, but we can't work out how to not leak it if iteration does
    # not complete.  Alternatively, we could add some RPython-only
    # dict-iterator method to move forward by N steps.

    w_dict.ensure_object_strategy()     # make sure both keys and values can
                                        # be borrwed
    try:
        w_iter = space.call_method(space.w_dict, "iteritems", w_dict)
        pos = ppos[0]
        while pos:
            space.call_method(w_iter, "next")
            pos -= 1

        w_item = space.call_method(w_iter, "next")
        w_key, w_value = space.fixedview(w_item, 2)
        if pkey:
            pkey[0]   = as_pyobj(space, w_key)
        if pvalue:
            pvalue[0] = as_pyobj(space, w_value)
        ppos[0] += 1
    except OperationError as e:
        if not e.match(space, space.w_StopIteration):
            raise
        return 0
    return 1
Пример #21
0
def PyDict_Next(space, w_dict, ppos, pkey, pvalue):
    """Iterate over all key-value pairs in the dictionary p.  The
    Py_ssize_t referred to by ppos must be initialized to 0
    prior to the first call to this function to start the iteration; the
    function returns true for each pair in the dictionary, and false once all
    pairs have been reported.  The parameters pkey and pvalue should either
    point to PyObject* variables that will be filled in with each key
    and value, respectively, or may be NULL.  Any references returned through
    them are borrowed.  ppos should not be altered during iteration. Its
    value represents offsets within the internal dictionary structure, and
    since the structure is sparse, the offsets are not consecutive.

    For example:

    PyObject *key, *value;
    Py_ssize_t pos = 0;

    while (PyDict_Next(self->dict, &pos, &key, &value)) {
        /* do something interesting with the values... */
        ...
    }

    The dictionary p should not be mutated during iteration.  It is safe
    (since Python 2.1) to modify the values of the keys as you iterate over the
    dictionary, but only so long as the set of keys does not change.  For
    example:

    PyObject *key, *value;
    Py_ssize_t pos = 0;

    while (PyDict_Next(self->dict, &pos, &key, &value)) {
        int i = PyInt_AS_LONG(value) + 1;
        PyObject *o = PyInt_FromLong(i);
        if (o == NULL)
            return -1;
        if (PyDict_SetItem(self->dict, key, o) < 0) {
            Py_DECREF(o);
            return -1;
        }
        Py_DECREF(o);
    }"""
    if w_dict is None:
        return 0

    # XXX XXX PyDict_Next is not efficient. Storing an iterator would probably
    # work, but we can't work out how to not leak it if iteration does
    # not complete.  Alternatively, we could add some RPython-only
    # dict-iterator method to move forward by N steps.

    w_dict.ensure_object_strategy()     # make sure both keys and values can
                                        # be borrwed
    try:
        w_iter = space.call_method(space.w_dict, "iteritems", w_dict)
        pos = ppos[0]
        while pos:
            space.call_method(w_iter, "next")
            pos -= 1

        w_item = space.call_method(w_iter, "next")
        w_key, w_value = space.fixedview(w_item, 2)
        if pkey:
            pkey[0]   = as_pyobj(space, w_key)
        if pvalue:
            pvalue[0] = as_pyobj(space, w_value)
        ppos[0] += 1
    except OperationError, e:
        if not e.match(space, space.w_StopIteration):
            raise
        return 0
Пример #22
0
def _get_ob_type(space, w_obj):
    # please ensure that w_obj stays alive
    ob_type = as_pyobj(space, space.type(w_obj))
    return rffi.cast(PyTypeObjectPtr, ob_type)
Пример #23
0
def _PyUnicode_Ready(space, w_obj):
    assert isinstance(w_obj, unicodeobject.W_UnicodeObject)
    py_obj = as_pyobj(space, w_obj)
    assert get_kind(py_obj) == WCHAR_KIND
    return _readify(space, py_obj, w_obj._value)