Skip to content

topmark.registry.filetypes

topmark / registry / filetypes

Advanced public registry for file type definitions.

This module exposes read-oriented views and limited mutation hooks for the composed file type registry used by TopMark. Most callers should prefer the stable facade in topmark.registry.registry.Registry; this module primarily serves advanced integrations, plugins, and tests.

Notes
  • Public views such as as_mapping_by_local_key() and iter_meta_by_local_key() expose the local-key compatibility view, while as_mapping() and iter_meta() expose the canonical qualified-key view.
  • register() and unregister() apply overlay-only changes; they do not mutate the base registry built by topmark.filetypes.instances.
  • Overlay state is process-local and guarded by an RLock.

FileTypeRegistry

Composed registry view for file type definitions.

Notes
  • Only validated FileType instances are admitted to the effective registry.
  • Mutation hooks are intended for plugin authors and test scaffolding. Most integrations should consume metadata and read-only views instead.

names classmethod

names()

Return all registered file type names (sorted).

Returns:

Type Description
tuple[str, ...]

Tuple with sorted file type names.

Source code in src/topmark/registry/filetypes.py
@classmethod
def names(cls) -> tuple[str, ...]:
    """Return all registered file type names (sorted).

    Returns:
        Tuple with sorted file type names.
    """
    with cls._lock:
        return tuple(sorted(cls._compose_by_local_key().keys()))

qualified_keys classmethod

qualified_keys()

Return the qualified keys of all registered file types (sorted).

TODO: define a stable and sensible "prioritized" sort helper (builtins lowest precedence).

Returns:

Type Description
tuple[str, ...]

Tuple with sorted file type qualified keys.

Source code in src/topmark/registry/filetypes.py
@classmethod
def qualified_keys(cls) -> tuple[str, ...]:
    """Return the qualified keys of all registered file types (sorted).

    TODO: define a stable and sensible "prioritized" sort helper (builtins lowest precedence).

    Returns:
        Tuple with sorted file type qualified keys.
    """
    with cls._lock:
        return tuple(sorted(cls._compose().keys()))

namespaces classmethod

namespaces()

Return the namespaces of all registered file types (sorted).

TODO: define a stable and sensible "prioritized" sort helper (builtins lowest precedence).

Returns:

Type Description
tuple[str, ...]

Tuple with sorted file type namepaces.

Source code in src/topmark/registry/filetypes.py
@classmethod
def namespaces(cls) -> tuple[str, ...]:
    """Return the namespaces of all registered file types (sorted).

    TODO: define a stable and sensible "prioritized" sort helper (builtins lowest precedence).

    Returns:
        Tuple with sorted file type namepaces.
    """
    with cls._lock:
        # Use set comprehension to return "sorted set" of namespaces
        return tuple(sorted({ft.namespace for ft in cls._compose().values()}))

resolve_filetype_id classmethod

resolve_filetype_id(
    file_type_id, *, default_namespace=None
)

Resolve a file type identifier to a FileType instance.

This helper supports both unqualified and qualified identifiers:

  • Unqualified: "<local_key>"
  • Qualified: "<namespace>:<local_key>"

Parameters:

Name Type Description Default
file_type_id str

Identifier to resolve (unqualified or qualified).

required
default_namespace str | None

Optional namespace constraint applied when the identifier is unqualified.

None

Returns:

Type Description
FileType | None

The resolved FileType instance, or None if no matching entry exists.

Raises:

Type Description
AmbiguousFileTypeIdentifierError

If an unqualified identifier would match multiple file types in the composed registry.

InvalidRegistryIdentityError

If registration is attempted with an invalid registry identifier.

Notes

The composed registry is still keyed by unqualified file type local_key for compatibility, but this resolver treats namespace:local_key as the canonical stable identity and is the preferred lookup entry point for namespace-aware code.

Source code in src/topmark/registry/filetypes.py
@classmethod
def resolve_filetype_id(
    cls,
    file_type_id: str,
    *,
    default_namespace: str | None = None,
) -> FileType | None:
    """Resolve a file type identifier to a `FileType` instance.

    This helper supports both *unqualified* and *qualified* identifiers:

    - Unqualified: ``"<local_key>"``
    - Qualified: ``"<namespace>:<local_key>"``

    Args:
        file_type_id: Identifier to resolve (unqualified or qualified).
        default_namespace: Optional namespace constraint applied when the identifier is
            unqualified.

    Returns:
        The resolved `FileType` instance, or ``None`` if no matching entry exists.

    Raises:
        AmbiguousFileTypeIdentifierError: If an unqualified identifier would match multiple
            file types in the composed registry.
        InvalidRegistryIdentityError: If registration is attempted with an invalid registry
            identifier.

    Notes:
        The composed registry is still keyed by unqualified file type local_key for
        compatibility, but this resolver treats ``namespace:local_key`` as the canonical stable
        identity and is the preferred lookup entry point for namespace-aware code.
    """
    raw: str = file_type_id.strip()
    if not raw:
        return None

    # Qualified form: "namespace:local_key"
    if ":" in raw:
        namespace, sep, local_key = raw.partition(":")
        if not sep or not namespace or not local_key or ":" in local_key:
            raise InvalidRegistryIdentityError(
                message=f"Malformed file type identifier: {raw!r}",
                identifier=raw,
                namespace=namespace or None,
                local_key=local_key or None,
            )

        with cls._lock:
            return cls._compose().get(
                make_qualified_key(namespace, local_key),
            )

    # Unqualified form: "local_key"
    with cls._lock:
        candidates: list[FileType] = [
            file_type
            for file_type in cls._compose_by_local_key().values()
            if file_type.local_key == raw
            and (default_namespace is None or file_type.namespace == default_namespace)
        ]
        if not candidates:
            return None
        if len(candidates) > 1:
            raise AmbiguousFileTypeIdentifierError(
                file_type=raw,
                candidates=tuple(sorted(ft.qualified_key for ft in candidates)),
            )
        return candidates[0]

get classmethod

get(file_type_key)

Return a file type by qualified key.

Parameters:

Name Type Description Default
file_type_key str

Qualified key used as the registry key.

required

Returns:

Type Description
FileType | None

The file type if found, else None.

Source code in src/topmark/registry/filetypes.py
@classmethod
def get(cls, file_type_key: str) -> FileType | None:
    """Return a file type by qualified key.

    Args:
        file_type_key: Qualified key used as the registry key.

    Returns:
        The file type if found, else None.
    """
    with cls._lock:
        return cls._compose().get(file_type_key)

as_mapping_by_local_key classmethod

as_mapping_by_local_key()

Return the read-only local-key compatibility view of file types.

Returns:

Type Description
Mapping[str, FileType]

Mapping of file type local key to FileType.

Notes

The returned mapping is a MappingProxyType and must not be mutated.

Source code in src/topmark/registry/filetypes.py
@classmethod
def as_mapping_by_local_key(cls) -> Mapping[str, FileType]:
    """Return the read-only local-key compatibility view of file types.

    Returns:
        Mapping of file type local key to `FileType`.

    Notes:
        The returned mapping is a ``MappingProxyType`` and must not be mutated.
    """
    with cls._lock:
        cached: Mapping[str, FileType] | None = cls._cache
        if cached is not None:
            return cached

        # Compose a fresh view and cache it.
        # NOTE: tests may monkeypatch `_compose()`; do not rely on `_compose()`
        # to populate `_cache`.
        composed: dict[str, FileType] = cls._compose_by_local_key()
        cls._cache = MappingProxyType(composed)
        return cls._cache

as_mapping classmethod

as_mapping()

Return the read-only qualified-key canonical view of file types.

Returns:

Type Description
Mapping[str, FileType]

Mapping of file type qualified key to FileType.

Notes

The returned mapping is a MappingProxyType and must not be mutated.

Source code in src/topmark/registry/filetypes.py
@classmethod
def as_mapping(cls) -> Mapping[str, FileType]:
    """Return the read-only qualified-key canonical view of file types.

    Returns:
        Mapping of file type qualified key to `FileType`.

    Notes:
        The returned mapping is a ``MappingProxyType`` and must not be mutated.
    """
    with cls._lock:
        cached: Mapping[str, FileType] | None = cls._cache_by_qualified_key
        if cached is not None:
            return cached

        # Compose a fresh view and cache it.
        # NOTE: tests may monkeypatch `_compose()`; do not rely on `_compose()`
        # to populate `_cache`.
        composed: dict[str, FileType] = cls._compose()
        cls._cache_by_qualified_key = MappingProxyType(composed)
        return cls._cache_by_qualified_key

iter_meta_by_local_key classmethod

iter_meta_by_local_key()

Iterate stable metadata for the local-key compatibility view.

No getattr needed because types are guaranteed.

Yields:

Type Description
FileTypeMeta

Serializable FileTypeMeta metadata about each file type.

Source code in src/topmark/registry/filetypes.py
@classmethod
def iter_meta_by_local_key(cls) -> Iterator[FileTypeMeta]:
    """Iterate stable metadata for the local-key compatibility view.

    No getattr needed because types are guaranteed.

    Yields:
        Serializable ``FileTypeMeta`` metadata about each file type.
    """
    with cls._lock:
        for ft in cls._compose_by_local_key().values():
            yield FileTypeMeta(
                local_key=ft.local_key,
                namespace=ft.namespace,
                description=ft.description or "",
                extensions=tuple(ft.extensions or ()),
                filenames=tuple(ft.filenames or ()),
                patterns=tuple(ft.patterns or ()),
                skip_processing=ft.skip_processing,
                content_matcher=ft.content_matcher is not None,
                header_policy=ft.header_policy.to_dict(),
            )

iter_meta classmethod

iter_meta()

Iterate stable metadata for the qualified-key canonical view.

No getattr needed because types are guaranteed.

Yields:

Type Description
FileTypeMeta

Serializable FileTypeMeta metadata about each file type.

Source code in src/topmark/registry/filetypes.py
@classmethod
def iter_meta(cls) -> Iterator[FileTypeMeta]:
    """Iterate stable metadata for the qualified-key canonical view.

    No getattr needed because types are guaranteed.

    Yields:
        Serializable `FileTypeMeta` metadata about each file type.
    """
    with cls._lock:
        for ft in cls._compose().values():
            yield FileTypeMeta(
                local_key=ft.local_key,
                namespace=ft.namespace,
                description=ft.description or "",
                extensions=tuple(ft.extensions or ()),
                filenames=tuple(ft.filenames or ()),
                patterns=tuple(ft.patterns or ()),
                skip_processing=ft.skip_processing,
                content_matcher=ft.content_matcher is not None,
                header_policy=ft.header_policy.to_dict(),
            )

register classmethod

register(ft_obj)

Register a new file type.

Parameters:

Name Type Description Default
ft_obj FileType

A FileType with a unique, non-empty .local_key.

required

Raises:

Type Description
ValueError

If .local_key is empty or already registered.

Notes
  • This mutates global registry state. Prefer temporary usage in tests with try/finally to ensure cleanup.
  • Thread safe via RLock; process-global state; do not mutate in long-lived multi-tenant processes.
Source code in src/topmark/registry/filetypes.py
@classmethod
def register(
    cls,
    ft_obj: FileType,
) -> None:
    """Register a new file type.

    Args:
        ft_obj: A `FileType` with a unique, non-empty `.local_key`.

    Raises:
        ValueError: If `.local_key` is empty or already registered.

    Notes:
        - This mutates global registry state. Prefer temporary usage in tests with
          try/finally to ensure cleanup.
        - Thread safe via RLock; process-global state; do not mutate in long-lived
          multi-tenant processes.
    """
    # Strict validation of ft_obj type (`FileType``) and ft_obj.local_key (nonempty `str`)
    # before touching state
    _ = cls._validate_ft(ft_obj)

    with cls._lock:
        local_key: str = ft_obj.local_key
        if not local_key.strip():
            raise ValueError(
                f"FileType.local_key must be a nonempty string (found {local_key!r})."
            )
        # Check against *composed* view to avoid dupes
        if local_key in cls._compose_by_local_key():
            raise ValueError(f"Duplicate FileType local_key: {local_key}")
        # Record override locally (no base mutation)
        cls._overrides[local_key] = ft_obj
        # If this local_key was previously removed, allow re-registration.
        cls._removals.discard(local_key)
        cls._clear_cache()

unregister_by_local_key classmethod

unregister_by_local_key(local_key)

Unregister a file type by unqualified local key.

Parameters:

Name Type Description Default
local_key str

Registered file type local_key.

required

Returns:

Type Description
bool

True if the entry existed and was removed, else False.

Notes
  • This mutates global registry state.
  • Thread safe via RLock; process-global state; do not mutate in long-lived multi-tenant processes.
Source code in src/topmark/registry/filetypes.py
@classmethod
def unregister_by_local_key(cls, local_key: str) -> bool:
    """Unregister a file type by unqualified local key.

    Args:
        local_key: Registered file type local_key.

    Returns:
        `True` if the entry existed and was removed, else `False`.

    Notes:
        - This mutates global registry state.
        - Thread safe via RLock; process-global state; do not mutate in long-lived
          multi-tenant processes.
    """
    with cls._lock:
        # Remove local override (if any) and mark for removal from base
        existed = False
        if local_key in cls._overrides:
            cls._overrides.pop(local_key, None)
            existed = True
        # If present only in base, we still support hiding it
        if local_key in cls._compose_by_local_key():
            cls._removals.add(local_key)
            existed = True
        cls._clear_cache()
        return existed

unregister classmethod

unregister(file_type_key)

Unregister a file type by qualified key.

Parameters:

Name Type Description Default
file_type_key str

Registered file type qualified key.

required

Returns:

Type Description
bool

True if the entry existed and was removed, else False.

Notes
  • This mutates global registry state.
  • Thread safe via RLock; process-global state; do not mutate in long-lived multi-tenant processes.
Source code in src/topmark/registry/filetypes.py
@classmethod
def unregister(cls, file_type_key: str) -> bool:
    """Unregister a file type by qualified key.

    Args:
        file_type_key: Registered file type qualified key.

    Returns:
        `True` if the entry existed and was removed, else `False`.

    Notes:
        - This mutates global registry state.
        - Thread safe via RLock; process-global state; do not mutate in long-lived
          multi-tenant processes.
    """
    with cls._lock:
        ft: FileType | None = cls._compose().get(file_type_key)
        if ft is None:
            return False

        # Remove local override (if any) and mark for removal from base
        local_key: str = ft.local_key
        existed = False
        if local_key in cls._overrides:
            cls._overrides.pop(local_key, None)
            existed = True
        # If present only in base, we still support hiding it
        if local_key in cls._compose_by_local_key():
            cls._removals.add(local_key)
            existed = True
        cls._clear_cache()
        return existed