From 6119c69a3c8c30b3305fde14a723d04decf21f06 Mon Sep 17 00:00:00 2001 From: Jakob Scheid Date: Tue, 7 Apr 2026 14:13:15 +0200 Subject: [PATCH] Add namespaces classes --- docs/CHANGELOG.md | 3 +- .../core/python/{core.py => _core.py} | 3 +- src/jcloud_docsgen/core/python/namespaces.py | 76 +++++++++++++++++++ 3 files changed, 80 insertions(+), 2 deletions(-) rename src/jcloud_docsgen/core/python/{core.py => _core.py} (89%) create mode 100644 src/jcloud_docsgen/core/python/namespaces.py diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index 48a4ee7..8d3658b 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -7,4 +7,5 @@ - 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 \ No newline at end of file +- Add python project documentation generator class +- Add namespaces classes \ No newline at end of file diff --git a/src/jcloud_docsgen/core/python/core.py b/src/jcloud_docsgen/core/python/_core.py similarity index 89% rename from src/jcloud_docsgen/core/python/core.py rename to src/jcloud_docsgen/core/python/_core.py index 9e57ff8..1a45223 100644 --- a/src/jcloud_docsgen/core/python/core.py +++ b/src/jcloud_docsgen/core/python/_core.py @@ -12,7 +12,8 @@ # See the License for the specific language governing permissions and # limitations under the License. -from .utils import ExistingDirectory, assert_that_is_instance +from __future__ import annotations +from ...utils import ExistingDirectory, assert_that_is_instance __all__ = [ 'PythonDocumentationGenerator' diff --git a/src/jcloud_docsgen/core/python/namespaces.py b/src/jcloud_docsgen/core/python/namespaces.py new file mode 100644 index 0000000..2d5dea7 --- /dev/null +++ b/src/jcloud_docsgen/core/python/namespaces.py @@ -0,0 +1,76 @@ +# Copyright 2026 jCloud Services GbR + +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at + +# http://www.apache.org/licenses/LICENSE-2.0 + +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from ...exceptions import InvalidNamespaceError, NamespaceNotFoundError + +class PythonNamespace: + ''' + The base class for all python namespaces such as modules or packages. + + :param name: The name of the namespace. + :type name: str + ''' + def __init__(self, name: str) -> None: + self.name = name + +class PythonPackageNamespace(PythonNamespace): + ''' + A subclass of ``PythonNamespace`` for python package namespaces. + + :param name: The name of the namespace. + :type name: str + :param sub_namespaces: The sub namespaces. + :type sub_namespaces: list[PythonNamespace] + ''' + + def __init__(self, name: str, sub_namespaces: dict[str, PythonNamespace]) -> None: + super().__init__(name) + + self.sub_namespaces = sub_namespaces + + def namespace(self, sub_namespaces: list[str]) -> PythonNamespace: + ''' + Returns the namespace object with a specific identifier, such as + ``package.subpackage.module``. + ''' + + if not sub_namespaces: + raise InvalidNamespaceError('invalid namespace') + + # check whether the sub namespace exists + if sub_namespaces[0] not in self.sub_namespaces: + raise NamespaceNotFoundError('no such namespace', namespace_identifier = sub_namespaces[0]) + + sub_namespace = self.sub_namespaces[sub_namespaces[0]] + + # package namespace + if isinstance(sub_namespace, PythonPackageNamespace): + if len(sub_namespaces) == 1: + return sub_namespace + return sub_namespace.namespace(sub_namespaces[1:]) + # module namespace + else: + return sub_namespace + + +class PythonModuleNamespace(PythonNamespace): + ''' + A subclass of ``PythonNamespace`` for python module namespaces. + + :param name: The name of the namespace. + :type name: str + ''' + + def __init__(self, name: str) -> None: + super().__init__(name) \ No newline at end of file