|
| 1 | +# Contributing |
| 2 | + |
| 3 | +If you would like to add new functionality or fix a bug, we welcome contributions. All change requests should start with |
| 4 | +an [issue on the repo](https://github.com/8451/confectioner/issues/new/choose). If you would like to develop the |
| 5 | +solution yourself, us the following flow: |
| 6 | + |
| 7 | +1. Read the [style guide](#style-guide) below |
| 8 | +2. Tag Austin Warner (austinwarner-8451) in the issue and request to be assigned the issue |
| 9 | + - If this is your first time contributing, ask to be granted write access to the repo |
| 10 | +3. Create a new branch based off of [develop](https://github.com/8451/confectioner/tree/develop) |
| 11 | + - Give your branch a name starting with `feature/`, `bug/` or `misc/` |
| 12 | + - For example, if you were requesting that toml files be supported by default, create |
| 13 | + a branch called `feature/toml` |
| 14 | +4. Clone the repo in your favorite IDE, check out your new branch, and add your changes |
| 15 | +5. Run the tests to ensure nothing breaks |
| 16 | + - `pip install -e .[test]` |
| 17 | + - `pytest` |
| 18 | +6. Push the changes on your branch to the repo, and open a Pull Request where the base branch is `develop` |
| 19 | + - Request a review from Austin Warner |
| 20 | + |
| 21 | +## Style Guide |
| 22 | + |
| 23 | +### Pre-Commit |
| 24 | +The repo has [pre-commit](https://pre-commit.com/) configured to enforce much (but not all) of the style guide |
| 25 | +automatically. When developing locally, please perform the one-time setup using `pip install pre-commit` followed by |
| 26 | +`pre-commit install` before making any commits. |
| 27 | + |
| 28 | +### PEP 8 |
| 29 | +We try to follow [PEP 8](https://peps.python.org/pep-0008/) wherever possible. Feel free to familiarize yourself |
| 30 | +with it, but most IDEs will automatically help you. Alternatively, you can use a code formatter like |
| 31 | +[black](https://pypi.org/project/black/) to format your code for you. |
| 32 | + |
| 33 | +### Imports |
| 34 | +Imports should take place at the top of the file and be broken into 4 sections, each section with a single empty line between |
| 35 | +them. The sections are: |
| 36 | +1. Standard library imports (i.e. typing, regex, math) |
| 37 | +2. 3rd-party library imports (i.e. numpy, pandas) |
| 38 | +3. Relative imports (importing other modules from the confectioner package) |
| 39 | + |
| 40 | +For sections 1-3, prefer using the fully-qualified namespace over an unqualified import (`import json` over |
| 41 | +`from json import load`). An exception to this rule is imports from the typing library (`from typing import List`). |
| 42 | + |
| 43 | +When importing another module from `confectioner`, write it like `from . import core`. |
| 44 | + |
| 45 | +Under no circumstances should `from module import *` be used. |
| 46 | + |
| 47 | +### Typing |
| 48 | +All function definitions should be fully type-hinted (arguments and return value). Where applicable, use |
| 49 | +generic types from the `typing` library like `List[str]` vs `list`. If a function does not return anything, mark the |
| 50 | +return type as `None`. |
| 51 | + |
| 52 | +### Naming |
| 53 | +Prefer long, descriptive function names over short abbreviated names. For example, `load_config` is preferred over |
| 54 | +`ld_cfg`. |
| 55 | + |
| 56 | +Function and variable names should be lowercase with underscores separating words (`my_function`). Class names should be |
| 57 | +camel case (`MyClass`). Constants should be all uppercase with underscores separating words (`MY_CONSTANT`). |
| 58 | + |
| 59 | +Any function, variable, or constant that is not intended to be used outside of the module it is defined in should be |
| 60 | +prefixed with an underscore (`_my_private_function`). |
| 61 | + |
| 62 | +### Documentation |
| 63 | +All public-facing functions should be documented using docstrings in the |
| 64 | +[Numpy Style](https://numpydoc.readthedocs.io/en/latest/format.html#docstring-standard). |
| 65 | + |
| 66 | +### Functional Programming |
| 67 | +We strongly prefer Functional Programming over Object-Oriented programming. OOP is used specifically to store |
| 68 | +configuration data in an object for later use. Regardless of paradigm, there is a preference for stateless programming |
| 69 | +and avoiding in-place data mutation where possible. For example, when combining two lists, prefer `list_a + list_b` |
| 70 | +over `list_a.extend(list_b)`. |
0 commit comments