Skip to content

Commit

Permalink
Use Black style (#98)
Browse files Browse the repository at this point in the history
  • Loading branch information
cbrnr authored Jul 21, 2022
1 parent 77ba89d commit f924393
Show file tree
Hide file tree
Showing 35 changed files with 1,433 additions and 1,425 deletions.
53 changes: 22 additions & 31 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -1,35 +1,26 @@
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v2.3.0
hooks:
- id: check-case-conflict
- id: check-merge-conflict
- id: check-yaml
- id: check-toml
- id: end-of-file-fixer
exclude: "svg"
- id: trailing-whitespace
- id: mixed-line-ending
- id: double-quote-string-fixer
- id: check-builtin-literals
- repo: https://github.com/psf/black
rev: 22.6.0
hooks:
- id: black

- repo: https://github.com/asottile/add-trailing-comma
rev: v2.1.0
hooks:
- id: add-trailing-comma
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v2.3.0
hooks:
- id: check-case-conflict
- id: check-merge-conflict
- id: check-yaml
- id: check-toml
- id: mixed-line-ending
- id: check-builtin-literals

- repo: https://github.com/pycqa/isort
rev: 5.8.0
hooks:
- id: isort
- repo: https://github.com/pycqa/flake8
rev: 4.0.1
hooks:
- id: flake8

- repo: https://github.com/pycqa/flake8
rev: 3.9.2
hooks:
- id: flake8

- repo: https://github.com/pycqa/pydocstyle
rev: 6.1.1
hooks:
- id: pydocstyle
files: ^sleepecg/
- repo: https://github.com/pycqa/pydocstyle
rev: 6.1.1
hooks:
- id: pydocstyle
files: ^sleepecg/
70 changes: 29 additions & 41 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -1,19 +1,25 @@
# Contributing to SleepECG
If you want to implement a new feature, fix an existing bug or help improve SleepECG in any other way (such as adding or improving documentation), please consider submitting a [pull request](https://github.com/cbrnr/sleepecg/pulls) on GitHub. It might be a good idea to open an [issue](https://github.com/cbrnr/sleepecg/issues) beforehand and discuss your planned contributions with the developers.
If you want to implement a new feature, fix an existing bug, or help improve SleepECG in any other way (such as adding or improving documentation), please consider submitting a [pull request](https://github.com/cbrnr/sleepecg/pulls) on GitHub. It might be a good idea to open an [issue](https://github.com/cbrnr/sleepecg/issues) beforehand and discuss your planned contributions with the developers.

Before you start working on your contribution, please make sure to follow the guidelines described in this document.


## GitHub workflow
### Setup
- Create a [fork](https://docs.github.com/en/get-started/quickstart/fork-a-repo) of the [GitHub repository](https://github.com/cbrnr/sleepecg).
- Clone the fork to your machine: `git clone https://github.com/<your-username>/sleepecg`.
- Create a [fork](https://docs.github.com/en/get-started/quickstart/fork-a-repo) of the [repository](https://github.com/cbrnr/sleepecg).
- Clone the fork to your machine:
```
git clone https://github.com/<your-username>/sleepecg
```
- Make sure your [username](https://docs.github.com/en/get-started/getting-started-with-git/setting-your-username-in-git) and [email](https://docs.github.com/en/github/setting-up-and-managing-your-github-user-account/managing-email-preferences/setting-your-commit-email-address#setting-your-commit-email-address-in-git) are configured to match your GitHub account.
- Add the original repository (also called _upstream_) as a remote to your local clone: `git remote add upstream git@github.com:cbrnr/sleepecg.git`.
- Add the original repository (also called _upstream_) as a remote to your local clone:
```
git remote add upstream git@github.com:cbrnr/sleepecg.git
```
### Add a feature or fix a bug
- Create and switch to a new branch: `git switch -c branch-name` (`branch-name` should be representative of what you are working on).
- Create and switch to a new branch (use a self-explanatory branch name).
- Make changes and commit them.
- Push the changes to your remote fork.
- Create a [pull request (PR)](https://github.com/cbrnr/sleepecg/pulls).
Expand All @@ -22,54 +28,36 @@ Before you start working on your contribution, please make sure to follow the gu
### Rebasing
If another PR is merged while you are working on something, a merge conflict may arise. To resolve it, perform the following steps in your local clone:
- Switch to the main branch: `git switch main`.
- Pull the current changes: `git pull upstream main`.
- Switch back to the branch you are working on: `git switch branch-name`.
- Rebase your commits onto main: `git rebase main`.
- Push to your remote fork: `git push` (might require `git push --force`).
- Fetch the upstream changes: `git fetch upstream`
- Rebase your commits: `git rebase upstream/main`
- Resolve any merge conflicts
- Push to your remote fork: `git push` (might require `git push --force`)
## Development enviroment
Make sure to use Python 3.8. You might want to [create a virtual environment](https://docs.python.org/3/library/venv.html#creating-virtual-environments) instead of installing everything into your main environment. In the root of the local clone of your fork, run
Make sure to use Python 3.8. You might want to [create a virtual environment](https://docs.python.org/3/library/venv.html#creating-virtual-environments) instead of working your main environment. In the root of the local clone of your fork, install SleepECG as follows:
```
pip install -e .[dev]
```
When using the flag [`-e`](https://pip.pypa.io/en/stable/cli/pip_install/#install-editable), pip does not copy the package to `site-packges`, but creates a link to your local repository. Any changes to the source code are directly reflected in the "installed" package. Installing the optional `[dev]` dependencies makes sure all tools for style checking, testing, and building documentation locally are available.
When using the flag [`-e`](https://pip.pypa.io/en/stable/cli/pip_install/#install-editable), pip does not copy the package to `site-packages/`, but creates a link to your local repository. Any changes to the source code are directly reflected in the "installed" package. Installing the optional `[dev]` dependencies makes sure all tools for style checking, testing, and building documentation are locally available.
## Code style
SleepECG adheres to [PEP 8](https://www.python.org/dev/peps/pep-0008/), with the following exceptions/specifications:
- Each source file contains a header listing the authors contributing to that module and mentions the license:
SleepECG adheres to [PEP 8](https://www.python.org/dev/peps/pep-0008/) and [Black](https://black.readthedocs.io/en/stable/index.html), with the following exceptions/specifications:
- Each source file contains the following header:
```python
# Authors: Firstname Lastname
# Another Name
# © SleepECG developers
#
# License: BSD (3-clause)
```
- The maximum line length is `92` (instead of `79`).
- If readability would suffer from a linebreak, append `# noqa` to the relevant line to disable line length checking.
- Single quotes are used, except if the string contains an apostrophe.
- The maximum line length is `92`.
- [Type hints](https://www.python.org/dev/peps/pep-0484/) are encouraged.
- If a container literal, function definition or function call does not fit on one line:
- Each argument or item is indented one level further than the function or container name.
- The last argument or item has a trailing comma.
- The closing parenthesis or bracket is indented at the same level as the starting line.
```python
# Example
def _download_file(
url: str,
target_filepath: Path,
checksum: Optional[str] = None,
checksum_type: Optional[str] = None,
verbose: bool = False,
) -> None:
```
## Public API
- Every non-public member (i.e. every member not intended to be accessed by an end user) is prefixed with an underscore: `_`.
- Every non-public member (i.e. every member not intended to be accessed by an end user) is prefixed with an underscore `_`.
- Inside a (sub-)package's `__init__.py`, public module members are imported explicitly.
- `__all__` is never set.
- To add a function or class to the API reference, list its _public_ name (e.g. `sleepecg.detect_heartbeats`, not `sleepecg.heartbeat_detection.detect_heartbeats`) in `doc/source/api.rst`.
Expand All @@ -78,24 +66,24 @@ SleepECG adheres to [PEP 8](https://www.python.org/dev/peps/pep-0008/), with the
## Documentation
For docstrings, SleepECG mainly follows [numpydoc](https://numpydoc.readthedocs.io/en/latest/format.html), with the following exceptions/specifications:
- The maximum line length is `75`.
- For parameters that may take multiple types, pipe characters are used instead of the word `or`, like this: `param_name : int | float`.
- For parameters that may take multiple types, pipe characters are used instead of the word `or`, for example `param_name : int | float`.
- For single return values, only the type is stated (no name).
- For multiple return values, both a name and a type are stated.
- Generators are treated similarly, so a type annotation `Iterator[int]` becomes just `int` in the docstring.
## pre-commit
Coding and documentation style are checked via a CI job. To make sure your contribution passes those checks, you can use [`pre-commit`](https://pre-commit.com/). To install the hooks configured in `.pre-commit-config.yml`, run
## Pre-commit
Coding and documentation style are checked via a CI job. To make sure your contribution passes those checks, you can use [`pre-commit`](https://pre-commit.com/) locally. To install the hooks configured in `.pre-commit-config.yml`, run
```
pre-commit install
```
inside your local clone. After that, the checks required in the CI job will be run on all staged files when you commit – and abort the commit in case any issues are found (in which case you should fix the found issues and commit again).
inside your local clone. After that, the checks required by the CI job will be run on all staged files when you commit – and abort the commit if any issues are found (in which case you should fix the issues and commit again).
## Tests
SleepECG uses [`pytest`](https://docs.pytest.org/) for unit tests. The structure of `sleepecg/tests/` follows that of the package itself, e.g. the test module for `sleepecg.io.nsrr` would be `sleepecg/tests/io/test_nsrr.py`. If a new test requires a package that is not part of the core dependencies (i.e. listed under `install_requires` in `setup.cfg`), make sure to add it to the optional requirement categories `dev` and `cibw`.
SleepECG uses [`pytest`](https://docs.pytest.org/) for testing. The structure of `sleepecg/test/` follows that of the package itself, e.g. the test module for `sleepecg.io.nsrr` would be `sleepecg/test/io/test_nsrr.py`. If a new test requires a package that is not part of the core dependencies (i.e. listed under `install_requires` in `setup.cfg`), make sure to add it to the optional requirement categories `dev` and `cibw`.
To run the tests, execute
```
Expand All @@ -106,7 +94,7 @@ in the project or package root. The tests for the C extension can be excluded us
pytest -m "not c_extension"
```
## Releasing
## Releases
Follow these steps to release a new version of SleepECG:
- In `sleepecg/__init__.py` remove the `-dev` suffix in `__version__`.
- In case of a patch release, modify the version number accordingly.
Expand All @@ -116,7 +104,7 @@ Follow these steps to release a new version of SleepECG:
- Create a new tag where the target version is prefixed with a `v`, e.g. `v0.4.0`.
- Use the tag as the release title.
- Mention the most important changes in the release description and include a link to the changelog.
- This triggers the [`release.yml`](https://github.com/cbrnr/sleepecg/blob/main/.github/workflows/release.yml) workflow which builds the wheels and publishes the package on [PyPI](https://pypi.org/project/sleepecg).
- This triggers the [`release.yml`](https://github.com/cbrnr/sleepecg/blob/main/.github/workflows/release.yml) workflow, which builds the wheels and publishes the package on [PyPI](https://pypi.org/project/sleepecg).
This concludes the new release. Now prepare the source for the next planned release as follows:
- Update `__version__` in `sleepecg/__init__.py` to the next planned version and append `-dev`.
Expand Down
77 changes: 37 additions & 40 deletions doc/source/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,46 +11,46 @@
import sleepecg

# -- Project information --------------------------------------------------
project = 'SleepECG'
copyright = 'SleepECG Developers'
project = "SleepECG"
copyright = "SleepECG Developers"
version = sleepecg.__version__

# -- General configuration ------------------------------------------------
extensions = [
'sphinx.ext.autodoc',
'sphinx.ext.autosummary',
'sphinx.ext.intersphinx',
'sphinx.ext.linkcode',
'numpydoc',
'myst_parser',
"sphinx.ext.autodoc",
"sphinx.ext.autosummary",
"sphinx.ext.intersphinx",
"sphinx.ext.linkcode",
"numpydoc",
"myst_parser",
]

source_suffix = {
'.rst': 'restructuredtext',
'.md': 'markdown',
".rst": "restructuredtext",
".md": "markdown",
}

myst_enable_extensions = [
'substitution',
'dollarmath',
"substitution",
"dollarmath",
]

myst_substitutions = {
'version': version,
"version": version,
}

intersphinx_mapping = {
'python': ('https://docs.python.org/3', None),
'numpy': ('https://numpy.org/devdocs', None),
'scipy': ('https://scipy.github.io/devdocs', None),
"python": ("https://docs.python.org/3", None),
"numpy": ("https://numpy.org/devdocs", None),
"scipy": ("https://scipy.github.io/devdocs", None),
}

default_role = 'code'
default_role = "code"

autoclass_content = 'class'
autoclass_content = "class"
autodoc_inherit_docstrings = False
autodoc_mock_imports = ['scipy', 'tqdm']
autodoc_typehints = 'none'
autodoc_mock_imports = ["scipy", "tqdm"]
autodoc_typehints = "none"
autosummary_generate = True
html_show_sourcelink = False

Expand All @@ -61,42 +61,39 @@
numpydoc_show_inherited_class_members = False
numpydoc_xref_param_type = True

# -- Options for HTML output ----------------------------------------------
html_theme = 'furo'
html_title = 'SleepECG'
html_last_updated_fmt = '%Y-%m-%d'

html_static_path = ['_static']
html_css_files = ['custom.css']

templates_path = ['_templates']

html_theme = "furo"
html_title = "SleepECG"
html_last_updated_fmt = "%Y-%m-%d"
html_static_path = ["_static"]
html_css_files = ["custom.css"]
templates_path = ["_templates"]
html_theme_options = {
'top_of_page_button': None,
"top_of_page_button": None,
}


def linkcode_resolve(domain, info):
"""
Determine the URL corresponding to a Python object.
Adapted from lasagne:
https://github.com/Lasagne/Lasagne/blob/master/docs/conf.py
Adapted from https://github.com/Lasagne/Lasagne/blob/master/docs/conf.py.
"""

def find_source():
obj = sys.modules[info['module']]
for part in info['fullname'].split('.'):
obj = sys.modules[info["module"]]
for part in info["fullname"].split("."):
obj = getattr(obj, part)
fn = inspect.getsourcefile(obj)
fn = os.path.relpath(fn, start=os.path.dirname(sleepecg.__file__))
source, lineno = inspect.getsourcelines(obj)
return fn, lineno, lineno + len(source) - 1

if domain != 'py' or not info['module']:
if domain != "py" or not info["module"]:
return None
try:
filename = 'sleepecg/%s#L%d-L%d' % find_source()
fn, start, end = find_source()
filename = f"sleepecg/{fn}#L{start}-L{end}"
except Exception:
filename = info['module'].replace('.', '/') + '.py'
tag = 'main' if 'dev' in version else ('v' + version)
return 'https://github.com/cbrnr/sleepecg/blob/%s/%s' % (tag, filename)
filename = info["module"].replace(".", "/") + ".py"
tag = "main" if "dev" in version else ("v" + version)
return f"https://github.com/cbrnr/sleepecg/blob/{tag}/{filename}"
Loading

0 comments on commit f924393

Please sign in to comment.