Skip to content

Support click >= 8.2.0#1883

Open
rly wants to merge 1 commit into
dandi:masterfrom
rly:support-click-8.2
Open

Support click >= 8.2.0#1883
rly wants to merge 1 commit into
dandi:masterfrom
rly:support-click-8.2

Conversation

@rly

@rly rly commented Jun 26, 2026

Copy link
Copy Markdown
Contributor

Closes #1631.

Summary

Removes the click < 8.2.0 upper bound so dandi-cli can be installed alongside packages that require newer click (for example linkml-runtime >= 1.11, which declares click >= 8.2). The bound guarded a behavior change in click 8.2's Choice rewrite; this PR adapts dandi's enum based options to that change while preserving the existing command line surface.

Background

click 8.2 made Choice generic. For an Enum, click.Choice(list(SomeEnum)) now matches on the enum member names instead of their values. dandi builds twelve options from (str, Enum) types whose values are the documented lowercase tokens (error, skip, refresh, ...), so under click 8.2+ those options accept --existing SKIP and reject --existing skip, breaking every documented invocation. The 8.2.2 release (referenced in click #2911) only changed how the default is rendered in --help; the matching behavior is unchanged and still reproduces on click 8.4.

Changes

  • Add EnumChoice to dandi/cli/base.py: a click.Choice subclass built from the enum member values that converts the matched value back to the enum member. This keeps the lowercase value tokens on the command line and passes the enum member to the command callback, matching pre 8.2 behavior on every supported click version.
  • Migrate the twelve click.Choice(list(SomeEnum)) options in cmd_upload, cmd_download, cmd_organize, and cmd_move to EnumChoice(SomeEnum). click.Choice(list(dandi_layout_fields)) is left as is because it is a dict of strings, unaffected by the enum change.
  • Drop the < 8.2.0 upper bound in pyproject.toml.
  • Add dandi/cli/tests/test_base.py.

EnumChoice follows the approach already used for --min-severity in cmd_validate.py, which builds its Choice from a list of strings derived from Severity ([i.name for i in Severity]) rather than from enum members, and is therefore unaffected by the click 8.2 change. EnumChoice generalizes that into a reusable type that is value-based and returns the enum member, which the upload, download, organize, and move callbacks expect. (NOTE: there are now two enum-to-Choice idioms in the CLI (value-based EnumChoice for str-enums, inline [i.name for i in …] for Severity). I kept the change minimal; happy to unify them in a follow-up if preferred.)

Compatibility

  • Behavior is identical on click 8.1.8 and 8.4.2: lowercase value accepted and converted to the enum member, string default converted to the member, member name rejected, and --help lists the lowercase values.
  • No use of other APIs removed in click 8.2 (BaseCommand, MultiCommand, the parser module, split_arg_string, OptionParser).

Testing

  • dandi/cli/tests/test_base.py, test_command.py, test_move.py, and the local organize choice mode tests pass on click 8.4.2; the new tests also pass on click 8.1.8.
  • black, isort, flake8, and mypy pass on all changed files.
  • Manual check of upload, download, organize, and move --help shows lowercase value choices; --existing skip resolves to the enum member and --existing SKIP is rejected as before.

click 8.2 made Choice generic and, for an Enum, matches on member names
instead of values. The (str, Enum) options in the CLI rely on their lowercase
values being the accepted tokens, so add an EnumChoice type that keeps choices
as the enum member values and returns the corresponding member, and use it for
the affected options. This lets the click < 8.2.0 upper bound be removed.

Closes dandi#1631

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@CodyCBakerPhD CodyCBakerPhD added patch Increment the patch version when merged dependencies Update one or more dependencies version labels Jun 26, 2026
@CodyCBakerPhD CodyCBakerPhD requested a review from yarikoptic June 26, 2026 20:24
@codecov

codecov Bot commented Jun 26, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 87.50000% with 8 lines in your changes missing coverage. Please review.
✅ Project coverage is 76.86%. Comparing base (65c79c9) to head (b10a299).

Files with missing lines Patch % Lines
dandi/cli/base.py 44.44% 5 Missing ⚠️
dandi/cli/tests/test_base.py 96.15% 2 Missing ⚠️
dandi/cli/cmd_organize.py 0.00% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master    #1883      +/-   ##
==========================================
+ Coverage   76.79%   76.86%   +0.07%     
==========================================
  Files          87       88       +1     
  Lines       12805    12866      +61     
==========================================
+ Hits         9833     9890      +57     
- Misses       2972     2976       +4     
Flag Coverage Δ
unittests 76.86% <87.50%> (+0.07%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

dependencies Update one or more dependencies version patch Increment the patch version when merged

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Support click >= 8.2.0

2 participants