##// END OF EJS Templates
Move widget shim into its own file
Move widget shim into its own file

File last commit:

r21253:ff3b995a
r21281:389f8c49
Show More
pycompat.rst
233 lines | 7.3 KiB | text/x-rst | RstLexer
Thomas Kluyver
Document single codebase Python 3 compatibility
r13388 Writing code for Python 2 and 3
===============================
Thomas Kluyver
Manually document py3compat module....
r14087 .. module:: IPython.utils.py3compat
:synopsis: Python 2 & 3 compatibility helpers
.. data:: PY3
Boolean indicating whether we're currently in Python 3.
Thomas Kluyver
Document single codebase Python 3 compatibility
r13388 Iterators
---------
Many built in functions and methods in Python 2 come in pairs, one
returning a list, and one returning an iterator (e.g. :func:`range` and
Thomas Kluyver
Manually document py3compat module....
r14087 :func:`python:xrange`). In Python 3, there is usually only the iterator form,
Thomas Kluyver
Document single codebase Python 3 compatibility
r13388 but it has the name which gives a list in Python 2 (e.g. :func:`range`).
The way to write compatible code depends on what you need:
* A list, e.g. for serialisation, or to test if something is in it.
* Iteration, but it will never be used for very many items, so efficiency
isn't especially important.
* Iteration over many items, where efficiency is important.
================ ================= =======================
list iteration (small) iteration(large)
================ ================= =======================
list(range(n)) range(n) py3compat.xrange(n)
list(map(f, it)) map(f, it) --
list(zip(a, b)) zip(a, b) --
list(d.items()) d.items() py3compat.iteritems(d)
list(d.values()) d.values() py3compat.itervalues(d)
================ ================= =======================
Iterating over a dictionary yields its keys, so there is rarely a need
to use :meth:`dict.keys` or :meth:`dict.iterkeys`.
Avoid using :func:`map` to cause function side effects. This is more
clearly written with a simple for loop.
Thomas Kluyver
Manually document py3compat module....
r14087 .. data:: xrange
A reference to ``range`` on Python 3, and :func:`python:xrange` on Python 2.
.. function:: iteritems(d)
itervalues(d)
Iterate over (key, value) pairs of a dictionary, or just over values.
``iterkeys`` is not defined: iterating over the dictionary yields its keys.
Thomas Kluyver
Document single codebase Python 3 compatibility
r13388 Changed standard library locations
----------------------------------
Several parts of the standard library have been renamed and moved. This
is a short list of things that we're using. A couple of them have names
in :mod:`IPython.utils.py3compat`, so you don't need both
imports in each module that uses them.
================== ============ ===========
Python 2 Python 3 py3compat
================== ============ ===========
:func:`raw_input` input input
:mod:`__builtin__` builtins builtin_mod
:mod:`StringIO` io
:mod:`Queue` queue
:mod:`cPickle` pickle
:mod:`thread` _thread
:mod:`copy_reg` copyreg
:mod:`urlparse` urllib.parse
:mod:`repr` reprlib
:mod:`Tkinter` tkinter
:mod:`Cookie` http.cookie
:mod:`_winreg` winreg
================== ============ ===========
Be careful with StringIO: :class:`io.StringIO` is available in Python 2.7,
but it behaves differently from :class:`StringIO.StringIO`, and much of
our code assumes the use of the latter on Python 2. So a try/except on
the import may cause problems.
Thomas Kluyver
Manually document py3compat module....
r14087 .. function:: input
Behaves like :func:`python:raw_input` on Python 2.
.. data:: builtin_mod
builtin_mod_name
A reference to the module containing builtins, and its name as a string.
Thomas Kluyver
Document single codebase Python 3 compatibility
r13388 Unicode
-------
Always be explicit about what is text (unicode) and what is bytes.
*Encoding* goes from unicode to bytes, and *decoding* goes from bytes
to unicode.
To open files for reading or writing text, use :func:`io.open`, which is
the Python 3 builtin ``open`` function, available on Python 2 as well.
We almost always need to specify the encoding parameter, because the
default is platform dependent.
Thomas Kluyver
Manually document py3compat module....
r14087 We have several helper functions for converting between string types. They all
use the encoding from :func:`IPython.utils.encoding.getdefaultencoding` by default,
and the ``errors='replace'`` option to do best-effort conversions for the user's
system.
.. function:: unicode_to_str(u, encoding=None)
str_to_unicode(s, encoding=None)
Convert between unicode and the native str type. No-ops on Python 3.
.. function:: str_to_bytes(s, encoding=None)
bytes_to_str(u, encoding=None)
Convert between bytes and the native str type. No-ops on Python 2.
.. function:: cast_unicode(s, encoding=None)
cast_bytes(s, encoding=None)
Convert strings to unicode/bytes when they may be of either type.
.. function:: cast_unicode_py2(s, encoding=None)
cast_bytes_py2(s, encoding=None)
Convert strings to unicode/bytes when they may be of either type on Python 2,
but return them unaltered on Python 3 (where string types are more
predictable).
.. data:: unicode_type
A reference to ``str`` on Python 3, and to ``unicode`` on Python 2.
.. data:: string_types
A tuple for isinstance checks: ``(str,)`` on Python 3, ``(str, unicode)`` on
Python 2.
Thomas Kluyver
Document single codebase Python 3 compatibility
r13388 Relative imports
----------------
::
# This makes Python 2 behave like Python 3:
from __future__ import absolute_import
import io # Imports the standard library io module
from . import io # Import the io module from the package
# containing the current module
from .io import foo # foo from the io module next to this module
from IPython.utils import io # This still works
Print function
--------------
::
# Support the print function on Python 2:
from __future__ import print_function
print(a, b)
print(foo, file=sys.stderr)
print(bar, baz, sep='\t', end='')
Metaclasses
-----------
The syntax for declaring a class with a metaclass is different in
Thomas Kluyver
Manually document py3compat module....
r14087 Python 2 and 3. A helper function works for most cases:
Thomas Kluyver
Document single codebase Python 3 compatibility
r13388
Thomas Kluyver
Manually document py3compat module....
r14087 .. function:: with_metaclass
Create a base class with a metaclass. Copied from the six library.
Used like this::
class FormatterABC(with_metaclass(abc.ABCMeta, object)):
...
Thomas Kluyver
Document single codebase Python 3 compatibility
r13388
Combining inheritance between Qt and the traitlets system, however, does
not work with this. Instead, we do this::
class QtKernelClientMixin(MetaQObjectHasTraits('NewBase', (HasTraits, SuperQObject), {})):
...
This gives the new class a metaclass of :class:`~IPython.qt.util.MetaQObjectHasTraits`,
Min RK
update dependency imports...
r21253 and the parent classes :class:`~traitlets.HasTraits` and
Thomas Kluyver
Document single codebase Python 3 compatibility
r13388 :class:`~IPython.qt.util.SuperQObject`.
Thomas Kluyver
Manually document py3compat module....
r14087
Doctests
--------
.. function:: doctest_refactor_print(func_or_str)
Refactors print statements in doctests in Python 3 only. Accepts a string
or a function, so it can be used as a decorator.
.. function:: u_format(func_or_str)
Handle doctests written with ``{u}'abcþ'``, replacing the ``{u}`` with ``u``
for Python 2, and removing it for Python 3.
Accepts a string or a function, so it can be used as a decorator.
Execfile
--------
.. function:: execfile(fname, glob, loc=None)
Equivalent to the Python 2 :func:`python:execfile` builtin. We redefine it in
Python 2 to better handle non-ascii filenames.
Miscellaneous
-------------
.. autofunction:: safe_unicode
.. function:: isidentifier(s, dotted=False)
Checks whether the string s is a valid identifier in this version of Python.
In Python 3, non-ascii characters are allowed. If ``dotted`` is True, it
allows dots (i.e. attribute access) in the string.
.. function:: getcwd()
Return the current working directory as unicode, like :func:`os.getcwdu` on
Python 2.
.. function:: MethodType
Constructor for :class:`types.MethodType` that takes two arguments, like
the real constructor on Python 3.