Skip to content
This repository was archived by the owner on Jun 2, 2026. It is now read-only.

Commit 257d55d

Browse files
committed
Fix CLI type annotations on Python 3.9
1 parent 5cd5bac commit 257d55d

2 files changed

Lines changed: 30 additions & 6 deletions

File tree

defectdojo_api_generated/cli/commands/apis.py

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,14 @@ def _get_click_type(
196196
raise TypeError(f'Unsupported CLI parameter type{param_name}: {current!r}. Only primitive types are supported.')
197197

198198

199+
def _get_class_annotation(click_type: Any) -> type:
200+
# Classyclick inspects annotations at import time and expects a runtime type,
201+
# not typing.Any or a ParamType instance such as click.Path(...).
202+
if click_type is Any or isinstance(click_type, click.ParamType):
203+
return str
204+
return click_type
205+
206+
199207
def _iter_command_parameters(api_class: type, target_method: str):
200208
signature = inspect.signature(getattr(api_class, target_method))
201209

@@ -286,7 +294,7 @@ def __call__(self):
286294
}
287295

288296
for field_name, field, click_type, multiple, _converter in required_fields:
289-
namespace['__annotations__'][field_name] = click_type
297+
namespace['__annotations__'][field_name] = _get_class_annotation(click_type)
290298
option_kwargs = {
291299
'help': _get_model_field_help(field),
292300
'required': True,
@@ -306,7 +314,7 @@ def __call__(self):
306314
namespace['__annotations__']['jq'] = str
307315

308316
for field_name, field, click_type, multiple, _converter in optional_fields:
309-
namespace['__annotations__'][field_name] = click_type
317+
namespace['__annotations__'][field_name] = _get_class_annotation(click_type)
310318
option_kwargs = {
311319
'help': _get_model_field_help(field),
312320
'default': field.default,
@@ -519,7 +527,7 @@ def __call__(self):
519527

520528
for name, parameter, click_type, multiple, _converter in required_parameters:
521529
# required request-body models are passed as JSON strings and converted before the API call
522-
namespace['__annotations__'][name] = click_type
530+
namespace['__annotations__'][name] = _get_class_annotation(click_type)
523531
option_kwargs = {
524532
'help': _get_help_from_annotation(parameter.annotation),
525533
'required': True,
@@ -539,7 +547,7 @@ def __call__(self):
539547
namespace['__annotations__']['jq'] = str
540548

541549
for name, parameter, click_type, multiple, _converter in optional_parameters:
542-
namespace['__annotations__'][name] = click_type
550+
namespace['__annotations__'][name] = _get_class_annotation(click_type)
543551
option_kwargs = {
544552
'help': _get_help_from_annotation(parameter.annotation),
545553
'default': parameter.default,

tests/unit/test_cli.py

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,11 @@
33
import unittest
44
from importlib.metadata import version
55
from pathlib import Path
6-
from typing import Optional
6+
from typing import Any, Optional
77
from unittest import mock
88

99
from click.testing import CliRunner
10-
from pydantic import Field
10+
from pydantic import BaseModel, Field
1111
from typing_extensions import Annotated
1212

1313
from defectdojo_api_generated.api.findings_api import FindingsApi
@@ -287,6 +287,22 @@ def test_required_request_body_parameters_become_field_flags(self):
287287
payload = json.loads(run_result.output)
288288
self.assertEqual(payload['name'], 'Example')
289289

290+
def test_request_model_fields_typed_as_any_register_without_import_errors(self):
291+
class AnyRequest(BaseModel):
292+
payload: Any = None
293+
294+
class AnyRequestApi:
295+
def __init__(self, api_client):
296+
self.api_client = api_client
297+
298+
def create(self, any_request: AnyRequest):
299+
return any_request.model_dump()
300+
301+
command = make_api_group('any_request_api', AnyRequestApi).click
302+
option = next(param for param in command.params if getattr(param, 'name', None) == 'payload')
303+
304+
self.assertEqual(option.type.name, 'text')
305+
290306
def test_bad_request_exception_uses_detail_message(self):
291307
runner = CliRunner()
292308

0 commit comments

Comments
 (0)