Skip to content

Packages

plateforme.core.packages

This module provides functionality for managing packages within the Plateforme framework. It includes classes and functions for importing modules, retrieving package configurations, and initializing the package catalog.

The Package class lifecycle is managed by the framework runtime environment that enforces a singleton behavior for package instances. It is initialized with a Python module name and provides access to the package's configuration, metadata, and resources.

The PackageImpl class is a proxy object that provides access to the implementation of a package within a given application context. It includes additional configuration settings such as the namespace, slug, and file system path.

Package

Package(
    name: str,
    module: ModuleType,
    *,
    info: dict[Any, Any] | None = None,
    settings: PackageSettings | None = None,
)

Bases: Representation

A package within the Plateforme framework.

It is initialized with a python module name. It checks for a package configuration to ensure the given module name corresponds to an importable package within the Plateforme framework. Each package is uniquely represented as a singleton object, identified by its module name. This process guarantees the consistent and correct identification of Plateforme packages for further operations.

The package class exposes a catalog attribute that maps the alias and slug names within the package namespace to their respective objects, either a resource type, an association (i.e. a tuple of one or two linked fields), or a service method. It also provides access to the package resources, dependencies, and dependents, as well as the package implementations within the current application context.

Attributes:

Name Type Description
_impls dict[Plateforme | None, PackageImpl]

The registered package implementations as a dictionary mapping the application context to the package implementation.

module ModuleType

The package module object.

name str

The package module name that is unique within the entire runtime environment.

info dict[Any, Any] | None

Additional information about the package.

catalog Catalog

A dictionary mapping the alias and slug names within the package namespace to their respective objects, either a resource type, an association, or a service method.

metadata MetaData

The package resource metadata.

registry Registry

The package resource registry.

Initialize a package.

Note

The import_package method should be used to retrieve a package instance based on the provided module name.

Source code in .venv/lib/python3.12/site-packages/plateforme/core/packages.py
def __init__(
    self,
    name: str,
    module: ModuleType,
    *,
    info: dict[Any, Any] | None = None,
    settings: PackageSettings | None = None,
) -> None:
    """Initialize a package.

    Note:
        The `import_package` method should be used to retrieve a package
        instance based on the provided module name.
    """
    object.__setattr__(self, '_impls', {})
    object.__setattr__(self, 'module', module)
    object.__setattr__(self, 'name', name)
    object.__setattr__(self, 'info', info)

    self._add_impl(None, settings=settings, auto_generated=True)

    catalog = Catalog(self)
    metadata = MetaData(
        schema=self.impl.settings.namespace,
        schema_factory=lambda: self.impl.namespace.alias,
        info=info,
    )
    registry = Registry(metadata=metadata)

    object.__setattr__(self, 'catalog', catalog)
    object.__setattr__(self, 'metadata', metadata)
    object.__setattr__(self, 'registry', registry)

impl property

The current package implementation based on the app context.

A read-only property that returns the package implementation based on the application context. If no context is available, it returns the package default implementation. Otherwise, it raises an error if the package implementation is not available in the current application context.

PackageManager

PackageManager(managed: Managed | type[Managed])

Bases: Manager['PackageImpl']

A package implementation manager.

It provides a common interface to access and manage the service methods associated with a package implementation.

Initialize a new manager instance.

Source code in .venv/lib/python3.12/site-packages/plateforme/core/managers.py
def __init__(self, managed: Managed | type[Managed]) -> None:
    """Initialize a new manager instance."""
    self.__config_managed__ = managed

PackageImpl

PackageImpl(
    package: Package,
    context: Plateforme | None,
    *,
    settings: PackageSettings | None = None,
    auto_generated: bool = False,
    auto_import_namespace: bool = True,
)

Bases: Proxy[Package], Representation

A package implementation proxy class.

It defines the implementation details of a package within the Plateforme framework. It extends the Proxy class and adds additional information about the package.

Attributes:

Name Type Description
context Plateforme | None

The application context associated with the package implementation.

namespace NamespaceImpl

The package namespace used to load the package and its resources within an application and to group resources to avoid alias collisions.

objects PackageManager

The package manager to access and manage the service methods associated with the package implementation.

services tuple[BaseService, ...]

The service instances associated with the package implementation.

settings PackageSettings

The package settings to use for the implementation.

auto_generated bool

Whether the package implementation is auto-generated and should not be persisted when removing dependent packages.

file_path str

A string that defines the filesystem path of the package module. It is used to load package related assets from the filesystem. When not provided, it is resolved from the package module.

Initialize a package implementation proxy instance.

Parameters:

Name Type Description Default
package Package

The package instance to proxy.

required
context Plateforme | None

The application context to associate with the package implementation.

required
settings PackageSettings | None

The package settings to use. Defaults to an empty PackageSettings object.

None
auto_generated bool

Whether the package implementation is auto-generated and should not be persisted when removing dependent packages. Defaults to False.

False
auto_import_namespace bool

Whether to automatically import and create the namespace for the package implementation. Defaults to True.

True
Source code in .venv/lib/python3.12/site-packages/plateforme/core/packages.py
def __init__(
    self,
    package: Package,
    context: 'Plateforme | None',
    *,
    settings: PackageSettings | None = None,
    auto_generated: bool = False,
    auto_import_namespace: bool = True,
) -> None:
    """Initialize a package implementation proxy instance.

    Args:
        package: The package instance to proxy.
        context: The application context to associate with the package
            implementation.
        settings: The package settings to use. Defaults to an empty
            `PackageSettings` object.
        auto_generated: Whether the package implementation is
            auto-generated and should not be persisted when removing
            dependent packages. Defaults to ``False``.
        auto_import_namespace: Whether to automatically import and create
            the namespace for the package implementation.
            Defaults to ``True``.
    """
    super().__init__(package)
    object.__setattr__(self, 'context', context)
    object.__setattr__(self, 'objects', PackageManager(self))
    object.__setattr__(self, 'auto_generated', auto_generated)

    # Merge default implementation settings using "getattr" method to
    # avoid circular import issues when the default implementation is
    # initialized within the package module.
    settings = settings or PackageSettings()
    default_impl: PackageImpl | None = \
        package._impls.get(None, None)
    if default_impl is not None:
        settings = merge_settings(default_impl.settings, settings)
    object.__setattr__(self, 'settings', settings)

    # Validate file path
    file_path = settings.file_path or self._resolve_file_path()
    object.__setattr__(self, 'file_path', file_path)

    # Initialize namespace implementation
    namespace = runtime.import_namespace(
        self.settings.namespace or '',
        create_if_missing=auto_import_namespace,
    )
    if self.context in namespace._impls:
        namespace_impl = namespace._impls[self.context]
    elif not auto_import_namespace:
        raise PlateformeError(
            f"Invalid package implementation for package "
            f"{package.name!r}. The namespace {namespace.name!r} is not "
            f"available in the current application context "
            f"{str(context)!r}.",
            code='package-invalid-implementation',
        )
    else:
        namespace_impl = namespace._add_impl(
            self.context, auto_generated=auto_generated
        )
    namespace_impl._add_package(self)
    object.__setattr__(self, 'namespace', namespace_impl)

    # Initialize services
    object.__setattr__(self, 'services', ())
    services = collect_api_services(self)
    for service in services:
        self._add_services(service)

    package._impls[context] = self

package property

package: Package

The package associated with the implementation.

path property

path: str

The package API route path.

It specifies the API route path of the package within an application.

Examples:

  • /my-namespace

collect_api_resources

collect_api_resources(
    package: PackageImpl,
    *,
    include: Iterable[str] | None = None,
    exclude: Iterable[str] | None = None,
) -> set[ResourceType]

Collect API resources from a package.

Parameters:

Name Type Description Default
package PackageImpl

The package to collect API resources from.

required
include Iterable[str] | None

An iterable of module or resource names that should be included in the collection. If provided, only the resources with the specified names are included. Defaults to None.

None
exclude Iterable[str] | None

An iterable of module or resource names that should be excluded from the collection. If provided, the resources with the specified names are excluded. Defaults to None.

None

Returns:

Type Description
set[ResourceType]

A set containing the matched resources based on the filter criteria.

Source code in .venv/lib/python3.12/site-packages/plateforme/core/packages.py
def collect_api_resources(
    package: PackageImpl,
    *,
    include: Iterable[str] | None = None,
    exclude: Iterable[str] | None = None,
) -> set['ResourceType']:
    """Collect API resources from a package.

    Args:
        package: The package to collect API resources from.
        include: An iterable of module or resource names that should be
            included in the collection. If provided, only the resources with
            the specified names are included. Defaults to ``None``.
        exclude: An iterable of module or resource names that should be
            excluded from the collection. If provided, the resources with the
            specified names are excluded. Defaults to ``None``.

    Returns:
        A set containing the matched resources based on the filter criteria.
    """
    modules: set[ModuleType] = set()
    resources: set['ResourceType'] = set()

    # Helper function to check if the object should be included
    def check(obj: Any) -> bool:
        name = get_object_name(obj, fullname=True)
        if include is not None and name not in include:
            return False
        if exclude is not None and name in exclude:
            return False
        return True

    # Helper function to filter resources
    def predicate(obj: Any) -> bool:
        return is_resource(obj) and not is_abstract(obj) and check(obj)

    # Helper function to collect resources
    def collect(module: ModuleType) -> None:
        if module in modules:
            return
        for _, member in inspect.getmembers(module):
            if inspect.ismodule(member):
                collect(member)
            elif predicate(member):
                resources.add(member)

    # Retrieve lookup settings
    if settings := package.settings.api_resources:
        lookup = ['.'] if settings is True else list(settings)
    else:
        return set()

    # Import objects from lookup names
    objects = []
    for name in lookup:
        try:
            obj = import_object(name.ljust(1, '.'), package=package.name)
            if check(obj):
                objects.append(obj)
        except ImportError:
            pass

    # Collect resources
    for obj in objects:
        if inspect.ismodule(obj):
            collect(obj)
        elif predicate(obj):
            resources.add(obj)
        else:
            raise PlateformeError(
                f"Invalid API resource settings for package {package.name!r}. "
                f"The provided resource {obj!r} is not a valid resource.",
                code='package-invalid-config',
            )

    return resources

collect_api_services

collect_api_services(
    package: PackageImpl,
    *,
    include: Iterable[str] | None = None,
    exclude: Iterable[str] | None = None,
) -> set[BaseService]

Collect API services from a package.

Parameters:

Name Type Description Default
package PackageImpl

The package to collect API services from.

required
include Iterable[str] | None

An iterable of module or service names that should be included in the collection. If provided, only the services with the specified names are included. Defaults to None.

None
exclude Iterable[str] | None

An iterable of module or service names that should be excluded from the collection. If provided, the services with the specified names are excluded. Defaults to None.

None

Returns:

Type Description
set[BaseService]

A set containing the matched services based on the filter criteria.

Source code in .venv/lib/python3.12/site-packages/plateforme/core/packages.py
def collect_api_services(
    package: PackageImpl,
    *,
    include: Iterable[str] | None = None,
    exclude: Iterable[str] | None = None,
) -> set[BaseService]:
    """Collect API services from a package.

    Args:
        package: The package to collect API services from.
        include: An iterable of module or service names that should be included
            in the collection. If provided, only the services with the
            specified names are included. Defaults to ``None``.
        exclude: An iterable of module or service names that should be excluded
            from the collection. If provided, the services with the specified
            names are excluded. Defaults to ``None``.

    Returns:
        A set containing the matched services based on the filter criteria.
    """
    modules: set[ModuleType] = set()
    services: set[BaseService] = set()

    # Helper function to check if the object should be included
    def check(obj: Any) -> bool:
        name = get_object_name(obj, fullname=True)
        if include is not None and name not in include:
            return False
        if exclude is not None and name in exclude:
            return False
        return True

    # Helper function to filter services
    def predicate(obj: Any) -> bool:
        if isinstance(obj, type):
            if obj is BaseService:
                return False
            return issubclass(obj, BaseService) \
                and not issubclass(obj, BaseServiceWithSpec) \
                and check(obj)
        else:
            return isinstance(obj, BaseService) \
                and not isinstance(obj, BaseServiceWithSpec) \
                and check(obj)

    # Helper function to collect services
    def collect(module: ModuleType) -> None:
        if module in modules:
            return
        for _, member in inspect.getmembers(module):
            if inspect.ismodule(member):
                collect(member)
            elif predicate(member):
                if isinstance(member, type):
                    member = member()
                services.add(member)

    # Retrieve lookup settings
    if settings := package.settings.api_services:
        lookup = ['.'] if settings is True else list(settings)
    else:
        return set()

    # Import objects from lookup names
    objects = []
    for name in lookup:
        try:
            obj = import_object(name.ljust(1, '.'), package=package.name)
            if check(obj):
                objects.append(obj)
        except ImportError:
            pass

    # Collect services
    for obj in objects:
        if inspect.ismodule(obj):
            collect(obj)
        elif predicate(obj):
            if isinstance(obj, type):
                obj = obj()
            services.add(obj)
        else:
            raise PlateformeError(
                f"Invalid API service settings for package {package.name!r}. "
                f"The provided service {obj!r} is not a valid service.",
                code='package-invalid-config',
            )

    return services

plateforme.core.modules

This module provides utilities for managing modules within the Plateforme framework.

ROOT_MODULE module-attribute

ROOT_MODULE = 'main'

The root module name used as a fallback for top-level modules.

get_root_module_name

get_root_module_name(*, prefix: str | None = None) -> str

Get the root module name used as a fallback for top-level modules.

Parameters:

Name Type Description Default
prefix str | None

An optional prefix to prepend to the root module name. Defaults to None.

None

Returns:

Type Description
str

The root module name.

Source code in .venv/lib/python3.12/site-packages/plateforme/core/modules.py
def get_root_module_name(*, prefix: str | None = None) -> str:
    """Get the root module name used as a fallback for top-level modules.

    Args:
        prefix: An optional prefix to prepend to the root module name.
            Defaults to ``None``.

    Returns:
        The root module name.
    """
    return f"__{prefix}_{ROOT_MODULE}__" if prefix else f"__{ROOT_MODULE}__"

import_module

import_module(
    name: str,
    package: str | None = None,
    *,
    force_resolution: bool = False,
) -> ModuleType

Import a module.

The package argument is required when performing a relative import. It specifies the package to use as the anchor point from which to resolve the relative import to an absolute import.

Parameters:

Name Type Description Default
name str

The name of the module to import.

required
package str | None

The package to use as the anchor point for relative imports.

None
force_resolution bool

When set to True, forces the resolution of the empty string module name to __main__ as a fallback if it is available. Defaults to False.

False

Returns:

Type Description
ModuleType

The imported module.

Note

This function is a wrapper around the importlib.import_module built-in function. It adds the ability to attempt the import of the modules __main__ when the given module name is an empty string.

Source code in .venv/lib/python3.12/site-packages/plateforme/core/modules.py
def import_module(
    name: str,
    package: str | None = None,
    *,
    force_resolution: bool = False,
) -> ModuleType:
    """Import a module.

    The `package` argument is required when performing a relative import. It
    specifies the package to use as the anchor point from which to resolve the
    relative import to an absolute import.

    Args:
        name: The name of the module to import.
        package: The package to use as the anchor point for relative imports.
        force_resolution: When set to ``True``, forces the resolution of the
            empty string module name to ``__main__`` as a fallback if it is
            available. Defaults to ``False``.

    Returns:
        The imported module.

    Note:
        This function is a wrapper around the `importlib.import_module`
        built-in function. It adds the ability to attempt the import of the
        modules ``__main__`` when the given module name is an empty string.
    """
    # Attempt to import the module normally
    if name:
        try:
            return importlib.import_module(name, package=package)
        except ModuleNotFoundError as error:
            raise ImportError(
                f"Could not find module name {name!r}. Make sure the module "
                f"is installed and importable.",
            ) from error

    # Attempt to import "__main__" as a fallback
    if not force_resolution:
        raise ImportError(
            "Empty module name is not allowed without `force_resolution` "
            "enabled."
        )

    try:
        return importlib.import_module(get_root_module_name(), package=package)
    except ModuleNotFoundError as error:
        raise ImportError(
            "Could not find the fallback module `__main__` while attempting "
            "to import an empty module name."
        ) from error

import_object

import_object(name: str, package: str | None = None) -> Any

Import an object.

The package argument is required when performing a relative import. It specifies the package to use as the anchor point from which to resolve the relative import to an absolute import.

Parameters:

Name Type Description Default
name str

The name of the object to import.

required
package str | None

The package to use as the anchor point for relative imports.

None

Returns:

Type Description
Any

The imported object.

Source code in .venv/lib/python3.12/site-packages/plateforme/core/modules.py
def import_object(
    name: str,
    package: str | None = None,
) -> Any:
    """Import an object.

    The `package` argument is required when performing a relative import. It
    specifies the package to use as the anchor point from which to resolve the
    relative import to an absolute import.

    Args:
        name: The name of the object to import.
        package: The package to use as the anchor point for relative imports.

    Returns:
        The imported object.
    """
    module_parts = name.lstrip('.').split('.')
    module_name = _get_relative_parent_levels(name) + module_parts.pop(0)

    obj = importlib.import_module(module_name, package)

    while module_parts:
        try:
            module_test = f'{module_name}.{module_parts[0]}'
            obj = importlib.import_module(module_test, package)

            module_name = module_test
            module_parts.pop(0)
        except ModuleNotFoundError:
            break

    for part in module_parts:
        try:
            obj = getattr(obj, part)
        except AttributeError:
            raise ImportError(
                f"Object {name!r} not found in module {module_name!r}."
            )

    return obj

is_namespace

is_namespace(module: ModuleType) -> bool

Whether a module is a valid namespace.

Source code in .venv/lib/python3.12/site-packages/plateforme/core/modules.py
def is_namespace(module: ModuleType) -> bool:
    """Whether a module is a valid namespace."""
    if not getattr(module, '__file__', None):
        return True
    return False

is_package

is_package(
    module: ModuleType, *, allow_root: bool = False
) -> bool

Whether a module is a valid package.

Source code in .venv/lib/python3.12/site-packages/plateforme/core/modules.py
def is_package(module: ModuleType, *, allow_root: bool = False) -> bool:
    """Whether a module is a valid package."""
    if getattr(module, '__path__', None):
        return True
    # Handle root module
    if allow_root \
        and not getattr(module, '__package__', None) \
        and is_root_module(module):
            return True
    return False

is_root_module

is_root_module(module: ModuleType | str) -> bool

Whether a module is the root module.

Source code in .venv/lib/python3.12/site-packages/plateforme/core/modules.py
def is_root_module(module: ModuleType | str) -> bool:
    """Whether a module is the root module."""
    name = module if isinstance(module, str) else module.__name__
    regex = re.compile(rf'^__(?:[a-z]+_)?{ROOT_MODULE}__$')
    return bool(regex.match(name))

resolve_file_paths

resolve_file_paths(module: ModuleType) -> list[str]

Resolve the filesystem paths of a module.

It first tries to resolve the filesystem paths from the module's __path__ attribute. If the attribute is not available or contains multiple paths, it attempts to resolve the filesystem path from the module's __file__ attribute. If neither is available, it returns an empty list.

Parameters:

Name Type Description Default
module ModuleType

The module to resolve the filesystem paths from.

required

Returns:

Type Description
list[str]

The resolved filesystem paths of the module.

Source code in .venv/lib/python3.12/site-packages/plateforme/core/modules.py
def resolve_file_paths(module: ModuleType) -> list[str]:
    """Resolve the filesystem paths of a module.

    It first tries to resolve the filesystem paths from the module's `__path__`
    attribute. If the attribute is not available or contains multiple paths, it
    attempts to resolve the filesystem path from the module's `__file__`
    attribute. If neither is available, it returns an empty list.

    Args:
        module: The module to resolve the filesystem paths from.

    Returns:
        The resolved filesystem paths of the module.
    """
    if is_root_module(module.__name__):
        return [Path.cwd().as_posix()]

    # Convert to list because "__path__" may not support indexing.
    paths: list[str] = list(getattr(module, '__path__', []))

    if len(paths) != 1:
        filename = getattr(module, '__file__', None)
        if filename is not None:
            paths = [os.path.dirname(filename)]
        else:
            # Handle edge case where the list returned by "__path__" contains
            # duplicates that must be removed.
            paths = list(set(paths))

    return paths

resolve_forwardref_fullname

resolve_forwardref_fullname(
    module_name: str,
    forwardref: str | ForwardRef,
    _guard: frozenset[str] = frozenset(),
) -> str | None

Resolves a forward reference to its fully qualified name.

It resolves a forward reference to its fully qualified name. This function is necessary because the Python interpreter does not resolve forward references module origin in annotations.

Parameters:

Name Type Description Default
module_name str

The module name where the forward reference occurs.

required
forwardref str | ForwardRef

The forward reference to resolve.

required
_guard frozenset[str]

A set of module names to prevent infinite recursion.

frozenset()

Returns:

Type Description
str | None

The fully qualified forward reference name.

Source code in .venv/lib/python3.12/site-packages/plateforme/core/modules.py
def resolve_forwardref_fullname(
    module_name: str,
    forwardref: str | ForwardRef,
    _guard: frozenset[str] = frozenset(),
) -> str | None:
    """Resolves a forward reference to its fully qualified name.

    It resolves a forward reference to its fully qualified name. This function
    is necessary because the Python interpreter does not resolve forward
    references module origin in annotations.

    Args:
        module_name: The module name where the forward reference occurs.
        forwardref: The forward reference to resolve.
        _guard: A set of module names to prevent infinite recursion.

    Returns:
        The fully qualified forward reference name.
    """
    # Check for infinite recursion
    if module_name in _guard:
        return None

    # Retrieve forward reference annotation
    if isinstance(forwardref, ForwardRef):
        annotation = forwardref.__forward_arg__
    else:
        annotation = forwardref

    # Split the forward reference annotation into its different parts
    if '.' in annotation:
        ann_base = '.'.join(annotation.split('.')[:-1])
        ann_root = annotation.split('.')[0]
        ann_name = annotation.split('.')[-1]
    else:
        ann_base = ''
        ann_root = annotation
        ann_name = annotation

    # Retrieve the source code of the module containing the forward reference
    if module_name not in sys.modules:
        file = resolve_path_from_module_name(module_name)
        with open(file, 'r') as f:
            source = f.read()
    else:
        source = inspect.getsource(sys.modules[module_name])

    # Handle import statements
    def handle_import_statement(node: ast.ImportFrom) -> str | None:
        for alias in node.names:
            if alias.name == ann_root or alias.asname == ann_root:
                import_base = resolve_import_statement(module_name, node)
                return resolve_forwardref_fullname(
                    import_base + ann_base,
                    ann_name,
                    _guard | {module_name},
                )
        return None

    # Parse the module source code into an AST walkable tree
    tree = ast.parse(source)
    for node in ast.walk(tree):
        # Check if the node is an import statement inside the `TYPE_CHECKING`
        # block. It's normally from here that forward references are imported.
        if (
            isinstance(node, ast.If)
            and isinstance(node.test, ast.Name)
            and node.test.id == 'TYPE_CHECKING'
        ):
            for if_node in node.body:
                if isinstance(if_node, ast.ImportFrom):
                    if import_statement := handle_import_statement(if_node):
                        return import_statement
        # Check if the node is an import statement outside the `TYPE_CHECKING`
        # block. This is an uncommon case when the forward reference is
        # imported directly in the module.
        elif isinstance(node, ast.ImportFrom):
            if import_statement := handle_import_statement(node):
                return import_statement
        # Check if the node is a class definition with the same name as the
        # forward reference annotation. This stops the forward reference
        # recursive resolution and returns the module name.
        elif isinstance(node, ast.ClassDef) and node.name == annotation:
            return _get_qualname_from_inspect(module_name, ann_name) \
                or _get_qualname_from_ast(module_name, ann_name, source) \
                or '%s.%s' % (module_name, ann_name)

    return None

resolve_import_statement

resolve_import_statement(
    name: str, import_statement: ImportFrom
) -> str

Resolve an import statement to a fully qualified module name.

It resolves the fully qualified module name from an import statement relative to a specified module name from which the import statement originates.

Parameters:

Name Type Description Default
name str

The module name against which to resolve the import statement.

required
import_statement ImportFrom

The import statement to resolve.

required

Returns:

Type Description
str

The import statement fully qualified module name.

Source code in .venv/lib/python3.12/site-packages/plateforme/core/modules.py
def resolve_import_statement(
    name: str,
    import_statement: ast.ImportFrom,
) -> str:
    """Resolve an import statement to a fully qualified module name.

    It resolves the fully qualified module name from an import statement
    relative to a specified module name from which the import statement
    originates.

    Args:
        name: The module name against which to resolve the import statement.
        import_statement: The import statement to resolve.

    Returns:
        The import statement fully qualified module name.
    """
    # Check for fully qualified import statement
    if import_statement.level == 0:
        return import_statement.module or ''

    # Otherwise resolve the relative import statement
    module_parts = name.split('.')
    import_base = '.'.join(module_parts[:-import_statement.level])
    import_name = import_statement.module or ''
    return '%s.%s' % (import_base, import_name)

resolve_path_from_module_name

resolve_path_from_module_name(name: str) -> str

Resolve the file path of a Python module without loading it.

Parameters:

Name Type Description Default
name str

The name of the module.

required

Returns:

Type Description
str

The file path of the module.

Source code in .venv/lib/python3.12/site-packages/plateforme/core/modules.py
def resolve_path_from_module_name(name: str) -> str:
    """Resolve the file path of a Python module without loading it.

    Args:
        name: The name of the module.

    Returns:
        The file path of the module.
    """
    spec = importlib.util.find_spec(name)
    if spec is not None and spec.origin is not None:
        return spec.origin
    raise ImportError(
        f"Could not find module {name!r}. Make sure the module is installed "
        f"and importable."
    )

resolve_relative_import_name

resolve_relative_import_name(
    from_name: str, to_name: str
) -> str

Resolve relative module import name from one module to another.

Source code in .venv/lib/python3.12/site-packages/plateforme/core/modules.py
def resolve_relative_import_name(from_name: str, to_name: str) -> str:
    """Resolve relative module import name from one module to another."""
    # Handle root module
    if is_root_module(from_name):
        return to_name

    from_parts = from_name.split('.')
    to_parts = to_name.split('.')

    # Find common prefix
    common = 0
    for f, t in zip(from_parts, to_parts):
        if f != t:
            break
        common += 1

    # Construct relative path
    up_levels = len(from_parts) - common
    relative_parts = ['.' * up_levels] if up_levels else []
    relative_parts.extend(to_parts[common:])

    return '.'.join(relative_parts) if relative_parts else '.'