[ Web Proxy ]
URL:
Viewing: https://raw.githubusercontent.com/Julio-Assis/intermediatePython/patch-1/targeting_python_2_3.rst [Back]  [Original]

Targeting Python 2+3
--------------------

In a lot of cases you might want to develop programs which can be run in
both Python 2+ and 3+.

Just imagine that you have a very popular Python module which is used by
hundreds of people but not all of them have the same version of Python (2 or 3). In that case
you have two choices. The first one is to distribute 2 modules, one for
Python 2 and the other for Python 3. The other choice is to modify your
current code and make it compatible with both Python 2 and 3.

In this section I am going to highlight some of the tricks which you can
employ to make a script compatible with both of them.

**Future imports**

The first and most important method is to use ``__future__`` imports. It
allows you to import Python 3 functionality in Python 2. Here are a couple
examples:

Context managers were new in Python 2.6+. For using them in Python 2.5 you can use:

.. code:: python

    from __future__ import with_statement

``print`` was changed to a function in Python 3. If you want to use it
in Python 2 you can import it from ``__future__``:

.. code:: python

    print
    # Output:

    from __future__ import print_function
    print(print)
    # Output: 

**Dealing with module renaming**

First, tell me how you import packages in your script ? Most of us do
this :

.. code:: python

    import foo
    # or
    from foo import bar

Do you know that you can do something like this as well?

.. code:: python

    import foo as foo

I know its function is the same as the above listed code but it is vital
for making your script compatible with Python 2 and 3. Now examine the
code below :

.. code:: python

    try:
        import urllib.request as urllib_request  # for Python 3
    except ImportError:
        import urllib2 as urllib_request  # for Python 2

So let me explain the above code a little. We are wrapping our importing
code in a ``try/except`` clause. We are doing it because in Python 2 there is
no ``urllib.request`` module so this would result in an ``ImportError``. The
functionality of ``urllib.request`` is provided by the ``urllib2`` module in
Python 2. So, when using Python 2, we try to import ``urllib.request`` and
if we get an ``ImportError`` then we tell Python to import ``urllib2`` instead.

The final thing you need to know about is the ``as`` keyword. It is
mapping the imported module to ``urllib_request``. So that all of
the classes and methods within ``urllib2`` are available to us via the alias
``urllib_request``.

**Obsolete Python 2 builtins**

Another thing to keep in mind is that there are 12 Python 2 builtins
which have been removed from Python 3. Make sure that you don't use them
in Python 2 in order to make your code compatible with Python 3.
Here is a way to enforce that you abandon these 12 builtins in Python 2 as
well:

.. code:: python

    from future.builtins.disabled import *

Now whenever you try to use the modules which are abandoned in Python 3,
it raises a ``NameError`` like this:

.. code:: python

    from future.builtins.disabled import *

    apply()
    # Output: NameError: obsolete Python 2 builtin apply is disabled

**External standard-library backports**

There are a few packages in the wild which provide Python 3
functionality in Python 2. For instance, we have:

-  enum ``pip install enum34``
-  singledispatch ``pip install singledispatch``
-  pathlib ``pip install pathlib``

For further reading, the Python documentation has a `comprehensive guide
`_ of steps you need to
take to make your code compatible with both Python 2 and 3.

Web Proxy Viewer  |  New URL  |  Original Page