---
# System prepended metadata

title: Code Standards

---


Code Standards
==============


General
-------

In order to provide a code base that is easy to maintain, as well as easy to
contribute to, **Robottelo** has adopted a set of code standards that all
contributers are held to. Violations to our strictly held standards will result in a rejected pull request until all violations have been resolved. While not adhering to our recomended standards isn't a show stopper, keeping to them will help our code base to stay great!


Strictly Held
-------------

Black

* Robottelo uses the code formatting tool black.
* This tool will handle most of the general formatting regarding indentation and others.
* In general, if black makes a change to your code, that is what we also desire.
* Black is integrated into our CI process, so make sure it is run via pre-commit hook or manually before submitting a pull request.

Linting

* All code will be linted to black-compatible `PEP8`_ standards using `flake8`_.
* In the root of the **Robottelo** directory, run :code:`flake8 .`
* If flake8 returns errors, make corrections before submitting a pull request.
* pre-commit configuration is available, and its use is strongly encouraged in local development.

Docstrings

* Every class, method and function will have a `properly formatted`_ docstring.
* Docstring will also contain `testimony`_ and `sphinx`_ directives, as
  appropriate.

  * testimony docstrings are specific to foreman tests, so every test in
    tests/foreman/* should have the testimony tags.

* In the root of the **Robottelo** directory, run :code:`make test-docstrings`
  to ensure you did not miss adding a docstring.

Strings

* Use string methods instead of the string module.
* Use f-strings for string formatting whenever possible.
* Use the string's format method when an f-string would become too complex.
* When using format, leave out indices, unless absolutely necessary (variable re-use).

Examples ::code::

    simple_example = f'This is a {simple_var} example'
    moderate_example = f'{some_var}: {some_func(arg="foo")}'
    multi_line_example = f'You can also do {"larger"} '
        'f-strings. Only using the f notation when a '
        f'string requires it like this one: {some_func()}'
    
    complex_formatting = 'This {} contains both {} and {}'.format(
        'string',
        '"layered"',
        ' '.join(['a', 'non-trivial list', 'converted to', 'a', 'string'])
    )
    indices_needed = (
        'this {var1} is a {var1} that has the {var2} {var1} {var3}'.format(
            var1='sentence', var2='word', var3='multiple times'
        )
    )

Naming

Variable names must follow the standard below in addition to Python's own language requirements for valid variable names.

* module_name
* method_name
* function_name
* instance_variable_name
* local_variable_name
* function_parameter_name
* ClassName
* ExceptionName
* GLOBAL_CONSTANT_NAME
* _private_method
* _private_variable
* _PrivateClass

Furthermore, when writing fixtures, make their scope clear at the beginning of the fixture function's name. An unspecified scope is assumed to be function-level

* org
* module_org
* session_org

Style

* Absolutely no semicolons.
* Lines are not to exceed 99 characters in length.
* Code will be indented with **4 spaces** instead of tabs.


Recommended
-----------

Importing

* Import modules in alphabetical order.
* Each non-module import should be on their own line.
* Import order is:

  * standard library
  * third-party
  * application-specific

* Put a blank line between groups of imports.

General

* Avoid global variables.
* Use :code:`.join()` for non-trivial string concatenation.
* Trivial string concatenation can be done either via f-strings or `+`, though f-strings are preferred.
    * string to string concatenation is faster with `+`.
    * if one or more values need to be converted to a string, f-strings are faster. 
    [jake] - i agree because of course 
* Handle data aggregation inside of functions when able.

Style

* Use single quotes instead of double quotes whenever possible. Single quotes
  are less visually noisy, and they are easier to type.
* When mixing nested strings, and you have exhausted both single and double quotes, use triple quotes on the outer string. ::code::

      bad = f'This "quoted \'string\' is \'messy\''.'''
      good = f'''This 'quoted "string" reads "better"'.'''

* One statement per line.


Read More!
----------

`Python Style Guide`_

`pre-commit Tutorial`_

`Code Like a Pythonista`_


Todo
----
Compile a list of standards used by the **Robottelo** team

Categorize each standard into how strictly they are enforced


.. _PEP8: http://legacy.python.org/dev/peps/pep-0008/
.. _flake8: http://flake8.readthedocs.org/
.. _testimony: https://github.com/SatelliteQE/testimony
.. _sphinx: http://sphinx-doc.org/markup/para.html
.. _properly format strings: https://docs.python.org/3/library/stdtypes.html#printf-style-string-formatting
.. _Python Style Guide: http://docs.python-guide.org/en/latest/writing/style/
.. _pre-commit Tutorial: https://pre-commit.com/#usage
.. _Code Like a Pythonista: http://python.net/~goodger/projects/pycon/2007/idiomatic/handout.html