From 8ef9d11bc40721e422b315258c7460776644a9bb Mon Sep 17 00:00:00 2001 From: Oliver Urs Lenz Date: Thu, 21 Jun 2018 15:03:00 +0200 Subject: [PATCH] Clarify contribution guidelines --- CONTRIBUTING.rst | 12 +++-- docs/contribute.rst | 107 +++++++++++++++++++++++--------------------- 2 files changed, 65 insertions(+), 54 deletions(-) diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst index 27002bdd..26ae338a 100644 --- a/CONTRIBUTING.rst +++ b/CONTRIBUTING.rst @@ -114,15 +114,21 @@ Using Git and GitHub `install hub `_ and then run `hub pull-request `_ to turn your GitHub issue into a pull request containing your code. +* After you have issued a pull request, Travis will run the test suite for all + supported Python versions and check for PEP8 compliance. If any of these + checks fail, you should fix them. (If tests fail on Travis but seem to pass + locally, ensure that local test runs aren't skipping any tests.) Contribution quality standards ------------------------------ -* Adhere to `PEP8 coding standards`_ whenever possible. This can be eased via - the `pep8 `_ or `flake8 +* Adhere to `PEP8 coding standards`_. This can be eased via the `pycodestyle + `_ or `flake8 `_ tools, the latter of which in particular will give you some useful hints about ways in which the - code/formatting can be improved. + code/formatting can be improved. If you are relying on your editor for PEP8 + compliance, note that the line length specified by PEP8 is 79 (excluding the + line break). * Ensure your code is compatible with the latest Python 2.7 and 3.x releases — see our `compatibility cheatsheet`_ for more details. * Add docs and tests for your changes. Undocumented and untested features will diff --git a/docs/contribute.rst b/docs/contribute.rst index be5325a0..cbaa8ab9 100644 --- a/docs/contribute.rst +++ b/docs/contribute.rst @@ -14,32 +14,32 @@ When doing so, please adhere to the following guidelines. Setting up the development environment ====================================== -While there are many ways to set up one's development environment, following -is a method that uses `virtualenv `_. +While there are many ways to set up one's development environment, we recommend +using `Virtualenv `_. This tool allows +you to set up separate environments for separate Python projects that are +isolated from one another so you can use different packages (and package +versions) for each. + If you don't have ``virtualenv`` installed, you can install it via:: $ pip install virtualenv -Virtual environments allow you to work on Python projects which are isolated -from one another so you can use different packages (and package versions) with -different projects. - -To create and activate a virtual environment, use the following syntax:: +Use ``virtualenv`` to create and activate a virtual environment:: $ virtualenv ~/virtualenvs/pelican $ cd ~/virtualenvs/pelican $ . bin/activate -To clone the Pelican source:: +Clone the Pelican source into a subfolder called ``src/pelican``:: $ git clone https://github.com/getpelican/pelican.git src/pelican - -To install the development dependencies:: - $ cd src/pelican + +Install the development dependencies:: + $ pip install -r requirements/developer.pip -To install Pelican and its dependencies:: +Install Pelican and its dependencies:: $ python setup.py develop @@ -47,7 +47,8 @@ Or using ``pip``:: $ pip install -e . -To conveniently test on multiple Python versions, we also provide a .tox file. +To conveniently test on multiple Python versions, we also provide a ``.tox`` +file. Building the docs @@ -57,7 +58,7 @@ If you make changes to the documentation, you should preview your changes before committing them:: $ pip install -r requirements/docs.pip - $ cd src/pelican/docs + $ cd docs $ make html Open ``_build/html/index.html`` in your browser to preview the documentation. @@ -89,56 +90,60 @@ functional tests. To do so, **make sure you have both ``en_EN.utf8`` and $ LC_ALL=en_US.utf8 pelican -o pelican/tests/output/basic/ \ samples/content/ -Testing on Python 2 and 3 -------------------------- +You may also find that some tests are skipped because some dependency (e.g., +Pandoc) is not installed. This does not automatically mean that these tests +have passed; you should at least verify that any skipped tests are not +affected by your changes. -Testing on Python 3 currently requires some extra steps: installing -Python 3-compatible versions of dependent packages and plugins. +You should run the test suite under each of the supported versions of Python. +This is best done by creating a separate Python environment for each version. +Tox_ is a useful tool to automate running tests inside ``virtualenv`` +environments. -Tox_ is a useful tool to run tests on both versions. It will install the -Python 3-compatible version of dependent packages. +.. _Tox: https://tox.readthedocs.io/en/latest/ -.. _Tox: http://testrun.org/tox/latest/ +Python 2/3 compatibility development tips +========================================= -Python 3 development tips -========================= +Here are some tips that may be useful for writing code that is compatible with +both Python 2.7 and Python 3: -Here are some tips that may be useful when doing some code for both Python 2.7 -and Python 3 at the same time: +- Use new syntax. For example: -- Assume every string and literal is unicode (import unicode_literals): + - ``print .. -> print(..)`` + - ``except .., e -> except .. as e`` - - Do not use prefix ``u'``. - - Do not encode/decode strings in the middle of sth. Follow the code to the - source (or target) of a string and encode/decode at the first/last possible - point. - - In other words, write your functions to expect and to return unicode. - - Encode/decode strings if e.g. the source is a Python function that is known - to handle this badly, e.g. strftime() in Python 2. +- Use new methods. For example: -- Use new syntax: print function, "except ... *as* e" (not comma), etc. -- Refactor method calls like ``dict.iteritems()``, ``xrange()``, etc. in a way - that runs without code change in both Python versions. -- Do not use magic method ``__unicode()__`` in new classes. Use only ``__str()__`` - and decorate the class with ``@python_2_unicode_compatible``. -- Do not start int literals with a zero. This is a syntax error in Py3k. -- Unfortunately I did not find an octal notation that is valid in both - Pythons. Use decimal instead. -- use six, e.g.: + - ``dict.iteritems() -> dict.items()`` + - ``xrange(..) - > list(range(..))`` + +- Use ``six`` where necessary. For example: - ``isinstance(.., basestring) -> isinstance(.., six.string_types)`` - ``isinstance(.., unicode) -> isinstance(.., six.text_type)`` -- ``setlocale()`` in Python 2 bails when we give the locale name as unicode, +- Assume every string and literal is Unicode: + + - Use ``from __future__ import unicode_literals`` + - Do not use the prefix ``u'`` before strings. + - Do not encode/decode strings in the middle of something. Follow the code to + the source/target of a string and encode/decode at the first/last possible + point. + - In particular, write your functions to expect and to return Unicode. + - Encode/decode strings if the string is the output of a Python function that + is known to handle this badly. For example, ``strftime()`` in Python 2. + - Do not use the magic method ``__unicode()__`` in new classes. Use only + ``__str()__`` and decorate the class with ``@python_2_unicode_compatible``. + +- ``setlocale()`` in Python 2 fails when we give the locale name as Unicode, and since we are using ``from __future__ import unicode_literals``, we do - that everywhere! As a workaround, I enclosed the localename with ``str()``; - in Python 2 this casts the name to a byte string, in Python 3 this should do - nothing, because the locale name already had been unicode. - -- Kept range() almost everywhere as-is (2to3 suggests list(range())), just - changed it where I felt necessary. - -- Changed xrange() back to range(), so it is valid in both Python versions. + that everywhere! As a workaround, enclose the locale name with ``str()``; + in Python 2 this casts the name to a byte string, while in Python 3 this + should do nothing, because the locale name was already Unicode. +- Do not start integer literals with a zero. This is a syntax error in Python 3. +- Unfortunately there seems to be no octal notation that is valid in both + Python 2 and 3. Use decimal notation instead. Logging tips