Todo-list

Todo

Close the click-extra-side gaps the sections below identify:

  • a @persistent_option decorator (or a persistent=True kwarg on @option) registering an option on a group and injecting it into every subcommand at decoration time, covering the inherited-flags family Click has consistently declined;

  • populate ctx.params during shell completion, so a completion callback can depend on parameter values already typed on the command line;

  • native NushellComplete and PowerShellComplete classes, for users without the carapace binary the Carapace spec needs;

  • a @completion_option bundling multi-shell detection and auto-install, matching Typer’s --install-completion.

(The original entry is located in /home/runner/work/click-extra/click-extra/docs/benchmark.md, line 71.)

Todo

Use platformdirs for more advanced configuration folder detection?

(The original entry is located in /home/runner/work/click-extra/click-extra/click_extra/config/option.py:docstring of click_extra.config.option.ConfigOption.default_pattern, line 12.)

Todo

Propose addition of meta keyword upstream to Click.

(The original entry is located in /home/runner/work/click-extra/click-extra/click_extra/context.py:docstring of click_extra.context.Context, line 20.)

Todo

Drop this override once the minimum supported Click rises to

8.4.0 (which includes pallets/click#3420). The term_len-based visible-width check below becomes redundant once Click’s own wrapper counts visible width.

(The original entry is located in /home/runner/work/click-extra/click-extra/click_extra/highlight.py:docstring of click_extra.highlight.HelpFormatter.write_usage, line 29.)

Todo

Support case-foldeing, so we can have the Straße string matching the Strasse content.

This could be tricky as it messes with string length and characters index, which our logic relies on.

Danger

Danger

Roundtrip through lower-casing/upper-casing is a can of worms, because some characters change length when their case is changed:

(The original entry is located in /home/runner/work/click-extra/click-extra/click_extra/highlight.py:docstring of click_extra.highlight.highlight, line 6.)

Todo

Let the -v/-q counter reach beyond the current LogLevel range, as sketched by the -vvvv (trace) and -q (silence everything) notes that used to live on _VerbosityOption:

  • a TRACE pseudo-level below LogLevel.DEBUG (numeric value 5, mirroring logging.DEBUG - 5) so repeated -v can surface finer-grained tracing past DEBUG;

  • a SILENT pseudo-level above LogLevel.CRITICAL (any value above logging.CRITICAL) so repeated -q can suppress every record, including LogLevel.CRITICAL.

Both require extending LogLevel, which ripples into the --verbosity EnumChoice, the Formatter level-name color lookup and the level-ordering tests. They are intentionally left out of the symmetric-counter change that introduced -q, where the counter simply clamps at DEBUG/CRITICAL.

(The original entry is located in /home/runner/work/click-extra/click-extra/click_extra/logging.py:docstring of click_extra.logging, line 3.)

Todo

Submit a PR to Click to separate production of param spec and help record. That way we can always produce the param spec even if the parameter is hidden. See: https://github.com/kdeldycke/click-extra/issues/689

(The original entry is located in /home/runner/work/click-extra/click-extra/click_extra/parameters.py:docstring of click_extra.parameters.get_param_spec, line 10.)

Todo

Add the following build-time template fields, mirroring the constants shadow-rs injects:

  • {build_time}: when the distribution was built (shadow-rs exposes it as BUILD_TIME, with RFC 2822 and RFC 3339 variants BUILD_TIME_2822 / BUILD_TIME_3339).

  • {build_os} / {build_target} / {build_target_arch}: the OS, target triple and architecture the build ran on. These describe the build host, unlike {env_info} which reports the runtime Python, OS and architecture, so both are worth keeping for cross-built binaries.

(The original entry is located in /home/runner/work/click-extra/click-extra/click_extra/prebake.py:docstring of click_extra.prebake, line 14.)

Todo

Tokenize a Windows command line with quoting/escaping support, like shlex does on POSIX. The str.split() fallback _split_args uses there only splits on whitespace, so a quoted argument such as --name "two words" is wrongly broken into three tokens. Use w32lex, the Windows counterpart to shlex.

(The original entry is located in /home/runner/work/click-extra/click-extra/click_extra/test_suite.py:docstring of click_extra.test_suite, line 21.)

Todo

Add support for JWCC / hujson format?

(The original entry is located in /home/runner/work/click-extra/click-extra/click_extra/config/formats.py:docstring of click_extra.config.formats.ConfigFormat, line 21.)

Todo

Propose upstream to Click to extract the inline name.replace("-", "_") into a private _normalize_param_name helper, so downstream projects like Click Extra can reuse it instead of duplicating the transform.

(The original entry is located in /home/runner/work/click-extra/click-extra/click_extra/config/schema.py:docstring of click_extra.config.schema.normalize_config_keys, line 23.)

Todo

Remove this module entirely once click-extra drops Python 3.10. myst-parser 5.0 requires Python 3.11, and that is what holds the test dependency group at myst-parser>=4, resolved to 4.0.1 below Python 3.11 and to 5.1.0 above it; the docs group already sits at >=5.1.

Moving that floor is not enough on its own, because none of this repository’s floors reaches a consumer: nothing declares myst-parser, so a project still on myst-parser 4.x would lose its alert rendering with no error to show for it. Declare myst-parser>=5.1 in the sphinx extra in the same change, then delete this module, the setup-time version gate (click_extra.sphinx.MYST_NATIVE_ALERTS_VERSION) and the optional myst_parser import it reads, the log message pointing projects at the upstream extension, and the MYST_HAS_NATIVE_ALERTS switch the Sphinx test suite branches on.

(The original entry is located in /home/runner/work/click-extra/click-extra/click_extra/sphinx/alerts.py:docstring of click_extra.sphinx.alerts, line 16.)

Todo

Retire the MyST content_offset workaround once the pinned myst-parser floor rises past the release carrying the fix:

  • delete _myst_content_offset_inflation() and this constant, and collapse ClickDirective.abs_content_offset onto its rST branch (content_offset verbatim);

  • drop the directive.content fallback in click_extra.sphinx._base.directive_source(), which stays off block_text only because that attribute is body-only in myst-parser <= 5.1.0 (#1164 is merged but unreleased). A released block_text anchors a robust line-number computation and retires the workaround from both sides.

The single-trailing-blank-line case documented on _myst_content_offset_inflation() stays off by one until then, and no local fix can reach it: the round-trip consumes that line without a trace.

(The original entry is located in /home/runner/work/click-extra/click-extra/click_extra/sphinx/click.py:docstring of click_extra.sphinx.click.MYST_CONTENT_OFFSET_INFLATED_MAX, line 16.)

Todo

Declare TerminatedEchoingStdin instead of rewriting the __class__ of the instance Click already built. That needs Click to make EchoingStdin overridable: an echo_stdin_class attribute on click.testing.CliRunner, say, that isolation() instantiates rather than hard-coding. Worth proposing upstream.

(The original entry is located in /home/runner/work/click-extra/click-extra/click_extra/sphinx/click.py:docstring of click_extra.sphinx.click.ClickRunner.isolation, line 3.)

Todo

Propose the deduplication upstream, as a sphinx.ext.todo feature rather than a third-party hook.

The repetition is a property of how autodoc renders a docstring, not of how a project writes one, so every autodoc project documenting a module twice hits it and none of them can fix it in their own source: :no-index: reads like the cure and is not. sphinx.ext.todo.TodoListProcessor already flattens the whole domain in one place, which is where a todo_deduplicate config value would apply; the two helpers this module needed (todo_identity() and is_reexport()) are the whole of the logic.

Should it land, keep this module as a shim for the Sphinx releases below that floor, then drop it once the floor moves past them.

(The original entry is located in /home/runner/work/click-extra/click-extra/click_extra/sphinx/todos.py:docstring of click_extra.sphinx.todos, line 28.)

Todo

Open a narrowly-scoped Click issue and PR for a public click.Context accessor returning a parameter’s resolved (value, ParameterSource) after parsing, without re-firing eager callbacks. That is the forward resolution --params actually consumes, and landing it retires the re-parse this constant exists to feed.

Reference pallets/click#1279 as related, not as home: it asks for the inverse direction (reconstructing a normalized argv from a Context), was scoped with about a dozen normalization rules, flagged underdefined, and has stalled since 2023. Tracked in docs/upstream.md under “Normalized arguments”; the developer note below records why the cheaper alternatives do not work.

(The original entry is located in /home/runner/work/click-extra/click-extra/click_extra/context.py:docstring of click_extra.context.RAW_ARGS, line 9.)