polyfills¶
basedpython backfills modern python syntax and stdlib features to older supported versions by rewriting them at transpile time. minimum supported runtime is python 3.10
scope of this page: rewrites that apply to plain python source (forms a user could type into a .py file). basedpython-specific surface syntax has its own feature page
polyfills fall into a few categories:
- syntax rewrites — new grammar that basedpython desugars into equivalent 3.10 code
- import redirects —
typingnames that are not yet in 3.10/3.11/3.12 stdlib, transparently redirected totyping_extensions - expression rewrites — simple attribute or call expressions with a direct 3.10 equivalent
- stdlib shims — functions or classes not yet in the stdlib, injected as pure-python implementations
Python 3.14¶
bracketless except (PEP 758)¶
except clauses without parentheses are rewritten to use them:
template strings / t-strings (PEP 750)¶
requires grammar support — planned for a future release.
t'...' literals produce string.templatelib.Template objects. basedpython will rewrite them to explicit constructor calls
operator.is_none / operator.is_not_none¶
rewritten to lambda equivalents or inline expressions:
heapq max-heap functions¶
heapq.heapify_max, heapq.heappush_max, heapq.heappop_max, heapq.heapreplace_max, and heapq.heappushpop_max are injected as pure-Python shims when used
datetime.date.strptime / datetime.time.strptime¶
rewritten to the existing datetime.datetime.strptime with appropriate extraction:
# python source
datetime.date.strptime("2024-01-15", "%Y-%m-%d")
datetime.time.strptime("14:30:00", "%H:%M:%S")
# generated Python
datetime.datetime.strptime("2024-01-15", "%Y-%m-%d").date()
datetime.datetime.strptime("14:30:00", "%H:%M:%S").time()
Python 3.13¶
generic type parameter defaults (PEP 696)¶
TypeVar with a default= argument requires Python 3.13+. basedpython imports TypeVar from typing_extensions instead (which supports default=).
this applies when using PEP 695 generic syntax with a default (see the generics polyfill below)
typing.TypeIs (PEP 742)¶
redirected to typing_extensions.TypeIs:
typing.ReadOnly (PEP 705)¶
redirected to typing_extensions.ReadOnly
warnings.deprecated (PEP 702)¶
redirected to typing_extensions.deprecated
copy.replace()¶
injected as a pure-Python shim that calls obj.__replace__(**changes):
# generated Python
def _replace(obj, **changes):
return obj.__replace__(**changes)
new = _replace(obj, x=1)
base64.z85encode / base64.z85decode¶
injected as pure-Python shims (the Z85 alphabet and algorithm are fully specifiable in Python)
Python 3.12¶
generic classes and functions (PEP 695)¶
the [T] type parameter syntax and type alias statement are desugared to TypeVar, Generic, and TypeAlias. See the detailed examples in the section below
typing.override (PEP 698)¶
redirected to typing_extensions.override on 3.10–3.11
typing.TypedDict with Unpack / **kwargs (PEP 692)¶
redirected to typing_extensions.Unpack on 3.10–3.11
itertools.batched()¶
injected as a pure-Python shim on 3.10–3.11:
def _batched(iterable, n, *, strict=False):
it = iter(iterable)
while batch := tuple(itertools.islice(it, n)):
if strict and len(batch) < n:
raise ValueError("batched(): incomplete batch")
yield batch
math.sumprod(x, y)¶
injected as sum(a * b for a, b in zip(x, y))
pathlib.Path.walk()¶
injected as a wrapper around os.walk()
random.binomialvariate(n, p)¶
injected as a pure-Python shim
Python 3.11¶
typing.Self (PEP 673)¶
redirected to typing_extensions.Self
typing.Never / typing.assert_never¶
redirected to typing_extensions.Never / typing_extensions.assert_never
typing.LiteralString (PEP 675)¶
redirected to typing_extensions.LiteralString
typing.Required / typing.NotRequired (PEP 655)¶
redirected to typing_extensions.Required / typing_extensions.NotRequired
typing.TypeVarTuple / typing.Unpack (PEP 646)¶
Redirected to typing_extensions.TypeVarTuple / typing_extensions.Unpack
typing.dataclass_transform (PEP 681)¶
Redirected to typing_extensions.dataclass_transform
typing.reveal_type / typing.assert_type¶
Redirected to typing_extensions.reveal_type / typing_extensions.assert_type
datetime.UTC¶
Rewritten to datetime.timezone.utc:
Or inline:
sys.exception()¶
Rewritten to sys.exc_info()[1]:
math.exp2(x)¶
Rewritten to 2 ** x.
math.cbrt(x)¶
Injected as a shim: x ** (1 / 3) for positive values, with sign handling for negative values.
enum.StrEnum¶
Injected as a pure-Python shim:
BaseException.add_note()¶
injected as a monkey-patch on 3.10 when used:
tomllib¶
rewritten to fall back to tomli (the third-party backport):
generic classes and functions (PEP 695)¶
Python 3.12 introduced compact generic syntax. basedpython rewrites it using typing.TypeVar and typing.Generic
| basedpython | Python output |
|---|---|
class A[T]: ... |
class A(Generic[T]): ... |
class A[T=int]: ... |
class A(Generic[T]): ... (with default=int) |
class A[T: int]: ... |
class A(Generic[T]): ... (with bound=int) |
def f[T](x: T) -> T: ... |
def f(x: T) -> T: ... |
type Point = tuple[float, float] |
Point: TypeAlias = tuple[float, float] |
each type parameter becomes a module-level TypeVar with a mangled name (_T, _K, etc)
# generated Python
from typing import TypeVar, Generic
_T = TypeVar("_T", default=int) # from typing_extensions
class A(Generic[_T]): ...
multiple parameters:
# generated Python
from typing import TypeVar, Generic
_K = TypeVar("_K")
_V = TypeVar("_V")
class Map(Generic[_K, _V]): ...
existing base classes are preserved:
generic functions:
a bound (T: Foo) maps to TypeVar("_T", bound=Foo). constraints (T: (Foo, Bar)) map to TypeVar("_T", Foo, Bar).
type aliases:
# generated Python
from typing_extensions import TypeAliasType
Point = TypeAliasType("Point", tuple[float, float])
Grid = TypeAliasType("Grid", list[list[T]])
import redirect summary¶
when basedpython detects one of these names imported from typing on a runtime older than the version that added it,
it silently redirects to typing_extensions
| Name | Added in | Redirect source |
|---|---|---|
Self |
3.11 | typing_extensions |
Never, assert_never |
3.11 | typing_extensions |
LiteralString |
3.11 | typing_extensions |
Required, NotRequired |
3.11 | typing_extensions |
TypeVarTuple, Unpack |
3.11 | typing_extensions |
dataclass_transform |
3.11 | typing_extensions |
reveal_type, assert_type |
3.11 | typing_extensions |
override |
3.12 | typing_extensions |
TypeVar(default=...) |
3.13 | typing_extensions |
TypeIs |
3.13 | typing_extensions |
ReadOnly |
3.13 | typing_extensions |
deprecated (warnings) |
3.13 | typing_extensions |