Re: Infinitely nested containers

2014-11-22 Thread Ethan Furman
On 11/21/2014 08:43 PM, Steven D'Aprano wrote:
 random...@fastmail.us wrote:
 
 I think I tried on at least one python version and printing the tuple
 crashed with a recursion depth error, since it had no special protection
 for this case the way list printing does.
 
 It works fine now (Python 3.3).
 
 py L = []
 py t = (L, None)
 py L.append(L)
 py L.append(t)  # For good measure.
 py print(t)
 ([[...], (...)], None)

This is a tuple in a list in a tuple, not a tuple in a tuple.

--
~Ethan~



signature.asc
Description: OpenPGP digital signature
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Infinitely nested containers

2014-11-22 Thread Terry Reedy

On 11/21/2014 2:30 PM, Zachary Ware wrote:

On Fri, Nov 21, 2014 at 12:37 PM, Ian Kelly ian.g.ke...@gmail.com wrote:

Here's a nice crash. I thought this might similarly produce a
recursion depth error, but no, it's a seg fault!

$ cat test.py
import itertools

l = []
it = itertools.chain.from_iterable(l)
l.append(it)
next(it)
$ python3 test.py
Segmentation fault (core dumped)


Would you mind submitting a bug report for that?  Any segfault
produced by pure Python code must be fixed.


This is too important to lose.
http://bugs.python.org/issue22920


--
Terry Jan Reedy

--
https://mail.python.org/mailman/listinfo/python-list


Re: Infinitely nested containers

2014-11-22 Thread Steven D'Aprano
Ethan Furman wrote:

 On 11/21/2014 08:43 PM, Steven D'Aprano wrote:
 random...@fastmail.us wrote:
 
 I think I tried on at least one python version and printing the tuple
 crashed with a recursion depth error, since it had no special protection
 for this case the way list printing does.
 
 It works fine now (Python 3.3).
 
 py L = []
 py t = (L, None)
 py L.append(L)
 py L.append(t)  # For good measure.
 py print(t)
 ([[...], (...)], None)
 
 This is a tuple in a list in a tuple, not a tuple in a tuple.

Really? I hadn't noticed.

*wink*

It's still a tuple in itself, recursively, and the tuple to str conversion
routine still has to deal with the fact.




-- 
Steven

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Infinitely nested containers

2014-11-22 Thread random832


On Sun, Nov 23, 2014, at 00:59, Steven D'Aprano wrote:
  It works fine now (Python 3.3).
  
  py L = []
  py t = (L, None)
  py L.append(L)
  py L.append(t)  # For good measure.
  py print(t)
  ([[...], (...)], None)
  
  This is a tuple in a list in a tuple, not a tuple in a tuple.
 
 Really? I hadn't noticed.
 
 *wink*
 
 It's still a tuple in itself, recursively, and the tuple to str
 conversion
 routine still has to deal with the fact.

Does it, or does it punt to the list to str routine?

Anyway, on python 2.7, print and str do not work the same way for
tuples. I'm remembering more about this issue now, and it was _strictly_
on print, not on str.
 t
([[...], ([...], None)], None)
 print(t)
([[...], ([...], None)], None)
 str(t)
'([[...], (...)], None)'


Notice that print never does (...), only [...]. And if it never finds a
[...]?
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Infinitely nested containers

2014-11-21 Thread Ian Kelly
On Thu, Nov 20, 2014 at 10:54 PM, Gill Shen gillar...@gmail.com wrote:
 How is this behavior implemented under the hood? And why is this allowed at 
 all? Is it just a curiosity or can you do something useful with it?

Reference cycles are common in Python and other OO languages. For
example, adding a widget to a window; the window contains references
to its child widgets, and it's probably useful for the widgets to know
what their parents are, so they would hold references back.

A list containing itself is similarly a reference cycle. I don't know
off-hand of any use for this specific case, but it's just a slightly
tighter cycle than normal.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Infinitely nested containers

2014-11-21 Thread random832
On Fri, Nov 21, 2014, at 02:00, Marko Rauhamaa wrote:
 Gill Shen gillar...@gmail.com:
 
  How is this [nesting] behavior implemented under the hood?
 
 Pointers.
 
  And why is this allowed at all?
 
 There's no reason not to.

There's no reason not to allow it with tuples, but you can't do it.
Mainly because doing it in a single literal would require special
syntax, whereas you can simply append to a list a reference to itself.

I think I tried on at least one python version and printing the tuple
crashed with a recursion depth error, since it had no special protection
for this case the way list printing does.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Infinitely nested containers

2014-11-21 Thread Chris Angelico
On Sat, Nov 22, 2014 at 4:39 AM,  random...@fastmail.us wrote:
 There's no reason not to allow it with tuples, but you can't do it.
 Mainly because doing it in a single literal would require special
 syntax, whereas you can simply append to a list a reference to itself.

 I think I tried on at least one python version and printing the tuple
 crashed with a recursion depth error, since it had no special protection
 for this case the way list printing does.

You can do it in C, I believe - PyTuple_New() followed by
PyTuple_SetItem(x, 0, x) should do it.

ChrisA
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Infinitely nested containers

2014-11-21 Thread random832
On Fri, Nov 21, 2014, at 12:47, Chris Angelico wrote:
 You can do it in C, I believe - PyTuple_New() followed by
 PyTuple_SetItem(x, 0, x) should do it.

Yeah, that's how I did it. I think python 2 crashed and python 3
didn't... or maybe it was the interactive interpreter that crashed and
calling repr didn't, within the same version - I don't remember that
well.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Infinitely nested containers

2014-11-21 Thread Ian Kelly
On Fri, Nov 21, 2014 at 10:39 AM,  random...@fastmail.us wrote:
 On Fri, Nov 21, 2014, at 02:00, Marko Rauhamaa wrote:
 Gill Shen gillar...@gmail.com:

  How is this [nesting] behavior implemented under the hood?

 Pointers.

  And why is this allowed at all?

 There's no reason not to.

 There's no reason not to allow it with tuples, but you can't do it.
 Mainly because doing it in a single literal would require special
 syntax, whereas you can simply append to a list a reference to itself.

 I think I tried on at least one python version and printing the tuple
 crashed with a recursion depth error, since it had no special protection
 for this case the way list printing does.

Here's a nice crash. I thought this might similarly produce a
recursion depth error, but no, it's a seg fault!

$ cat test.py
import itertools

l = []
it = itertools.chain.from_iterable(l)
l.append(it)
next(it)
$ python3 test.py
Segmentation fault (core dumped)
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Infinitely nested containers

2014-11-21 Thread Zachary Ware
On Fri, Nov 21, 2014 at 12:37 PM, Ian Kelly ian.g.ke...@gmail.com wrote:
 Here's a nice crash. I thought this might similarly produce a
 recursion depth error, but no, it's a seg fault!

 $ cat test.py
 import itertools

 l = []
 it = itertools.chain.from_iterable(l)
 l.append(it)
 next(it)
 $ python3 test.py
 Segmentation fault (core dumped)

Would you mind submitting a bug report for that?  Any segfault
produced by pure Python code must be fixed.

-- 
Zach
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Infinitely nested containers

2014-11-21 Thread Steven D'Aprano
random...@fastmail.us wrote:

 On Fri, Nov 21, 2014, at 02:00, Marko Rauhamaa wrote:
 Gill Shen gillar...@gmail.com:
 
  How is this [nesting] behavior implemented under the hood?
 
 Pointers.
 
  And why is this allowed at all?
 
 There's no reason not to.
 
 There's no reason not to allow it with tuples, but you can't do it.
 Mainly because doing it in a single literal would require special
 syntax, whereas you can simply append to a list a reference to itself.

You can't append a list to itself in a single expression, you have to create
the list first.

 I think I tried on at least one python version and printing the tuple
 crashed with a recursion depth error, since it had no special protection
 for this case the way list printing does.


It works fine now (Python 3.3).

py L = []
py t = (L, None)
py L.append(L)
py L.append(t)  # For good measure.
py print(t)
([[...], (...)], None)


but yes, in old versions of Python printing self-recursive containers may
break.



-- 
Steven

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Infinitely nested containers

2014-11-21 Thread Chris Angelico
On Sat, Nov 22, 2014 at 3:43 PM, Steven D'Aprano
steve+comp.lang.pyt...@pearwood.info wrote:
 random...@fastmail.us wrote:

 There's no reason not to allow it with tuples, but you can't do it.
 Mainly because doing it in a single literal would require special
 syntax, whereas you can simply append to a list a reference to itself.

 You can't append a list to itself in a single expression, you have to create
 the list first.

It's possible to have a list directly refer to itself:

lst = []
lst.append(lst)

It's not possible, with pure Python code, to create a tuple with a
reference to itself, because you have to create a tuple with a single
expression. Hence the comments about using the C API... and breaking
stuff.

ChrisA
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Infinitely nested containers

2014-11-21 Thread Rustom Mody
On Saturday, November 22, 2014 10:20:36 AM UTC+5:30, Chris Angelico wrote:
 On Sat, Nov 22, 2014 at 3:43 PM, Steven D'Aprano wrote:
  random832 wrote:
 
  There's no reason not to allow it with tuples, but you can't do it.
  Mainly because doing it in a single literal would require special
  syntax, whereas you can simply append to a list a reference to itself.
 
  You can't append a list to itself in a single expression, you have to create
  the list first.
 
 It's possible to have a list directly refer to itself:
 
 lst = []
 lst.append(lst)

Thats not a single expression; which is possible with a lazy
evaluation language like Haskell.
Prelude let ones = 1 : ones
Prelude ones
[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
until the Control-C
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Infinitely nested containers

2014-11-21 Thread Chris Angelico
On Sat, Nov 22, 2014 at 4:02 PM, Rustom Mody rustompm...@gmail.com wrote:
 Thats not a single expression; which is possible with a lazy
 evaluation language like Haskell.
 Prelude let ones = 1 : ones

I'm not sure lazy evaluation is the key here, unless it also does
name lookups lazily. What happens if you do this:

let foo = 1 : bar
let bar = 2 : 3
foo

Will that show 1, 2, 3? If so, then sure, lazy eval is what achieved
that - but it's also going to make it hard to track down name errors.

ChrisA
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Infinitely nested containers

2014-11-21 Thread Rustom Mody
On Saturday, November 22, 2014 10:40:23 AM UTC+5:30, Chris Angelico wrote:
 On Sat, Nov 22, 2014 at 4:02 PM, Rustom Mody  wrote:
  Thats not a single expression; which is possible with a lazy
  evaluation language like Haskell.
  Prelude let ones = 1 : ones
 
 I'm not sure lazy evaluation is the key here, unless it also does
 name lookups lazily. What happens if you do this:
 
 let foo = 1 : bar
 let bar = 2 : 3
 foo
 
 Will that show 1, 2, 3? If so, then sure, lazy eval is what achieved
 that - but it's also going to make it hard to track down name errors.

Prelude let foo = 1 : bar; bar = 2 : [3]
Prelude foo
[1,2,3]


Prelude let foo = 1 : bar; bar = 2 : foo
Prelude foo
[1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1
 Control-C
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Infinitely nested containers

2014-11-20 Thread Chris Angelico
On Fri, Nov 21, 2014 at 4:54 PM, Gill Shen gillar...@gmail.com wrote:
 How is this behavior implemented under the hood? And why is this allowed at 
 all? Is it just a curiosity or can you do something useful with it?

Simple: The list contains itself. When you dereference the list, you
get back the original list. It does have value; you just have to be
careful of any recursive operation like printing it out - the repr()
for a list carefully checks for this.

ChrisA
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Infinitely nested containers

2014-11-20 Thread Marko Rauhamaa
Gill Shen gillar...@gmail.com:

 How is this [nesting] behavior implemented under the hood?

Pointers.

 And why is this allowed at all?

There's no reason not to.

 Is it just a curiosity or can you do something useful with it?

It absolutely does arise every here and there. It's so natural you don't
even pay attention to it.


Marko
-- 
https://mail.python.org/mailman/listinfo/python-list