Refactor(utils): move general utility functions to utility module #73

Merged
jakob.scheid merged 2 commits from refactor/restructure-general-utility-functions into main 2026-10-21 13:14:27 +02:00
3 changed files with 111 additions and 110 deletions
Showing only changes of commit 6ddbd17497 - Show all commits

No files matched your search

+3 -105
View File
@@ -28,7 +28,7 @@ from ...exceptions import (
InvalidNamespaceError,
PythonArgumentStructureError,
)
from ...utils import fit_row_length, get_relative_path_segments, non_empty_str
from ...utils import get_relative_path_segments, markdown_table, non_empty_str
from .arguments import PythonArgumentKind, PythonFunctionArgument
from .definitions import (
PythonAsyncFunctionDefinition,
@@ -184,108 +184,6 @@ def _signature_argument_list(
return args
def _markdown_table(
header: tuple,
body: list[tuple],
*,
allow_markdown_table: bool = False,
force_row_lengths: bool = False,
one_line_values: bool = True,
missing_value: str = '--',
) -> str:
"""
Generates a table.
If ``allow_markdown_table`` is ``False``, an alternative
representation is used.
:param headers: The table headers.
:type headers: tuple
:param body: The table body.
:type body: list[tuple]
:param allow_markdown_table: Controls whether a markdown table may be
used.
:type allow_markdown_table: bool
:param force_row_lengths: Controls whether an exception is raised if
a row does not have the correct length.
:type force_row_lengths: bool
:param one_line_values: Controls whether all newlines in all values
are replaced with spaces.
:type one_line_values: bool
:param missing_value: The string that is used if a value is missing
(only if ``force_row_lengths`` is ``False``).
:type missing_value: str
"""
if not header or not body:
return ''
header_len = len(header)
if allow_markdown_table:
table = (
'| ' + ' | '.join(header) + ' |\n|' + ' --- |' * len(header) + '\n'
)
for row in body:
if len(row) != header_len:
if force_row_lengths:
raise ValueError(
f'expected {header_len} value'
f'{"s" if header_len > 1 else ""}, got {len(row)}'
)
else:
row = fit_row_length(header_len, row)
table += (
'| '
+ ' | '.join(
[
str(col if col is not None else missing_value)
.replace('\n', ' ')
.replace('|', '\\|')
if one_line_values
else str(
col if col is not None else missing_value
).replace('|', '\\|')
for col in row
]
)
+ ' |\n'
)
else:
table = ''
for row in body:
if len(row) != header_len:
if force_row_lengths:
raise ValueError(
f'expected {header_len} value'
f'{"s" if header_len > 1 else ""}, got {len(row)}'
)
else:
row = fit_row_length(header_len, row)
sep = '- '
for i, col in enumerate(row):
table += (
sep
+ header[i]
+ ': '
+ (
str(col if col is not None else missing_value).replace(
'\n', ' '
)
if one_line_values
else str(col if col is not None else missing_value)
)
+ '\n\n'
)
sep = ' '
return table.strip()
def _is_docstring(docstring: str | PythonDocstring | None) -> bool:
"""
Checks whether the docstring is a docstring or an empty docstring.
@@ -621,7 +519,7 @@ class PythonDefinitionDocumentationGenerator:
)
if params_types:
md += _markdown_table(
md += markdown_table(
['Parameter', 'Type', 'Kind', 'Default value', 'Description'],
[
(
@@ -700,7 +598,7 @@ class PythonDefinitionDocumentationGenerator:
md += self.level * '#' + '# Exceptions\n\n'
if self._docstring.raises:
md += _markdown_table(
md += markdown_table(
('Exception', 'Description'),
[
(
+103
View File
@@ -35,6 +35,7 @@ __all__ = [
'non_empty_str',
'get_relative_path_segments',
'fit_row_length',
'markdown_table',
]
@@ -260,3 +261,105 @@ def fit_row_length(expected: int, row: tuple) -> tuple:
return row[:expected]
else:
return row + (None,) * (expected - len(row))
def markdown_table(
header: tuple,
body: list[tuple],
*,
allow_markdown_table: bool = False,
force_row_lengths: bool = False,
one_line_values: bool = True,
missing_value: str = '--',
) -> str:
"""
Generates a table.
If ``allow_markdown_table`` is ``False``, an alternative
representation is used.
:param headers: The table headers.
:type headers: tuple
:param body: The table body.
:type body: list[tuple]
:param allow_markdown_table: Controls whether a markdown table may be
used.
:type allow_markdown_table: bool
:param force_row_lengths: Controls whether an exception is raised if
a row does not have the correct length.
:type force_row_lengths: bool
:param one_line_values: Controls whether all newlines in all values
are replaced with spaces.
:type one_line_values: bool
:param missing_value: The string that is used if a value is missing
(only if ``force_row_lengths`` is ``False``).
:type missing_value: str
"""
if not header or not body:
return ''
header_len = len(header)
if allow_markdown_table:
table = (
'| ' + ' | '.join(header) + ' |\n|' + ' --- |' * len(header) + '\n'
)
for row in body:
if len(row) != header_len:
if force_row_lengths:
raise ValueError(
f'expected {header_len} value'
f'{"s" if header_len > 1 else ""}, got {len(row)}'
)
else:
row = fit_row_length(header_len, row)
table += (
'| '
+ ' | '.join(
[
str(col if col is not None else missing_value)
.replace('\n', ' ')
.replace('|', '\\|')
if one_line_values
else str(
col if col is not None else missing_value
).replace('|', '\\|')
for col in row
]
)
+ ' |\n'
)
else:
table = ''
for row in body:
if len(row) != header_len:
if force_row_lengths:
raise ValueError(
f'expected {header_len} value'
f'{"s" if header_len > 1 else ""}, got {len(row)}'
)
else:
row = fit_row_length(header_len, row)
sep = '- '
for i, col in enumerate(row):
table += (
sep
+ header[i]
+ ': '
+ (
str(col if col is not None else missing_value).replace(
'\n', ' '
)
if one_line_values
else str(col if col is not None else missing_value)
)
+ '\n\n'
)
sep = ' '
return table.strip()
@@ -14,7 +14,7 @@
import pytest
from src.jcloud_docsgen.core.python._core import _markdown_table
from src.jcloud_docsgen.utils import markdown_table
@pytest.mark.parametrize(
@@ -318,7 +318,7 @@ from src.jcloud_docsgen.core.python._core import _markdown_table
),
],
)
def test__markdown_table(
def test_markdown_table(
header,
body,
allow_markdown_table,
@@ -328,7 +328,7 @@ def test__markdown_table(
expected,
):
assert (
_markdown_table(
markdown_table(
header,
body,
allow_markdown_table=allow_markdown_table,
@@ -468,7 +468,7 @@ def test__markdown_table(
),
],
)
def test__markdown_table_exceptions(
def test_markdown_table_exceptions(
header,
body,
allow_markdown_table,
@@ -479,7 +479,7 @@ def test__markdown_table_exceptions(
expected_exception_msg,
):
with pytest.raises(expected_exception) as exc_info:
_markdown_table(
markdown_table(
header,
body,
allow_markdown_table=allow_markdown_table,