/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

  1. from pypy.rpython.lltypesystem import rffi, lltype
  2. from pypy.module.cpyext.api import (
  3. cpython_api, cpython_struct, bootstrap_function, build_type_checkers,
  4. CANNOT_FAIL, Py_ssize_t, Py_ssize_tP, PyObjectFields)
  5. from pypy.module.cpyext.pyobject import (
  6. Py_DecRef, PyObject, make_ref, make_typedescr)
  7. from pypy.module.cpyext.pyerrors import PyErr_BadInternalCall
  8. from pypy.interpreter.error import OperationError
  9. from pypy.objspace.std.sliceobject import W_SliceObject
  10. # Slice objects directly expose their members as PyObject.
  11. # Don't change them!
  12. PySliceObjectStruct = lltype.ForwardReference()
  13. PySliceObject = lltype.Ptr(PySliceObjectStruct)
  14. PySliceObjectFields = PyObjectFields + \
  15. (("start", PyObject), ("step", PyObject), ("stop", PyObject), )
  16. cpython_struct("PySliceObject", PySliceObjectFields, PySliceObjectStruct)
  17. @bootstrap_function
  18. def init_sliceobject(space):
  19. "Type description of PySliceObject"
  20. make_typedescr(W_SliceObject.typedef,
  21. basestruct=PySliceObject.TO,
  22. attach=slice_attach,
  23. dealloc=slice_dealloc)
  24. def slice_attach(space, py_obj, w_obj):
  25. """
  26. Fills a newly allocated PySliceObject with the given slice object. The
  27. fields must not be modified.
  28. """
  29. py_slice = rffi.cast(PySliceObject, py_obj)
  30. assert isinstance(w_obj, W_SliceObject)
  31. py_slice.c_start = make_ref(space, w_obj.w_start)
  32. py_slice.c_stop = make_ref(space, w_obj.w_stop)
  33. py_slice.c_step = make_ref(space, w_obj.w_step)
  34. @cpython_api([PyObject], lltype.Void, external=False)
  35. def slice_dealloc(space, py_obj):
  36. """Frees allocated PyStringObject resources.
  37. """
  38. py_slice = rffi.cast(PySliceObject, py_obj)
  39. Py_DecRef(space, py_slice.c_start)
  40. Py_DecRef(space, py_slice.c_stop)
  41. Py_DecRef(space, py_slice.c_step)
  42. from pypy.module.cpyext.object import PyObject_dealloc
  43. PyObject_dealloc(space, py_obj)
  44. PySlice_Check, PySlice_CheckExact = build_type_checkers("Slice")
  45. @cpython_api([PyObject, PyObject, PyObject], PyObject)
  46. def PySlice_New(space, w_start, w_stop, w_step):
  47. """Return a new slice object with the given values. The start, stop, and
  48. step parameters are used as the values of the slice object attributes of
  49. the same names. Any of the values may be NULL, in which case the
  50. None will be used for the corresponding attribute. Return NULL if
  51. the new object could not be allocated."""
  52. if w_start is None:
  53. w_start = space.w_None
  54. if w_stop is None:
  55. w_stop = space.w_None
  56. if w_step is None:
  57. w_step = space.w_None
  58. return W_SliceObject(w_start, w_stop, w_step)
  59. @cpython_api([PySliceObject, Py_ssize_t, Py_ssize_tP, Py_ssize_tP, Py_ssize_tP,
  60. Py_ssize_tP], rffi.INT_real, error=-1)
  61. def PySlice_GetIndicesEx(space, w_slice, length, start_p, stop_p, step_p,
  62. slicelength_p):
  63. """Usable replacement for PySlice_GetIndices(). Retrieve the start,
  64. stop, and step indices from the slice object slice assuming a sequence of
  65. length length, and store the length of the slice in slicelength. Out
  66. of bounds indices are clipped in a manner consistent with the handling of
  67. normal slices.
  68. Returns 0 on success and -1 on error with exception set."""
  69. if not PySlice_Check(space, w_slice):
  70. PyErr_BadInternalCall(space)
  71. assert isinstance(w_slice, W_SliceObject)
  72. start_p[0], stop_p[0], step_p[0], slicelength_p[0] = \
  73. w_slice.indices4(space, length)
  74. return 0
  75. @cpython_api([PySliceObject, Py_ssize_t, Py_ssize_tP, Py_ssize_tP, Py_ssize_tP],
  76. rffi.INT_real, error=-1)
  77. def PySlice_GetIndices(space, w_slice, length, start_p, stop_p, step_p):
  78. """Retrieve the start, stop and step indices from the slice object slice,
  79. assuming a sequence of length length. Treats indices greater than
  80. length as errors.
  81. Returns 0 on success and -1 on error with no exception set (unless one of
  82. the indices was not None and failed to be converted to an integer,
  83. in which case -1 is returned with an exception set).
  84. You probably do not want to use this function. If you want to use slice
  85. objects in versions of Python prior to 2.3, you would probably do well to
  86. incorporate the source of PySlice_GetIndicesEx(), suitably renamed,
  87. in the source of your extension."""
  88. if not PySlice_Check(space, w_slice):
  89. PyErr_BadInternalCall(space)
  90. assert isinstance(w_slice, W_SliceObject)
  91. start_p[0], stop_p[0], step_p[0] = \
  92. w_slice.indices3(space, length)
  93. return 0