Skip to content

Conversation

@Jeff-Lowrey
Copy link

I have been experiencing errors when trying to run mypy checks against code using Marko.

I added some cast() and created type stubs to resolve the following issues:

1. Any Return Type Resolution

File Fix Error
element.py:46 cast(str, objstr(...)) objstr() returns Any, not str
helpers.py:132 cast(MarkoExtension, module.make_extension(...)) Dynamic call returns Any

2. Renderer Return Types

Error Type Fix
render() returns Any Declared -> str for HTML/Markdown, -> dict for AST
render_children() ambiguous Overloads: str -> str, Element -> str/dict
All render_* methods untyped 20+ methods declared -> str per renderer

3. Block Element Attributes

Element Attributes Typed
BlockElement children, priority, virtual, inline_body, override
Document link_ref_defs: dict[str, tuple[str, str]]
Heading level: int, inline_body: str
CodeBlock/FencedCode lang: str, extra: str, children: list[Element]
List tight: bool, ordered: bool, start: int, bullet: str
ListItem ParseInfo NamedTuple with typed fields
LinkRefDef label: str, dest: str, title: str | None

4. Inline Element Attributes

Element Attributes Typed
InlineElement pattern, parse_children, parse_group, children: str | Sequence[Element]
Link/Image dest: str, title: str | None
CodeSpan/RawText children: str
AutoLink dest: str, title: str
LineBreak soft: bool, children: str

5. Inline Parser Infrastructure

Class/Function Types Added
Token etype, match, start, end, text, children
Delimiter start, end, content, can_open, can_close
MatchObj group(), start(), end(), span() methods
Group NamedTuple(start, end, text)
parse() Full signature with ElementType

6. Source Overloads

@overload
def next_line(self, require_prefix: Literal[False] = ...) -> str: ...
@overload
def next_line(self, require_prefix: Literal[True] = ...) -> str | None: ...

Error fixed: str | None union couldn't be narrowed based on argument


7. Helper Functions

Function/Class Types Added
MarkoExtension Full dataclass with renderer_mixins, parser_mixins, elements
load_extension() -> MarkoExtension
render_dispatch Descriptor with overloads
camel_to_snake_case() str -> str
normalize_label() str -> str

8. Public API

Function Signature
Markdown.convert() str -> str
Markdown.parse() str -> Document
Markdown.render() Document -> str
Module-level convert, parse, render Same as above

Summary by File

Category Stub File Lines Errors Fixed
Block elements block.pyi 190 Attribute types, match()/parse() returns
Inline parser inline_parser.pyi 100 Token/Delimiter/MatchObj classes
Inline elements inline.pyi 89 Element attributes, children union
Helpers helpers.pyi 50 Extension types, dispatch descriptor
Markdown renderer md_renderer.pyi 40 All render methods -> str
HTML renderer html_renderer.pyi 38 All render methods -> str
Source source.pyi 37 next_line() overloads
AST renderer ast_renderer.pyi 32 -> dict vs -> str overloads
Public API __init__.pyi 29 Markdown class, module functions
Renderer base renderer.pyi 18 Base render() signature
Parser parser.pyi 15 parse() returns Document
Element base element.pyi 7 get_type(), __repr__()
Runtime casts element.py, helpers.py 2 Any -> str, Any -> MarkoExtension

@Jeff-Lowrey Jeff-Lowrey mentioned this pull request Jan 8, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant