Skip to content

Commit 749b5aa

Browse files
committed
Replace magic string arguments with enums
1 parent cb86c9c commit 749b5aa

19 files changed

+620
-388
lines changed

dandi/cli/cmd_digest.py

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
from __future__ import annotations
2+
13
import click
24

35
from .base import map_to_click_exceptions
@@ -18,7 +20,7 @@
1820
)
1921
@click.argument("paths", nargs=-1, type=click.Path(exists=True))
2022
@map_to_click_exceptions
21-
def digest(paths, digest_alg):
23+
def digest(paths: tuple[str, ...], digest_alg: str) -> None:
2224
"""Calculate file digests"""
2325
from ..support.digests import get_digest
2426

dandi/cli/cmd_download.py

+18-15
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,13 @@
1+
from __future__ import annotations
2+
3+
from collections.abc import Sequence
14
import os
25

36
import click
47

58
from .base import ChoiceList, IntColonInt, instance_option, map_to_click_exceptions
69
from ..dandiarchive import _dandi_url_parser, parse_dandi_url
10+
from ..download import DownloadExisting, DownloadFormat, PathType
711
from ..utils import get_instance
812

913

@@ -28,9 +32,8 @@
2832
@click.option(
2933
"-e",
3034
"--existing",
31-
type=click.Choice(
32-
["error", "skip", "overwrite", "overwrite-different", "refresh"]
33-
), # TODO: verify-reupload (to become default)
35+
type=click.Choice(list(DownloadExisting)),
36+
# TODO: verify-reupload (to become default)
3437
help="What to do if a file found existing locally. 'refresh': verify "
3538
"that according to the size and mtime, it is the same file, if not - "
3639
"download and overwrite.",
@@ -41,12 +44,12 @@
4144
"-f",
4245
"--format",
4346
help="Choose the format/frontend for output. TODO: support all of the ls",
44-
type=click.Choice(["pyout", "debug"]),
47+
type=click.Choice(list(DownloadFormat)),
4548
default="pyout",
4649
)
4750
@click.option(
4851
"--path-type",
49-
type=click.Choice(["exact", "glob"]),
52+
type=click.Choice(list(PathType)),
5053
default="exact",
5154
help="Whether to interpret asset paths in URLs as exact matches or glob patterns",
5255
show_default=True,
@@ -96,16 +99,16 @@
9699
@click.argument("url", nargs=-1)
97100
@map_to_click_exceptions
98101
def download(
99-
url,
100-
output_dir,
101-
existing,
102-
jobs,
103-
format,
104-
download_types,
105-
sync,
106-
dandi_instance,
107-
path_type,
108-
):
102+
url: Sequence[str],
103+
output_dir: str,
104+
existing: DownloadExisting,
105+
jobs: tuple[int, int],
106+
format: DownloadFormat,
107+
download_types: set[str],
108+
sync: bool,
109+
dandi_instance: str,
110+
path_type: PathType,
111+
) -> None:
109112
# We need to import the download module rather than the download function
110113
# so that the tests can properly patch the function with a mock.
111114
from .. import download

dandi/cli/cmd_move.py

+6-5
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import click
44

55
from .base import devel_debug_option, instance_option, map_to_click_exceptions
6+
from ..move import MoveExisting, MoveWorkOn
67

78

89
@click.command()
@@ -15,7 +16,7 @@
1516
@click.option(
1617
"-e",
1718
"--existing",
18-
type=click.Choice(["error", "skip", "overwrite"]),
19+
type=click.Choice(list(MoveExisting)),
1920
default="error",
2021
help="How to handle assets that would be moved to a destination that already exists",
2122
show_default=True,
@@ -29,7 +30,7 @@
2930
@click.option(
3031
"-w",
3132
"--work-on",
32-
type=click.Choice(["auto", "both", "local", "remote"]),
33+
type=click.Choice(list(MoveWorkOn)),
3334
default="auto",
3435
help=(
3536
"Whether to operate on the local Dandiset, remote Dandiset, or both;"
@@ -44,13 +45,13 @@
4445
@devel_debug_option()
4546
@map_to_click_exceptions
4647
def move(
47-
paths: tuple[str],
48+
paths: tuple[str, ...],
4849
dandiset: str | None,
4950
dry_run: bool,
50-
existing: str,
51+
existing: MoveExisting,
5152
jobs: int | None,
5253
regex: bool,
53-
work_on: str,
54+
work_on: MoveWorkOn,
5455
dandi_instance: str,
5556
devel_debug: bool = False,
5657
) -> None:

dandi/cli/cmd_organize.py

+15-14
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@
33
import click
44

55
from .base import dandiset_path_option, devel_debug_option, map_to_click_exceptions
6-
from ..consts import dandi_layout_fields, file_operation_modes
6+
from ..consts import dandi_layout_fields
7+
from ..organize import CopyMode, FileOperationMode, OrganizeInvalid
78

89

910
@click.command()
@@ -16,7 +17,7 @@
1617
@click.option(
1718
"--invalid",
1819
help="What to do if files without sufficient metadata are encountered.",
19-
type=click.Choice(["fail", "warn"]),
20+
type=click.Choice(list(OrganizeInvalid)),
2021
default="fail",
2122
show_default=True,
2223
)
@@ -29,7 +30,7 @@
2930
"If 'auto' - whichever of symlink, hardlink, copy is allowed by system. "
3031
"The other modes (copy, move, symlink, hardlink) define how data files "
3132
"should be made available.",
32-
type=click.Choice(file_operation_modes),
33+
type=click.Choice(list(FileOperationMode)),
3334
default="auto",
3435
show_default=True,
3536
)
@@ -44,7 +45,7 @@
4445
)
4546
@click.option(
4647
"--media-files-mode",
47-
type=click.Choice(["copy", "move", "symlink", "hardlink"]),
48+
type=click.Choice(list(CopyMode)),
4849
default=None,
4950
help="How to relocate video files referenced by NWB files",
5051
)
@@ -63,16 +64,16 @@
6364
@devel_debug_option()
6465
@map_to_click_exceptions
6566
def organize(
66-
paths,
67-
required_fields,
68-
dandiset_path=None,
69-
invalid="fail",
70-
files_mode="auto",
71-
devel_debug=False,
72-
update_external_file_paths=False,
73-
media_files_mode=None,
74-
jobs=None,
75-
):
67+
paths: tuple[str, ...],
68+
required_fields: tuple[str, ...],
69+
dandiset_path: str | None,
70+
invalid: OrganizeInvalid,
71+
files_mode: FileOperationMode,
72+
media_files_mode: CopyMode | None,
73+
update_external_file_paths: bool,
74+
jobs: int | None,
75+
devel_debug: bool = False,
76+
) -> None:
7677
"""(Re)organize files according to the metadata.
7778
7879
The purpose of this command is to take advantage of metadata contained in

dandi/cli/cmd_upload.py

+18-14
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
from __future__ import annotations
2+
13
import click
24

35
from .base import (
@@ -7,13 +9,14 @@
79
instance_option,
810
map_to_click_exceptions,
911
)
12+
from ..upload import UploadExisting, UploadValidation
1013

1114

1215
@click.command()
1316
@click.option(
1417
"-e",
1518
"--existing",
16-
type=click.Choice(["error", "skip", "force", "overwrite", "refresh"]),
19+
type=click.Choice(list(UploadExisting)),
1720
help="What to do if a file found existing on the server. 'skip' would skip"
1821
"the file, 'force' - force reupload, 'overwrite' - force upload if "
1922
"either size or modification time differs; 'refresh' - upload only if "
@@ -24,6 +27,7 @@
2427
@click.option(
2528
"-J",
2629
"--jobs",
30+
"jobs_pair",
2731
type=IntColonInt(),
2832
help=(
2933
"Number of assets to upload in parallel and, optionally, number of"
@@ -36,7 +40,7 @@
3640
@click.option(
3741
"--validation",
3842
help="Data must pass validation before the upload. Use of this option is highly discouraged.",
39-
type=click.Choice(["require", "skip", "ignore"]),
43+
type=click.Choice(list(UploadValidation)),
4044
default="require",
4145
show_default=True,
4246
)
@@ -61,17 +65,17 @@
6165
@devel_debug_option()
6266
@map_to_click_exceptions
6367
def upload(
64-
paths,
65-
jobs,
66-
sync,
67-
dandi_instance,
68-
existing="refresh",
69-
validation="require",
68+
paths: tuple[str, ...],
69+
jobs_pair: tuple[int, int] | None,
70+
sync: bool,
71+
dandi_instance: str,
72+
existing: UploadExisting,
73+
validation: UploadValidation,
7074
# Development options should come as kwargs
71-
allow_any_path=False,
72-
upload_dandiset_metadata=False,
73-
devel_debug=False,
74-
):
75+
allow_any_path: bool = False,
76+
upload_dandiset_metadata: bool = False,
77+
devel_debug: bool = False,
78+
) -> None:
7579
"""
7680
Upload Dandiset files to DANDI Archive.
7781
@@ -89,11 +93,11 @@ def upload(
8993
"""
9094
from ..upload import upload
9195

92-
if jobs is None:
96+
if jobs_pair is None:
9397
jobs = None
9498
jobs_per_file = None
9599
else:
96-
jobs, jobs_per_file = jobs
100+
jobs, jobs_per_file = jobs_pair
97101

98102
upload(
99103
paths,

0 commit comments

Comments
 (0)