Script 'mail_helper' called by obssrc
Hello community,
here is the log from the commit of package python-Markdown for openSUSE:Factory
checked in at 2023-11-02 20:20:03
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-Markdown (Old)
and /work/SRC/openSUSE:Factory/.python-Markdown.new.17445 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-Markdown"
Thu Nov 2 20:20:03 2023 rev:44 rq:1122132 version:3.5.1
Changes:
--------
--- /work/SRC/openSUSE:Factory/python-Markdown/python-Markdown.changes
2023-10-12 11:51:22.869232578 +0200
+++
/work/SRC/openSUSE:Factory/.python-Markdown.new.17445/python-Markdown.changes
2023-11-02 20:20:05.420789939 +0100
@@ -1,0 +2,8 @@
+Wed Nov 1 20:56:04 UTC 2023 - Benoît Monin <[email protected]>
+
+- update to version 3.5.1:
+ * Fix a performance problem with HTML extraction where large HTML
+ input could trigger quadratic line counting behavior (#1392).
+ * Improve and expand type annotations in the code base (#1394).
+
+-------------------------------------------------------------------
Old:
----
Markdown-3.5.tar.gz
New:
----
Markdown-3.5.1.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ python-Markdown.spec ++++++
--- /var/tmp/diff_new_pack.IswkUJ/_old 2023-11-02 20:20:06.080814226 +0100
+++ /var/tmp/diff_new_pack.IswkUJ/_new 2023-11-02 20:20:06.084814373 +0100
@@ -18,7 +18,7 @@
%{?sle15_python_module_pythons}
Name: python-Markdown
-Version: 3.5
+Version: 3.5.1
Release: 0
Summary: Python implementation of Markdown
License: BSD-3-Clause
++++++ Markdown-3.5.tar.gz -> Markdown-3.5.1.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/Markdown-3.5/Markdown.egg-info/PKG-INFO
new/Markdown-3.5.1/Markdown.egg-info/PKG-INFO
--- old/Markdown-3.5/Markdown.egg-info/PKG-INFO 2023-10-06 21:08:08.000000000
+0200
+++ new/Markdown-3.5.1/Markdown.egg-info/PKG-INFO 2023-10-31
20:59:09.000000000 +0100
@@ -1,6 +1,6 @@
Metadata-Version: 2.1
Name: Markdown
-Version: 3.5
+Version: 3.5.1
Summary: Python implementation of John Gruber's Markdown.
Author: Manfred Stienstra, Yuri Takhteyev
Author-email: Waylan limberg <[email protected]>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/Markdown-3.5/PKG-INFO new/Markdown-3.5.1/PKG-INFO
--- old/Markdown-3.5/PKG-INFO 2023-10-06 21:08:08.315934400 +0200
+++ new/Markdown-3.5.1/PKG-INFO 2023-10-31 20:59:09.902230000 +0100
@@ -1,6 +1,6 @@
Metadata-Version: 2.1
Name: Markdown
-Version: 3.5
+Version: 3.5.1
Summary: Python implementation of John Gruber's Markdown.
Author: Manfred Stienstra, Yuri Takhteyev
Author-email: Waylan limberg <[email protected]>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/Markdown-3.5/docs/changelog.md
new/Markdown-3.5.1/docs/changelog.md
--- old/Markdown-3.5/docs/changelog.md 2023-10-06 21:07:58.000000000 +0200
+++ new/Markdown-3.5.1/docs/changelog.md 2023-10-31 20:58:52.000000000
+0100
@@ -8,6 +8,14 @@
The format is based on [Keep a
Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic
Versioning](https://semver.org/spec/v2.0.0.html). See the [Contributing
Guide](contributing.md) for details.
+## [3.5.1] -- 2023-10-31
+
+### Fixed
+
+* Fix a performance problem with HTML extraction where large HTML input could
+ trigger quadratic line counting behavior (#1392).
+* Improve and expand type annotations in the code base (#1394).
+
## [3.5] -- 2023-10-06
### Added
@@ -51,21 +59,16 @@
## [3.4.2] -- 2023-03-22
-### Added
-
-* Officially support Python 3.11.
-
### Fixed
-
+* Officially support Python 3.11.
* Improve standalone * and _ parsing (#1300).
* Consider `<html>` HTML tag a block-level element (#1309).
-
-### Infrastructure
-
* Switch from `setup.py` to `pyproject.toml`.
## [3.4.1] -- 2022-07-15
+### Fixed
+
* Fix an import issue with `importlib.util` (#1274).
## [3.4] -- 2022-07-15
@@ -187,10 +190,6 @@
## [3.3.5] -- 2021-11-16
-### Added
-
-* Support Python 3.10 (#1124).
-
### Fixed
* Make the `slugify_unicode` function not remove diacritical marks (#1118).
@@ -199,6 +198,7 @@
* Don't process shebangs in fenced code blocks when using CodeHilite (#1156).
* Improve email address validation for Automatic Links (#1165).
* Ensure `<summary>` tags are parsed correctly (#1079).
+* Support Python 3.10 (#1124).
## [3.3.4] -- 2021-02-24
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/Markdown-3.5/markdown/__meta__.py
new/Markdown-3.5.1/markdown/__meta__.py
--- old/Markdown-3.5/markdown/__meta__.py 2023-10-06 21:07:58.000000000
+0200
+++ new/Markdown-3.5.1/markdown/__meta__.py 2023-10-31 20:58:52.000000000
+0100
@@ -28,7 +28,7 @@
from __future__ import annotations
-__version_info__ = (3, 5, 0, 'final', 0)
+__version_info__ = (3, 5, 1, 'final', 0)
def _get_version(version_info):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/Markdown-3.5/markdown/blockparser.py
new/Markdown-3.5.1/markdown/blockparser.py
--- old/Markdown-3.5/markdown/blockparser.py 2023-10-06 21:07:58.000000000
+0200
+++ new/Markdown-3.5.1/markdown/blockparser.py 2023-10-31 20:58:52.000000000
+0100
@@ -30,11 +30,12 @@
from __future__ import annotations
import xml.etree.ElementTree as etree
-from typing import TYPE_CHECKING, Sequence, Any
+from typing import TYPE_CHECKING, Iterable, Any
from . import util
if TYPE_CHECKING: # pragma: no cover
from markdown import Markdown
+ from .blockprocessors import BlockProcessor
class State(list):
@@ -59,7 +60,7 @@
""" Set a new state. """
self.append(state)
- def reset(self):
+ def reset(self) -> None:
""" Step back one step in nested state. """
self.pop()
@@ -92,11 +93,11 @@
[`blockprocessors`][markdown.blockprocessors].
"""
- self.blockprocessors = util.Registry()
+ self.blockprocessors: util.Registry[BlockProcessor] = util.Registry()
self.state = State()
self.md = md
- def parseDocument(self, lines: Sequence[str]) -> etree.ElementTree:
+ def parseDocument(self, lines: Iterable[str]) -> etree.ElementTree:
""" Parse a Markdown document into an `ElementTree`.
Given a list of lines, an `ElementTree` object (not just a parent
@@ -116,7 +117,7 @@
self.parseChunk(self.root, '\n'.join(lines))
return etree.ElementTree(self.root)
- def parseChunk(self, parent: etree.Element, text: str):
+ def parseChunk(self, parent: etree.Element, text: str) -> None:
""" Parse a chunk of Markdown text and attach to given `etree` node.
While the `text` argument is generally assumed to contain multiple
@@ -134,7 +135,7 @@
"""
self.parseBlocks(parent, text.split('\n\n'))
- def parseBlocks(self, parent: etree.Element, blocks: Sequence[str]):
+ def parseBlocks(self, parent: etree.Element, blocks: list[str]) -> None:
""" Process blocks of Markdown text and attach to given `etree` node.
Given a list of `blocks`, each `blockprocessor` is stepped through
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/Markdown-3.5/markdown/blockprocessors.py
new/Markdown-3.5.1/markdown/blockprocessors.py
--- old/Markdown-3.5/markdown/blockprocessors.py 2023-10-06
21:07:58.000000000 +0200
+++ new/Markdown-3.5.1/markdown/blockprocessors.py 2023-10-31
20:58:52.000000000 +0100
@@ -82,7 +82,7 @@
else:
return None
- def detab(self, text: str, length: int = None) -> str:
+ def detab(self, text: str, length: int | None = None) -> tuple[str, str]:
""" Remove a tab from the front of each line of the given text. """
if length is None:
length = self.tab_length
@@ -105,7 +105,7 @@
lines[i] = lines[i][self.tab_length*level:]
return '\n'.join(lines)
- def test(self, parent: etree.Element, block: list[str]) -> bool:
+ def test(self, parent: etree.Element, block: str) -> bool:
""" Test for block type. Must be overridden by subclasses.
As the parser loops through processors, it will call the `test`
@@ -214,7 +214,7 @@
self.create_item(sibling, block)
self.parser.state.reset()
- def create_item(self, parent: etree.Element, block: str):
+ def create_item(self, parent: etree.Element, block: str) -> None:
""" Create a new `li` and parse the block with it as the parent. """
li = etree.SubElement(parent, 'li')
self.parser.parseBlocks(li, [block])
@@ -329,7 +329,7 @@
TAG: str = 'ol'
""" The tag used for the the wrapping element. """
- STARTSWITH: int = '1'
+ STARTSWITH: str = '1'
"""
The integer (as a string ) with which the list starts. For example, if a
list is initialized as
`3. Item`, then the `ol` tag will be assigned an HTML attribute of
`starts="3"`. Default: `"1"`.
@@ -342,7 +342,7 @@
This is the list of types which can be mixed.
"""
- def __init__(self, parser):
+ def __init__(self, parser: BlockParser):
super().__init__(parser)
# Detect an item (`1. item`). `group(1)` contains contents of item.
self.RE = re.compile(r'^[ ]{0,%d}\d+\.[ ]+(.*)' % (self.tab_length -
1))
@@ -448,7 +448,7 @@
TAG: str = 'ul'
""" The tag used for the the wrapping element. """
- def __init__(self, parser):
+ def __init__(self, parser: BlockParser):
super().__init__(parser)
# Detect an item (`1. item`). `group(1)` contains contents of item.
self.RE = re.compile(r'^[ ]{0,%d}[*+-][ ]+(.*)' % (self.tab_length -
1))
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/Markdown-3.5/markdown/core.py
new/Markdown-3.5.1/markdown/core.py
--- old/Markdown-3.5/markdown/core.py 2023-10-06 21:07:58.000000000 +0200
+++ new/Markdown-3.5.1/markdown/core.py 2023-10-31 20:58:52.000000000 +0100
@@ -23,7 +23,7 @@
import sys
import logging
import importlib
-from typing import TYPE_CHECKING, Any, TextIO, Callable
+from typing import TYPE_CHECKING, Any, Callable, ClassVar, Mapping, Sequence,
TextIO
from . import util
from .preprocessors import build_preprocessors
from .blockprocessors import build_block_parser
@@ -76,7 +76,7 @@
doc_tag = "div" # Element used to wrap document - later removed
- output_formats: dict[str, Callable[Element]] = {
+ output_formats: ClassVar[dict[str, Callable[[Element], str]]] = {
'html': to_html_string,
'xhtml': to_xhtml_string,
}
@@ -156,7 +156,11 @@
self.postprocessors = build_postprocessors(self)
return self
- def registerExtensions(self, extensions: list[Extension | str], configs:
dict[str, dict[str, Any]]) -> Markdown:
+ def registerExtensions(
+ self,
+ extensions: Sequence[Extension | str],
+ configs: Mapping[str, Mapping[str, Any]]
+ ) -> Markdown:
"""
Load a list of extensions into an instance of the `Markdown` class.
@@ -188,7 +192,7 @@
)
return self
- def build_extension(self, ext_name: str, configs: dict[str, Any]) ->
Extension:
+ def build_extension(self, ext_name: str, configs: Mapping[str, Any]) ->
Extension:
"""
Build extension from a string name, then return an instance using the
given `configs`.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/Markdown-3.5/markdown/extensions/__init__.py
new/Markdown-3.5.1/markdown/extensions/__init__.py
--- old/Markdown-3.5/markdown/extensions/__init__.py 2023-10-06
21:07:58.000000000 +0200
+++ new/Markdown-3.5.1/markdown/extensions/__init__.py 2023-10-31
20:58:52.000000000 +0100
@@ -27,7 +27,7 @@
from __future__ import annotations
-from typing import TYPE_CHECKING, Any
+from typing import TYPE_CHECKING, Any, Mapping, Sequence
from ..util import parseBoolValue
if TYPE_CHECKING: # pragma: no cover
@@ -37,7 +37,7 @@
class Extension:
""" Base class for extensions to subclass. """
- config: dict[str, list[Any, str]] = {}
+ config: Mapping[str, list] = {}
"""
Default configuration for an extension.
@@ -91,7 +91,7 @@
"""
return [(key, self.config[key][1]) for key in self.config.keys()]
- def setConfig(self, key: str, value: Any):
+ def setConfig(self, key: str, value: Any) -> None:
"""
Set a configuration option.
@@ -112,7 +112,7 @@
value = parseBoolValue(value, preserve_none=True)
self.config[key][0] = value
- def setConfigs(self, items: dict[str, Any] | list[tuple[str, Any]]):
+ def setConfigs(self, items: Mapping[str, Any] | Sequence[tuple[str, Any]]):
"""
Loop through a collection of configuration options, passing each to
[`setConfig`][markdown.extensions.Extension.setConfig].
@@ -129,7 +129,7 @@
for key, value in items:
self.setConfig(key, value)
- def extendMarkdown(self, md: Markdown):
+ def extendMarkdown(self, md: Markdown) -> None:
"""
Add the various processors and patterns to the Markdown Instance.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/Markdown-3.5/markdown/extensions/attr_list.py
new/Markdown-3.5.1/markdown/extensions/attr_list.py
--- old/Markdown-3.5/markdown/extensions/attr_list.py 2023-10-06
21:07:58.000000000 +0200
+++ new/Markdown-3.5.1/markdown/extensions/attr_list.py 2023-10-31
20:58:52.000000000 +0100
@@ -146,7 +146,7 @@
self.assign_attrs(elem, m.group(1))
elem.tail = elem.tail[m.end():]
- def assign_attrs(self, elem: Element, attrs: dict[str, str]):
+ def assign_attrs(self, elem: Element, attrs: str) -> None:
""" Assign `attrs` to element. """
for k, v in get_attrs(attrs):
if k == '.':
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/Markdown-3.5/markdown/extensions/footnotes.py
new/Markdown-3.5.1/markdown/extensions/footnotes.py
--- old/Markdown-3.5/markdown/extensions/footnotes.py 2023-10-06
21:07:58.000000000 +0200
+++ new/Markdown-3.5.1/markdown/extensions/footnotes.py 2023-10-31
20:58:52.000000000 +0100
@@ -98,14 +98,14 @@
# Insert a postprocessor after amp_substitute processor
md.postprocessors.register(FootnotePostprocessor(self), 'footnote', 25)
- def reset(self):
+ def reset(self) -> None:
""" Clear footnotes on reset, and prepare for distinct document. """
- self.footnotes = OrderedDict()
+ self.footnotes: OrderedDict[str, str] = OrderedDict()
self.unique_prefix += 1
self.found_refs = {}
self.used_refs = set()
- def unique_ref(self, reference, found=False):
+ def unique_ref(self, reference, found: bool = False):
""" Get a unique reference if there are duplicates. """
if not found:
return reference
@@ -144,7 +144,7 @@
res = finder(root)
return res
- def setFootnote(self, id, text):
+ def setFootnote(self, id, text) -> None:
""" Store a footnote for later retrieval. """
self.footnotes[id] = text
@@ -159,7 +159,7 @@
else:
return 'fn{}{}'.format(self.get_separator(), id)
- def makeFootnoteRefId(self, id, found=False):
+ def makeFootnoteRefId(self, id, found: bool = False):
""" Return footnote back-link id. """
if self.getConfig("UNIQUE_IDS"):
return self.unique_ref('fnref%s%d-%s' % (self.get_separator(),
self.unique_prefix, id), found)
@@ -329,7 +329,7 @@
def __init__(self, footnotes):
self.footnotes = footnotes
- def add_duplicates(self, li, duplicates):
+ def add_duplicates(self, li, duplicates) -> None:
""" Adjust current `li` and add the duplicates: `fnref2`, `fnref3`,
etc. """
for link in li.iter('a'):
# Find the link that needs to be duplicated.
@@ -355,7 +355,7 @@
link_id = '{}ref{}{}'.format(fn, self.footnotes.get_separator(), rest)
return self.footnotes.found_refs.get(link_id, 0)
- def handle_duplicates(self, parent):
+ def handle_duplicates(self, parent) -> None:
""" Find duplicate footnotes and format and add the duplicates. """
for li in list(parent):
# Check number of duplicates footnotes and insert
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/Markdown-3.5/markdown/extensions/meta.py
new/Markdown-3.5.1/markdown/extensions/meta.py
--- old/Markdown-3.5/markdown/extensions/meta.py 2023-10-06
21:07:58.000000000 +0200
+++ new/Markdown-3.5.1/markdown/extensions/meta.py 2023-10-31
20:58:52.000000000 +0100
@@ -44,7 +44,7 @@
self.md = md
md.preprocessors.register(MetaPreprocessor(md), 'meta', 27)
- def reset(self):
+ def reset(self) -> None:
self.md.Meta = {}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/Markdown-3.5/markdown/extensions/smarty.py
new/Markdown-3.5.1/markdown/extensions/smarty.py
--- old/Markdown-3.5/markdown/extensions/smarty.py 2023-10-06
21:07:58.000000000 +0200
+++ new/Markdown-3.5.1/markdown/extensions/smarty.py 2023-10-31
20:58:52.000000000 +0100
@@ -193,7 +193,7 @@
name = 'smarty-%s-%d' % (serie, ind)
self.inlinePatterns.register(pattern, name, priority-ind)
- def educateDashes(self, md):
+ def educateDashes(self, md) -> None:
emDashesPattern = SubstituteTextPattern(
r'(?<!-)---(?!-)', (self.substitutions['mdash'],), md
)
@@ -203,13 +203,13 @@
self.inlinePatterns.register(emDashesPattern, 'smarty-em-dashes', 50)
self.inlinePatterns.register(enDashesPattern, 'smarty-en-dashes', 45)
- def educateEllipses(self, md):
+ def educateEllipses(self, md) -> None:
ellipsesPattern = SubstituteTextPattern(
r'(?<!\.)\.{3}(?!\.)', (self.substitutions['ellipsis'],), md
)
self.inlinePatterns.register(ellipsesPattern, 'smarty-ellipses', 10)
- def educateAngledQuotes(self, md):
+ def educateAngledQuotes(self, md) -> None:
leftAngledQuotePattern = SubstituteTextPattern(
r'\<\<', (self.substitutions['left-angle-quote'],), md
)
@@ -219,7 +219,7 @@
self.inlinePatterns.register(leftAngledQuotePattern,
'smarty-left-angle-quotes', 40)
self.inlinePatterns.register(rightAngledQuotePattern,
'smarty-right-angle-quotes', 35)
- def educateQuotes(self, md):
+ def educateQuotes(self, md) -> None:
lsquo = self.substitutions['left-single-quote']
rsquo = self.substitutions['right-single-quote']
ldquo = self.substitutions['left-double-quote']
@@ -243,7 +243,7 @@
def extendMarkdown(self, md):
configs = self.getConfigs()
- self.inlinePatterns = Registry()
+ self.inlinePatterns: Registry[HtmlInlineProcessor] = Registry()
if configs['smart_ellipses']:
self.educateEllipses(md)
if configs['smart_quotes']:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/Markdown-3.5/markdown/extensions/toc.py
new/Markdown-3.5.1/markdown/extensions/toc.py
--- old/Markdown-3.5/markdown/extensions/toc.py 2023-10-06 21:07:58.000000000
+0200
+++ new/Markdown-3.5.1/markdown/extensions/toc.py 2023-10-31
20:58:52.000000000 +0100
@@ -71,7 +71,7 @@
return ''.join(text).strip()
-def stashedHTML2text(text, md, strip_entities=True):
+def stashedHTML2text(text, md, strip_entities: bool = True):
""" Extract raw HTML from stash, reduce to plain text and swap with
placeholder. """
def _html_sub(m):
""" Substitute raw html with plain text. """
@@ -198,7 +198,7 @@
yield node, child
yield from self.iterparent(child)
- def replace_marker(self, root, elem):
+ def replace_marker(self, root, elem) -> None:
""" Replace marker with elem. """
for (p, c) in self.iterparent(root):
text = ''.join(c.itertext()).strip()
@@ -219,14 +219,14 @@
p[i] = elem
break
- def set_level(self, elem):
+ def set_level(self, elem) -> None:
""" Adjust header level according to base level. """
level = int(elem.tag[-1]) + self.base_level
if level > 6:
level = 6
elem.tag = 'h%d' % level
- def add_anchor(self, c, elem_id):
+ def add_anchor(self, c, elem_id) -> None:
anchor = etree.Element("a")
anchor.text = c.text
anchor.attrib["href"] = "#" + elem_id
@@ -238,7 +238,7 @@
c.remove(c[0])
c.append(anchor)
- def add_permalink(self, c, elem_id):
+ def add_permalink(self, c, elem_id) -> None:
permalink = etree.Element("a")
permalink.text = ("%spara;" % AMP_SUBSTITUTE
if self.use_permalinks is True
@@ -399,7 +399,7 @@
tocext = self.TreeProcessorClass(md, self.getConfigs())
md.treeprocessors.register(tocext, 'toc', 5)
- def reset(self):
+ def reset(self) -> None:
self.md.toc = ''
self.md.toc_tokens = []
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/Markdown-3.5/markdown/htmlparser.py
new/Markdown-3.5.1/markdown/htmlparser.py
--- old/Markdown-3.5/markdown/htmlparser.py 2023-10-06 21:07:58.000000000
+0200
+++ new/Markdown-3.5.1/markdown/htmlparser.py 2023-10-31 20:58:52.000000000
+0100
@@ -83,6 +83,8 @@
# Block tags that should contain no content (self closing)
self.empty_tags = set(['hr'])
+ self.lineno_start_cache = [0]
+
# This calls self.reset
super().__init__(*args, **kwargs)
self.md = md
@@ -94,6 +96,8 @@
self.stack = [] # When `inraw==True`, stack contains a list of tags
self._cache = []
self.cleandoc = []
+ self.lineno_start_cache = [0]
+
super().reset()
def close(self):
@@ -114,15 +118,15 @@
@property
def line_offset(self) -> int:
"""Returns char index in `self.rawdata` for the start of the current
line. """
- if self.lineno > 1 and '\n' in self.rawdata:
- m = re.match(r'([^\n]*\n){{{}}}'.format(self.lineno-1),
self.rawdata)
- if m:
- return m.end()
- else: # pragma: no cover
- # Value of `self.lineno` must exceed total number of lines.
- # Find index of beginning of last line.
- return self.rawdata.rfind('\n')
- return 0
+ for ii in range(len(self.lineno_start_cache)-1, self.lineno-1):
+ last_line_start_pos = self.lineno_start_cache[ii]
+ lf_pos = self.rawdata.find('\n', last_line_start_pos)
+ if lf_pos == -1:
+ # No more newlines found. Use end of raw data as start of line
beyond end.
+ lf_pos = len(self.rawdata)
+ self.lineno_start_cache.append(lf_pos+1)
+
+ return self.lineno_start_cache[self.lineno-1]
def at_line_start(self) -> bool:
"""
@@ -152,7 +156,7 @@
# Failed to extract from raw data. Assume well formed and
lowercase.
return '</{}>'.format(tag)
- def handle_starttag(self, tag: str, attrs: dict[str, str]):
+ def handle_starttag(self, tag: str, attrs: list[tuple[str, str]]):
# Handle tags that should always be empty and do not specify a closing
tag
if tag in self.empty_tags:
self.handle_startendtag(tag, attrs)
@@ -231,7 +235,7 @@
else:
self.cleandoc.append(data)
- def handle_startendtag(self, tag: str, attrs: dict[str, str]):
+ def handle_startendtag(self, tag: str, attrs: list[tuple[str, str]]):
self.handle_empty_tag(self.get_starttag_text(),
is_block=self.md.is_block_level(tag))
def handle_charref(self, name: str):
@@ -273,7 +277,7 @@
# As `__startag_text` is private, all references to it must be in this
subclass.
# The last few lines of `parse_starttag` are reversed so that
`handle_starttag`
# can override `cdata_mode` in certain situations (in a code span).
- __starttag_text = None
+ __starttag_text: str | None = None
def get_starttag_text(self) -> str:
"""Return full source of start tag: `<...>`."""
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/Markdown-3.5/markdown/inlinepatterns.py
new/Markdown-3.5.1/markdown/inlinepatterns.py
--- old/Markdown-3.5/markdown/inlinepatterns.py 2023-10-06 21:07:58.000000000
+0200
+++ new/Markdown-3.5.1/markdown/inlinepatterns.py 2023-10-31
20:58:52.000000000 +0100
@@ -41,8 +41,7 @@
from __future__ import annotations
from . import util
-from collections import namedtuple
-from typing import TYPE_CHECKING, Match, Any
+from typing import TYPE_CHECKING, Any, Collection, NamedTuple
import re
import xml.etree.ElementTree as etree
try: # pragma: no cover
@@ -54,7 +53,7 @@
from markdown import Markdown
-def build_inlinepatterns(md: Markdown, **kwargs: Any) -> util.Registry:
+def build_inlinepatterns(md: Markdown, **kwargs: Any) ->
util.Registry[InlineProcessor]:
"""
Build the default set of inline patterns for Markdown.
@@ -181,8 +180,11 @@
return string
-class EmStrongItem(namedtuple('EmStrongItem', ['pattern', 'builder', 'tags'])):
+class EmStrongItem(NamedTuple):
"""Emphasis/strong pattern item."""
+ pattern: re.Pattern[str]
+ builder: str
+ tags: str
# The pattern classes
@@ -209,7 +211,7 @@
"""
- ANCESTOR_EXCLUDES = tuple()
+ ANCESTOR_EXCLUDES: Collection[str] = tuple()
"""
A collection of elements which are undesirable ancestors. The processor
will be skipped if it
would cause the content to be a descendant of one of the listed tag names.
@@ -236,7 +238,7 @@
""" Return a compiled regular expression. """
return self.compiled_re
- def handleMatch(self, m: Match) -> etree.Element:
+ def handleMatch(self, m: re.Match[str]) -> etree.Element | str:
"""Return a ElementTree element from the given match.
Subclasses should override this method.
@@ -298,7 +300,7 @@
self.safe_mode = False
self.md = md
- def handleMatch(self, m: Match, data: str) -> tuple[etree.Element | str |
None, int | None, int | None]:
+ def handleMatch(self, m: re.Match[str], data: str) -> tuple[etree.Element
| str | None, int | None, int | None]:
"""Return a ElementTree element from the given match and the
start and end index of the matched text.
@@ -322,14 +324,14 @@
class SimpleTextPattern(Pattern): # pragma: no cover
""" Return a simple text of `group(2)` of a Pattern. """
- def handleMatch(self, m: Match) -> str:
+ def handleMatch(self, m: re.Match[str]) -> str:
""" Return string content of `group(2)` of a matching pattern. """
return m.group(2)
class SimpleTextInlineProcessor(InlineProcessor):
""" Return a simple text of `group(1)` of a Pattern. """
- def handleMatch(self, m: Match, data: str) -> tuple[str, int, int]:
+ def handleMatch(self, m: re.Match[str], data: str) -> tuple[str, int, int]:
""" Return string content of `group(1)` of a matching pattern. """
return m.group(1), m.start(0), m.end(0)
@@ -337,7 +339,7 @@
class EscapeInlineProcessor(InlineProcessor):
""" Return an escaped character. """
- def handleMatch(self, m: Match, data: str) -> tuple[str | None, int, int]:
+ def handleMatch(self, m: re.Match[str], data: str) -> tuple[str | None,
int, int]:
"""
If the character matched by `group(1)` of a pattern is in
[`ESCAPED_CHARS`][markdown.Markdown.ESCAPED_CHARS]
then return the integer representing the character's Unicode code
point (as returned by [`ord`][]) wrapped
@@ -372,7 +374,7 @@
self.tag = tag
""" The tag of the rendered element. """
- def handleMatch(self, m: Match) -> etree.Element:
+ def handleMatch(self, m: re.Match[str]) -> etree.Element:
"""
Return [`Element`][xml.etree.ElementTree.Element] of type `tag` with
the string in `group(3)` of a
matching pattern as the Element's text.
@@ -401,7 +403,7 @@
self.tag = tag
""" The tag of the rendered element. """
- def handleMatch(self, m: Match, data: str) -> tuple[etree.Element, int,
int]: # pragma: no cover
+ def handleMatch(self, m: re.Match[str], data: str) -> tuple[etree.Element,
int, int]: # pragma: no cover
"""
Return [`Element`][xml.etree.ElementTree.Element] of type `tag` with
the string in `group(2)` of a
matching pattern as the Element's text.
@@ -413,14 +415,14 @@
class SubstituteTagPattern(SimpleTagPattern): # pragma: no cover
""" Return an element of type `tag` with no children. """
- def handleMatch(self, m: Match) -> etree.Element:
+ def handleMatch(self, m: re.Match[str]) -> etree.Element:
""" Return empty [`Element`][xml.etree.ElementTree.Element] of type
`tag`. """
return etree.Element(self.tag)
class SubstituteTagInlineProcessor(SimpleTagInlineProcessor):
""" Return an element of type `tag` with no children. """
- def handleMatch(self, m: Match, data: str) -> tuple[etree.Element, int,
int]:
+ def handleMatch(self, m: re.Match[str], data: str) -> tuple[etree.Element,
int, int]:
""" Return empty [`Element`][xml.etree.ElementTree.Element] of type
`tag`. """
return etree.Element(self.tag), m.start(0), m.end(0)
@@ -433,7 +435,7 @@
self.tag = 'code'
""" The tag of the rendered element. """
- def handleMatch(self, m: Match, data: str) -> tuple[etree.Element | str,
int, int]:
+ def handleMatch(self, m: re.Match[str], data: str) -> tuple[etree.Element
| str, int, int]:
"""
If the match contains `group(3)` of a pattern, then return a `code`
[`Element`][xml.etree.ElementTree.Element] which contains HTML escaped
text (with
@@ -456,7 +458,7 @@
Useful for strong emphasis etc.
"""
- def handleMatch(self, m: Match) -> etree.Element:
+ def handleMatch(self, m: re.Match[str]) -> etree.Element:
"""
Return [`Element`][xml.etree.ElementTree.Element] in following format:
`<tag1><tag2>group(3)</tag2>group(4)</tag2>` where `group(4)` is
optional.
@@ -477,7 +479,7 @@
Useful for strong emphasis etc.
"""
- def handleMatch(self, m: Match, data: str) -> tuple[etree.Element, int,
int]: # pragma: no cover
+ def handleMatch(self, m: re.Match[str], data: str) -> tuple[etree.Element,
int, int]: # pragma: no cover
"""
Return [`Element`][xml.etree.ElementTree.Element] in following format:
`<tag1><tag2>group(2)</tag2>group(3)</tag2>` where `group(3)` is
optional.
@@ -494,7 +496,7 @@
class HtmlInlineProcessor(InlineProcessor):
""" Store raw inline html and return a placeholder. """
- def handleMatch(self, m: Match, data: str) -> tuple[str, int, int]:
+ def handleMatch(self, m: re.Match[str], data: str) -> tuple[str, int, int]:
""" Store the text of `group(1)` of a pattern and return a placeholder
string. """
rawhtml = self.backslash_unescape(self.unescape(m.group(1)))
place_holder = self.md.htmlStash.store(rawhtml)
@@ -577,7 +579,7 @@
self.parse_sub_patterns(text, el2, None, idx)
return el1
- def parse_sub_patterns(self, data, parent, last, idx):
+ def parse_sub_patterns(self, data, parent, last, idx) -> None:
"""
Parses sub patterns.
@@ -651,7 +653,7 @@
else:
return self.build_single(m, tags, index)
- def handleMatch(self, m: Match, data: str) -> tuple[etree.Element, int,
int]:
+ def handleMatch(self, m: re.Match[str], data: str) -> tuple[etree.Element
| None, int | None, int | None]:
"""Parse patterns."""
el = None
@@ -686,7 +688,7 @@
RE_LINK =
re.compile(r'''\(\s*(?:(<[^<>]*>)\s*(?:('[^']*'|"[^"]*")\s*)?\))?''', re.DOTALL
| re.UNICODE)
RE_TITLE_CLEAN = re.compile(r'\s')
- def handleMatch(self, m: Match, data: str) -> tuple[etree.Element | None,
int | None, int | None]:
+ def handleMatch(self, m: re.Match[str], data: str) -> tuple[etree.Element
| None, int | None, int | None]:
""" Return an `a` [`Element`][xml.etree.ElementTree.Element] or
`(None, None, None)`. """
text, index, handled = self.getText(data, m.end(0))
@@ -846,7 +848,7 @@
class ImageInlineProcessor(LinkInlineProcessor):
""" Return a `img` element from the given match. """
- def handleMatch(self, m: Match, data: str) -> tuple[etree.Element | None,
int | None, int | None]:
+ def handleMatch(self, m: re.Match[str], data: str) -> tuple[etree.Element
| None, int | None, int | None]:
""" Return an `img` [`Element`][xml.etree.ElementTree.Element] or
`(None, None, None)`. """
text, index, handled = self.getText(data, m.end(0))
if not handled:
@@ -873,7 +875,7 @@
RE_LINK = re.compile(r'\s?\[([^\]]*)\]', re.DOTALL | re.UNICODE)
- def handleMatch(self, m: Match, data: str) -> tuple[etree.Element | None,
int | None, int | None]:
+ def handleMatch(self, m: re.Match[str], data: str) -> tuple[etree.Element
| None, int | None, int | None]:
"""
Return [`Element`][xml.etree.ElementTree.Element] returned by
`makeTag` method or `(None, None, None)`.
@@ -953,7 +955,7 @@
class AutolinkInlineProcessor(InlineProcessor):
""" Return a link Element given an auto-link (`<http://example/com>`). """
- def handleMatch(self, m: Match, data: str) -> tuple[etree.Element, int,
int]:
+ def handleMatch(self, m: re.Match[str], data: str) -> tuple[etree.Element,
int, int]:
""" Return an `a` [`Element`][xml.etree.ElementTree.Element] of
`group(1)`. """
el = etree.Element("a")
el.set('href', self.unescape(m.group(1)))
@@ -965,7 +967,7 @@
"""
Return a `mailto` link Element given an auto-mail link
(`<[email protected]>`).
"""
- def handleMatch(self, m: Match, data: str) -> tuple[etree.Element, int,
int]:
+ def handleMatch(self, m: re.Match[str], data: str) -> tuple[etree.Element,
int, int]:
""" Return an [`Element`][xml.etree.ElementTree.Element] containing a
`mailto` link of `group(1)`. """
el = etree.Element('a')
email = self.unescape(m.group(1))
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/Markdown-3.5/markdown/postprocessors.py
new/Markdown-3.5.1/markdown/postprocessors.py
--- old/Markdown-3.5/markdown/postprocessors.py 2023-10-06 21:07:58.000000000
+0200
+++ new/Markdown-3.5.1/markdown/postprocessors.py 2023-10-31
20:58:52.000000000 +0100
@@ -37,7 +37,7 @@
from markdown import Markdown
-def build_postprocessors(md: Markdown, **kwargs: Any) -> util.Registry:
+def build_postprocessors(md: Markdown, **kwargs: Any) ->
util.Registry[Postprocessor]:
""" Build the default postprocessors for Markdown. """
postprocessors = util.Registry()
postprocessors.register(RawHtmlPostprocessor(md), 'raw_html', 30)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/Markdown-3.5/markdown/preprocessors.py
new/Markdown-3.5.1/markdown/preprocessors.py
--- old/Markdown-3.5/markdown/preprocessors.py 2023-10-06 21:07:58.000000000
+0200
+++ new/Markdown-3.5.1/markdown/preprocessors.py 2023-10-31
20:58:52.000000000 +0100
@@ -34,7 +34,7 @@
from markdown import Markdown
-def build_preprocessors(md: Markdown, **kwargs: Any) -> util.Registry:
+def build_preprocessors(md: Markdown, **kwargs: Any) ->
util.Registry[Preprocessor]:
""" Build and return the default set of preprocessors used by Markdown. """
preprocessors = util.Registry()
preprocessors.register(NormalizeWhitespace(md), 'normalize_whitespace', 30)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/Markdown-3.5/markdown/treeprocessors.py
new/Markdown-3.5.1/markdown/treeprocessors.py
--- old/Markdown-3.5/markdown/treeprocessors.py 2023-10-06 21:07:58.000000000
+0200
+++ new/Markdown-3.5.1/markdown/treeprocessors.py 2023-10-31
20:58:52.000000000 +0100
@@ -28,7 +28,7 @@
import re
import xml.etree.ElementTree as etree
-from typing import TYPE_CHECKING, Sequence, Any
+from typing import TYPE_CHECKING, Any
from . import util
from . import inlinepatterns
@@ -36,7 +36,7 @@
from markdown import Markdown
-def build_treeprocessors(md: Markdown, **kwargs: Any) -> util.Registry:
+def build_treeprocessors(md: Markdown, **kwargs: Any) ->
util.Registry[Treeprocessor]:
""" Build the default `treeprocessors` for Markdown. """
treeprocessors = util.Registry()
treeprocessors.register(InlineProcessor(md), 'inline', 20)
@@ -87,7 +87,7 @@
self.inlinePatterns = md.inlinePatterns
self.ancestors = []
- def __makePlaceholder(self, type):
+ def __makePlaceholder(self, type) -> tuple[str, str]:
""" Generate a placeholder """
id = "%04d" % len(self.stashed_nodes)
hash = util.INLINE_PLACEHOLDER % id
@@ -111,7 +111,7 @@
else:
return None, index + 1
- def __stashNode(self, node, type):
+ def __stashNode(self, node, type) -> str:
""" Add node to stash. """
placeholder, id = self.__makePlaceholder(type)
self.stashed_nodes[id] = node
@@ -169,7 +169,12 @@
for newChild in childResult:
node.insert(pos, newChild[0])
- def __processPlaceholders(self, data: str, parent: etree.Element, isText:
bool = True) -> list[etree.ElementTree]:
+ def __processPlaceholders(
+ self,
+ data: str,
+ parent: etree.Element,
+ isText: bool = True
+ ) -> list[tuple[etree.Element, Any]]:
"""
Process string with placeholders and generate `ElementTree` tree.
@@ -245,7 +250,13 @@
return result
- def __applyPattern(self, pattern: str, data: str, patternIndex: int,
startIndex: int = 0) -> tuple[str, bool, int]:
+ def __applyPattern(
+ self,
+ pattern: inlinepatterns.Pattern,
+ data: str,
+ patternIndex: int,
+ startIndex: int = 0
+ ) -> tuple[str, bool, int]:
"""
Check if the line fits the pattern, create the necessary
elements, add it to `stashed_nodes`.
@@ -329,7 +340,7 @@
ancestors.reverse()
parents.extend(ancestors)
- def run(self, tree: etree.Element, ancestors: Sequence[str] | None = None)
-> etree.Element:
+ def run(self, tree: etree.Element, ancestors: list[str] | None = None) ->
etree.Element:
"""Apply inline patterns to a parsed Markdown tree.
Iterate over `Element`, find elements with inline tag, apply inline
@@ -347,7 +358,7 @@
An element tree object with applied inline patterns.
"""
- self.stashed_nodes = {}
+ self.stashed_nodes: dict[str, etree.Element] = {}
# Ensure a valid parent list, but copy passed in lists
# to ensure we don't have the user accidentally change it on us.
@@ -448,7 +459,7 @@
def _unescape(self, m):
return chr(int(m.group(1)))
- def unescape(self, text):
+ def unescape(self, text: str) -> str:
return self.RE.sub(self._unescape, text)
def run(self, root):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/Markdown-3.5/markdown/util.py
new/Markdown-3.5.1/markdown/util.py
--- old/Markdown-3.5/markdown/util.py 2023-10-06 21:07:58.000000000 +0200
+++ new/Markdown-3.5.1/markdown/util.py 2023-10-31 20:58:52.000000000 +0100
@@ -27,14 +27,15 @@
import re
import sys
import warnings
-from collections import namedtuple
from functools import wraps, lru_cache
from itertools import count
-from typing import TYPE_CHECKING, Any
+from typing import TYPE_CHECKING, Generic, Iterator, NamedTuple, TypeVar,
overload
if TYPE_CHECKING: # pragma: no cover
from markdown import Markdown
+_T = TypeVar('_T')
+
"""
Constants you might want to modify
@@ -108,7 +109,7 @@
return metadata.entry_points(group='markdown.extensions')
-def deprecated(message, stacklevel=2):
+def deprecated(message: str, stacklevel: int = 2):
"""
Raise a [`DeprecationWarning`][] when wrapped function/method is called.
@@ -133,7 +134,7 @@
return wrapper
-def parseBoolValue(value: str, fail_on_errors: bool = True, preserve_none:
bool = False) -> bool | None:
+def parseBoolValue(value: str | None, fail_on_errors: bool = True,
preserve_none: bool = False) -> bool | None:
"""Parses a string representing a boolean value. If parsing was successful,
returns `True` or `False`. If `preserve_none=True`, returns `True`,
`False`,
or `None`. If parsing was not successful, raises `ValueError`, or, if
@@ -174,7 +175,7 @@
return size
-def nearing_recursion_limit():
+def nearing_recursion_limit() -> bool:
"""Return true if current stack depth is within 100 of maximum limit."""
return sys.getrecursionlimit() - _get_stack_depth() < 100
@@ -198,7 +199,7 @@
md: The `Markdown` instance this processor is a part of.
"""
- def __init__(self, md: Markdown = None):
+ def __init__(self, md: Markdown | None = None):
self.md = md
@@ -233,15 +234,15 @@
self.html_counter += 1
return placeholder
- def reset(self):
+ def reset(self) -> None:
""" Clear the stash. """
self.html_counter = 0
self.rawHtmlBlocks = []
- def get_placeholder(self, key):
+ def get_placeholder(self, key: int) -> str:
return HTML_PLACEHOLDER % key
- def store_tag(self, tag, attrs, left_index, right_index) -> str:
+ def store_tag(self, tag: str, attrs: list, left_index: int, right_index:
int) -> str:
"""Store tag data and return a placeholder."""
self.tag_data.append({'tag': tag, 'attrs': attrs,
'left_index': left_index,
@@ -254,10 +255,12 @@
# Used internally by `Registry` for each item in its sorted list.
# Provides an easier to read API when editing the code later.
# For example, `item.name` is more clear than `item[0]`.
-_PriorityItem = namedtuple('PriorityItem', ['name', 'priority'])
+class _PriorityItem(NamedTuple):
+ name: str
+ priority: float
-class Registry:
+class Registry(Generic[_T]):
"""
A priority sorted registry.
@@ -298,25 +301,33 @@
"""
def __init__(self):
- self._data = {}
+ self._data: dict[str, _T] = {}
self._priority = []
self._is_sorted = False
- def __contains__(self, item):
+ def __contains__(self, item: str | _T) -> bool:
if isinstance(item, str):
# Check if an item exists by this name.
return item in self._data.keys()
# Check if this instance exists.
return item in self._data.values()
- def __iter__(self):
+ def __iter__(self) -> Iterator[_T]:
self._sort()
return iter([self._data[k] for k, p in self._priority])
- def __getitem__(self, key):
+ @overload
+ def __getitem__(self, key: str | int) -> _T: # pragma: no cover
+ ...
+
+ @overload
+ def __getitem__(self, key: slice) -> Registry[_T]: # pragma: no cover
+ ...
+
+ def __getitem__(self, key: str | int | slice) -> _T | Registry[_T]:
self._sort()
if isinstance(key, slice):
- data = Registry()
+ data: Registry[_T] = Registry()
for k, p in self._priority[key]:
data.register(self._data[k], k, p)
return data
@@ -324,13 +335,13 @@
return self._data[self._priority[key].name]
return self._data[key]
- def __len__(self):
+ def __len__(self) -> int:
return len(self._priority)
def __repr__(self):
return '<{}({})>'.format(self.__class__.__name__, list(self))
- def get_index_for_name(self, name) -> int:
+ def get_index_for_name(self, name: str) -> int:
"""
Return the index of the given name.
"""
@@ -341,7 +352,7 @@
)
raise ValueError('No item named "{}" exists.'.format(name))
- def register(self, item: Any, name: str, priority: int):
+ def register(self, item: _T, name: str, priority: float) -> None:
"""
Add an item to the registry with the given name and priority.
@@ -363,7 +374,7 @@
self._data[name] = item
self._priority.append(_PriorityItem(name, priority))
- def deregister(self, name, strict=True):
+ def deregister(self, name: str, strict: bool = True) -> None:
"""
Remove an item from the registry.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/Markdown-3.5/mkdocs.yml new/Markdown-3.5.1/mkdocs.yml
--- old/Markdown-3.5/mkdocs.yml 2023-10-06 21:07:58.000000000 +0200
+++ new/Markdown-3.5.1/mkdocs.yml 2023-10-31 20:58:52.000000000 +0100
@@ -5,7 +5,7 @@
copyright: "Copyright © 2010-2023"
use_directory_urls: true
-watch: [markdown]
+watch: [markdown, scripts]
theme:
name: nature