From 57ec15302443000fadfdfdc8bdd75c9ef2b892de Mon Sep 17 00:00:00 2001 From: Yaroslav Halchenko Date: Thu, 16 Oct 2025 17:32:14 -0400 Subject: [PATCH 1/3] progress flake8 to next version in pre-commit need to ignore one more test A005 since we have queue.py and it shadows built-in queue --- .pre-commit-config.yaml | 2 +- tox.ini | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 029e041b..85ef5e5e 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -25,7 +25,7 @@ repos: - id: isort - repo: https://github.com/PyCQA/flake8 - rev: 6.0.0 + rev: 7.1.1 hooks: - id: flake8 additional_dependencies: diff --git a/tox.ini b/tox.ini index 55eca3e0..8395c9b6 100644 --- a/tox.ini +++ b/tox.ini @@ -55,7 +55,7 @@ exclude = .*/,build/,dist/,test/data,venv/ hang-closing = False unused-arguments-ignore-stub-functions = True select = A,B,B902,C,E,E242,F,U100,W -ignore = A003,B005,E203,E262,E266,E501,W503 +ignore = A003,A005,B005,E203,E262,E266,E501,W503 [isort] atomic = True From e9c9936732dd54a556bf20217ecccbb424c4d559 Mon Sep 17 00:00:00 2001 From: Yaroslav Halchenko Date: Thu, 16 Oct 2025 17:32:23 -0400 Subject: [PATCH 2/3] ENH: plug a full list of entities for BIDSFile current BIDS release, and boost BIDSVersion then to 1.10.1 --- heudiconv/bids.py | 68 +++++++++++++++++++++++++++++++++++++++++--- heudiconv/convert.py | 4 +++ 2 files changed, 68 insertions(+), 4 deletions(-) diff --git a/heudiconv/bids.py b/heudiconv/bids.py index 6a347977..289ce7e6 100644 --- a/heudiconv/bids.py +++ b/heudiconv/bids.py @@ -68,7 +68,7 @@ class BIDSError(Exception): pass -BIDS_VERSION = "1.8.0" +BIDS_VERSION = "1.10.1" # List defining allowed parameter matching for fmap assignment: SHIM_KEY = "ShimSetting" @@ -1067,17 +1067,33 @@ def populate_intended_for( class BIDSFile: - """as defined in https://bids-specification.readthedocs.io/en/stable/99-appendices/04-entity-table.html - which might soon become machine readable - order matters + """Representation of a BIDS file with order of entities following BIDS + + Full ordered list from + http://github.com/bids-standard/bids-specification/blob/HEAD/src/schema/rules/entities.yaml + while taking shortened versions from + https://github.com/bids-standard/bids-specification/blob/master/src/schema/objects/entities.yaml + + Use + + python -c 'from heudiconv.bids import BIDSFile; BIDSFile._print_entities()' + + to print the current list of entities to plug in below. """ + # For release 1.10.1 _known_entities = [ "sub", "ses", + "sample", "task", + "tracksys", "acq", + "nuc", + "voi", "ce", + "trc", + "stain", "rec", "dir", "run", @@ -1087,9 +1103,53 @@ class BIDSFile: "inv", "mt", "part", + "proc", + "hemi", + "space", + "split", "recording", + "chunk", + "seg", + "res", + "den", + "label", + "desc", ] + @staticmethod + def _get_entities(version: str = BIDS_VERSION) -> list[str]: + """Load BIDS entity rules and print entity names to plug above.""" + + from urllib.request import urlopen + + import yaml + + is_released = version and version[0].isdigit() + version_url = f"refs/tags/v{version}" if is_released else version + + base_url = f"https://raw.githubusercontent.com/bids-standard/bids-specification/{version_url}/src/schema" + + # Load the list of entity keys + with urlopen(f"{base_url}/rules/entities.yaml") as response: + entity_keys = yaml.safe_load(response) + + # Load the entities dictionary + with urlopen(f"{base_url}/objects/entities.yaml") as response: + entities_dict = yaml.safe_load(response) + + return [entities_dict[key]["name"] for key in entity_keys] + + @staticmethod + def _print_entities(version: str = BIDS_VERSION) -> None: + # Print the name for each entity + is_released = version and version[0].isdigit() + if is_released: + print(f" # For release {version}") + print(" _known_entities = [") + for ent in BIDSFile._get_entities(version=version): + print(f' "{ent}",') + print(" ]") + def __init__( self, entities: dict[str, str], suffix: str, extension: Optional[str] ) -> None: diff --git a/heudiconv/convert.py b/heudiconv/convert.py index 03de785a..17b933f4 100644 --- a/heudiconv/convert.py +++ b/heudiconv/convert.py @@ -1088,6 +1088,10 @@ def rename_files() -> None: # If we have failed to modify this_prefix_basename, because it didn't fall # into any of the options above, just add the suffix at the end: if this_prefix_basename == prefix_basename: + # TODO: never hit by tests! So what are the suffixes for?! + import pdb + + pdb.set_trace() this_prefix_basename += suffix # Finally, form the outname by stitching the directory and outtype: From 4b54f0e4f24a8aae9028048889b5ad939a15891f Mon Sep 17 00:00:00 2001 From: Yaroslav Halchenko Date: Thu, 16 Oct 2025 18:35:39 -0400 Subject: [PATCH 3/3] RF: get rid of pyyaml, just load from json serialization shipped along with website --- heudiconv/bids.py | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/heudiconv/bids.py b/heudiconv/bids.py index 289ce7e6..67a961d4 100644 --- a/heudiconv/bids.py +++ b/heudiconv/bids.py @@ -1120,24 +1120,25 @@ class BIDSFile: def _get_entities(version: str = BIDS_VERSION) -> list[str]: """Load BIDS entity rules and print entity names to plug above.""" - from urllib.request import urlopen - - import yaml + import json + from urllib.request import Request, urlopen is_released = version and version[0].isdigit() - version_url = f"refs/tags/v{version}" if is_released else version - - base_url = f"https://raw.githubusercontent.com/bids-standard/bids-specification/{version_url}/src/schema" - - # Load the list of entity keys - with urlopen(f"{base_url}/rules/entities.yaml") as response: - entity_keys = yaml.safe_load(response) + version_url = f"v{version}" if is_released else version - # Load the entities dictionary - with urlopen(f"{base_url}/objects/entities.yaml") as response: - entities_dict = yaml.safe_load(response) + schema_url = ( + f"https://bids-specification.readthedocs.io/en/{version_url}/schema.json" + ) + headers = { + "User-Agent": "heudiconv/{__version__}", + } + with urlopen(Request(schema_url, headers=headers)) as response: + schema = json.loads(response.read().decode()) - return [entities_dict[key]["name"] for key in entity_keys] + return [ + schema["objects"]["entities"][key]["name"] + for key in schema["rules"]["entities"] + ] @staticmethod def _print_entities(version: str = BIDS_VERSION) -> None: