generated from jCloud/repository-template
Add feature to get the signature representation of a Python function argument
This commit is contained in:
@@ -19,3 +19,4 @@
|
|||||||
- Add classes for Python function arguments
|
- Add classes for Python function arguments
|
||||||
- Add classes for Python definitions
|
- Add classes for Python definitions
|
||||||
- Add class for Python modules
|
- Add class for Python modules
|
||||||
|
- Add feature to get the signature representation of a Python function argument
|
||||||
@@ -17,7 +17,7 @@ from enum import Enum
|
|||||||
from typing import Union
|
from typing import Union
|
||||||
import ast
|
import ast
|
||||||
from ...utils import assert_that_is_instance
|
from ...utils import assert_that_is_instance
|
||||||
from ...exceptions import InvalidPythonIdentifierError, InvalidPythonAnnotationError
|
from ...exceptions import InvalidPythonIdentifierError, InvalidPythonAnnotationError, PythonArgumentStructureError
|
||||||
import keyword
|
import keyword
|
||||||
import types
|
import types
|
||||||
|
|
||||||
@@ -69,6 +69,9 @@ class PythonFunctionArgument:
|
|||||||
self.default = default
|
self.default = default
|
||||||
self.annotation = annotation
|
self.annotation = annotation
|
||||||
|
|
||||||
|
if self.kind in (PythonArgumentKind.VARARG, PythonArgumentKind.KWARGS) and self.default is not None:
|
||||||
|
raise PythonArgumentStructureError('* or ** arguments cannot have default values', definition = self.signature_repr())
|
||||||
|
|
||||||
def __eq__(self, value: PythonFunctionArgument) -> bool:
|
def __eq__(self, value: PythonFunctionArgument) -> bool:
|
||||||
if not isinstance(value, PythonFunctionArgument):
|
if not isinstance(value, PythonFunctionArgument):
|
||||||
return False
|
return False
|
||||||
@@ -82,6 +85,31 @@ class PythonFunctionArgument:
|
|||||||
self.annotation
|
self.annotation
|
||||||
))
|
))
|
||||||
|
|
||||||
|
def signature_repr(self) -> str:
|
||||||
|
'''
|
||||||
|
Returns the function signature representation of the argument.
|
||||||
|
|
||||||
|
:return: The string representation of the argument.
|
||||||
|
:rtype: str
|
||||||
|
'''
|
||||||
|
|
||||||
|
if self.kind == PythonArgumentKind.KWARGS:
|
||||||
|
str_repr = '**'
|
||||||
|
elif self.kind == PythonArgumentKind.VARARG:
|
||||||
|
str_repr = '*'
|
||||||
|
else:
|
||||||
|
str_repr = ''
|
||||||
|
|
||||||
|
str_repr += self.name
|
||||||
|
|
||||||
|
if self.annotation is not None:
|
||||||
|
str_repr += ': ' + self.annotation
|
||||||
|
|
||||||
|
if self.default is not None:
|
||||||
|
str_repr += ' = ' + self.default
|
||||||
|
|
||||||
|
return str_repr
|
||||||
|
|
||||||
class PythonASTArgumentsListParser:
|
class PythonASTArgumentsListParser:
|
||||||
'''
|
'''
|
||||||
A parser for making ``PythonFunctionArgument`` objects from an
|
A parser for making ``PythonFunctionArgument`` objects from an
|
||||||
|
|||||||
@@ -61,3 +61,19 @@ class PythonAnnotationError(ValueError):
|
|||||||
return f'{self.args[0]}{": " if self.annotation and self.args[0] else ""}{self.annotation if self.args[0] else ""}'
|
return f'{self.args[0]}{": " if self.annotation and self.args[0] else ""}{self.annotation if self.args[0] else ""}'
|
||||||
|
|
||||||
class InvalidPythonAnnotationError(PythonAnnotationError): ...
|
class InvalidPythonAnnotationError(PythonAnnotationError): ...
|
||||||
|
|
||||||
|
class PythonDefinitionError(ValueError):
|
||||||
|
'''
|
||||||
|
Base class for Python definition errors.
|
||||||
|
'''
|
||||||
|
def __init__(self, *args: object, definition: str = '') -> None:
|
||||||
|
super().__init__(*args)
|
||||||
|
self.definition = definition
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
if not self.args:
|
||||||
|
return ''
|
||||||
|
else:
|
||||||
|
return f'{self.args[0]}{": " if self.definition and self.args[0] else ""}{self.definition if self.args[0] else ""}'
|
||||||
|
|
||||||
|
class PythonArgumentStructureError(PythonDefinitionError): ...
|
||||||
@@ -13,8 +13,7 @@
|
|||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
|
||||||
from src.jcloud_docsgen.core.python.arguments import PythonFunctionArgument, PythonArgumentKind
|
from src.jcloud_docsgen.core.python.arguments import PythonFunctionArgument, PythonArgumentKind
|
||||||
from src.jcloud_docsgen.exceptions import InvalidPythonIdentifierError, InvalidPythonAnnotationError
|
from src.jcloud_docsgen.exceptions import InvalidPythonIdentifierError, InvalidPythonAnnotationError, PythonArgumentStructureError
|
||||||
import ast
|
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
@pytest.mark.parametrize('name,kind,default,annotation,expected_exception,expected_exception_msg', [
|
@pytest.mark.parametrize('name,kind,default,annotation,expected_exception,expected_exception_msg', [
|
||||||
@@ -59,6 +58,8 @@ import pytest
|
|||||||
('lambda', PythonArgumentKind.NORMAL, None, None, InvalidPythonIdentifierError, 'invalid identifier: lambda'),
|
('lambda', PythonArgumentKind.NORMAL, None, None, InvalidPythonIdentifierError, 'invalid identifier: lambda'),
|
||||||
('None', PythonArgumentKind.NORMAL, None, None, InvalidPythonIdentifierError, 'invalid identifier: None'),
|
('None', PythonArgumentKind.NORMAL, None, None, InvalidPythonIdentifierError, 'invalid identifier: None'),
|
||||||
('True', PythonArgumentKind.NORMAL, None, None, InvalidPythonIdentifierError, 'invalid identifier: True'),
|
('True', PythonArgumentKind.NORMAL, None, None, InvalidPythonIdentifierError, 'invalid identifier: True'),
|
||||||
|
('a', PythonArgumentKind.VARARG, '1', None, PythonArgumentStructureError, '* or ** arguments cannot have default values: *a = 1'),
|
||||||
|
('a', PythonArgumentKind.KWARGS, '1', None, PythonArgumentStructureError, '* or ** arguments cannot have default values: **a = 1'),
|
||||||
])
|
])
|
||||||
def test_PythonFunctionArgument_exceptions(name, kind, default, annotation, expected_exception, expected_exception_msg):
|
def test_PythonFunctionArgument_exceptions(name, kind, default, annotation, expected_exception, expected_exception_msg):
|
||||||
with pytest.raises(expected_exception) as exc_info:
|
with pytest.raises(expected_exception) as exc_info:
|
||||||
@@ -79,13 +80,14 @@ def test_PythonFunctionArgument_exceptions(name, kind, default, annotation, expe
|
|||||||
'case',
|
'case',
|
||||||
'type',
|
'type',
|
||||||
'ä',
|
'ä',
|
||||||
|
'none',
|
||||||
|
'true',
|
||||||
|
'false',
|
||||||
])
|
])
|
||||||
@pytest.mark.parametrize('kind', [
|
@pytest.mark.parametrize('kind', [
|
||||||
PythonArgumentKind.NORMAL,
|
PythonArgumentKind.NORMAL,
|
||||||
PythonArgumentKind.POSITIONAL_ONLY,
|
PythonArgumentKind.POSITIONAL_ONLY,
|
||||||
PythonArgumentKind.KEYWORD_ONLY,
|
PythonArgumentKind.KEYWORD_ONLY,
|
||||||
PythonArgumentKind.VARARG,
|
|
||||||
PythonArgumentKind.KWARGS,
|
|
||||||
])
|
])
|
||||||
@pytest.mark.parametrize('default', [
|
@pytest.mark.parametrize('default', [
|
||||||
None,
|
None,
|
||||||
@@ -101,3 +103,34 @@ def test_PythonFunctionArgument_exceptions(name, kind, default, annotation, expe
|
|||||||
])
|
])
|
||||||
def test_PythonFunctionArgument(name, kind, default, annotation):
|
def test_PythonFunctionArgument(name, kind, default, annotation):
|
||||||
PythonFunctionArgument(name, kind, default, annotation)
|
PythonFunctionArgument(name, kind, default, annotation)
|
||||||
|
|
||||||
|
@pytest.mark.parametrize('name', [
|
||||||
|
'a',
|
||||||
|
'_a',
|
||||||
|
'a1',
|
||||||
|
'a0',
|
||||||
|
'a_',
|
||||||
|
'_',
|
||||||
|
'_abc',
|
||||||
|
'abc',
|
||||||
|
'abc_',
|
||||||
|
'match',
|
||||||
|
'case',
|
||||||
|
'type',
|
||||||
|
'ä',
|
||||||
|
'none',
|
||||||
|
'true',
|
||||||
|
'false',
|
||||||
|
])
|
||||||
|
@pytest.mark.parametrize('kind', [
|
||||||
|
PythonArgumentKind.VARARG,
|
||||||
|
PythonArgumentKind.KWARGS,
|
||||||
|
])
|
||||||
|
@pytest.mark.parametrize('annotation', [
|
||||||
|
None,
|
||||||
|
'a',
|
||||||
|
'list[int]',
|
||||||
|
'_',
|
||||||
|
])
|
||||||
|
def test_PythonFunctionArgument_asterik(name, kind, annotation):
|
||||||
|
PythonFunctionArgument(name, kind, None, annotation)
|
||||||
Reference in New Issue
Block a user