Upgrading MarkupSafe 2 to 3
Breaking2.1.5 → 3.0.4Breaking2Platform2Deprecated2Changed3Fixed3Other9
BreakingUpgrade verdict
2 breaking changes and 2 platform requirement changes.
In plain terms
- Several text-manipulation methods on the safe string type no longer escape the text you pass in, so the result may contain unescaped markup.
- Updates Markup method signatures to match str signatures, using positional-only arguments.
- The library now works on the newest Python version, including a special build that runs without the global interpreter lock.
- If you are still on Python 3.7 or 3.8, you cannot use this version and must upgrade Python first.
Must act Top 5 of 6 that need code or config changes
Python requirement changed in 3.0.0: >=3.7 → >=3.9.
What you must change
Breaking2
Some str methods on Markup no longer escape their argument: strip, lstrip, rstrip, removeprefix, removesuffix, partition, and rpartition; replace only escapes its new argument.
MarkupstriplstriprstripremoveprefixremovesuffixpartitionrpartitionUpdates Markup method signatures to match str signatures, using positional-only arguments.
MarkupPlatform2
Adds support for Python 3.13 and its experimental free-threaded build.
Drops support for Python 3.7 and 3.8.
Deprecations to plan for
Deprecated2
__version__ now raises DeprecationWarning instead of UserWarning.__version__Deprecates the __version__ attribute in favor of feature detection or importlib.metadata.version("markupsafe").
__version__importlib.metadata.version()API changes
Generated by DepDelta from published Python source. Not mixed with prose notes.
- removed:
class HasHTML(te.Protocol) - removed:
export escape - removed:
export escape_silent - removed:
export soft_str - removed:
field Markup.capitalize - removed:
field Markup.casefold - removed:
field Markup.center - removed:
field Markup.expandtabs - removed:
field Markup.ljust - removed:
field Markup.lower - removed:
field Markup.lstrip - removed:
field Markup.removeprefix - removed:
field Markup.removesuffix - removed:
field Markup.replace - removed:
field Markup.rjust - removed:
field Markup.rstrip - removed:
field Markup.strip - removed:
field Markup.swapcase - removed:
field Markup.title - removed:
field Markup.translate - removed:
field Markup.upper - removed:
field Markup.zfill - changed:
constructor EscapeFormatter(escape: t.Callable[[t.Any], Markup]) -> None → constructor EscapeFormatter(escape: _TPEscape) -> None - changed:
method Markup.format_map(map: t.Mapping[str, t.Any]) -> te.Self → method Markup.format_map(mapping: cabc.Mapping[str, t.Any], /) -> te.Self - changed:
method Markup.join(seq: t.Iterable[t.Union[str, HasHTML]]) -> te.Self → method Markup.join(iterable: cabc.Iterable[str | _HasHTML], /) -> te.Self - changed:
method Markup.partition(sep: str) -> t.Tuple[te.Self, te.Self, te.Self] → method Markup.partition(sep: str, /) -> tuple[te.Self, te.Self, te.Self] - changed:
method Markup.rpartition(sep: str) -> t.Tuple[te.Self, te.Self, te.Self] → method Markup.rpartition(sep: str, /) -> tuple[te.Self, te.Self, te.Self] - changed:
method Markup.rsplit(sep: t.Optional[str]=…, maxsplit: int=…) -> t.List[te.Self] → method Markup.rsplit(sep: str | None=…, maxsplit: t.SupportsIndex=…) -> list[te.Self] - changed:
method Markup.split(sep: t.Optional[str]=…, maxsplit: int=…) -> t.List[te.Self] → method Markup.split(sep: str | None=…, maxsplit: t.SupportsIndex=…) -> list[te.Self] - changed:
method Markup.splitlines(keepends: bool=…) -> t.List[te.Self] → method Markup.splitlines(keepends: bool=…) -> list[te.Self] - changed:
static method Markup.escape(s: t.Any) -> te.Self → static method Markup.escape(s: t.Any, /) -> te.Self - added:
function escape(s: t.Any, /) -> Markup - added:
function escape_silent(s: t.Any | None, /) -> Markup - added:
function soft_str(s: t.Any, /) -> str - added:
method Markup.capitalize() -> te.Self - added:
method Markup.casefold() -> te.Self - added:
method Markup.center(width: t.SupportsIndex, fillchar: str=…, /) -> te.Self - added:
method Markup.expandtabs(tabsize: t.SupportsIndex=…) -> te.Self - added:
method Markup.ljust(width: t.SupportsIndex, fillchar: str=…, /) -> te.Self - added:
method Markup.lower() -> te.Self - added:
method Markup.lstrip(chars: str | None=…, /) -> te.Self - added:
method Markup.removeprefix(prefix: str, /) -> te.Self - added:
method Markup.removesuffix(suffix: str) -> te.Self - added:
method Markup.replace(old: str, new: str, count: t.SupportsIndex=…, /) -> te.Self - added:
method Markup.rjust(width: t.SupportsIndex, fillchar: str=…, /) -> te.Self - added:
method Markup.rstrip(chars: str | None=…, /) -> te.Self - added:
method Markup.strip(chars: str | None=…, /) -> te.Self - added:
method Markup.swapcase() -> te.Self - added:
method Markup.title() -> te.Self - added:
method Markup.translate(table: cabc.Mapping[int, str | int | None], /) -> str - added:
method Markup.upper() -> te.Self - added:
method Markup.zfill(width: t.SupportsIndex, /) -> te.Self