diff options
| author | xmo-odoo <xmo@odoo.com> | 2017-05-10 09:39:55 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2017-05-10 09:39:55 +0200 |
| commit | fffaf735f58f1ac57781c095eb552de6d1fcdc47 (patch) | |
| tree | 88ab0ab65430d871862a836524e0ecc890d1674d /doc | |
| parent | 10eee18a047d35305dc46282e610e88936d81ffc (diff) | |
[FIX] P3: list -> iterable builtins (#16811)
In Python 3:
* various builtins and dict methods were changed to return
view/iterable objects rather than lists
* and the separate Python 2 view/iterable builtins and methods were
removed altogether
This is problematic when using these items as list (which the happens
repeatedly in Odoo), but more viciously when iterating *multiple times*
over them (which also happens, which I've messed up multiple times while
writing this, and which is a pain to debug even when you've just created
the issue).
Convert all code using these to semantics-matching cross-version
helper functions to get the LCD behaviour between P2 and P3, and
forbid the builtins via lint.
issue #8530
Diffstat (limited to 'doc')
| -rw-r--r-- | doc/_extensions/odoo_ext/translator.py | 6 | ||||
| -rw-r--r-- | doc/python3.rst | 50 |
2 files changed, 39 insertions, 17 deletions
diff --git a/doc/_extensions/odoo_ext/translator.py b/doc/_extensions/odoo_ext/translator.py index 48c5e901f28..1f7fba93772 100644 --- a/doc/_extensions/odoo_ext/translator.py +++ b/doc/_extensions/odoo_ext/translator.py @@ -71,9 +71,9 @@ class BootstrapTranslator(nodes.NodeVisitor, object): tagname = unicode(tagname).lower() # extract generic attributes - attrs = {name.lower(): value for name, value in attributes.iteritems()} + attrs = {name.lower(): value for name, value in attributes.items()} attrs.update( - (name, value) for name, value in node.attributes.iteritems() + (name, value) for name, value in node.attributes.items() if name.startswith('data-') ) @@ -97,7 +97,7 @@ class BootstrapTranslator(nodes.NodeVisitor, object): prefix=u''.join(prefix), tag=tagname, attrs=u' '.join(u'{}="{}"'.format(name, self.attval(value)) - for name, value in attrs.iteritems()), + for name, value in attrs.items()), postfix=u''.join(postfix), ) # only "space characters" SPACE, CHARACTER TABULATION, LINE FEED, diff --git a/doc/python3.rst b/doc/python3.rst index df86107c35b..ba368572c13 100644 --- a/doc/python3.rst +++ b/doc/python3.rst @@ -172,6 +172,37 @@ statement to the following cross-language forms:: exec(source, globals) exec(source, globals, locals) +List/iteration builtins and methods +----------------------------------- + +In Python 3, a number of builtins and methods formerly returning *lists* were +converted to return *iterators* or *views*, with the corresponding redundant +methods or functions having been *removed entirely*: + +* In Python 3, ``map``, ``filter`` and ``zip`` return iterators, + ``itertools.imap``, ``itertools.ifilter`` and ``itertools.izip`` have been + removed. + + .. important:: + + When possible, use comprehensions (list, generator, ...) rather than + ``map`` or ``filter``, otherwise use the cross-version ``pycompat`` + versions (``pycompat.imap``, ``pycompat.ifilter`` and + ``pycompat.izip``). The ``pycompat`` versions all return *iterators* and + may need to be wrapped in a ``list()`` call to yield a list. + +* In Python 3, ``dict.keys``, ``dict.values`` and ``dict.items`` return + *views* rather than lists, and the ``iter*`` and ``view*`` methods have + been removed. + + .. important:: + + Prefer using :func:`odoo.tools.pycompat.keys`, + :func:`odoo.tools.pycompat.values` and :func:`odoo.tools.pycompat.items` + return cross-version iterators. When needing actual lists (e.g. to + modify a dictionary during iteration), wrap one of the calls above in a + ``list()``. + builtins -------- @@ -258,21 +289,12 @@ code by replacing it with some other method altogether. ``xrange`` ########## -In Python 3, ``range()`` behaves the same as Python 3's ``xrange``. For -cross-versions code you can: - -* just use ``range()`` everywhere and ignore the allocation cost of a list in - Python 2 (often not an issue) -* conditionally alias ``xrange`` to ``range`` in Python 3 and use that -* use a combination of ``itertools.count`` and ``takewhile`` for a - cross-compatible lazy increasing sequence of numbers - -.. warning:: +In Python 3, ``range()`` behaves the same as Python 3's ``xrange``. - In the *rare* cases where you need conditional code (code which applies - for one version of python and not the other), use ``sys.version_info`` - e.g. ``sys.version_info() >= (3,)`` for Python3+ code or - ``sys.version_info() < (3,)`` for Python 2 code. +For cross-version code, you can just use ``range()`` everywhere: while this +will incur a slight allocation cost on Python 2, Python 3's ``range`` supports +the entire Sequence protocol and thus behaves very much like a regular +list or tuple. Removed/renamed methods ----------------------- |
