|
1 | 1 | from __future__ import annotations as _annotations
|
2 | 2 |
|
| 3 | +import inspect |
3 | 4 | import json
|
4 | 5 | import os
|
5 | 6 | import re
|
|
17 | 18 | from enum import Enum
|
18 | 19 | from pathlib import Path
|
19 | 20 | from textwrap import dedent
|
20 |
| -from types import FunctionType |
21 | 21 | from typing import (
|
22 | 22 | TYPE_CHECKING,
|
23 | 23 | Any,
|
@@ -1718,8 +1718,9 @@ def _metavar_format_choices(self, args: list[str], obj_qualname: str | None = No
|
1718 | 1718 | def _metavar_format_recurse(self, obj: Any) -> str:
|
1719 | 1719 | """Pretty metavar representation of a type. Adapts logic from `pydantic._repr.display_as_type`."""
|
1720 | 1720 | obj = _strip_annotated(obj)
|
1721 |
| - if isinstance(obj, FunctionType): |
1722 |
| - return obj.__name__ |
| 1721 | + if _is_function(obj): |
| 1722 | + # If function is locally defined use __name__ instead of __qualname__ |
| 1723 | + return obj.__name__ if '<locals>' in obj.__qualname__ else obj.__qualname__ |
1723 | 1724 | elif obj is ...:
|
1724 | 1725 | return '...'
|
1725 | 1726 | elif isinstance(obj, Representation):
|
@@ -1762,13 +1763,13 @@ def _help_format(self, field_name: str, field_info: FieldInfo, model_default: An
|
1762 | 1763 | default = f'(default: {self.cli_parse_none_str})'
|
1763 | 1764 | if is_model_class(type(model_default)) or is_pydantic_dataclass(type(model_default)):
|
1764 | 1765 | default = f'(default: {getattr(model_default, field_name)})'
|
1765 |
| - elif model_default not in (PydanticUndefined, None) and callable(model_default): |
| 1766 | + elif model_default not in (PydanticUndefined, None) and _is_function(model_default): |
1766 | 1767 | default = f'(default factory: {self._metavar_format(model_default)})'
|
1767 | 1768 | elif field_info.default not in (PydanticUndefined, None):
|
1768 | 1769 | enum_name = _annotation_enum_val_to_name(field_info.annotation, field_info.default)
|
1769 | 1770 | default = f'(default: {field_info.default if enum_name is None else enum_name})'
|
1770 | 1771 | elif field_info.default_factory is not None:
|
1771 |
| - default = f'(default: {field_info.default_factory})' |
| 1772 | + default = f'(default factory: {self._metavar_format(field_info.default_factory)})' |
1772 | 1773 | _help += f' {default}' if _help else default
|
1773 | 1774 | return _help.replace('%', '%%') if issubclass(type(self._root_parser), ArgumentParser) else _help
|
1774 | 1775 |
|
@@ -2092,3 +2093,7 @@ def _annotation_enum_name_to_val(annotation: type[Any] | None, name: Any) -> Any
|
2092 | 2093 | if name in tuple(val.name for val in type_):
|
2093 | 2094 | return type_[name]
|
2094 | 2095 | return None
|
| 2096 | + |
| 2097 | + |
| 2098 | +def _is_function(obj: Any) -> bool: |
| 2099 | + return inspect.isfunction(obj) or inspect.isbuiltin(obj) or inspect.isroutine(obj) or inspect.ismethod(obj) |
0 commit comments