Calling tuple on pytz.all_timezones produces an empty tuple

Bug #1435617 reported by david@drmaciver.com on 2015-03-23
6
This bug affects 1 person
Affects Status Importance Assigned to Milestone
pytz
Undecided
Unassigned

Bug Description

The following program crashes on pytz-2014.10:

import pytz

if __name__ == '__main__':
    assert tuple(pytz.all_timezones)

The following succeeds:

import pytz

if __name__ == '__main__':
    list(pytz.all_timezones)
    assert tuple(pytz.all_timezones)

I'm not sure what's going on here exactly. Something about the tuple invocation is bypassing your LazyList mechanism, but I can't figure out exactly what. The initial list invocation (bool also works) seems to force it to load and subsequent calls to work.

david@drmaciver.com (6-david-h) wrote :

Additional detail: Against all my expectations, this works correctly on pypy-2.5.0 and does not error.

david@drmaciver.com (6-david-h) wrote :

The following demonstrates the source of the problem:

from __future__ import print_function

class TestList(list):

    def __iter__(self):
        yield 1
        yield 2
        yield 3

if __name__ == '__main__':
    x = TestList()

    x.extend([4, 5, 6])
    print(repr(tuple(x)))
    print(repr(list(x)))

Basically it looks like in CPython there's a special case for calling tuple on a list which bypasses all the normal methods.

david@drmaciver.com (6-david-h) wrote :

I've now also filed a bug with CPython about this: http://bugs.python.org/issue23757

david@drmaciver.com (6-david-h) wrote :

Based on the response on the linked issue and the additional link provided to http://bugs.python.org/issue10977, I think the only thing I can recommend here is that subclassing builtin types like list is a really bad idea and you probably shouldn't do it. Sorry.

Stuart Bishop (stub) wrote :

Work around the Python issue, or flag this as WONTFIX if that isn't possible. We can't backout lazy loading of these data structures.

Changed in pytz:
status: New → Triaged
david@drmaciver.com (6-david-h) wrote :

Can you stop making your LazyList type a subclass of list and just have it implement the general protocol? Because that would be sufficient to work around the Python issue.

Stuart Bishop (stub) wrote :

Yes, that would be a suitable work around. It just needs to look like a list and do lazy loading, so people not using the structure don't have to pay the startup cost.

david@drmaciver.com (6-david-h) wrote :

FWIW, this manifests a similar but slightly different problem in Jython: list(pytz.all_timezones) evaluates to an empty list.

Stuart Bishop (stub) on 2017-10-20
Changed in pytz:
status: Triaged → Won't Fix
status: Won't Fix → Triaged
To post a comment you must log in.
This report contains Public information  Edit
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.