/pypy/module/cpyext/listobject.py

https://github.com/alemacgo/pypy · Python · 127 lines · 98 code · 5 blank · 24 comment · 9 complexity · d237f820f27d9d4b1022f0511f135032 MD5 · raw file

  1. from pypy.rpython.lltypesystem import rffi, lltype
  2. from pypy.module.cpyext.api import (cpython_api, CANNOT_FAIL, Py_ssize_t,
  3. build_type_checkers)
  4. from pypy.module.cpyext.pyerrors import PyErr_BadInternalCall
  5. from pypy.module.cpyext.pyobject import Py_DecRef, PyObject, borrow_from
  6. from pypy.objspace.std.listobject import W_ListObject
  7. from pypy.interpreter.error import OperationError
  8. PyList_Check, PyList_CheckExact = build_type_checkers("List")
  9. @cpython_api([Py_ssize_t], PyObject)
  10. def PyList_New(space, len):
  11. """Return a new list of length len on success, or NULL on failure.
  12. If length is greater than zero, the returned list object's items are
  13. set to NULL. Thus you cannot use abstract API functions such as
  14. PySequence_SetItem() or expose the object to Python code before
  15. setting all items to a real object with PyList_SetItem().
  16. """
  17. return space.newlist([None] * len)
  18. @cpython_api([PyObject, Py_ssize_t, PyObject], rffi.INT_real, error=-1)
  19. def PyList_SetItem(space, w_list, index, w_item):
  20. """Set the item at index index in list to item. Return 0 on success
  21. or -1 on failure.
  22. This function "steals" a reference to item and discards a reference to
  23. an item already in the list at the affected position.
  24. """
  25. Py_DecRef(space, w_item)
  26. if not isinstance(w_list, W_ListObject):
  27. PyErr_BadInternalCall(space)
  28. wrappeditems = w_list.wrappeditems
  29. if index < 0 or index >= len(wrappeditems):
  30. raise OperationError(space.w_IndexError, space.wrap(
  31. "list assignment index out of range"))
  32. wrappeditems[index] = w_item
  33. return 0
  34. @cpython_api([PyObject, Py_ssize_t], PyObject)
  35. def PyList_GetItem(space, w_list, index):
  36. """Return the object at position pos in the list pointed to by p. The
  37. position must be positive, indexing from the end of the list is not
  38. supported. If pos is out of bounds, return NULL and set an
  39. IndexError exception."""
  40. if not isinstance(w_list, W_ListObject):
  41. PyErr_BadInternalCall(space)
  42. wrappeditems = w_list.wrappeditems
  43. if index < 0 or index >= len(wrappeditems):
  44. raise OperationError(space.w_IndexError, space.wrap(
  45. "list index out of range"))
  46. return borrow_from(w_list, wrappeditems[index])
  47. @cpython_api([PyObject, PyObject], rffi.INT_real, error=-1)
  48. def PyList_Append(space, w_list, w_item):
  49. if not isinstance(w_list, W_ListObject):
  50. PyErr_BadInternalCall(space)
  51. w_list.append(w_item)
  52. return 0
  53. @cpython_api([PyObject, Py_ssize_t, PyObject], rffi.INT_real, error=-1)
  54. def PyList_Insert(space, w_list, index, w_item):
  55. """Insert the item item into list list in front of index index. Return
  56. 0 if successful; return -1 and set an exception if unsuccessful.
  57. Analogous to list.insert(index, item)."""
  58. space.call_method(w_list, "insert", space.wrap(index), w_item)
  59. return 0
  60. @cpython_api([PyObject], Py_ssize_t, error=CANNOT_FAIL)
  61. def PyList_GET_SIZE(space, w_list):
  62. """Macro form of PyList_Size() without error checking.
  63. """
  64. assert isinstance(w_list, W_ListObject)
  65. return len(w_list.wrappeditems)
  66. @cpython_api([PyObject], Py_ssize_t, error=-1)
  67. def PyList_Size(space, ref):
  68. """Return the length of the list object in list; this is equivalent to
  69. len(list) on a list object.
  70. """
  71. if not PyList_Check(space, ref):
  72. raise OperationError(space.w_TypeError,
  73. space.wrap("expected list object"))
  74. return PyList_GET_SIZE(space, ref)
  75. @cpython_api([PyObject], PyObject)
  76. def PyList_AsTuple(space, w_list):
  77. """Return a new tuple object containing the contents of list; equivalent to
  78. tuple(list)."""
  79. return space.call_function(space.w_tuple, w_list)
  80. @cpython_api([PyObject], rffi.INT_real, error=-1)
  81. def PyList_Sort(space, w_list):
  82. """Sort the items of list in place. Return 0 on success, -1 on
  83. failure. This is equivalent to list.sort()."""
  84. if not isinstance(w_list, W_ListObject):
  85. PyErr_BadInternalCall(space)
  86. space.call_method(w_list, "sort")
  87. return 0
  88. @cpython_api([PyObject], rffi.INT_real, error=-1)
  89. def PyList_Reverse(space, w_list):
  90. """Reverse the items of list in place. Return 0 on success, -1 on
  91. failure. This is the equivalent of list.reverse()."""
  92. if not isinstance(w_list, W_ListObject):
  93. PyErr_BadInternalCall(space)
  94. space.call_method(w_list, "reverse")
  95. return 0
  96. @cpython_api([PyObject, Py_ssize_t, Py_ssize_t, PyObject], rffi.INT_real, error=-1)
  97. def PyList_SetSlice(space, w_list, low, high, w_sequence):
  98. """Set the slice of list between low and high to the contents of
  99. itemlist. Analogous to list[low:high] = itemlist. The itemlist may
  100. be NULL, indicating the assignment of an empty list (slice deletion).
  101. Return 0 on success, -1 on failure. Negative indices, as when
  102. slicing from Python, are not supported."""
  103. w_start = space.wrap(low)
  104. w_stop = space.wrap(high)
  105. if w_sequence:
  106. space.setslice(w_list, w_start, w_stop, w_sequence)
  107. else:
  108. space.delslice(w_list, w_start, w_stop)
  109. return 0