diff -r 223c8125853a pep-0008.txt --- a/pep-0008.txt Tue Jul 30 20:01:06 2013 +0200 +++ b/pep-0008.txt Thu Aug 01 22:16:51 2013 +1000 @@ -3,12 +3,13 @@ Version: $Revision$ Last-Modified: $Date$ Author: Guido van Rossum , - Barry Warsaw + Barry Warsaw , + Nick Coghlan Status: Active Type: Process Content-Type: text/x-rst Created: 05-Jul-2001 -Post-History: 05-Jul-2001 +Post-History: 05-Jul-2001, 01-Aug-2013 Introduction @@ -23,6 +24,10 @@ Guido's original Python Style Guide essay, with some additions from Barry's style guide [2]_. +This style guide evolves over time as additional conventions are +identified and past conventions are rendered obsolete by changes in +the language itself. + A Foolish Consistency is the Hobgoblin of Little Minds ====================================================== @@ -41,15 +46,24 @@ judgment. Look at other examples and decide what looks best. And don't hesitate to ask! -Two good reasons to break a particular rule: +In particular: do not break backwards compatibility just to comply with +this PEP! -1. When applying the rule would make the code less readable, even for - someone who is used to reading code that follows the rules. +Some other good reasons to ignore a particular guideline: + +1. When applying the guideline would make the code less readable, even + for someone who is used to reading code that follows this PEP. 2. To be consistent with surrounding code that also breaks it (maybe for historic reasons) -- although this is also an opportunity to clean up someone else's mess (in true XP style). +3. Because the code in question predates the introduction of the + guideline and there is no other reason to be modifying that code. + +4. When the code needs to remain compatible with older versions of + Python that don't support the feature recommended by the style guide. + Code lay-out ============ @@ -59,9 +73,6 @@ Use 4 spaces per indentation level. -For really old code that you don't want to mess up, you can continue -to use 8-space tabs. - Continuation lines should align wrapped elements either vertically using Python's implicit line joining inside parentheses, brackets and braces, or using a hanging indent. When using a hanging indent the @@ -129,31 +140,41 @@ Tabs or Spaces? --------------- -Never mix tabs and spaces. +Spaces are the preferred indentation method. -The most popular way of indenting Python is with spaces only. The -second-most popular way is with tabs only. Code indented with a -mixture of tabs and spaces should be converted to using spaces -exclusively. When invoking the Python command line interpreter with +Tabs should be used solely to remain consistent with code that is +already indented with tabs. + +Python 3 disallows mixing the use of tabs and spaces for indentation. + +Python 2 code indented with a mixture of tabs and spaces should be +converted to using spaces exclusively. + +When invoking the Python 2 command line interpreter with the ``-t`` option, it issues warnings about code that illegally mixes tabs and spaces. When using ``-tt`` these warnings become errors. These options are highly recommended! -For new projects, spaces-only are strongly recommended over tabs. -Most editors have features that make this easy to do. Maximum Line Length ------------------- -Limit all lines to a maximum of 79 characters. +Aim to limit all lines to a maximum of 79 characters, but up to 99 +characters is acceptable when it improves readability. -There are still many devices around that are limited to 80 character -lines; plus, limiting windows to 80 characters makes it possible to -have several windows side-by-side. The default wrapping on such -devices disrupts the visual structure of the code, making it more -difficult to understand. Therefore, please limit all lines to a -maximum of 79 characters. For flowing long blocks of text (docstrings -or comments), limiting the length to 72 characters is recommended. +For flowing long blocks of text with fewer structural restrictions +(docstrings or comments), limiting the line length to 72 characters +is recommended. + +Limiting the required editor window width makes it possible to have +several files open side-by-side, and works well when using code +review tools that present the two versions in adjacent columns. + +The default wrapping in most tools disrupts the visual structure of the +code, making it more difficult to understand. The limits are chosen to +avoid wrapping in editors with the window width set to 80 (or 100), even +if the tool places a marker glyph in the final column when wrapping +lines. Some web based tools may not offer dynamic line wrapping at all. The preferred way of wrapping long lines is by using Python's implied line continuation inside parentheses, brackets and braces. Long lines @@ -214,15 +235,17 @@ Encodings (PEP 263) ------------------- -Code in the core Python distribution should always use the ASCII or -Latin-1 encoding (a.k.a. ISO-8859-1). For Python 3.0 and beyond, -UTF-8 is preferred over Latin-1, see PEP 3120. +Code in the core Python distribution should always use UTF-8 (or ASCII +in Python 2). -Files using ASCII should not have a coding cookie. Latin-1 (or UTF-8) -should only be used when a comment or docstring needs to mention an -author name that requires Latin-1; otherwise, using ``\x``, ``\u`` or -``\U`` escapes is the preferred way to include non-ASCII data in -string literals. +Files using ASCII (in Python 2) or UTF-8 (in Python 3) should not have a +coding cookie. + +In the standard library, non-default encodings should be used only for +test purposes or when a comment or docstring needs to mention an author +name that that contains non-ASCII characters; otherwise, using ``\x``, +``\u``, ``\U``, or ``\N`` escapes is the preferred way to include +non-ASCII data in string literals. For Python 3.0 and beyond, the following policy is prescribed for the standard library (see PEP 3131): All identifiers in the Python @@ -266,11 +289,27 @@ Put any relevant ``__all__`` specification after the imports. -- Relative imports for intra-package imports are highly discouraged. - Always use the absolute package path for all imports. Even now that - PEP 328 is fully implemented in Python 2.5, its style of explicit - relative imports is actively discouraged; absolute imports are more - portable and usually more readable. +- Absolute imports are recommended, as they are usually more readable + and tend to be better behaved (or at least give better error + messages) if the import system is incorrectly configured (such as + when a directory inside a package ends up on ``sys.path``):: + + import mypkg.sibling + from mypkg import sibling + from mypkg.sibling import example + + However, explicit relative imports are an acceptable alternative to + absolute imports, especially when dealing with complex package layouts + where using absolute imports would be unecessarily verbose:: + + from . import sibling + from .sibling import example + + Standard library code should avoid complex package layouts and always + use absolute imports. + + Implicit relative imports should *never* be used and have been removed + in Python 3. - When importing a class from a class-containing module, it's usually okay to spell this:: @@ -285,6 +324,18 @@ and use "myclass.MyClass" and "foo.bar.yourclass.YourClass". +- Wildcard imports (``from import *``) should be avoided, as + they make it unclear which names are present in the namespace, + confusing both readers and many automated tools. There is one + defensible use case for a wildcard import, which is to republish an + internal interface as part of a public API (for example, overwriting + a pure Python implementation of an interface with the definitions + from an optional accelerator module and exactly which definitions + will be overwritten isn't known in advance). + + When republishing names this way, the guidelines below regarding + public and internal interfaces still apply. + Whitespace in Expressions and Statements ======================================== @@ -760,6 +811,36 @@ advanced callers. +Public and internal interfaces +------------------------------ + +Any backwards compatibility guarantees apply only to public interfaces. +Accordingly, it is important that users be able to clearly distinguish +between public and internal interfaces. + +Documented interfaces are considered public, unless the documentation +explicitly declares them to be provisional or internal interfaces exempt +from the usual backwards compatibility guarantees. All undocumented +interfaces should be assumed to be internal. + +To better support introspection, modules should explicitly declare the +names in their public API using the ``__all__`` attribute. Setting +``__all__`` to an empty list indicates that the module has no public API. + +Even with ``__all__`` set appropriately, internal interfaces (packages, +modules, classes, functions, attributes or other names) should still be +prefixed with a single leading underscore. + +An interface is also considered internal if any containing namespace +(package, module or class) is considered internal. + +Imported names should always be considered an implementation detail. +Other modules must not rely on indirect access to such imported names +unless they are an explicitly documented part of the containing module's +API, such as ``os.path`` or a package's ``__init__`` module that exposes +functionality from submodules. + + Programming Recommendations =========================== @@ -769,10 +850,12 @@ For example, do not rely on CPython's efficient implementation of in-place string concatenation for statements in the form ``a += b`` - or ``a = a + b``. Those statements run more slowly in Jython. In - performance sensitive parts of the library, the ``''.join()`` form - should be used instead. This will ensure that concatenation occurs - in linear time across various implementations. + or ``a = a + b``. This optimization is fragile even in CPython (it + only works for some types) and isn't present at all in implementations + that don't use refcounting. In performance sensitive parts of the + library, the ``''.join()`` form should be used instead. This will + ensure that concatenation occurs in linear time across various + implementations. - Comparisons to singletons like None should always be done with ``is`` or ``is not``, never the equality operators. @@ -799,29 +882,59 @@ operator. However, it is best to implement all six operations so that confusion doesn't arise in other contexts. -- Use class-based exceptions. +- Always use a def statement instead of assigning a lambda expression + to a name. - String exceptions in new code are forbidden, and this language - feature has been removed in Python 2.6. + Yes:: - Modules or packages should define their own domain-specific base - exception class, which should be subclassed from the built-in - Exception class. Always include a class docstring. E.g.:: + def f(x): return 2*x - class MessageError(Exception): - """Base class for errors in the email package.""" + No:: + + f = lambda x: 2*x + + The first form means that the name of the resulting function object is + specifically 'f' instead of the generic ''. This is more + useful for tracebacks and string representations in general. The use + of the assignment statement eliminates the sole benefit a lambda + expression can offer over an explicit def statement (i.e. that it can + be embedded inside a larger expression) + +- Derive exceptions from ``Exception`` rather than ``BaseException``. + Direct inheritance from ``BaseException`` is reserved for exceptions + where catching them is almost always the wrong thing to do. + + Design exception hierarchies based on the distinctions that code + *catching* the exceptions is likely to need, rather than the locations + where the exceptions are raised. Aim to answer the question + "What went wrong?" programmatically, rather than only stating that + "A problem occurred" (see PEP 3151 for an example of this lesson being + learned for the builtin exception hierarchy) Class naming conventions apply here, although you should add the - suffix "Error" to your exception classes, if the exception is an - error. Non-error exceptions need no special suffix. + suffix "Error" to your exception classes if the exception is an + error. Non-error exceptions that are used for non-local flow control + or other forms of signalling need no special suffix. -- When raising an exception, use ``raise ValueError('message')`` +- Use exception chaining appropriately. In Python 3, "raise X from Y" + should be used to indicate explicit replacement without losing the + original traceback. + + When deliberately replacing an inner exception (using "raise X" in + Python 2 or "raise X from None" in Python 3.3+), ensure that relevant + details are transferred to the new exception (such as preserving the + attribute name when converting KeyError to AttributeError, or + embedding the text of the original exception in the new exception + message). + +- When raising an exception in Python 2, use ``raise ValueError('message')`` instead of the older form ``raise ValueError, 'message'``. - The paren-using form is preferred because when the exception - arguments are long or include string formatting, you don't need to - use line continuation characters thanks to the containing - parentheses. The older form is not legal syntax in Python 3. + The latter form is not legal Python 3 syntax. + + The paren-using form also means that when the exception arguments are + long or include string formatting, you don't need to use line + continuation characters thanks to the containing parentheses. - When catching exceptions, mention specific exceptions whenever possible instead of using a bare ``except:`` clause. @@ -851,6 +964,21 @@ exception propagate upwards with ``raise``. ``try...finally`` can be a better way to handle this case. +- When binding caught exceptions to a name, prefer the explicit name + binding syntax added in Python 2.6:: + + try: + process_data() + except Exception as exc: + raise DataProcessingFailedError(str(exc)) + + This is the only syntax supported in Python 3, and avoids the + ambiguity problems associated with the older comma-based syntax. + +- When catching operating system errors, prefer the explicit exception + hierarchy introduced in Python 3.3 over introspection of ``errno`` + values. + - Additionally, for all try/except clauses, limit the ``try`` clause to the absolute minimum amount of code necessary. Again, this avoids masking bugs. @@ -873,6 +1001,10 @@ # Will also catch KeyError raised by handle_value() return key_not_found(key) +- When a resource is local to a particular section of code, use a + ``with`` statement to ensure it is cleaned up promptly and reliably + after use. A try/finally statement is also acceptable. + - Context managers should be invoked through separate functions or methods whenever they do something other than acquire and release resources. For example: @@ -907,9 +1039,6 @@ Yes: if foo.startswith('bar'): No: if foo[:3] == 'bar': - The exception is if your code must work with Python 1.5.2 (but let's - hope not!). - - Object type comparisons should always use isinstance() instead of comparing types directly. :: @@ -918,11 +1047,15 @@ No: if type(obj) is type(1): When checking if an object is a string, keep in mind that it might - be a unicode string too! In Python 2.3, str and unicode have a + be a unicode string too! In Python 2, str and unicode have a common base class, basestring, so you can do:: if isinstance(obj, basestring): + Note that in Python 3, ``unicode`` and ``basestring`` no longer exist + (there is only ``str``) and a bytes object is no longer a kind of + string (it is a sequence of integers instead) + - For sequences, (strings, lists, tuples), use the fact that empty sequences are false. :: @@ -947,6 +1080,10 @@ annotation style. Instead, the annotations are left for users to discover and experiment with useful annotation styles. + It is recommended that third party experimants with annotations use an + associated decorator to indicate how the annotation should be + interpreted. + Early core developer attempts to use function annotations revealed inconsistent, ad-hoc annotation styles. For example: @@ -1004,6 +1141,8 @@ .. [3] http://www.wikipedia.com/wiki/CamelCase +.. [4] PEP 8 modernisation, July 2013 + http://bugs.python.org/issue18472 Copyright =========