Skip to content

Commit

Permalink
Merge pull request #449 from yarikoptic/enh-codespell
Browse files Browse the repository at this point in the history
Add codespell support (config, workflow to detect/not fix) and make it fix few typos
  • Loading branch information
pvandyken authored Jul 25, 2024
2 parents 03cbb4a + 3e31472 commit 96fb5e1
Show file tree
Hide file tree
Showing 26 changed files with 75 additions and 36 deletions.
25 changes: 25 additions & 0 deletions .github/workflows/codespell.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Codespell configuration is within pyproject.toml
---
name: Codespell

on:
push:
branches: [main]
pull_request:
branches: [main]

permissions:
contents: read

jobs:
codespell:
name: Check for spelling errors
runs-on: ubuntu-latest

steps:
- name: Checkout
uses: actions/checkout@v4
- name: Annotate locations with typos
uses: codespell-project/codespell-problem-matcher@v1
- name: Codespell
uses: codespell-project/actions-codespell@v2
7 changes: 7 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,10 @@ repos:
language: system
exclude: ^docs
types_or: [cython, pyi, python]
- repo: https://github.com/codespell-project/codespell
# Configuration for codespell is in pyproject.toml
rev: v2.2.6
hooks:
- id: codespell
additional_dependencies:
- tomli
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ Snakebids is a Python package that extends [Snakemake](https://snakemake.github.

Snakebids includes all of the features of Snakemake, including flexible configuration, parallel execution, and Docker/Singularity support, plus:

- **Built-in support for BIDS datasets**: Seamless workflow functionality with a wide range of BIDS datasets, accomodating various levels of complexity.
- **Built-in support for BIDS datasets**: Seamless workflow functionality with a wide range of BIDS datasets, accommodating various levels of complexity.
- **BIDS App Creation**: Provide command-line invocations of your workflow following BIDS App guidelines, ensuring reproducibility and enhancing accessibility of your workflow.
- **BIDS Path Construction**: Easy, flexible construction of valid BIDS paths following BIDS guiding principles, promoting data organization and sharing.
- **Plugin System**: Extend the functionality of Snakebids by creating and using plugins to meet your workflow's needs.
Expand Down
2 changes: 1 addition & 1 deletion docs/api/paths.rst
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ Specs

.. py:currentmodule:: snakebids.paths.specs
BIDS specs control the formatting of paths produced by the :func:`~snakebids.bids` function. They specify the order of recognized entities, placing ``ses-X`` after ``sub-Y``, for instance, no matter what order they are specified in the function. Unrecognized entitites are placed in the order specified in the function call.
BIDS specs control the formatting of paths produced by the :func:`~snakebids.bids` function. They specify the order of recognized entities, placing ``ses-X`` after ``sub-Y``, for instance, no matter what order they are specified in the function. Unrecognized entities are placed in the order specified in the function call.

Because of this, each addition of entities to the spec presents a potentially breaking change. Suppose an entity called ``foo`` were added to the spec. Calls to :func:`~snakebids.bids` with ``foo`` as an argument would place the entity at the end of the path:

Expand Down
2 changes: 1 addition & 1 deletion docs/migration/0.11_to_0.12.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
(migrate-to-bidsapp)=
# 0.11 to 0.12+

Snakebids 0.12 introduces a [new, more flexible module](#snakebids.bidsapp) for creating bidsapps. This affects the syntax of the `run.py` file. Older versions used the {class}`snakebids.app.SnakeBidsApp` class to initialize the bidsapp, and this method will still work for the forseeable future. Switching to the new syntax will give access to new plugins and integrations and ensure long term support.
Snakebids 0.12 introduces a [new, more flexible module](#snakebids.bidsapp) for creating bidsapps. This affects the syntax of the `run.py` file. Older versions used the {class}`snakebids.app.SnakeBidsApp` class to initialize the bidsapp, and this method will still work for the foreseeable future. Switching to the new syntax will give access to new plugins and integrations and ensure long term support.

If you haven't heavily modified your `run.py` file, you can transition simply by replacing it with the following:

Expand Down
2 changes: 1 addition & 1 deletion docs/migration/0.7_to_0.8.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ Be sure to also [migrate](0.11_to_0.12.md) your `run.py` file to the new snakebi

## Default return of {func}`~snakebids.generate_inputs()`

V0.8 switches the default return value of {func}`~snakebids.generate_inputs()` from {class}`~snakebids.BidsDatasetDict` to {class}`~snakebids.BidsDataset`. Legacy code still relying on the old dictionary can avoid the update by setting the `use_bids_inputs` pararmeter in {func}`~snakebids.generate_inputs()` to `False`:
V0.8 switches the default return value of {func}`~snakebids.generate_inputs()` from {class}`~snakebids.BidsDatasetDict` to {class}`~snakebids.BidsDataset`. Legacy code still relying on the old dictionary can avoid the update by setting the `use_bids_inputs` parameter in {func}`~snakebids.generate_inputs()` to `False`:

```python
config.update(generate_inputs(
Expand Down
11 changes: 9 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ pvandyken-deprecated = "0.0.4"
# Need this until py39
importlib-resources = ">=5.12.0"

# Below are non-direct dependencies (i.e. dependencies of other depenencies)
# Below are non-direct dependencies (i.e. dependencies of other dependencies)
# specified to ensure a version with a pre-built wheel is installed depending
# on the python version being used.
numpy = [
Expand Down Expand Up @@ -83,7 +83,7 @@ pytest = "^8"
pytest-mock = "^3.7.0"
poethepoet = "^0.27"
pre-commit = "^3.0.0"
# a mkinit dep has the 'platform_system == "Windows"' as a marker on an incompatible dependeny
# a mkinit dep has the 'platform_system == "Windows"' as a marker on an incompatible dependency
# (pydantic<2.0 cf copier), so set the inverse as a marker here so mkinit can
# still be resolved
mkinit = { version="^1.1.0", markers = "platform_system != 'Windows'" }
Expand Down Expand Up @@ -308,3 +308,10 @@ more_itertools = "itx"

[tool.ruff.lint.flake8-pytest-style]
fixture-parentheses = false

[tool.codespell]
# Ref: https://github.com/codespell-project/codespell#using-a-config-file
skip = '.git*,*.lock,*.css,./typings'
check-hidden = true
# ignore-regex = ''
# ignore-words-list = ''
2 changes: 1 addition & 1 deletion scripts/update_bids.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ def generate_stub(mod: ModuleType, imports: list[str], funcs: Iterable[str]):
mod
module for which stub file should be written
imports
list of imports and other statemets to appear at the beginning of the file
list of imports and other statements to appear at the beginning of the file
funcs
list of function declarations
"""
Expand Down
2 changes: 1 addition & 1 deletion snakebids/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ def _check_deprecations(self):
if self.version is not None:
msg = (
"`SnakeBidsApp.version` is deprecated and no longer has any effect. To "
"explcitly set the app version, use the `snakebids.plugins.Version` "
"explicitly set the app version, use the `snakebids.plugins.Version` "
"plugin"
)
warnings.warn(msg, stacklevel=3)
Expand Down
2 changes: 1 addition & 1 deletion snakebids/bidsapp/hookspecs.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ def update_cli_namespace(namespace: dict[str, Any], config: dict[str, Any]):
:meth:`~argparse.ArgumentParser.parse_args` (equivalent to
:class:`vars(Namespace) <argparse.Namespace>`). Any modifications made to this
:class:`dict` will be carried forward in app initialization. For instance, if
an entry is deleleted from ``namespace``, it will not be available to downstream
an entry is deleted from ``namespace``, it will not be available to downstream
plugins or be copied into ``config``.
Parameters
Expand Down
2 changes: 1 addition & 1 deletion snakebids/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ def add_dynamic_args(
) -> None:
"""Do nothing.
Originally added --filter-<comp> and --wildcards-<comp> argumets to the CLI. Kept
Originally added --filter-<comp> and --wildcards-<comp> arguments to the CLI. Kept
as a placeholder for apps that relied on it for generating documentation. This
functionality is now native to `SnakeBidsApp`.
"""
Expand Down
10 changes: 5 additions & 5 deletions snakebids/core/datasets.py
Original file line number Diff line number Diff line change
Expand Up @@ -363,7 +363,7 @@ def expand(
"""Safely expand over given paths with component wildcards.
Uses the entity-value combinations found in the dataset to expand over the given
paths. Extra wildcards can be specifed as keyword arguments.
paths. Extra wildcards can be specified as keyword arguments.
By default, expansion over paths with extra wildcards not accounted for by the
component causes an error. This prevents accidental partial expansion. To allow
Expand Down Expand Up @@ -430,8 +430,8 @@ def filter(
This method allows you to expand over a subset of your wildcards. This could be
useful for extracting subjects from a specific patient group, running different
rules on different aquisitions, and any other reason you may need to filter your
data after the workflow has already started.
rules on different acquisitions, and any other reason you may need to filter
your data after the workflow has already started.
Takes entities as keyword arguments assigned to values or list of values to
select from the component. Only columns containing the provided entity-values
Expand Down Expand Up @@ -468,7 +468,7 @@ class BidsComponent(BidsPartialComponent):
A component is a set of data entries all corresponding to the same type of object.
Entries vary over a set of entities. For example, a component may represent all the
unprocessed, T1-weighted anatomical images aqcuired from a group of 100 subjects,
unprocessed, T1-weighted anatomical images acquired from a group of 100 subjects,
across 2 sessions, with three runs per session. Here, the subject, session, and run
are the entities over which the component varies. Each entry in the component has
a single value assigned for each of the three entities (e.g subject 002, session
Expand Down Expand Up @@ -791,7 +791,7 @@ def input_wildcards(self) -> dict[str, MultiSelectDict[str, str]]:
def as_dict(self) -> BidsDatasetDict:
"""Get the layout as a legacy dict.
Included primarily for backward compatability with older versions of snakebids,
Included primarily for backward compatibility with older versions of snakebids,
where generate_inputs() returned a dict rather than the `BidsDataset` class
Returns
Expand Down
2 changes: 1 addition & 1 deletion snakebids/core/input_generation.py
Original file line number Diff line number Diff line change
Expand Up @@ -423,7 +423,7 @@ def _gen_bids_layout(
existing database.
index_metadata
A boolen that determines whether to parse and index metadata
A boolean that determines whether to parse and index metadata
validate
A boolean that determines whether to validate the bids dataset
Expand Down
4 changes: 2 additions & 2 deletions snakebids/io/printing.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ def new_col(val: str):


def _find_elision(widths: list[int], excluded: slice, overflow: int) -> slice:
# Add 4 to overflow to account for elipses
# Add 4 to overflow to account for ellipses
if max(sum(widths[excluded]) - 4, 0) >= overflow:
return excluded
span = excluded.stop - excluded.start
Expand All @@ -118,7 +118,7 @@ def _find_elision(widths: list[int], excluded: slice, overflow: int) -> slice:
mid = floor(num_vals / 2)

# need different rules for handling exclusions of even length depending on whether
# theres an even or odd total number of values.
# there's an even or odd total number of values.
left_bias = floor if num_vals % 2 else ceil
right_bias = ceil if num_vals % 2 else floor

Expand Down
2 changes: 1 addition & 1 deletion snakebids/jinja2_ext/snakebids_version.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@


class SnakebidsVersionExtension(Extension):
"""Retrieve the latest snakebids vesion from pypi.
"""Retrieve the latest snakebids version from pypi.
Stores value in the ``snakebids_version`` global variable.
"""
Expand Down
2 changes: 1 addition & 1 deletion snakebids/plugins/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ def add_argument(
*name_or_flags: str,
**kwargs: Unpack[AnyArgumentArgs],
) -> argparse.Action | None:
"""Add argument to parser, applying prefix to dest as necesary."""
"""Add argument to parser, applying prefix to dest as necessary."""
if self.PREFIX and not kwargs["dest"].startswith(self.PREFIX):
kwargs["dest"] = f"{self.PREFIX}.{kwargs['dest']}"
return parser.add_argument(*name_or_flags, **kwargs)
4 changes: 2 additions & 2 deletions snakebids/plugins/bidsargs.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ class BidsArgs(PluginBase):
CLI Arguments
~~~~~~~~~~~~~
All arguments are added by default, but can be disabled using their respective
parameters. Additinally, arguments can be directly overriden by adding arguments
parameters. Additionally, arguments can be directly overridden by adding arguments
to the parser before the plugin runs, using the following ``dests``:
- ``bids_dir``: The input bids directory
Expand All @@ -93,7 +93,7 @@ class BidsArgs(PluginBase):
Overriding just one or two of the positional arguments may alter the order,
preventing the app from being called correctly. Thus, if any of the positional
args are being overriden, they all should be.
args are being overridden, they all should be.
Analysis levels
Expand Down
2 changes: 1 addition & 1 deletion snakebids/plugins/component_edit.py
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ class ComponentEdit(PluginBase):
4. ``ENTITY:none`` selects all paths without the entity.
5. ``ENTITY:any`` removes filters for the entity.
CLI arguments created by this plugin cannot be overriden.
CLI arguments created by this plugin cannot be overridden.
Parameters
----------
Expand Down
2 changes: 1 addition & 1 deletion snakebids/plugins/pybidsdb.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ class Pybidsdb(PluginBase):
CLI Arguments
~~~~~~~~~~~~~
Two arguments are added to the CLI. These can be overriden by adding arguments
Two arguments are added to the CLI. These can be overridden by adding arguments
with corresponding ``dests`` before this plugin is run:
- ``plugins.pybidsdb.dir``: (:class:`~pathlib.Path`) Path of the database
Expand Down
2 changes: 1 addition & 1 deletion snakebids/plugins/validator.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ class BidsValidator(PluginBase):
InvalidBidsError is raised.
An argument --skip-bids-validation is added to the CLI. This argument can be
overriden by adding an argument with dest ``plugins.validator.skip`` before this
overridden by adding an argument with dest ``plugins.validator.skip`` before this
plugin runs.
Two entries are added to config:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ targets_by_analysis_level:
- 'all' # if '', then the first rule is run

# Configure components:
# Each entry creates a new component that can be retreived within the workflow
# Each entry creates a new component that can be retrieved within the workflow
# via `generate_inputs`.
# Filters are used to select paths: each filter has an `entity` key and a
# single value or list of values to select.
Expand Down
2 changes: 1 addition & 1 deletion snakebids/tests/test_datasets.py
Original file line number Diff line number Diff line change
Expand Up @@ -355,7 +355,7 @@ class TestBidsComponentExpand:
"""
`extension` is generally excluded from the generated components because its wildcard
is immediately adjacent to the previous wildcard (e.g.
sub-{subject}_{suffix}{extenions}), making it impossible to correctly parse using
sub-{subject}_{suffix}{extension}), making it impossible to correctly parse using
`glob_wildcards`. Its absence does not affect the spirit of the tests.
We also exclude extra_entities from the generated Components for the same reason:
Expand Down
8 changes: 4 additions & 4 deletions snakebids/tests/test_generate_inputs.py
Original file line number Diff line number Diff line change
Expand Up @@ -994,7 +994,7 @@ def path_entities(draw: st.DrawFn):
valid_chars = st.characters(
min_codepoint=48, max_codepoint=122, whitelist_categories=["Ll", "Lu"]
)
# We need to explicitely exclude keywords here because the current implementation
# We need to explicitly exclude keywords here because the current implementation
# of glob_wildcards uses a named tuple, which doesn't allow keywords as attributes.
path_text = st.text(valid_chars, min_size=1).filter(
lambda s: not keyword.iskeyword(s)
Expand Down Expand Up @@ -1821,9 +1821,9 @@ def test_exclude_participant_does_not_make_all_other_filters_regex(
for comp in dataset.values()
)

# Create an extra set of paths by modifing one of the existing components to put
# foo after a set of entity values. If that filter gets changed to a regex, all
# of the suffixed decoys will get picked up by pybids
# Create an extra set of paths by modifying one of the existing components to
# put foo after a set of entity values. If that filter gets changed to a regex,
# all of the suffixed decoys will get picked up by pybids
ziplist = dict(itx.first(rooted.values()).zip_lists)
mut_entity = itx.first(
filter(lambda e: e not in {"subject", "extension"}, ziplist)
Expand Down
2 changes: 1 addition & 1 deletion snakebids/utils/containers.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ class ImmutableList(Sequence[_T_co], Generic[_T_co]):
Unlike tuples, only a single type parameter is supported. In other words,
``ImmutableList`` cannot be specified via type hints as a fixed length sequence
containing heterogenous items. A tuple specified as ``tuple[str, int, str]`` would
containing heterogeneous items. A tuple specified as ``tuple[str, int, str]`` would
be specified as ``ImmutableList[str | int]``
"""

Expand Down
6 changes: 3 additions & 3 deletions snakebids/utils/output.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,8 +77,8 @@ def write_output_mode(dotfile: Path, mode: Mode) -> None:
def _get_snakebids_file(outputdir: Path) -> dict[str, str] | None:
"""Ensure populated dir contains .snakebids file, retrieving it if it does.
First checks if outputdir doesn't exist or is completely empty, returing None if so.
If it does have data, it checks for a .snakebids file, returning its contents if
First checks if outputdir doesn't exist or is completely empty, returning None if
so. If it does have data, it checks for a .snakebids file, returning its contents if
found. If no .snakebids file is found, it raises an exception.
Parameters
Expand All @@ -89,7 +89,7 @@ def _get_snakebids_file(outputdir: Path) -> dict[str, str] | None:
Returns
-------
Dict or None
None if output dir is nonexistant or empty, otherwise the contents
None if output dir is nonexistent or empty, otherwise the contents
of the .snakebids file
Raises
Expand Down
2 changes: 1 addition & 1 deletion snakebids/utils/snakemake_io.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ def regex(filepattern: str) -> str:
if match.group("constraint"):
msg = (
"Constraint regex must be defined only in the first "
"occurence of the wildcard in a string."
"occurrence of the wildcard in a string."
)
raise ValueError(msg)
regex_list.append(f"(?P={wildcard})")
Expand Down

0 comments on commit 96fb5e1

Please sign in to comment.