Skip to content

Commit

Permalink
Add a @public decorator to match @internal
Browse files Browse the repository at this point in the history
  • Loading branch information
bartfeenstra committed Jul 4, 2024
1 parent 80f940d commit 9ec835b
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 2 deletions.
13 changes: 12 additions & 1 deletion betty/tests/test_typing.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from betty.typing import internal
from betty.typing import internal, public


class TestInternal:
Expand All @@ -10,3 +10,14 @@ def _target() -> object:
return sentinel

assert _target() is sentinel


class TestPublic:
def test(self) -> None:
sentinel = object()

@public
def _target() -> object:
return sentinel

assert _target() is sentinel
29 changes: 28 additions & 1 deletion betty/typing.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,46 @@
Providing typing utilities.
"""

import re
from typing import TypeVar


_T = TypeVar("_T")


_INTERNAL_INDENTATION_PATTERN = re.compile(r"( +)")


def _internal(target: _T) -> _T:
doc = target.__doc__ or ""
doc_last_line = doc.rsplit("\n")[-1]
indentation_match = _INTERNAL_INDENTATION_PATTERN.match(doc_last_line)
indentation = indentation_match.group(0) if indentation_match else ""
target.__doc__ = (
doc
+ f"\n\n{indentation}This is internal. It **MAY** be used anywhere in Betty's source code, but **MUST NOT** be used by third-party code."
)
return target


@_internal
def internal(target: _T) -> _T:
"""
Mark a target as internal to Betty.
Anything decorated with ``@internal`` MAY be used anywhere in Betty's source code,
but MUST be considered private by third-party code.
"""
return _internal(target)


@internal
def public(target: _T) -> _T:
"""
Mark a target as publicly usable.
This function is internal (and ironically cannot be decorated with itself).
This is intended for items nested inside something marked with :py:func:`betty.typing.internal`,
such as class attributes: third-party code **SHOULD NOT** use a class marked ``@internal``
directly, but **MAY** use any of its attributes that are marked ``@public``.
"""
return target

0 comments on commit 9ec835b

Please sign in to comment.