{ "cells": [ { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "# pep257 \n", "\n", "\n", "## a static linter for docstring conventions\n", "\n", " \n", "\n", "Amir Rachum \n", "PyWeb-IL 45" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true, "slideshow": { "slide_type": "slide" } }, "outputs": [], "source": [ "# kennethreitz/requests\n", "\n", "\"\"\"\n", "Determines appropriate setting for a given request, taking into account the\n", "explicit setting on that request, and the setting in the session. If a\n", "setting is a dictionary, they will be merged together using `dict_class`\n", "\"\"\"" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true, "slideshow": { "slide_type": "fragment" } }, "outputs": [], "source": [ "# cool-RR/python_toolbox\n", "\n", "'''\n", "Defines the `profile_ready` decorator.\n", "\n", "See its documentation for more details.\n", "'''" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true, "slideshow": { "slide_type": "fragment" } }, "outputs": [], "source": [ "# docopt/docopt\n", "\n", "\"\"\"Expand pattern into an (almost) equivalent one, but with single Either.\n", "\n", "Example: ((-a | -b) (-c | -d)) => (-a -c | -a -d | -b -c | -b -d)\n", "Quirks: [-a] => (-a), (-a...) => (-a -a)\n", "\n", "\"\"\"" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true, "slideshow": { "slide_type": "slide" } }, "outputs": [], "source": [ "# django/django\n", "\n", "\"\"\"\n", "Output the approximate number of changed/added strings in the en catalog.\n", "\"\"\"" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true, "slideshow": { "slide_type": "fragment" } }, "outputs": [], "source": [ "# kumar303/disable-docstring\n", "\n", " \"\"\"THIS IS FAIL\"\"\"" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## Who can say which convention is better?" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "fragment" } }, "source": [ "#Guido. Guido can." ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "#PEP257 Examples" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "fragment" } }, "source": [ "* One-liners should fit on one line." ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "fragment" } }, "source": [ "* All *public* modules, classes, methods and functions should be documented." ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "fragment" } }, "source": [ "* 1 blank line required after class docstring." ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "fragment" } }, "source": [ "* The first line of a method or function docstring should begin with an imperative verb." ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "fragment" } }, "source": [ "* And so forth..." ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "collapsed": false, "slideshow": { "slide_type": "slide" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "test.py:1 at module level:\r\n", " D100: Missing docstring in public module\r\n", "test.py:22 in public class `class_`:\r\n", " D101: Missing docstring in public class\r\n", "test.py:26 in private nested class `meta`:\r\n", " D101: Missing docstring in public class\r\n", "test.py:30 in public method `method`:\r\n", " D102: Missing docstring in public method\r\n", "test.py:37 in public method `__init__`:\r\n", " D102: Missing docstring in public method\r\n" ] } ], "source": [ "%%bash\n", "pep257 test.py 2>&1 >/dev/null | head" ] }, { "cell_type": "code", "execution_count": 8, "metadata": { "collapsed": false, "slideshow": { "slide_type": "slide" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "test.py:1 at module level:\r\n", " D100: Missing docstring in public module\r\n", "\r\n", " All modules should normally have docstrings. [...] all functions and\r\n", " classes exported by a module should also have docstrings. Public\r\n", " methods (including the __init__ constructor) should also have\r\n", " docstrings.\r\n", " Note: Public (exported) definitions are either those with names listed\r\n", " in __all__ variable (if present), or those that do not start\r\n", " with a single underscore.\r\n" ] } ], "source": [ "%%bash\n", "pep257 test.py --explain 2>&1 >/dev/null | head " ] }, { "cell_type": "code", "execution_count": 16, "metadata": { "collapsed": false, "slideshow": { "slide_type": "slide" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "test.py:54 in public function `asdlkfasd`:\r\n", " D200: One-line docstring should fit on one line with quotes (found 3)\r\n", "\r\n", " 54: def asdlkfasd():\r\n", " 55: \"\"\"\r\n", " 56: Wrong.\r\n", " 57: \"\"\"\r\n", "\r\n" ] } ], "source": [ "%%bash\n", "pep257 test.py --source --ignore=D100,D101,D102,D103 2>&1 >/dev/null | head -n8" ] }, { "cell_type": "code", "execution_count": 17, "metadata": { "collapsed": false, "scrolled": true, "slideshow": { "slide_type": "slide" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Usage: pep257 [options] [...]\r\n", "\r\n", "Options:\r\n", " --version show program's version number and exit\r\n", " -h, --help show this help message and exit\r\n", " -e, --explain show explanation of each error\r\n", " -s, --source show source for each error\r\n", " --ignore= ignore a list comma-separated error codes, for\r\n", " example: --ignore=D101,D202\r\n", " --match= check only files that exactly match regular\r\n", " expression; default is --match='(?!test_).*\\.py' which\r\n", " matches files that don't start with 'test_' but end\r\n", " with '.py'\r\n", " --match-dir=\r\n", " search only dirs that exactly match regular\r\n", " expression; default is --match-dir='[^\\.].*', which\r\n", " matches all dirs that don't start with a dot\r\n", " -d, --debug print debug information\r\n", " -v, --verbose print status information\r\n", " --count print total number of errors to stdout\r\n" ] } ], "source": [ "%%bash\n", "pep257 --help" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "# What Else?" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "fragment" } }, "source": [ "* Static analysis - it does not import your code (safe from side effects)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "fragment" } }, "source": [ "* No dependencies (for now). Install via `pip install pep257`." ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "fragment" } }, "source": [ "* Integrates with `flake8` via `flake8-docstrings`." ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "fragment" } }, "source": [ "* Coming up: better error selection, to support several \"convention sets\", such as pep257, numpy, _your own_." ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "fragment" } }, "source": [ "* Authored by Vladimir Keleshev (of `docopt` notoriety)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "fragment" } }, "source": [ "* I am currently the sole maintainer" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "In conclusion:\n", "\n", "#Conventions are arbitrary," ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "fragment" } }, "source": [ "#so use this one." ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "### Thanks for listening\n", "\n", "## `https://github.com/GreenSteam/pep257`\n", "\n", "\n", "Amir Rachum \n", "amir@rachum.com" ] } ], "metadata": { "celltoolbar": "Slideshow", "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.4.3" } }, "nbformat": 4, "nbformat_minor": 0 }