/pypy/module/cpyext/sliceobject.py
https://github.com/alemacgo/pypy · Python · 105 lines · 64 code · 9 blank · 32 comment · 5 complexity · 2307b4acd7963aac3f011f3abc0000f0 MD5 · raw file
- from pypy.rpython.lltypesystem import rffi, lltype
- from pypy.module.cpyext.api import (
- cpython_api, cpython_struct, bootstrap_function, build_type_checkers,
- CANNOT_FAIL, Py_ssize_t, Py_ssize_tP, PyObjectFields)
- from pypy.module.cpyext.pyobject import (
- Py_DecRef, PyObject, make_ref, make_typedescr)
- from pypy.module.cpyext.pyerrors import PyErr_BadInternalCall
- from pypy.interpreter.error import OperationError
- from pypy.objspace.std.sliceobject import W_SliceObject
- # Slice objects directly expose their members as PyObject.
- # Don't change them!
- PySliceObjectStruct = lltype.ForwardReference()
- PySliceObject = lltype.Ptr(PySliceObjectStruct)
- PySliceObjectFields = PyObjectFields + \
- (("start", PyObject), ("step", PyObject), ("stop", PyObject), )
- cpython_struct("PySliceObject", PySliceObjectFields, PySliceObjectStruct)
- @bootstrap_function
- def init_sliceobject(space):
- "Type description of PySliceObject"
- make_typedescr(W_SliceObject.typedef,
- basestruct=PySliceObject.TO,
- attach=slice_attach,
- dealloc=slice_dealloc)
- def slice_attach(space, py_obj, w_obj):
- """
- Fills a newly allocated PySliceObject with the given slice object. The
- fields must not be modified.
- """
- py_slice = rffi.cast(PySliceObject, py_obj)
- assert isinstance(w_obj, W_SliceObject)
- py_slice.c_start = make_ref(space, w_obj.w_start)
- py_slice.c_stop = make_ref(space, w_obj.w_stop)
- py_slice.c_step = make_ref(space, w_obj.w_step)
- @cpython_api([PyObject], lltype.Void, external=False)
- def slice_dealloc(space, py_obj):
- """Frees allocated PyStringObject resources.
- """
- py_slice = rffi.cast(PySliceObject, py_obj)
- Py_DecRef(space, py_slice.c_start)
- Py_DecRef(space, py_slice.c_stop)
- Py_DecRef(space, py_slice.c_step)
- from pypy.module.cpyext.object import PyObject_dealloc
- PyObject_dealloc(space, py_obj)
- PySlice_Check, PySlice_CheckExact = build_type_checkers("Slice")
- @cpython_api([PyObject, PyObject, PyObject], PyObject)
- def PySlice_New(space, w_start, w_stop, w_step):
- """Return a new slice object with the given values. The start, stop, and
- step parameters are used as the values of the slice object attributes of
- the same names. Any of the values may be NULL, in which case the
- None will be used for the corresponding attribute. Return NULL if
- the new object could not be allocated."""
- if w_start is None:
- w_start = space.w_None
- if w_stop is None:
- w_stop = space.w_None
- if w_step is None:
- w_step = space.w_None
- return W_SliceObject(w_start, w_stop, w_step)
- @cpython_api([PySliceObject, Py_ssize_t, Py_ssize_tP, Py_ssize_tP, Py_ssize_tP,
- Py_ssize_tP], rffi.INT_real, error=-1)
- def PySlice_GetIndicesEx(space, w_slice, length, start_p, stop_p, step_p,
- slicelength_p):
- """Usable replacement for PySlice_GetIndices(). Retrieve the start,
- stop, and step indices from the slice object slice assuming a sequence of
- length length, and store the length of the slice in slicelength. Out
- of bounds indices are clipped in a manner consistent with the handling of
- normal slices.
-
- Returns 0 on success and -1 on error with exception set."""
- if not PySlice_Check(space, w_slice):
- PyErr_BadInternalCall(space)
- assert isinstance(w_slice, W_SliceObject)
- start_p[0], stop_p[0], step_p[0], slicelength_p[0] = \
- w_slice.indices4(space, length)
- return 0
- @cpython_api([PySliceObject, Py_ssize_t, Py_ssize_tP, Py_ssize_tP, Py_ssize_tP],
- rffi.INT_real, error=-1)
- def PySlice_GetIndices(space, w_slice, length, start_p, stop_p, step_p):
- """Retrieve the start, stop and step indices from the slice object slice,
- assuming a sequence of length length. Treats indices greater than
- length as errors.
-
- Returns 0 on success and -1 on error with no exception set (unless one of
- the indices was not None and failed to be converted to an integer,
- in which case -1 is returned with an exception set).
-
- You probably do not want to use this function. If you want to use slice
- objects in versions of Python prior to 2.3, you would probably do well to
- incorporate the source of PySlice_GetIndicesEx(), suitably renamed,
- in the source of your extension."""
- if not PySlice_Check(space, w_slice):
- PyErr_BadInternalCall(space)
- assert isinstance(w_slice, W_SliceObject)
- start_p[0], stop_p[0], step_p[0] = \
- w_slice.indices3(space, length)
- return 0