[Django] #20989: tuple() and dict() accept iterators

11 views
Skip to first unread message

Django

unread,
Aug 28, 2013, 7:19:18 AM8/28/13
to django-...@googlegroups.com
#20989: tuple() and dict() accept iterators
---------------------------------+--------------------
Reporter: jeroen.pulles@… | Owner: nobody
Type: Uncategorized | Status: new
Component: Uncategorized | Version: master
Severity: Normal | Keywords:
Triage Stage: Unreviewed | Has patch: 0
Easy pickings: 0 | UI/UX: 0
---------------------------------+--------------------
As I understand it, dict() and tuple() accept iterators, e.g.

{{{
l = [1, 2, 3]
tuple(v for v in l)
}}}

There are various calls to tuple() that place the iterator in a list
comprehension before feeding the list to tuple(). For example in
django/db/models/sql/query.py:

{{{
aliases = tuple([change_map.get(a, a) for a in aliases])
}}}

can be written as:

{{{
aliases = tuple(change_map.get(a, a) for a in aliases)
}}}

saving two characters, an extra iteration and list creation. The same goes
for dict(), where dict([(v, v) for v in l]) can be rewritten as dict((v,
v) for v in l).


----


A shell command like this can replace the calls. When I tried it, I got
lots of errors in the unit tests, but my impression was that that didn't
have anything to do with the edit...

{{{
find django/ -name '*.py' -print0 \
| xargs -n 200 -0 grep -l 'tuple([[][^]]\+[]])' \
| while read F
do
cp "$F" "$F.orig"
sed -e 's/tuple([[]\(.*\)[]])/tuple(\1)/' "$F.orig" > "$F"
done
}}}

--
Ticket URL: <https://code.djangoproject.com/ticket/20989>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

Django

unread,
Aug 28, 2013, 7:25:50 AM8/28/13
to django-...@googlegroups.com
#20989: tuple() and dict() accept iterators
--------------------------------------+------------------------------------
Reporter: jeroen.pulles@… | Owner: nobody
Type: Cleanup/optimization | Status: new
Component: Uncategorized | Version: master
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

Easy pickings: 0 | UI/UX: 0
--------------------------------------+------------------------------------
Changes (by mjtamlyn):

* needs_better_patch: => 0
* stage: Unreviewed => Accepted
* type: Uncategorized => Cleanup/optimization
* needs_tests: => 0
* needs_docs: => 0


--
Ticket URL: <https://code.djangoproject.com/ticket/20989#comment:1>

Django

unread,
Aug 29, 2013, 12:21:31 PM8/29/13
to django-...@googlegroups.com
#20989: tuple() and dict() accept iterators
--------------------------------------+------------------------------------
Reporter: jeroen.pulles@… | Owner: nobody
Type: Cleanup/optimization | Status: closed
Component: Uncategorized | Version: master
Severity: Normal | Resolution: fixed

Keywords: | Triage Stage: Accepted
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

Easy pickings: 0 | UI/UX: 0
--------------------------------------+------------------------------------
Changes (by Tim Graham <timograham@…>):

* status: new => closed
* resolution: => fixed


Comment:

In [changeset:"c7d0ff0cad24dbf444f2e4b534377c3352c7aa98"]:
{{{
#!CommitTicketReference repository=""
revision="c7d0ff0cad24dbf444f2e4b534377c3352c7aa98"
Fixed #20989 -- Removed explicit list comprehension inside dict() and
tuple()

Thanks jeroen.pulles at redslider.net for the suggestion and
helper script.
}}}

--
Ticket URL: <https://code.djangoproject.com/ticket/20989#comment:2>

Django

unread,
Aug 29, 2013, 1:14:16 PM8/29/13
to django-...@googlegroups.com
#20989: tuple() and dict() accept iterators
--------------------------------------+------------------------------------
Reporter: jeroen.pulles@… | Owner: nobody
Type: Cleanup/optimization | Status: closed
Component: Uncategorized | Version: master

Severity: Normal | Resolution: fixed
Keywords: | Triage Stage: Accepted
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

Easy pickings: 0 | UI/UX: 0
--------------------------------------+------------------------------------

Comment (by charettes):

I think the provided regex missed a few ones:

{{{
(django)simon@simon-laptop:~/workspace/django$ grep "dict(\[" django/ -R
django/db/backends/oracle/introspection.py: return dict([(d[0], i)
for i, d in enumerate(self.get_table_description(cursor, table_name))])
django/db/backends/mysql/introspection.py: numeric_map =
dict([(line[0], tuple([int(n) for n in line[1:]])) for line in
cursor.fetchall()])
django/db/backends/mysql/introspection.py: return dict([(d[0], i)
for i, d in enumerate(self.get_table_description(cursor, table_name))])
django/db/models/sql/query.py: return dict([
django/template/loader_tags.py: blocks = dict([(n.name,
n) for n in
django/template/loader_tags.py: values = dict([(name,
var.resolve(context)) for name, var
django/template/defaulttags.py: kwargs = dict([(smart_text(k,
'ascii'), v.resolve(context))
django/template/defaulttags.py: values = dict([(key,
val.resolve(context)) for key, val in
django/utils/html.py: kwargs_safe = dict([(k, conditional_escape(v))
for (k, v) in
django/utils/termcolors.py:foreground = dict([(color_names[x], '3%s' % x)
for x in range(8)])
django/utils/termcolors.py:background = dict([(color_names[x], '4%s' % x)
for x in range(8)])
django/utils/cache.py: cc = dict([_to_tuple(el) for el in
django/contrib/admin/filters.py: self.date_params = dict([(k, v)
for k, v in params.items()
django/contrib/messages/storage/cookie.py: return dict([(key,
self.process_messages(value))
django/core/management/__init__.py:
_commands.update(dict([(name, app_name)
}}}
{{{
(django)simon@simon-laptop:~/workspace/django$ grep "tuple(\[" django/ -R
django/db/backends/oracle/base.py: return tuple([_rowfactory(r,
self.cursor)
django/db/backends/oracle/base.py: return tuple([_rowfactory(r,
self.cursor)
django/db/backends/mysql/introspection.py: numeric_map =
dict([(line[0], tuple([int(n) for n in line[1:]])) for line in
cursor.fetchall()])
django/db/models/query.py: yield tuple([data[f] for f in
fields])
django/db/models/sql/compiler.py: row =
tuple(row[:aggregate_start]) + tuple([
django/template/base.py: return self.msg % tuple([force_text(p,
errors='replace')
django/contrib/gis/gdal/geometries.py: return tuple([self[i] for i
in xrange(len(self))])
django/contrib/gis/gdal/geometries.py: return tuple([self[i].tuple
for i in xrange(self.geom_count)])
django/contrib/gis/gdal/geometries.py: return tuple([self[i].tuple
for i in xrange(self.geom_count)])
django/contrib/gis/geos/coordseq.py: else: return tuple([self[i]
for i in xrange(n)])
django/contrib/gis/geos/polygon.py: return tuple([self[i].tuple for
i in xrange(len(self))])
}}}

--
Ticket URL: <https://code.djangoproject.com/ticket/20989#comment:3>

Django

unread,
Aug 29, 2013, 1:28:00 PM8/29/13
to django-...@googlegroups.com
#20989: tuple() and dict() accept iterators
--------------------------------------+------------------------------------
Reporter: jeroen.pulles@… | Owner: nobody
Type: Cleanup/optimization | Status: new
Component: Uncategorized | Version: master
Severity: Normal | Resolution:

Keywords: | Triage Stage: Accepted
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

Easy pickings: 0 | UI/UX: 0
--------------------------------------+------------------------------------
Changes (by timo):

* status: closed => new
* resolution: fixed =>


--
Ticket URL: <https://code.djangoproject.com/ticket/20989#comment:4>

Django

unread,
Aug 29, 2013, 7:28:23 PM8/29/13
to django-...@googlegroups.com
#20989: Remove useless list comprehensions
--------------------------------------+------------------------------------
Reporter: jeroen.pulles@… | Owner: nobody
Type: Cleanup/optimization | Status: new
Component: Uncategorized | Version: master

Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

Easy pickings: 0 | UI/UX: 0
--------------------------------------+------------------------------------

Comment (by charettes):

Added a patch which remove the missed ones and also consider the following
cases:

1. `set` and `set.update`
2. `OrderedDict`
3. `list.extend`
4. `join`
5. `min`,`max`,`sum` and `any`
6. `sorted`

All tests pass on py2/py3 SQlite and Postgres.

--
Ticket URL: <https://code.djangoproject.com/ticket/20989#comment:5>

Django

unread,
Aug 30, 2013, 7:47:23 AM8/30/13
to django-...@googlegroups.com
#20989: Remove useless list comprehensions
-------------------------------------+-------------------------------------
Reporter: jeroen.pulles@… | Owner: nobody
Type: | Status: new
Cleanup/optimization | Version: master
Component: Uncategorized | Resolution:
Severity: Normal | Triage Stage: Ready for
Keywords: | checkin
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by claudep):

* has_patch: 0 => 1
* stage: Accepted => Ready for checkin


Comment:

As far as tests are green, I'd say go ahead.

--
Ticket URL: <https://code.djangoproject.com/ticket/20989#comment:6>

Django

unread,
Aug 30, 2013, 10:58:17 AM8/30/13
to django-...@googlegroups.com
#20989: Remove useless list comprehensions
-------------------------------------+-------------------------------------
Reporter: jeroen.pulles@… | Owner: nobody
Type: | Status: closed
Cleanup/optimization | Version: master
Component: Uncategorized | Resolution: fixed

Severity: Normal | Triage Stage: Ready for
Keywords: | checkin
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Simon Charette <charette.s@…>):

* status: new => closed
* resolution: => fixed


Comment:

In [changeset:"11cd7388f77aa9d12ab6b57285c3801b237e241b"]:
{{{
#!CommitTicketReference repository=""
revision="11cd7388f77aa9d12ab6b57285c3801b237e241b"
Fixed #20989 -- Removed useless explicit list comprehensions.
}}}

--
Ticket URL: <https://code.djangoproject.com/ticket/20989#comment:7>

Reply all
Reply to author
Forward
0 new messages