Skip to content

Commit 7e306ff

Browse files
yarikopticclaude
andcommitted
Replace Literal zarr_mode with ZarrMode(str, Enum)
Follow existing codebase pattern (UploadExisting, DownloadExisting, etc.) to define ZarrMode as a str Enum in upload.py. Eliminates the duplicated Literal["full", "patch"] across three files and the cast() workaround in cmd_upload.py. Uses TYPE_CHECKING guard in files/zarr.py to avoid circular import (files/zarr.py -> upload.py -> .files). Co-Authored-By: Claude Code 2.1.63 / Claude Opus 4.6 <noreply@anthropic.com>
1 parent a9d61f4 commit 7e306ff

File tree

3 files changed

+19
-10
lines changed

3 files changed

+19
-10
lines changed

dandi/cli/cmd_upload.py

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
from __future__ import annotations
22

3-
from typing import Literal, cast
4-
53
import click
64

75
from .base import (
@@ -11,7 +9,7 @@
119
instance_option,
1210
map_to_click_exceptions,
1311
)
14-
from ..upload import UploadExisting, UploadValidation
12+
from ..upload import UploadExisting, UploadValidation, ZarrMode
1513

1614

1715
@click.command()
@@ -52,7 +50,7 @@
5250
)
5351
@click.option(
5452
"--zarr-mode",
55-
type=click.Choice(["full", "patch"]),
53+
type=click.Choice(list(ZarrMode)),
5654
default="full",
5755
help=(
5856
"Zarr sync mode: 'full' (default) syncs completely; "
@@ -87,7 +85,7 @@ def upload(
8785
dandi_instance: str,
8886
existing: UploadExisting,
8987
validation: UploadValidation,
90-
zarr_mode: str,
88+
zarr_mode: ZarrMode,
9189
# Development options should come as kwargs
9290
allow_any_path: bool = False,
9391
upload_dandiset_metadata: bool = False,
@@ -128,5 +126,5 @@ def upload(
128126
jobs=jobs,
129127
jobs_per_file=jobs_per_file,
130128
sync=sync,
131-
zarr_mode=cast(Literal["full", "patch"], zarr_mode),
129+
zarr_mode=zarr_mode,
132130
)

dandi/files/zarr.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,10 @@
1212
import os.path
1313
from pathlib import Path
1414
from time import sleep
15-
from typing import Any, Literal, Optional
15+
from typing import TYPE_CHECKING, Any, Optional
16+
17+
if TYPE_CHECKING:
18+
from ..upload import ZarrMode
1619
import urllib.parse
1720

1821
from dandischema.models import BareAsset, DigestType
@@ -557,7 +560,7 @@ def iter_upload(
557560
metadata: dict[str, Any],
558561
jobs: int | None = None,
559562
replacing: RemoteAsset | None = None,
560-
zarr_mode: Literal["full", "patch"] = "full",
563+
zarr_mode: ZarrMode = "full", # type: ignore[assignment]
561564
) -> Iterator[dict]:
562565
"""
563566
Upload the Zarr directory as an asset with the given metadata to the

dandi/upload.py

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
import re
2222
import time
2323
from time import sleep
24-
from typing import Any, Literal, TypedDict, cast
24+
from typing import Any, TypedDict, cast
2525
from unittest.mock import patch
2626

2727
import click
@@ -101,6 +101,14 @@ def __str__(self) -> str:
101101
return self.value
102102

103103

104+
class ZarrMode(str, Enum):
105+
FULL = "full"
106+
PATCH = "patch"
107+
108+
def __str__(self) -> str:
109+
return self.value
110+
111+
104112
def upload(
105113
paths: Sequence[str | Path] | None = None,
106114
existing: UploadExisting = UploadExisting.REFRESH,
@@ -112,7 +120,7 @@ def upload(
112120
jobs: int | None = None,
113121
jobs_per_file: int | None = None,
114122
sync: bool = False,
115-
zarr_mode: Literal["full", "patch"] = "full",
123+
zarr_mode: ZarrMode = ZarrMode.FULL,
116124
) -> None:
117125
if paths:
118126
paths = [Path(p).absolute() for p in paths]

0 commit comments

Comments
 (0)