Merge pull request 'Chore: prepare release 0.1.0' (#4) from chore/prepare-0-1-0 into main
Release package / Build package (release) Failing after 20s
Release package / Publish package to package registry (release) Skipped
Release package / Prepare release asset upload (release) Failing after 13s
Release package / Upload release asset (${{ fromJSON(needs.prepare_upload_release_asset.outputs.files) }}) (release) Skipped

Reviewed-on: #4
This commit was merged in pull request #4.
This commit is contained in:
jakob.scheid authored and Gitea committed 2026-09-03 17:18:38 +02:00
commit 42f8a65933
48 files changed
+57 -72

No files matched your search

+1 -1
View File
@@ -2,4 +2,4 @@ dist/
src/*.egg-info/
.vscode/
.pytest_cache/
__pycache__/
__pycache__/
+1 -1
View File
@@ -19,4 +19,4 @@ API reference and generated documentation can be found in [docs/reference](docs/
## Notice
This project is under active development. The documentation will be expanded over time.
This project is under active development. The documentation will be expanded over time.
+9 -24
View File
@@ -1,29 +1,14 @@
# Changelog
## [Unreleased]
## [0.1.0] - 2026-09-01
### Added
- Add class for existing directories
- Add function to format a list human-readable
- Add function to assert that an object is an instance of a specific type
- Add Python project documentation generator class
- Add Python namespaces classes
- Add type checking for the `name` attribute at the constructor of `core.python.namespaces.PythonNamespace`
- Add check whether sub-namespaces are not empty in `core.python.namespaces.PythonPackageNamespace.namespace`
- Add feature to get the names of all sub-namespaces of a `core.python.namespaces.PythonPackageNamespace`
- Add feature to compare `core.python.namespaces.PythonPackageNamespace` instances or `core.python.namespaces.PythonModuleNamespace` instances
- Add string representation for Python namespace objects
- Add `PythonDocumentationGenerator` method to collect all namespaces
- Add class for existing files
- Add classes for Python function arguments
- Add classes for Python definitions
- Add class for Python modules
- Add feature to get the signature representation of a Python function argument
- Add class for Python docstrings
- Add feature to parse Python docstrings
- Add function to ensure a non-empty string.
- Add Python definition documentation generator
- Add function to get the path segments of a path relative to another
- Add Python module documentation generator
- Add Python project documentation generator
- utility class for existing directories
- utility class for existing files
- Python project documentation generator
- Python definition documentation generator
- Python module documentation generator
- Python namespaces
- signature representation of a Python function argument
- Python docstrings
+1 -1
View File
@@ -18,4 +18,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
SOFTWARE.
+1 -1
View File
@@ -18,4 +18,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
SOFTWARE.
+1 -1
View File
@@ -174,4 +174,4 @@
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
END OF TERMS AND CONDITIONS
+1 -1
View File
@@ -18,4 +18,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
SOFTWARE.
+1 -1
View File
@@ -22,4 +22,4 @@ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+1 -1
View File
@@ -16,4 +16,4 @@ INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PA
PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
DEALINGS IN THE SOFTWARE.
+1 -1
View File
@@ -18,4 +18,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
SOFTWARE.
+2 -2
View File
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
[project]
name = "jcloud-docsgen"
version = "1.0.0"
version = "0.1.0"
description = "A tool that generates Markdown documentation for software project source code"
dependencies = ["docstring-parser"]
license = "Apache-2.0"
@@ -13,4 +13,4 @@ license = "Apache-2.0"
package-dir = {"" = "src"}
[tool.setuptools.packages.find]
where = ["src"]
where = ["src"]
+1 -1
View File
@@ -19,4 +19,4 @@ from .core import __all__ as _core__all__
__all__ = [
'cli',
*_core__all__
]
]
+1 -1
View File
@@ -34,4 +34,4 @@ def main() -> int:
argument_parser = argparse.ArgumentParser()
argument_parser.add_argument('project_directory', type = existing_directory, default = pathlib.Path('.'), help = 'The directory of the project')
args = argument_parser.parse_args()
return 0
return 0
+1 -1
View File
@@ -16,4 +16,4 @@ from . import python
__all__ = [
'python'
]
]
+1 -1
View File
@@ -19,4 +19,4 @@ from . import namespaces
__all__ = [
*_core__all__,
'namespaces'
]
]
+1 -1
View File
@@ -951,4 +951,4 @@ class PythonDocumentationGenerator:
self.project_directory / 'src',
self.include_sections,
self.kwargs
)
)
+1 -1
View File
@@ -170,4 +170,4 @@ class PythonASTArgumentsListParser:
else:
arguments.append(PythonFunctionArgument(self.ast_arguments_list.kwarg.arg, PythonArgumentKind.KWARGS, None, ast.unparse(self.ast_arguments_list.kwarg.annotation)))
return arguments
return arguments
@@ -229,4 +229,4 @@ class PythonClassDefinition(PythonDefinition):
for expr in node.body
if isinstance(expr, (ast.FunctionDef, ast.AsyncFunctionDef, ast.ClassDef))
]
)
)
+1 -1
View File
@@ -46,4 +46,4 @@ class PythonDocstring:
:rtype: docstring_parser.Docstring
'''
return docstring_parser.parse(self.docstring)
return docstring_parser.parse(self.docstring)
+1 -1
View File
@@ -186,4 +186,4 @@ class PythonModuleNamespace(PythonNamespace):
super().__init__(name)
def __eq__(self, value: PythonModuleNamespace) -> bool:
return self.name == value.name
return self.name == value.name
+1 -1
View File
@@ -76,4 +76,4 @@ class PythonDefinitionError(ValueError):
else:
return f'{self.args[0]}{": " if self.definition and self.args[0] else ""}{self.definition if self.args[0] else ""}'
class PythonArgumentStructureError(PythonDefinitionError): ...
class PythonArgumentStructureError(PythonDefinitionError): ...
+1 -1
View File
@@ -172,4 +172,4 @@ def get_relative_path_segments(path: pathlib.Path, root: pathlib.Path) -> list[s
root.resolve()
)
.parts
)
)
@@ -1410,4 +1410,4 @@ Examples
>>> A()''')
])
def test_PythonDefinitionDocumentationGenerator_generate_documentation(definition_documentation_generator, expected):
assert definition_documentation_generator.generate_documentation() == expected
assert definition_documentation_generator.generate_documentation() == expected
@@ -59,4 +59,4 @@ def test_generate_documentation(dir, expectdir):
allow_tables = True,
allow_html = False
).generate_documentation(
) # simplify the tests
) # simplify the tests
@@ -961,4 +961,4 @@ Barks.
A dog.'''),
])
def test_PythonModuleDocumentationGenerator_exceptions(module_documentation_generator, expected):
assert module_documentation_generator.generate_documentation() == expected
assert module_documentation_generator.generate_documentation() == expected
@@ -24,4 +24,4 @@ import pytest
(PythonArgumentKind.KWARGS, 'kwargs'),
])
def test__argument_kind_human_readable(argument_kind, expected):
assert _argument_kind_human_readable(argument_kind) == expected
assert _argument_kind_human_readable(argument_kind) == expected
@@ -136,4 +136,4 @@ def test_PythonDocumentationGenerator_collect_modules(python_documentation_gener
])
])
def test___collect_definitions(module, expected):
assert list(_collect_definitions(module)) == expected
assert list(_collect_definitions(module)) == expected
@@ -53,4 +53,4 @@ def test__fit_row_length(expected_length, row, expected):
def test__fit_row_length_exceptions(expected_length, row, expected_exception):
with pytest.raises(expected_exception) as exc_info:
_fit_row_length(expected_length, row)
assert str(exc_info.value) == 'expected must be larger than or equal 0.'
assert str(exc_info.value) == 'expected must be larger than or equal 0.'
@@ -101,4 +101,4 @@ def docstring_args_list(docstring: str) -> list[docstring_parser.DocstringParam]
([], '', {}),
])
def test__function_params_types(arg_list, docstring, expected):
assert _function_params_info(arg_list, docstring_args_list(docstring)) == expected
assert _function_params_info(arg_list, docstring_args_list(docstring)) == expected
@@ -90,4 +90,4 @@ def test__markdown_table(header, body, allow_markdown_table, force_row_lengths,
def test__markdown_table_exceptions(header, body, allow_markdown_table, force_row_lengths, one_line_values, missing_value, expected_exception, expected_exception_msg):
with pytest.raises(expected_exception) as exc_info:
_markdown_table(header, body, allow_markdown_table = allow_markdown_table, force_row_lengths = force_row_lengths, one_line_values = one_line_values, missing_value = missing_value)
assert str(exc_info.value) == expected_exception_msg
assert str(exc_info.value) == expected_exception_msg
@@ -94,4 +94,4 @@ import pytest
], ['a: int = 1']),
])
def test__signature_argument_list(argument_list, expected):
assert _signature_argument_list(argument_list) == expected
assert _signature_argument_list(argument_list) == expected
@@ -47,4 +47,4 @@ class Dog(Animal):
Barks.
'''
print('Woof!')
print('Woof!')
@@ -212,4 +212,4 @@ def argument_list(argument_list: str) -> ast.arguments:
]),
])
def test_PythonASTArgumentsListParser_to_argument_list(ast_arguments_list, expected):
assert PythonASTArgumentsListParser(ast_arguments_list).to_argument_list() == expected
assert PythonASTArgumentsListParser(ast_arguments_list).to_argument_list() == expected
@@ -154,4 +154,4 @@ def test_PythonFunctionArgument_asterik(name, kind, annotation):
(PythonFunctionArgument('a', PythonArgumentKind.KWARGS, None, 'int'), '**a: int'),
])
def test_PythonFunctionArgument_signature_repr(argument, expected):
assert argument.signature_repr() == expected
assert argument.signature_repr() == expected
@@ -94,4 +94,4 @@ def test_PythonFunctionDefinition_exceptions(name, args, returns, doc, decorator
])),
])
def test_PythonDefinition_from_node(node, expected):
assert PythonClassDefinition.from_node(node) == expected
assert PythonClassDefinition.from_node(node) == expected
@@ -81,4 +81,4 @@ def test_PythonDefinition_exceptions(name, doc, decorators, expected_exception,
])
def test_PythonDefinition___eq__(definition1, definition2, expected):
assert (definition1 == definition2) == expected
assert (definition2 == definition1) == expected
assert (definition2 == definition1) == expected
@@ -84,4 +84,4 @@ def test_PythonFunctionDefinition_exceptions(name, args, returns, doc, decorator
(ast_node('@decorator\ndef func(): ...'), PythonFunctionDefinition('func', [], None, None, ['decorator'])),
])
def test_PythonDefinition_from_node(node, expected):
assert PythonFunctionDefinition.from_node(node) == expected
assert PythonFunctionDefinition.from_node(node) == expected
@@ -44,4 +44,4 @@ def test_PythonModuleNamespace___eq__(namespace1, namespace2, expected):
(PythonModuleNamespace(StrSubclass('a')), 'PythonModuleNamespace(\'a\')'),
])
def test_PythonModuleNamespace_string_representation(namespace, expected):
assert repr(namespace) == expected
assert repr(namespace) == expected
@@ -31,4 +31,4 @@ def test_PythonNamespace_name_attribute(namespace, expected_name):
(PythonNamespace(StrSubclass('a')), 'PythonNamespace(\'a\')'),
])
def test_PythonNamespace_string_representation(namespace, expected):
assert repr(namespace) == expected
assert repr(namespace) == expected
@@ -105,4 +105,4 @@ def test_PythonPackageNamespace_string_representation(namespace, expected):
])
def test_PythonPackageNamespace___getitem__(namespace, new_namespace, expected):
namespace.add(new_namespace)
assert namespace == expected
assert namespace == expected
+1 -1
View File
@@ -39,4 +39,4 @@ def test_ExistingDirectory(path, expected):
def test_ExistingDirectory_exceptions(path, expected_exception, expected_exception_message):
with pytest.raises(expected_exception) as exc_info:
ExistingDirectory(path)
assert str(exc_info.value) == expected_exception_message
assert str(exc_info.value) == expected_exception_message
+1 -1
View File
@@ -32,4 +32,4 @@ def test_ExistingDirectory(path, expected):
def test_ExistingDirectory_exceptions(path, expected_exception, expected_exception_message):
with pytest.raises(expected_exception) as exc_info:
ExistingFile(path)
assert str(exc_info.value) == expected_exception_message
assert str(exc_info.value) == expected_exception_message
@@ -40,4 +40,4 @@ def test_assert_that_is_instance(obj, class_or_tuple):
def test_assert_that_is_instance_exceptions(obj, class_or_tuple, expected_exception_msg):
with pytest.raises(TypeError) as exc_info:
assert_that_is_instance(obj, class_or_tuple)
assert str(exc_info.value) == expected_exception_msg
assert str(exc_info.value) == expected_exception_msg
@@ -73,4 +73,4 @@ import pathlib
])
def test_get_relative_path_segments(path, root, expected):
assert get_relative_path_segments(path, root) == expected
assert get_relative_path_segments(path, root) == expected
+1 -1
View File
@@ -51,4 +51,4 @@ import pytest
([1, 2, 3, 42, 'a', 23], 'and', '\'', '\'1\', \'2\', \'3\', \'42\', \'a\' and \'23\''),
])
def test_human_readable_list(ls, final_separator, quotation_mark, expected):
assert human_readable_list(ls, final_separator, quotation_mark) == expected
assert human_readable_list(ls, final_separator, quotation_mark) == expected
+1 -1
View File
@@ -27,4 +27,4 @@ import pytest
('a', 'a'),
])
def test_non_empty_str(value, expected):
assert non_empty_str(value) == expected
assert non_empty_str(value) == expected
+1 -1
View File
@@ -33,4 +33,4 @@ def ast_node(statement: str) -> Union[ast.stmt, None]:
body = ast.parse(statement).body
if not body:
return None
return body[0]
return body[0]