Skip to content

Commit

Permalink
Add more words, esp. on imports
Browse files Browse the repository at this point in the history
  • Loading branch information
encukou committed Mar 30, 2016
1 parent 3fe735d commit 3cce778
Show file tree
Hide file tree
Showing 2 changed files with 102 additions and 2 deletions.
18 changes: 17 additions & 1 deletion source/exceptions.rst
Original file line number Diff line number Diff line change
@@ -1,7 +1,21 @@
Exceptions
----------

XXX
Very early Python versions used simple strings to signalize errors.
Later, Python allowed raising arbitrary classes, and added specialized
exception classes to the standard library.
For backwards compatibility reasons, some deprecated practices were still
allowed in Python 2.
This presents confusion to learners of the language, and prevents some
performance optimizations.

Python 3 consolidates the exception model.
Exceptions are now instances of dedicated classes.
They contain all information about the error: the type, value and traceback.

This chapter mentions all exception-related changes needed to start
supportingPython 3.


.. _except-syntax:

Expand Down Expand Up @@ -146,6 +160,8 @@ Raising Non-Exceptions

In Python 3, an object used with ``raise`` must be an instance of
:py:class:`BaseException`, while Python 2 also allowed old-style classes.
Similarly, Python 3 bans catching non-exception classes in the ``except``
statement.

.. todo:: Link "old-style classes" to their section

Expand Down
86 changes: 85 additions & 1 deletion source/imports.rst
Original file line number Diff line number Diff line change
@@ -1,10 +1,94 @@
Importing
---------

XXX
Python 3 brings a complete overhaul of the way ``import`` works,
but developer-visible changes


Absolute imports
~~~~~~~~~~~~~~~~

* :ref:`Fixer <python-modernize>`: ``python-modernize -wnf lib2to3.fixes.fix_import`` (See caveat below)
* Prevalence: Common
* Future import: ``from __future__ import absolute_imports``
* Specification: `PEP 328 <https://www.python.org/dev/peps/pep-0328/>`_

Under Python 2, when importing from inside a package, the package's own modules
were considered before global ones.
For example, given a package like this::

mypkg/
__init__.py
collections.py
core.py
...

If ``core.py`` contains::

from collections import deque

it would import the ``deque`` from ``collections.py``.
The standard library's ``collections`` module would be unavailable.

In Python 2.5, the situation began changing with the introduction of explicit
relative imports, using a dot (``.``) before the submodule name.
Given the structure above, these statements would be equivalent
(in ``core.py``)::

from .collections import deque
from mypkg.collections import deque

Additionally, a *future import* was added to make all imports absolute
(unless explicitly relative)::

from __future__ import absolute_imports

Using this feature, ``from collections import deque`` will import from
the standard library's ``collections`` module.

.. todo:: Link future import

In Python 3, the feature becomes the default.

To prepare for this, make sure all imports are either absolute, or *explicitly*
relative.
Both the ``mypkg.collections`` stlye and the ``.collections`` style are
adequate; we recommend the former for increased readibility [#f1]_.

The recommended fixer simply adds the future import to all files that
do a potentially ambiguous import.
This may be too much churn for your project; in most cases it is enough to
verify that your imports are not ambiguous.


``import *`` in Functions
~~~~~~~~~~~~~~~~~~~~~~~~~

In Python 3, “star imports” are only allowed on the module level, not in
classes or functions.
For example, this won't work::

def coords(angle, distance):
from math import *
return distance * cos(angle), distance * sin(angle)

The reason for this limitation is that a function's local variables are
optimized at compile time, but the names imported via ``*`` are not known
in advance.
Python 2 reverted to using unoptimized bytecode for such functions;
Python 3 includes only the optimized case.

This code raised a :py:func:`SyntaxWarning` already in Python 2.6.

XXX

Import Cycles
~~~~~~~~~~~~~


.. rubric:: Footnotes

.. [#f1] The downside of spelling out the package name is that it becomes
harder to rename or reorganize the package.
In practice, the added work tends to be insignificant compared to updating
all external modules that import your package.

0 comments on commit 3cce778

Please sign in to comment.