modifiers and visibility¶
basedpython promotes commonly-used decorators and typing annotations into first-class
keyword modifiers on classes, functions, and assignments. the surface keywords replace
boilerplate decorator/annotation pairs at transpile time
class modifiers¶
| basedpython | Python output |
|---|---|
final class Foo |
@final + class Foo |
abstract class Foo |
class Foo (keyword stripped, no decorator) |
open class Foo |
class Foo (keyword stripped, no decorator) |
data class Foo |
@dataclass(slots=True) + class Foo |
frozen data class Foo |
@dataclass(frozen=True, slots=True) + class Foo |
enum class Color |
class Color(Enum) (base added) |
protocol Foo |
class Foo(Protocol) (base added) |
abstract is a marker for the type checker; it has no runtime decorator.
open is the inverse of final — a marker that the class is intended to be
subclassed. neither emits a runtime artefact
bases are preserved when the modifier injects one — enum class Color(str) becomes
class Color(str, Enum): ...
function modifiers¶
| basedpython | Python output |
|---|---|
final def m |
@final def m |
abstract def m |
@abstractmethod def m |
override def m |
@override def m |
static def m |
@staticmethod def m |
class def m |
@classmethod def m |
override is sourced from typing on 3.12+ and typing_extensions below.
abstract def with no body is filled in with : raise NotImplementedError
instead of the usual : ...
let / class-var / newtype¶
| basedpython | Python output |
|---|---|
let MAX = 100 |
MAX: Final = 100 |
class count = 0 |
count: ClassVar = 0 (inside a class) |
newtype UserId = int |
UserId = NewType("UserId", int) |
let works at module and class scope. inside a class, class x = ... is the
class-variable form (distinct from the regular let x = ... which is Final).
newtype introduces a distinct typing.NewType-backed type at module scope
assignment modifiers¶
override, final override, and abstract may also appear on assignments
and annotated assignments. the modifier keyword is stripped at transpile time:
| basedpython | Python output |
|---|---|
override x = 1 |
x = 1 |
final override x = 1 |
x = 1 |
abstract x: T |
x: T |
these are compile-time-only markers — they constrain how the symbol is checked but emit no runtime artefact
export / public / private¶
basedpython infers __all__ from explicit visibility keywords:
transpiles to:
__all__ = ["public_api", "also_exported"]
def public_api(): ...
def also_exported(): ...
def _helper(): ...
exportandpublicare aliases. each marked symbol is added to a synthesized__all__list at module levelprivatestrips the keyword and renames the symbol with a leading underscore at the definition site and every same-module call site. it is excluded from__all__even when noexport/publicdeclarations exist- visibility keywords are module-level only. inside a class they are stripped without renaming