diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 6b200e8..f9feb43 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -6,6 +6,7 @@ repos: rev: v6.0.0 hooks: - id: trailing-whitespace + exclude: .gitignore - id: end-of-file-fixer - id: check-yaml - id: check-json diff --git a/pyproject.toml b/pyproject.toml index 26eb474..562176f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -99,61 +99,12 @@ exclude_lines = [ [tool.black] exclude = ".*" -[tool.ruff] -line-length = 99 -extend-exclude = [ - "_version.py", - "tests/data", -] - -[tool.ruff.lint] -extend-select = [ - "F", - "E", - "W", - "I", - "D", - "UP", - "YTT", - "S", - "BLE", - "B", - "A", - # "CPY", - "C4", - "DTZ", - "T10", - # "EM", - "EXE", - "ISC", - "ICN", - "PT", - "Q", -] -ignore = [ - "ISC001", - "D105", - "D107", - "D203", - "D213", -] - -[tool.ruff.lint.flake8-quotes] -inline-quotes = "single" - -[tool.ruff.lint.extend-per-file-ignores] -"setup.py" = ["D"] -"*/test_*.py" = [ - "S101", - "D", -] - -[tool.ruff.format] -quote-style = "single" +# Ruff configured in ruff.toml [dependency-groups] dev = [ "ipython>=8.37.0", + "ruff>=0.15.5", ] test = [ "pytest >=8", diff --git a/ruff.toml b/ruff.toml new file mode 100644 index 0000000..f3f462b --- /dev/null +++ b/ruff.toml @@ -0,0 +1,49 @@ +line-length = 99 +extend-exclude = [ + "_version.py", # Auto-generated + "tests/data", # Submodules +] + +[format] +quote-style = "single" +line-ending = "lf" +docstring-code-format = true + +[lint] +extend-select = [ + "F", # pyflakes + "E", # pycodestyle errors + "W", # pycodestyle warnings + "I", # isort + "D", # pydocstyle + "UP", # pyupgrade + "YTT", # flake8-2020 + "S", # bandit + "BLE", # blind-except + "B", # bugbear + "A", # builtins + "C4", # comprehensions + "DTZ", # datetimez + "T10", # debugger + # "EM", # errmsg + "EXE", # executable + "ISC", # implicit-str-concat + "ICN", # import-conventions + "PT", # pytest-style + "Q", # quotes +] +ignore = [ + "D105", # undocumented-magic-method + "D107", # undocumented __init__ + "D203", # blank line before class docstring + "D213", # multi-line-summary-first-line + "Q000", # double quotes + "Q003", # avoidable-escaped-quote +] + +[lint.extend-per-file-ignores] +"setup.py" = ["D"] +"*/test_*.py" = [ + "S101", # assert + "D", +] diff --git a/src/bids_validator/bids_validator.py b/src/bids_validator/bids_validator.py index 6c25ab5..2c81741 100644 --- a/src/bids_validator/bids_validator.py +++ b/src/bids_validator/bids_validator.py @@ -136,16 +136,16 @@ def parse(cls, path: str) -> dict[str, str]: -------- >>> from bids_validator import BIDSValidator >>> validator = BIDSValidator() - >>> validator.parse("/sub-01/anat/sub-01_rec-CSD_T1w.nii.gz") + >>> validator.parse('/sub-01/anat/sub-01_rec-CSD_T1w.nii.gz') {'subject': '01', 'datatype': 'anat', 'reconstruction': 'CSD', 'suffix': 'T1w', 'extension': '.nii.gz'} - >>> validator.parse("/sub-01/anat/sub-01_acq-23_rec-CSD_T1w.exe") + >>> validator.parse('/sub-01/anat/sub-01_acq-23_rec-CSD_T1w.exe') {} - >>> validator.parse("home/username/my_dataset/participants.tsv") + >>> validator.parse('home/username/my_dataset/participants.tsv') Traceback (most recent call last): ... ValueError: Path must be relative to root of a BIDS dataset, ... - >>> validator.parse("/participants.tsv") + >>> validator.parse('/participants.tsv') {'stem': 'participants', 'extension': '.tsv'} """ @@ -196,10 +196,10 @@ def is_bids(cls, path: str) -> bool: >>> from bids_validator import BIDSValidator >>> validator = BIDSValidator() >>> filepaths = [ - ... "/sub-01/anat/sub-01_rec-CSD_T1w.nii.gz", - ... "/sub-01/anat/sub-01_acq-23_rec-CSD_T1w.exe", # wrong extension - ... "home/username/my_dataset/participants.tsv", # not relative to root - ... "/participants.tsv", + ... '/sub-01/anat/sub-01_rec-CSD_T1w.nii.gz', + ... '/sub-01/anat/sub-01_acq-23_rec-CSD_T1w.exe', # wrong extension + ... 'home/username/my_dataset/participants.tsv', # not relative to root + ... '/participants.tsv', ... ] >>> for filepath in filepaths: ... print(validator.is_bids(filepath)) diff --git a/src/bids_validator/test_bids_validator.py b/src/bids_validator/test_bids_validator.py index de3bc8f..ba8f218 100644 --- a/src/bids_validator/test_bids_validator.py +++ b/src/bids_validator/test_bids_validator.py @@ -204,9 +204,7 @@ def test_is_session_level(validator: BIDSValidator, fname: str) -> None: '/sub-01/sub-01_acq_dwi.bval', # missed suffix value '/sub-01/sub-01_acq-23-singleband_dwi.bvec', # redundant -23- '/sub-01/anat/sub-01_acq-singleband_dwi.json', # redundant /anat/ - ( - '/sub-01/sub-01_recrod-record_acq-singleband_run-01_dwi.bval' - ), # redundant record-record_ + '/sub-01/sub-01_recrod-record_acq-singleband_run-01_dwi.bval', # redundant record-record_ '/sub_01/sub-01_acq-singleband_run-01_dwi.bvec', # wrong /sub_01/ '/sub-01/sub-01_acq-singleband__run-01_dwi.json', # wrong __ '/sub-01/ses-test/sub-01_ses_test_dwi.bval', # wrong ses_test diff --git a/uv.lock b/uv.lock index 49c180e..d815a5f 100644 --- a/uv.lock +++ b/uv.lock @@ -80,6 +80,7 @@ cli = [ [package.dev-dependencies] dev = [ { name = "ipython" }, + { name = "ruff" }, ] test = [ { name = "cattrs" }, @@ -105,7 +106,10 @@ requires-dist = [ provides-extras = ["cli"] [package.metadata.requires-dev] -dev = [{ name = "ipython", specifier = ">=8.37.0" }] +dev = [ + { name = "ipython", specifier = ">=8.37.0" }, + { name = "ruff", specifier = ">=0.15.5" }, +] test = [ { name = "cattrs", specifier = ">=24.1.3" }, { name = "coverage", extras = ["toml"], specifier = ">=7.2" }, @@ -1563,6 +1567,31 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/25/7a/b0178788f8dc6cafce37a212c99565fa1fe7872c70c6c9c1e1a372d9d88f/rich-14.2.0-py3-none-any.whl", hash = "sha256:76bc51fe2e57d2b1be1f96c524b890b816e334ab4c1e45888799bfaab0021edd", size = 243393, upload-time = "2025-10-09T14:16:51.245Z" }, ] +[[package]] +name = "ruff" +version = "0.15.6" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/51/df/f8629c19c5318601d3121e230f74cbee7a3732339c52b21daa2b82ef9c7d/ruff-0.15.6.tar.gz", hash = "sha256:8394c7bb153a4e3811a4ecdacd4a8e6a4fa8097028119160dffecdcdf9b56ae4", size = 4597916, upload-time = "2026-03-12T23:05:47.51Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9e/2f/4e03a7e5ce99b517e98d3b4951f411de2b0fa8348d39cf446671adcce9a2/ruff-0.15.6-py3-none-linux_armv6l.whl", hash = "sha256:7c98c3b16407b2cf3d0f2b80c80187384bc92c6774d85fefa913ecd941256fff", size = 10508953, upload-time = "2026-03-12T23:05:17.246Z" }, + { url = "https://files.pythonhosted.org/packages/70/60/55bcdc3e9f80bcf39edf0cd272da6fa511a3d94d5a0dd9e0adf76ceebdb4/ruff-0.15.6-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:ee7dcfaad8b282a284df4aa6ddc2741b3f4a18b0555d626805555a820ea181c3", size = 10942257, upload-time = "2026-03-12T23:05:23.076Z" }, + { url = "https://files.pythonhosted.org/packages/e7/f9/005c29bd1726c0f492bfa215e95154cf480574140cb5f867c797c18c790b/ruff-0.15.6-py3-none-macosx_11_0_arm64.whl", hash = "sha256:3bd9967851a25f038fc8b9ae88a7fbd1b609f30349231dffaa37b6804923c4bb", size = 10322683, upload-time = "2026-03-12T23:05:33.738Z" }, + { url = "https://files.pythonhosted.org/packages/5f/74/2f861f5fd7cbb2146bddb5501450300ce41562da36d21868c69b7a828169/ruff-0.15.6-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:13f4594b04e42cd24a41da653886b04d2ff87adbf57497ed4f728b0e8a4866f8", size = 10660986, upload-time = "2026-03-12T23:05:53.245Z" }, + { url = "https://files.pythonhosted.org/packages/c1/a1/309f2364a424eccb763cdafc49df843c282609f47fe53aa83f38272389e0/ruff-0.15.6-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e2ed8aea2f3fe57886d3f00ea5b8aae5bf68d5e195f487f037a955ff9fbaac9e", size = 10332177, upload-time = "2026-03-12T23:05:56.145Z" }, + { url = "https://files.pythonhosted.org/packages/30/41/7ebf1d32658b4bab20f8ac80972fb19cd4e2c6b78552be263a680edc55ac/ruff-0.15.6-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:70789d3e7830b848b548aae96766431c0dc01a6c78c13381f423bf7076c66d15", size = 11170783, upload-time = "2026-03-12T23:06:01.742Z" }, + { url = "https://files.pythonhosted.org/packages/76/be/6d488f6adca047df82cd62c304638bcb00821c36bd4881cfca221561fdfc/ruff-0.15.6-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:542aaf1de3154cea088ced5a819ce872611256ffe2498e750bbae5247a8114e9", size = 12044201, upload-time = "2026-03-12T23:05:28.697Z" }, + { url = "https://files.pythonhosted.org/packages/71/68/e6f125df4af7e6d0b498f8d373274794bc5156b324e8ab4bf5c1b4fc0ec7/ruff-0.15.6-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1c22e6f02c16cfac3888aa636e9eba857254d15bbacc9906c9689fdecb1953ab", size = 11421561, upload-time = "2026-03-12T23:05:31.236Z" }, + { url = "https://files.pythonhosted.org/packages/f1/9f/f85ef5fd01a52e0b472b26dc1b4bd228b8f6f0435975442ffa4741278703/ruff-0.15.6-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:98893c4c0aadc8e448cfa315bd0cc343a5323d740fe5f28ef8a3f9e21b381f7e", size = 11310928, upload-time = "2026-03-12T23:05:45.288Z" }, + { url = "https://files.pythonhosted.org/packages/8c/26/b75f8c421f5654304b89471ed384ae8c7f42b4dff58fa6ce1626d7f2b59a/ruff-0.15.6-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:70d263770d234912374493e8cc1e7385c5d49376e41dfa51c5c3453169dc581c", size = 11235186, upload-time = "2026-03-12T23:05:50.677Z" }, + { url = "https://files.pythonhosted.org/packages/fc/d4/d5a6d065962ff7a68a86c9b4f5500f7d101a0792078de636526c0edd40da/ruff-0.15.6-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:55a1ad63c5a6e54b1f21b7514dfadc0c7fb40093fa22e95143cf3f64ebdcd512", size = 10635231, upload-time = "2026-03-12T23:05:37.044Z" }, + { url = "https://files.pythonhosted.org/packages/d6/56/7c3acf3d50910375349016cf33de24be021532042afbed87942858992491/ruff-0.15.6-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:8dc473ba093c5ec238bb1e7429ee676dca24643c471e11fbaa8a857925b061c0", size = 10340357, upload-time = "2026-03-12T23:06:04.748Z" }, + { url = "https://files.pythonhosted.org/packages/06/54/6faa39e9c1033ff6a3b6e76b5df536931cd30caf64988e112bbf91ef5ce5/ruff-0.15.6-py3-none-musllinux_1_2_i686.whl", hash = "sha256:85b042377c2a5561131767974617006f99f7e13c63c111b998f29fc1e58a4cfb", size = 10860583, upload-time = "2026-03-12T23:05:58.978Z" }, + { url = "https://files.pythonhosted.org/packages/cb/1e/509a201b843b4dfb0b32acdedf68d951d3377988cae43949ba4c4133a96a/ruff-0.15.6-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:cef49e30bc5a86a6a92098a7fbf6e467a234d90b63305d6f3ec01225a9d092e0", size = 11410976, upload-time = "2026-03-12T23:05:39.955Z" }, + { url = "https://files.pythonhosted.org/packages/6c/25/3fc9114abf979a41673ce877c08016f8e660ad6cf508c3957f537d2e9fa9/ruff-0.15.6-py3-none-win32.whl", hash = "sha256:bbf67d39832404812a2d23020dda68fee7f18ce15654e96fb1d3ad21a5fe436c", size = 10616872, upload-time = "2026-03-12T23:05:42.451Z" }, + { url = "https://files.pythonhosted.org/packages/89/7a/09ece68445ceac348df06e08bf75db72d0e8427765b96c9c0ffabc1be1d9/ruff-0.15.6-py3-none-win_amd64.whl", hash = "sha256:aee25bc84c2f1007ecb5037dff75cef00414fdf17c23f07dc13e577883dca406", size = 11787271, upload-time = "2026-03-12T23:05:20.168Z" }, + { url = "https://files.pythonhosted.org/packages/7f/d0/578c47dd68152ddddddf31cd7fc67dc30b7cdf639a86275fda821b0d9d98/ruff-0.15.6-py3-none-win_arm64.whl", hash = "sha256:c34de3dd0b0ba203be50ae70f5910b17188556630e2178fd7d79fc030eb0d837", size = 11060497, upload-time = "2026-03-12T23:05:25.968Z" }, +] + [[package]] name = "s3transfer" version = "0.14.0"