Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,9 @@ classifiers = [
requires-python = ">=3.10"
dependencies = [
"globus-sdk==4.6.0",
"click>=8.1.4,<8.4",
# NOTE: `click` does not use semver; minor releases are expected to contain
# minor breaking changes
"click>=8.4,<8.5",
"jmespath==1.1.0",
"packaging>=17.0",
"typing_extensions>=4.0;python_version<'3.11'",
Expand Down Expand Up @@ -61,7 +63,7 @@ test = [
]
test-mindeps = [
{include-group = "test"},
"click==8.1.8",
"click==8.4.0",
"requests==2.32.4",
"pyjwt==2.0.0",
"cryptography==3.3.1",
Expand Down
55 changes: 0 additions & 55 deletions src/globus_cli/_click_compat.py

This file was deleted.

17 changes: 4 additions & 13 deletions src/globus_cli/commands/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
from globus_sdk.scopes import ScopeParser

from globus_cli import termio, version
from globus_cli._click_compat import shim_get_metavar
from globus_cli.login_manager import LoginManager, is_client_login
from globus_cli.login_manager.scopes import CLI_SCOPE_REQUIREMENTS
from globus_cli.parsing import command, endpoint_id_arg, group, mutex_option_group
Expand All @@ -20,8 +19,7 @@
C = t.TypeVar("C", bound=AnyCommand)


class QueryParamType(click.ParamType):
@shim_get_metavar
class QueryParamType(click.ParamType[tuple[str, str] | None]):
def get_metavar(self, param: click.Parameter, ctx: click.Context) -> str:
return "Key=Value"

Expand All @@ -33,21 +31,17 @@ def get_type_annotation(self, param: click.Parameter) -> type:

def convert(
self,
value: str | None,
value: str,
param: click.Parameter | None,
ctx: click.Context | None,
) -> tuple[str, str] | None:
value = super().convert(value, param, ctx)
Comment thread
kurtmckee marked this conversation as resolved.
if value is None:
return None
if "=" not in value:
self.fail("invalid query param", param=param, ctx=ctx)
left, right = value.split("=", 1)
return (left, right)


class HeaderParamType(click.ParamType):
@shim_get_metavar
class HeaderParamType(click.ParamType[tuple[str, str] | None]):
def get_metavar(self, param: click.Parameter, ctx: click.Context) -> str:
return "Key:Value"

Expand All @@ -59,13 +53,10 @@ def get_type_annotation(self, param: click.Parameter) -> type:

def convert(
self,
value: str | None,
value: str,
param: click.Parameter | None,
ctx: click.Context | None,
) -> tuple[str, str] | None:
value = super().convert(value, param, ctx)
if value is None:
return None
if ":" not in value:
self.fail("invalid header param", param=param, ctx=ctx)
left, right = value.split(":", 1)
Expand Down
21 changes: 2 additions & 19 deletions src/globus_cli/commands/collection/list.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
from __future__ import annotations

import sys
import typing as t
import uuid

Expand All @@ -12,22 +11,8 @@
from globus_cli.termio import Field, display, formatters
from globus_cli.utils import PagingWrapper

if sys.version_info >= (3, 10):
from typing import TypeAlias
else:
from typing_extensions import TypeAlias

# until our minimum click version is 8.2.0+ , we need to handle the fact that
# click.Choice became a generic in 8.2.0
# we cannot leave it without a defined type parameter, as we have
# "no-any-generics" set for mypy
if t.TYPE_CHECKING:
ChoiceType: TypeAlias = click.Choice[str]
else:
ChoiceType = click.Choice


class ChoiceSlugified(ChoiceType):
class ChoiceSlugified(click.Choice[str]):
"""
Allow either hyphens or underscores, e.g. both 'mapped-collections' or
'mapped_collections'
Expand All @@ -37,10 +22,8 @@ def get_type_annotation(self, param: click.Parameter) -> type:
return t.cast(type, t.Literal[tuple(self._slugify(c) for c in self.choices)])

def convert(
self, value: t.Any, param: click.Parameter | None, ctx: click.Context | None
self, value: str, param: click.Parameter | None, ctx: click.Context | None
) -> t.Any:
if value is None:
return None
return self._slugify(super().convert(value.replace("_", "-"), param, ctx))

def _slugify(self, value: str) -> str:
Expand Down
2 changes: 1 addition & 1 deletion src/globus_cli/commands/endpoint/set_subscription_id.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
from globus_cli.termio import display


class SubscriptionIdType(click.ParamType):
class SubscriptionIdType(click.ParamType[str]):
def convert(
self, value: str, param: click.Parameter | None, ctx: click.Context | None
) -> str:
Expand Down
4 changes: 3 additions & 1 deletion src/globus_cli/commands/flows/_common.py
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,9 @@
)


class SubscriptionIdType(click.ParamType):
class SubscriptionIdType(
click.ParamType[uuid.UUID | t.Literal["DEFAULT"] | globus_sdk.MissingType]
):
name = "SUBSCRIPTION_ID"

def __init__(self, *, omittable: bool = False) -> None:
Expand Down
2 changes: 0 additions & 2 deletions src/globus_cli/commands/flows/start.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
import click
import globus_sdk

from globus_cli._click_compat import shim_get_metavar
from globus_cli.commands.flows._common import FlowScopeInjector
from globus_cli.commands.flows._fields import flow_run_format_fields
from globus_cli.login_manager import LoginManager
Expand Down Expand Up @@ -43,7 +42,6 @@ class ActivityNotificationPolicyType(JSONStringOrFile):

choices = ("INACTIVE", "FAILED", "SUCCEEDED")

@shim_get_metavar
def get_metavar(self, param: click.Parameter, ctx: click.Context) -> str:
return f"[{{{','.join(self.choices)}}}|JSON_FILE|JSON]"

Expand Down
2 changes: 1 addition & 1 deletion src/globus_cli/commands/gcp/set_subscription_id.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
from globus_cli.termio import display


class GCPSubscriptionIdType(click.ParamType):
class GCPSubscriptionIdType(click.ParamType[uuid.UUID | ExplicitNullType]):
def convert(
self, value: str, param: click.Parameter | None, ctx: click.Context | None
) -> uuid.UUID | ExplicitNullType:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@
from globus_cli.termio import display


class GCSSubscriptionIdType(click.ParamType):
class GCSSubscriptionIdType(
click.ParamType[uuid.UUID | t.Literal["DEFAULT"] | ExplicitNullType]
):
def convert(
self, value: str, param: click.Parameter | None, ctx: click.Context | None
) -> uuid.UUID | t.Literal["DEFAULT"] | ExplicitNullType:
Expand Down
4 changes: 1 addition & 3 deletions src/globus_cli/commands/gcs/endpoint/update.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
import click
import globus_sdk

from globus_cli._click_compat import shim_get_metavar
from globus_cli.commands.gcs.endpoint._common import GCS_ENDPOINT_FIELDS
from globus_cli.constants import EXPLICIT_NULL, ExplicitNullType
from globus_cli.login_manager import LoginManager
Expand All @@ -19,8 +18,7 @@
F = t.TypeVar("F", bound=AnyCallable)


class SubscriptionIdType(click.ParamType):
@shim_get_metavar
class SubscriptionIdType(click.ParamType[str | ExplicitNullType]):
def get_metavar(self, param: click.Parameter, ctx: click.Context) -> str:
return "[<uuid>|DEFAULT|null]"

Expand Down
2 changes: 1 addition & 1 deletion src/globus_cli/commands/group/_common.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ def group_id_arg(f: C) -> C:
return click.argument("GROUP_ID", type=click.UUID)(f)


class GroupSubscriptionVerifiedIdType(click.ParamType):
class GroupSubscriptionVerifiedIdType(click.ParamType[uuid.UUID | ExplicitNullType]):
name = "TEXT"

def convert(
Expand Down
7 changes: 2 additions & 5 deletions src/globus_cli/commands/login.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
)
from globus_sdk.services.flows import SpecificFlowClient

from globus_cli._click_compat import shim_get_metavar
from globus_cli.login_manager import LoginManager, is_client_login
from globus_cli.parsing import command, no_local_server_option
from globus_cli.termio import verbosity
Expand Down Expand Up @@ -50,10 +49,9 @@
"""


class GCSEndpointType(click.ParamType):
class GCSEndpointType(click.ParamType[uuid.UUID | tuple[uuid.UUID, uuid.UUID]]):
name = "GCS Server"

@shim_get_metavar
def get_metavar(self, param: click.Parameter, ctx: click.Context) -> str:
return "<endpoint_id>[:<collection_id>]"

Expand Down Expand Up @@ -88,10 +86,9 @@ def convert(
return endpoint_id if not collection_id else (endpoint_id, collection_id)


class TimerResourceType(click.ParamType):
class TimerResourceType(click.ParamType[tuple[t.Literal["flow"], uuid.UUID]]):
name = "TIMER_RESOURCE"

@shim_get_metavar
def get_metavar(self, param: click.Parameter, ctx: click.Context) -> str:
return "flow:<flow_id>"

Expand Down
18 changes: 0 additions & 18 deletions src/globus_cli/parsing/commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@

import click

from globus_cli._click_compat import OLDER_CLICK_API
from globus_cli.exception_handling import custom_except_hook
from globus_cli.termio import env_interactive

Expand Down Expand Up @@ -176,23 +175,6 @@ def _lazy_load(self, ctx: click.Context, cmd_name: str) -> click.Command:
)
return cmd_object

# only redefine `invoke()` if we're on click<8.2.0
# on newer versions, the behavior is improved upstream
if OLDER_CLICK_API:

def invoke(self, ctx: click.Context) -> t.Any:
# if no subcommand was given (but, potentially, flags were passed),
# ctx.protected_args will be empty
# improves upon the built-in detection given on click.Group by
# no_args_is_help , since that treats options (without a subcommand) as
# being arguments and blows up with a "Missing command" failure
# for reference to the original version (as of 2017-02-26):
# https://github.com/pallets/click/blob/02ea9ee7e864581258b4902d6e6c1264b0226b9f/click/core.py#L1039-L1052
if self.no_args_is_help and not ctx.protected_args:
click.echo(ctx.get_help())
ctx.exit()
return super().invoke(ctx)


class TopLevelGroup(GlobusCommandGroup):
"""
Expand Down
23 changes: 3 additions & 20 deletions src/globus_cli/parsing/param_types/delimited.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,11 @@
import click
import globus_sdk

from globus_cli._click_compat import (
OLDER_CLICK_API,
shim_get_metavar,
shim_get_missing_message,
)

if t.TYPE_CHECKING:
from click.shell_completion import CompletionItem


class CommaDelimitedList(click.ParamType):
class CommaDelimitedList(click.ParamType[list[str] | globus_sdk.MissingType]):
def __init__(
self,
*,
Expand All @@ -28,7 +22,6 @@ def __init__(
self.convert_values = convert_values
self.choices = list(choices) if choices is not None else None

@shim_get_metavar
def get_metavar(self, param: click.Parameter, ctx: click.Context) -> str:
if self.choices is not None:
return "{" + ",".join(self.choices) + "}"
Expand Down Expand Up @@ -75,7 +68,7 @@ def get_type_annotation(self, param: click.Parameter) -> type:
return list[str]


class ColonDelimitedChoiceTuple(click.ParamType):
class ColonDelimitedChoiceTuple(click.ParamType[tuple[str, ...]]):
"""
A colon-delimited choice type which wraps the existing click.Choice type.

Expand All @@ -102,25 +95,15 @@ def __init__(

self.unpacked_choices = self._unpack_choices()

def to_info_dict(self) -> dict[str, t.Any]:
def to_info_dict(self) -> click.types.ParamTypeInfoDict:
return self.inner_choice_param.to_info_dict()

@shim_get_metavar
def get_metavar(self, param: click.Parameter, ctx: click.Context) -> str | None:
if OLDER_CLICK_API:
# type checking on newer click versions will flag this, but incorrectly so
return self.inner_choice_param.get_metavar(param) # type: ignore[call-arg]
return self.inner_choice_param.get_metavar(param, ctx)

@shim_get_missing_message
def get_missing_message(
self, param: click.Parameter, ctx: click.Context | None
) -> str:
if OLDER_CLICK_API:
# type checking on newer click versions will flag this, but incorrectly so
return self.inner_choice_param.get_missing_message(
param=param # type: ignore[call-arg]
)
return self.inner_choice_param.get_missing_message(param=param, ctx=ctx)

def shell_complete(
Expand Down
Loading
Loading