Monday, June 3, 2019

They say a python tuple can't contain itself...

... but here at PDW we abhor that kind of defeatism!

>>> import ctypes
>>> tup = (None,)
>>> ctypes.pythonapi.PyTuple_SetItem.argtypes = ctypes.c_void_p, ctypes.c_int, ctypes.c_void_p
>>> ctypes.pythonapi.PyTuple_SetItem(id(tup), 0, id(tup))
0


Showing the tuple itself is a little problematic
>>> tup
# ... hundreds of lines of parens ...
(((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((
(((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((
(((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((
(((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((
(((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((
((Segmentation fault

3 comments:

  1. This is not surprising, since C-API is actually used. Without it, making a tuple instance with a part of itself will not possible.

    ReplyDelete
    Replies
    1. yup! only the C-API makes it possible

      it is kind of interesting though that tuple doesn't have any recursion handling in its repr()

      >>> a = []
      >>> a.append((a,))
      >>> a
      [([...],)]
      >>> a[0]
      ([([...],)],)

      rather than tuple(list(tuple)) showing ([(...,)]) it relies on the list repr() to detect the cycle and handle it one layer deeper

      contract with dict(list(dict)) in which the dict repr() detects the cycle

      >>> b = {}
      >>> b[0] = [b]
      >>> b
      {0: [{...}]}

      Delete
  2. Odd; not getting this error under ipython, though I do get it with plain python. Both should(?) be running the same python executable; at any rate both report running 2.7.15 (can't even try this in python3 it seems). But under ipython I just get ((...),) as one might expect.

    ReplyDelete