Skip to content

Commit 20dd9b7

Browse files
MoffittAndrewJoeZiminskipre-commit-ci[bot]
authored
Add docstring linting (#493)
* Removing type hints from all docstrings * formatting parameter headings * Removing black + configuring ruff using movement repo config * moving per-file-ignores for __init__.py to the list in tool.ruff.lint * run pre-commit * enabling ruff-format * fixing pre-commit errors for test_configs and test_validation_unit * disabling pre-commit * Editing all test files to comply with linting rules * ignoring rule D100 for now * fixed datashuttle_functions.py * fixing datashuttle_class * fixing utils * fixed tui * fixed configs * run pre-commit * renaming TCH to TC * moving Iterable import into type checking block to comply with TC003 * re-arranging rules * Adding informative comment about ruff config * Filling in PLACEHOLDER dosctrings in configs and utils * syncing branch with main and adding PLACEHOLDER docstring * enabling ruff-format * pre-commit autofix * pre-commit autofix * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Fix linting. * Fixing validation as a test. * Rewrite config_class.py * Update canonical_folders.py * Update canonical_configs.py * Update load_configs.py * Update load_configs.py * Update datashuttle_class.py * Update ds_logger.py * Update decorators.py * Update data_transfer.py * Update rlcone.py. * Update getters.py * update formatting.py * update folders.py * Update folder_class.py * Update folder_utils.py * Update ssh.py * Update validate.py * Update tooltips.py * Update app.py * Update custom widgets. * Update interface.py * Update decorators.py * Update tui_validators.py * Update configs_content.py * Update validate_content.py * Update create_folders.py. * Update transfer_status_tree.py * Update logging.py. * Update transfer.py * Update new_project.py * update get_help.py * Update validate_at_path.py * Update settings.py * Update project_selector.py * Update project_manager.py * Update setup_ssh.py * Update modal_dialogs.py * Update datatypes.py * Update create_folder_settings.py * Add Returns sections. * Fix tests and remove PLACEHOLDER in tests. --------- Co-authored-by: JoeZiminski <[email protected]> Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
1 parent e47c162 commit 20dd9b7

File tree

79 files changed

+2906
-2334
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

79 files changed

+2906
-2334
lines changed

.pre-commit-config.yaml

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,23 +8,33 @@ repos:
88
- repo: https://github.com/pre-commit/pre-commit-hooks
99
rev: v5.0.0
1010
hooks:
11+
- id: check-added-large-files
1112
- id: check-docstring-first
1213
- id: check-executables-have-shebangs
14+
- id: check-case-conflict
1315
- id: check-merge-conflict
16+
- id: check-symlinks
17+
- id: check-yaml
1418
- id: check-toml
19+
- id: debug-statements
1520
- id: end-of-file-fixer
1621
- id: mixed-line-ending
1722
args: [--fix=lf]
23+
#- id: name-tests-test
24+
# args: ["--pytest-test-first"]
1825
- id: requirements-txt-fixer
1926
- id: trailing-whitespace
27+
- repo: https://github.com/pre-commit/pygrep-hooks
28+
rev: v1.10.0
29+
hooks:
30+
- id: rst-backticks
31+
- id: rst-directive-colons
32+
- id: rst-inline-touching-normal
2033
- repo: https://github.com/astral-sh/ruff-pre-commit
2134
rev: v0.11.12
2235
hooks:
2336
- id: ruff
24-
- repo: https://github.com/psf/black
25-
rev: 25.1.0
26-
hooks:
27-
- id: black
37+
- id: ruff-format
2838
- repo: https://github.com/pre-commit/mirrors-mypy
2939
rev: v1.16.0
3040
hooks:

datashuttle/configs/canonical_configs.py

Lines changed: 47 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,10 @@
1-
"""
2-
This module contains all information for the required
3-
format of the configs class. This is clearly defined
4-
as configs can be provided from file or input dynamically
5-
and so careful checks must be done.
6-
7-
If adding a new config, first add the key to
8-
get_canonical_configs() and type to
9-
get_canonical_configs()
1+
"""Contains all information defining the required format of the Configs class.
2+
3+
This format is clearly specified because configs can be supplied
4+
either from a file or dynamically, so careful validation is required.
5+
6+
If adding a new config key:
7+
- First add the key to `get_canonical_configs()` and define its type in the same function
108
"""
119

1210
from __future__ import annotations
@@ -31,10 +29,7 @@
3129

3230

3331
def get_canonical_configs() -> dict:
34-
"""
35-
The only permitted types for DataShuttle
36-
config values.
37-
"""
32+
"""Return the only permitted types for DataShuttle config values."""
3833
canonical_configs = {
3934
"local_path": Union[str, Path],
4035
"central_path": Optional[Union[str, Path]],
@@ -47,10 +42,9 @@ def get_canonical_configs() -> dict:
4742

4843

4944
def keys_str_on_file_but_path_in_class() -> list[str]:
50-
"""
51-
All configs which are paths are converted to pathlib.Path
52-
objects on load. This list indicates which config entries
53-
are to be converted to Path.
45+
"""Return a list of all config keys that are paths but stored as str in the file.
46+
47+
These are converted to pathlib.Path objects when loaded.
5448
"""
5549
return [
5650
"local_path",
@@ -64,18 +58,18 @@ def keys_str_on_file_but_path_in_class() -> list[str]:
6458

6559

6660
def check_dict_values_raise_on_fail(config_dict: Configs) -> None:
67-
"""
68-
Central function for performing checks on a
69-
DataShuttle Configs UserDict class. This should
70-
be run after any change to the configs (e.g.
71-
make_config_file, update_config_file, supply_config_file).
61+
"""Perform checks on a DataShuttle Configs UserDict class.
7262
73-
This will raise assert if condition is not met.
63+
This should be run after any change to the configs
64+
(e.g. make_config_file, update_config_file, supply_config_file).
65+
66+
This will raise an error if a condition is not met.
7467
7568
Parameters
7669
----------
70+
config_dict
71+
datashuttle config UserDict
7772
78-
config_dict : datashuttle config UserDict
7973
"""
8074
canonical_dict = get_canonical_configs()
8175

@@ -142,10 +136,10 @@ def check_dict_values_raise_on_fail(config_dict: Configs) -> None:
142136

143137

144138
def raise_on_bad_local_only_project_configs(config_dict: Configs) -> None:
145-
"""
146-
There is no circumstance where one of `central_path` and `connection_method`
147-
should be set and not the other. Either both are set ('full' project) or
148-
neither are ('local only' project). Check this assumption here.
139+
"""Check that both or neither of `central_path` and `connection_method` are set.
140+
141+
There is no circumstance where one is set and not the other. Either both are set
142+
('full' project) or both are `None` ('local only' project).
149143
"""
150144
params_are_none = local_only_configs_are_none(config_dict)
151145

@@ -159,6 +153,7 @@ def raise_on_bad_local_only_project_configs(config_dict: Configs) -> None:
159153

160154

161155
def local_only_configs_are_none(config_dict: Configs) -> list[bool]:
156+
"""Check whether `central_path` and `connection_method` are both set to None."""
162157
return [
163158
config_dict[key] is None
164159
for key in ["central_path", "connection_method"]
@@ -169,14 +164,10 @@ def raise_on_bad_path_syntax(
169164
path_name: str,
170165
path_type: str,
171166
) -> None:
172-
"""
173-
Error if some common, unsupported patterns are observed
174-
(e.g. ~, .) for path.
175-
"""
167+
"""Raise error if path contains unsupported patterns (e.g. ~, .)."""
176168
if path_name[0] == "~":
177169
utils.log_and_raise_error(
178-
f"{path_type} must contain the full folder path "
179-
"with no ~ syntax.",
170+
f"{path_type} must contain the full folder path with no ~ syntax.",
180171
ConfigError,
181172
)
182173

@@ -191,13 +182,10 @@ def raise_on_bad_path_syntax(
191182

192183

193184
def check_config_types(config_dict: Configs) -> None:
194-
"""
195-
Check the type of passed configs matches the canonical types.
196-
"""
185+
"""Check the type of passed configs matches the canonical types."""
197186
required_types = get_canonical_configs()
198187

199188
for key in config_dict.keys():
200-
201189
expected_type = required_types[key]
202190
try:
203191
typeguard.check_type(config_dict[key], expected_type)
@@ -216,14 +204,12 @@ def check_config_types(config_dict: Configs) -> None:
216204

217205

218206
def get_tui_config_defaults() -> Dict:
219-
"""
220-
Get the default settings for the datatype checkboxes
221-
in the TUI.
207+
"""Return the default settings for the datatype checkboxes in the TUI.
222208
223-
Two sets are maintained (one for creating,
224-
one for transfer) which have different defaults.
209+
Two sets are maintained (one for checkboxes on the create tab,
210+
the other for transfer tab) which have different defaults.
225211
By default, all broad datatype checkboxes are displayed,
226-
and narrow are turned off.
212+
and narrow datatypes are hidden and turned off.
227213
"""
228214
settings = {
229215
"tui": {
@@ -247,7 +233,6 @@ def get_tui_config_defaults() -> Dict:
247233

248234
# Fill all datatype options
249235
for broad_key in get_broad_datatypes():
250-
251236
settings["tui"]["create_checkboxes_on"][broad_key] = { # type: ignore
252237
"on": True,
253238
"displayed": True,
@@ -271,18 +256,16 @@ def get_tui_config_defaults() -> Dict:
271256

272257

273258
def get_name_templates_defaults() -> Dict:
259+
"""Return the default values for name_templates."""
274260
return {"name_templates": {"on": False, "sub": None, "ses": None}}
275261

276262

277263
def get_persistent_settings_defaults() -> Dict:
278-
"""
279-
Persistent settings are settings that are maintained
280-
across sessions. Currently, persistent settings for
281-
both the API and TUI are stored in the same place.
264+
"""Return the default persistent settings maintained across sessions.
282265
283-
Currently, settings for the working top level folder,
284-
TUI checkboxes and name templates (i.e. regexp
285-
validation for sub and ses names) are stored.
266+
Currently, these include settings for both the API and TUI, such as the
267+
working top level folder, TUI checkboxes, and name templates
268+
(i.e. regexp validation for sub and ses names).
286269
"""
287270
settings = {}
288271
settings.update(get_tui_config_defaults())
@@ -292,21 +275,21 @@ def get_persistent_settings_defaults() -> Dict:
292275

293276

294277
def get_datatypes() -> List[str]:
295-
"""
296-
Canonical list of datatype flags based on NeuroBlueprint.
278+
"""Return canonical list of datatype flags based on NeuroBlueprint.
297279
298280
This must be kept up to date with the datatypes in the NeuroBlueprint specification.
299281
"""
300282
return get_broad_datatypes() + quick_get_narrow_datatypes()
301283

302284

303285
def get_broad_datatypes():
286+
"""Return a list of broad datatypes."""
304287
return ["ephys", "behav", "funcimg", "anat"]
305288

306289

307290
def get_narrow_datatypes():
308-
"""
309-
Return the narrow datatype associated with each broad datatype.
291+
"""Return the narrow datatype associated with each broad datatype.
292+
310293
The mapping between broad and narrow datatypes is required for validation.
311294
"""
312295
return {
@@ -337,9 +320,9 @@ def get_narrow_datatypes():
337320

338321

339322
def quick_get_narrow_datatypes():
340-
"""
341-
A convenience wrapper around `get_narrow_datatypes()`
342-
to quickly get a list of all narrow datatypes.
323+
"""Return a flat list of all narrow datatypes.
324+
325+
This is a convenience wrapper around `get_narrow_datatypes()`.
343326
"""
344327
all_narrow_datatypes = get_narrow_datatypes()
345328
top_level_keys = list(all_narrow_datatypes.keys())
@@ -352,7 +335,8 @@ def quick_get_narrow_datatypes():
352335

353336

354337
def in_place_update_narrow_datatypes_if_required(user_settings: dict):
355-
"""
338+
"""Update legacy settings with the new version format.
339+
356340
In versions < v0.6.0, only 'broad' datatypes were implemented
357341
and available in the TUI. Since, 'narrow' datatypes are introduced
358342
and datatype tui can be set to be both on / off but also
@@ -389,7 +373,9 @@ def in_place_update_narrow_datatypes_if_required(user_settings: dict):
389373
dtype in user_settings["tui"]["transfer_checkboxes_on"]
390374
for dtype in all_narrow_datatypes
391375
]
392-
), "Somehow there are datatypes missing in `transfer_checkboxes_on` but not `create_checkboxes_on`"
376+
), (
377+
"Somehow there are datatypes missing in `transfer_checkboxes_on` but not `create_checkboxes_on`"
378+
)
393379

394380
if has_narrow_datatypes and is_not_missing_any_narrow_datatypes:
395381
return
@@ -421,15 +407,12 @@ def in_place_update_narrow_datatypes_if_required(user_settings: dict):
421407
# Copy any datatype information that exists. Broad datatypes will all be there
422408
# but some narrow datatypes might be missing.
423409
for checkbox_type in ["create_checkboxes_on", "transfer_checkboxes_on"]:
424-
425410
datatypes_that_user_has = list(
426411
user_settings["tui"][checkbox_type].keys()
427412
)
428413

429414
for dtype in get_datatypes():
430-
431415
if dtype in datatypes_that_user_has:
432-
433416
if has_narrow_datatypes:
434417
new_checkbox_configs[checkbox_type][dtype] = user_settings[
435418
"tui"

datashuttle/configs/canonical_folders.py

Lines changed: 20 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,7 @@
1111

1212

1313
def get_datatype_folders() -> dict:
14-
"""
15-
This function holds the canonical folders
16-
managed by datashuttle.
14+
"""Return the canonical folders managed by datashuttle.
1715
1816
Notes
1917
-----
@@ -24,14 +22,19 @@ def get_datatype_folders() -> dict:
2422
kept in case this changes.
2523
2624
The value is a Folder() class instance with
27-
the required fields
25+
the required fields.
2826
29-
name : The display name for the datatype, that will
27+
Parameters
28+
----------
29+
name
30+
The display name for the datatype, that will
3031
be used for making and transferring files in practice.
3132
This should always match the canonical name, but left as
3233
an option for rare cases in which advanced users want to change it.
3334
34-
level : "sub" or "ses", level to make the folder at.
35+
level
36+
"sub" or "ses", level to make the folder at.
37+
3538
"""
3639
return {
3740
datatype: Folder(name=datatype, level="ses")
@@ -40,9 +43,9 @@ def get_datatype_folders() -> dict:
4043

4144

4245
def get_non_sub_names() -> List[str]:
43-
"""
44-
Get all arguments that are not allowed at the
45-
subject level for data transfer, i.e. as sub_names
46+
"""Return all arguments that are not allowed at the subject level.
47+
48+
These are invalid as `sub_names` for data transfer.
4649
"""
4750
return [
4851
"all_ses",
@@ -53,10 +56,7 @@ def get_non_sub_names() -> List[str]:
5356

5457

5558
def get_non_ses_names() -> List[str]:
56-
"""
57-
Get all arguments that are not allowed at the
58-
session level for data transfer, i.e. as ses_names
59-
"""
59+
"""Return all arguments that are not allowed at the session level."""
6060
return [
6161
"all_sub",
6262
"all_non_sub",
@@ -66,34 +66,26 @@ def get_non_ses_names() -> List[str]:
6666

6767

6868
def canonical_reserved_keywords() -> List[str]:
69-
"""
70-
Key keyword arguments that are passed to `sub_names` or
71-
`ses_names` but that we
72-
"""
69+
"""Return key keyword arguments passed to `sub_names` or `ses_names`."""
7370
return get_non_sub_names() + get_non_ses_names()
7471

7572

7673
def get_top_level_folders() -> List[TopLevelFolder]:
74+
"""Return a list of canonical top level folder names."""
7775
return ["rawdata", "derivatives"]
7876

7977

8078
def get_datashuttle_path() -> Path:
81-
"""
82-
Get the datashuttle path where all project
83-
configs are stored.
84-
"""
79+
"""Return the datashuttle path where all project configs are stored."""
8580
return Path.home() / ".datashuttle"
8681

8782

8883
def get_project_datashuttle_path(project_name: str) -> Tuple[Path, Path]:
89-
"""
90-
Get the datashuttle path for the project,
91-
where configuration files are stored.
92-
Also, return a temporary path in this for logging in
93-
some cases where local_path location is not clear.
84+
"""Return the datashuttle config path for the project.
9485
95-
The datashuttle configuration path is stored in the user home
96-
folder.
86+
Also returns a temporary logging path used in cases when
87+
the `local_path` is not yet defined. The base configuration
88+
path is the user home directory.
9789
"""
9890
base_path = get_datashuttle_path() / project_name
9991
temp_logs_path = base_path / "temp_logs"

0 commit comments

Comments
 (0)