#23088 closed Cleanup/optimization (fixed)
Paginator.page_range is of inconsistent type in Py2/Py3
Reported by: | Owned by: | mardini | |
---|---|---|---|
Component: | Core (Other) | Version: | dev |
Severity: | Normal | Keywords: | |
Cc: | cmawebsite@… | Triage Stage: | Accepted |
Has patch: | yes | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
Currently, Paginator.page_range uses the implementation native version of range
, which under Python 2.x yields a list
, while on 3.x it is a class of type range
, largely analogous to 2.x's xrange
six
is already imported into the module for Page.__getitem__
and so could be leveraged to at least be consistent.
In the pathological case, the python 2.x version could be considered problematic if yielding a large range, because the list is built up immediately in memory, where the 3.x version uses the efficient iterator.
I actually encountered this by passing a page_range
in a template's context, which then gets copied into every child context (eg: via {% include %}
) ... and gets worse when you try and figure out what happened by enabling debug-toolbar's context peeking panel (commit where I handled it by basically removing a 65,000 item list)
Change History (14)
comment:1 by , 10 years ago
Triage Stage: | Unreviewed → Accepted |
---|
comment:2 by , 10 years ago
Owner: | changed from | to
---|---|
Status: | new → assigned |
comment:3 by , 10 years ago
Has patch: | set |
---|
comment:4 by , 10 years ago
Resolution: | → fixed |
---|---|
Status: | assigned → closed |
comment:6 by , 10 years ago
This might cause problems if someone iterates over page_range
twice; eg to show a list of pages above and below the content. So this change has the possibility to break existing code; not sure what the best way to go ahead is -- one option would be to also force a list on python3 and tell ddt to get smarter :þ
comment:7 by , 10 years ago
Hi apollo13,
Thanks for the feedback. I actually tried a small example in which I used the new version of page_range
twice and didn't face any issues.
I think the reason for this is that although xrange
(Python2)/range
(Python3) is a generator in theory, the actual implementation is not.
A couple of links that discuss this behavior:
http://stackoverflow.com/questions/10776250/why-is-xrange-able-to-go-back-to-beginning-in-python
http://stackoverflow.com/questions/13092267/if-range-is-a-generator-in-python-3-3-why-can-i-not-call-next-on-a-range
comment:8 by , 10 years ago
I've been relying on this being a list. #23140
comment:9 by , 10 years ago
Cc: | added |
---|
comment:14 by , 10 years ago
this ticket is closed as "fixed", so here's a new ticket for converting to an iterator #23190
PR: https://github.com/django/django/pull/2954