Python Extension Proposal
https://www.python.org/dev/peps/
xBeautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
xReadability counts.
Special cases aren't special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.
In the face of ambiguity, refuse the temptation to guess.
xThere should be one-- and preferably only one --obvious way to do it.
Although that way may not be obvious at first unless you're Dutch.
Now is better than never.
Although never is often better than *right* now.
xIf the implementation is hard to explain, it's a bad idea.
If the implementation is easy to explain, it may be a good idea.
Namespaces are one honking great idea-- let's do more of those!
Écrivons un peu de python dans un fichier code.py
.
xxxxxxxxxx
def MySum(x,x):
return x+y
print(MySum(1,2))
xxxxxxxxxx
$ python code.py
File "code.py", line 4
def MySum(x,x):
^
SyntaxError: duplicate argument 'x' in function definition
xxxxxxxxxx
Flake8: Your Tool For Style Guide Enforcement
xxxxxxxxxx
$ pip install flake8
xxxxxxxxxx
Simple Python style checker in one Python file
xxxxxxxxxx
A simple program which checks Python source files for errors
xxxxxxxxxx
Python code complexity micro-tool
xxxxxxxxxx
$ flake8 code.py
code.py:1:1: F831 duplicate argument 'x' in function definition
code.py:2:14: F821 undefined name 'y'
xxxxxxxxxx
def MySum(x,x):
return x+y
print(MySum(1,2))
xxxxxxxxxx
$ flake8 code.py
code.py:1:1: F831 duplicate argument 'x' in function definition
code.py:1:13: E231 missing whitespace after ','
code.py:2:14: F821 undefined name 'y'
code.py:3:1: E305 expected 2 blank lines after class or function definition, found 0
code.py:3:14: E231 missing whitespace after ','
xAs PEP 20 says, “Readability counts”.
A style guide is about consistency.
Consistency with this style guide is important.
Consistency within a project is more important.
Consistency within one module or function is the most important.
xxxxxxxxxx
However, know when to be inconsistent.
Sometimes style guide recommendations just aren't applicable.
When in doubt, use your best judgment.
Look at other examples and decide what looks best.
And don’t hesitate to ask!
Code layout
Comments
Naming Conventions
Overriding Principle
Descriptive: Naming Styles
Prescriptive: Naming Conventions
Public and internal interfaces
Programming Recommendations
xxxxxxxxxx
$ flake8 code.py
code.py:1:1: F831 duplicate argument 'x' in function definition
code.py:1:13: E231 missing whitespace after ','
code.py:2:14: F821 undefined name 'y'
code.py:3:1: E305 expected 2 blank lines after class
or function definition, found 0
code.py:3:14: E231 missing whitespace after ','
xxxxxxxxxx
def MySum(x,x):
return x+y
print(MySum(1,2))
xxxxxxxxxx
def MySum(x, y):
return x+y
print(MySum(1, 2))
xxxxxxxxxx
Extension for flake8 which uses pydocstyle to check docstrings
xxxxxxxxxx
A static analysis tool for checking compliance with Python docstring conventions.
Supports most of PEP 257 out of the box, but it should not be considered a reference implementation.
xxxxxxxxxx
The aim of this PEP is to standardize the high-level structure of docstrings:
what they should contain, and how to say it (without touching on any markup syntax within docstrings).
The PEP contains conventions, not laws or syntax.
A universal convention supplies all of maintainability, clarity,consistency, and a foundation for good programming habits too.What it doesn't do is insist that you follow it against your will.That's Python!"
—Tim Peters on comp.lang.python, 2001-06-16
xxxxxxxxxx
$ pip install flake8-docstrings
xxxxxxxxxx
$ flake8 code.py
code.py:1:1: D100 Missing docstring in public module
code.py:1:1: D103 Missing docstring in public function
xxxxxxxxxx
'a simple script to add two numbers'
def MySum(x, y):
'add x and y'
return x+y
print(MySum(1, 2))
xxxxxxxxxx
$ flake8 code.py
code.py:1:1: D300 Use """triple double quotes"""
code.py:1:1: D400 First line should end with a period
code.py:2:1: E302 expected 2 blank lines, found 0
code.py:2:1: D300 Use """triple double quotes"""
code.py:2:1: D400 First line should end with a period
code.py:2:1: D403 First word of the first line should be properly capitalized
xxxxxxxxxx
"""A simple script to add two numbers."""
def MySum(x, y):
"""We add x and y."""
return x+y
print(MySum(1, 2))
xxxxxxxxxx
Pylint is a tool that checks for errors in Python code, tries to enforce a coding standard and looks for code smells.
It can also look for certain type errors, it can recommend suggestions about how particular blocks can be refactored and can offer you details about the code's complexity.
xxxxxxxxxx
$ pip install pylint
xxxxxxxxxx
$ pylint code.py
No config file found, using default configuration
************* Module code
C: 4, 0: Function name "MySum" doesn't conform to snake_case naming style (invalid-name)
C: 4, 0: Argument name "x" doesn't conform to snake_case naming style (invalid-name)
C: 4, 0: Argument name "y" doesn't conform to snake_case naming style (invalid-name)
-------------------------------------------------------------
Your code has been rated at 0.00/10
xxxxxxxxxx
"""a simple script to add two numbers."""
def my_sum(first, second):
"""We add first and second."""
return first+second
print(my_sum(1, 2))
Parameter documentation checker
If you document the parameters of your functions, methods and constructors and their types systematically in your code this optional component might be useful for you. Sphinx style, Google style, and Numpy style are supported.
:param first: The first number to add :type first: int :param second: The second number to add :type second: int :returns: The result of the computation of first and second :rtype: int
Args: first (int): The first number to add second (int): The second number to add Returns: int: The result of the computation of first and second
Parameters ---------- first: int The first number to add second: int The second number to add Returns ------- int The result of the computation of first and second
xxxxxxxxxx
$ pylint --generate-rcfile > .pylintrc
x[MASTER]
load-plugins=pylint.extensions.docparams
[DESIGN]
accept-no-param-doc=no
xxxxxxxxxx
$ pylint code.py
Using config file .pylintrc
************* Module code
W: 4, 0: "first, second" missing in parameter documentation (missing-param-doc)
W: 4, 0: "first, second" missing in parameter type documentation (missing-type-doc)
--------------------------------------------------------------
Your code has been rated at 3.33/10
xxxxxxxxxx
"""a simple script to add two numbers."""
def my_sum(first, second):
"""We add first and second.
Parameters
----------
first: int
The first number to add
second: int
The second number to add
Returns
-------
int
The result of the computation of first and second
"""
return first+second
print(my_sum(1, 2))
xxxxxxxxxx
$ flake8 code.py
code.py:4:1: D413 Missing blank line after last section
xxxxxxxxxx
"""a simple script to add two numbers."""
def my_sum(first, second):
"""We add first and second.
Parameters
----------
first: int
The first number to add
second: int
The second number to add
Returns
-------
int
The result of the computation of first and second
"""
return first+second
print(my_sum(1, 2))
Pour
xxxxxxxxxx
def MySum(x,y):
return x+y
print(MySum(1,2))
A tool that automatically formats Python code to conform to the PEP 8 style guide.
It uses the pycodestyle utility to determine what parts of the code needs to be formatted. autopep8 is capable of fixing most of the formatting issues that can be reported by pycodestyle.
xxxxxxxxxx
$ pip install autopep8
xxxxxxxxxx
$ autopep8 code.py > code2.py
xxxxxxxxxx
def MySum(x, y):
return x+y
print(MySum(1, 2))
Yet another Python formatter
A formatter for Python files
The ultimate goal is that the code YAPF produces is as good as the code that a programmer would write if they were following the style guide.
xxxxxxxxxx
$ pip install yapf
xxxxxxxxxx
$ yapf code.py > code2.py
xxxxxxxxxx
def MySum(x, y):
return x + y
print(MySum(1, 2))
The uncompromising Python code formatter
xxxxxxxxxx
By using it, you agree to cede control over minutiae of hand-formatting.
In return, Black gives you speed, determinism, and freedom from pycodestyle nagging about formatting. You will save time and mental energy for more important matters.
xxxxxxxxxx
$ pip install black
xxxxxxxxxx
$ black code.py
reformatted code.py
All done! ✨ 🍰 ✨
1 file reformatted.
xxxxxxxxxx
def MySum(x, y):
return x + y
print(MySum(1, 2))
xxxxxxxxxx
l = [1,
2,
3,
]
xxxxxxxxxx
l = [1, 2, 3]
xxxxxxxxxx
TracebackException.from_exception(exc, limit, lookup_lines, capture_locals)
xxxxxxxxxx
TracebackException.from_exception(
exc, limit, lookup_lines, capture_locals
)
xxxxxxxxxx
def very_important_function(
template: str, *variables, file: os.PathLike, debug: bool = False):
"""Applies `variables` to the `template` and writes to `file`."""
with open(file, 'w') as f:
...
xxxxxxxxxx
def very_important_function(
template: str,
*variables,
file: os.PathLike,
debug: bool = False,
):
"""Applies `variables` to the `template` and writes to `file`."""
with open(file, "w") as f:
...
Rien.
Nada.
Que tchi.
xxxxxxxxxx
def MySum(x, y):
"""
Parameters
----------
x :
y :
Returns
-------
"""
return x + y
print(MySum(1, 2))
Sort your python imports for you so you don't have to.
xxxxxxxxxx
$ pip install isort
xxxxxxxxxx
from my_lib import Object
print("Hey")
import os
from my_lib import Object3
from my_lib import Object2
import sys
from third_party import lib15, lib1, lib2, lib3, lib4, lib5, lib6, lib7, lib8, lib9, lib10, lib11, lib12, lib13, lib14
import sys
from __future__ import absolute_import
from third_party import lib3
print("yo")
xxxxxxxxxx
from __future__ import absolute_import
import os
import sys
from third_party import (lib1, lib2, lib3, lib4, lib5, lib6, lib7, lib8,
lib9, lib10, lib11, lib12, lib13, lib14, lib15)
from my_lib import Object, Object2, Object3
print("Hey")
print("yo")
This PEP introduces a syntax for adding arbitrary metadata annotations to Python functions.
xxxxxxxxxx
def haul(item: Haulable, *vargs: PackAnimal) -> Distance:
...
xxxxxxxxxx
def compile(source: "something compilable",
filename: "where the compilable thing comes from",
mode: "is this a single statement or a suite?"):
...
[...]the community would benefit from a standard vocabulary and baseline tools within the standard library. This PEP introduces a provisional module to provide these standard definitions and tools, along with some conventions for situations where annotations are not available.
xxxxxxxxxx
def greeting(name: str) -> str:
return 'Hello ' + name
msg = greeting('John') # type: str
This PEP aims at adding syntax to Python for annotating the types of variables.
xxxxxxxxxx
msg: str = greeting('John')
Python will remain a dynamically typed language, and the authors have no desire to ever make type hints mandatory, even by convention.
Python restera un langage dynamiquement typé, et les auteurs n'ont aucun désir de obligatoires les indications de type, jamais, même par convention.
xxxxxxxxxx
def MySum(x: str, y: list) -> float:
return x + y
print(MySum(1, 2))
xxxxxxxxxx
$ python code.py
3
Optional Static Typing for Python
xxxxxxxxxx
Mypy is an experimental optional static type checker for Python that aims to combine the benefits of dynamic (or "duck") typing and static typing.
Mypy combines the expressive power and convenience of Python with a powerful type system and compile-time type checking.
xxxxxxxxxx
$ pip install mypy
xxxxxxxxxx
def MySum(x: str, y: list) -> float:
return x + y
print(MySum(1, 2))
xxxxxxxxxx
$ mypy code.py
code.py:2: error: Incompatible return value type (got "str", expected "float")
code.py:2: error: Unsupported operand types for + ("str" and "List[Any]")
code.py:5: error: Argument 1 to "MySum" has incompatible type "int"; expected "str"
code.py:5: error: Argument 2 to "MySum" has incompatible type "int"; expected "List[Any]"
xxxxxxxxxx
def MySum(x: int, y: int) -> int:
return x + y
print(MySum(1, "foo8"))
xxxxxxxxxx
$ mypy code.py
code.py:5: error: Argument 2 to "MySum" has incompatible type "str"; expected "int"
A performant type-checker for Python 3
We believe statically typing what are essentially fully dynamic languages gives our code stability and improves developer productivity.
xxxxxxxxxx
$ pip install pyre-check
xxxxxxxxxx
def MySum(x: str, y: list) -> float:
return x + y
print(MySum(1, 2))
xxxxxxxxxx
$ pyre check
ƛ Found 2 type errors!
code.py:2:4 Incompatible return type [7]: Expected `float` but got `str`.
code.py:2:19 Incompatible parameter type [6]: Expected `str` but got `typing.List[typing.Any]`.
Auto-generate PEP-484 annotations
A system for Python that generates static type annotations by collecting runtime types
xxxxxxxxxx
def MySum(x,x):
return x+y
print(MySum(1,2))
xxxxxxxxxx
"""a simple script to add two numbers."""
def my_sum(first, second):
"""We add first and second.
Parameters
----------
first: int
The first number to add
second: int
The second number to add
Returns
-------
int
The result of the computation of first and second
"""
return first+second
print(my_sum(1, 2)
Configuration éditeur / IDE
docstrings
analyse de code
ré-écriture automatique
Coder
Lancer les checks avant chaque commit (ou via commithook)
lint
tests
Si OK
push
pull/merge-request...
Revue de code
ENJOY. Adieu:
Vous et votre équipe me remercierez à la prochaine conf ;)
mixt: https://github.com/twidi/mixt/
Take back control of your Github issues, pull requests, and notifications
Les slides seront publiés sur https://twidi.github.io/