summaryrefslogtreecommitdiff
path: root/doc
diff options
context:
space:
mode:
authorxmo-odoo <xmo@odoo.com>2017-05-10 09:39:55 +0200
committerGitHub <noreply@github.com>2017-05-10 09:39:55 +0200
commitfffaf735f58f1ac57781c095eb552de6d1fcdc47 (patch)
tree88ab0ab65430d871862a836524e0ecc890d1674d /doc
parent10eee18a047d35305dc46282e610e88936d81ffc (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.py6
-rw-r--r--doc/python3.rst50
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
-----------------------