Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

## Unreleased

* πŸ‘Œ Speed up parsing (~6% on the CommonMark spec) by making `StateBase.src` a plain attribute instead of a property, in [#450](https://github.com/executablebooks/markdown-it-py/pull/450)
* ✨ Add `--enable-tables` to the CLI for file, standard input and interactive parsing in [#422](https://github.com/executablebooks/markdown-it-py/pull/422)
* πŸ› Fix CLI interactive mode joining input lines with an extra newline, which split every line into its own paragraph and broke hard line breaks, in [#172](https://github.com/executablebooks/markdown-it-py/issues/172)
* πŸ› Fix trimming and splitting with the Python whitespace set instead of the CommonMark one, which dropped U+001C–U+001F and U+0085 from paragraphs, headings, table cells and fence info strings and let distinct reference labels resolve each other, in [#418](https://github.com/executablebooks/markdown-it-py/pull/418), thanks to [@Nexory](https://github.com/Nexory)
Expand Down
24 changes: 12 additions & 12 deletions markdown_it/ruler.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,30 +30,30 @@ class Ruler


class StateBase:
# `src` is a plain attribute, not a property: rules read it on almost
# every step, and a property call there costs ~5% of total parse time.
src: str

# Cache for the deprecated `srcCharCode`, as `(src, char_codes)`.
# This is a class-level default, since subclasses do not call `__init__`.
_src_char_code: tuple[str, tuple[int, ...]] | None = None

def __init__(self, src: str, md: MarkdownIt, env: EnvType):
self.src = src
self.env = env
self.md = md

@property
def src(self) -> str:
return self._src

@src.setter
def src(self, value: str) -> None:
self._src = value
self._srcCharCode: tuple[int, ...] | None = None

@property
def srcCharCode(self) -> tuple[int, ...]:
warnings.warn(
"StateBase.srcCharCode is deprecated. Use StateBase.src instead.",
DeprecationWarning,
stacklevel=2,
)
if self._srcCharCode is None:
self._srcCharCode = tuple(ord(c) for c in self._src)
return self._srcCharCode
# rebuild the cache if `src` has been reassigned since it was built
if self._src_char_code is None or self._src_char_code[0] is not self.src:
self._src_char_code = (self.src, tuple(ord(c) for c in self.src))
return self._src_char_code[1]


class RuleOptionsType(TypedDict, total=False):
Expand Down
12 changes: 12 additions & 0 deletions tests/test_api/test_main.py
Original file line number Diff line number Diff line change
Expand Up @@ -544,3 +544,15 @@ def peek_rule(state, silent):
# the rule saw the text accumulate one character at a time
assert seen[:4] == [0, 1, 2, 3]
assert max(seen) == 9_999


def test_src_char_code_follows_src():
"""The deprecated ``srcCharCode`` is rebuilt when ``src`` is reassigned."""
from markdown_it.rules_block.state_block import StateBlock

state = StateBlock("ab", MarkdownIt(), {}, [])
with pytest.warns(DeprecationWarning):
assert state.srcCharCode == (97, 98)
state.src = "xyz"
with pytest.warns(DeprecationWarning):
assert list(state.srcCharCode) == [120, 121, 122]