frostming / marko

A markdown parser with high extensibility.
https://marko-py.readthedocs.io/en/latest/
MIT License
346 stars 38 forks source link

Running Parser.parse_inline fails if Parser.parse was not invoked earlier #131

Closed bluefish6 closed 1 year ago

bluefish6 commented 1 year ago

Hi,

import marko
marko.parser.Parser().parse_inline('*vbdfgd* dsfjfio sio `dsfs fwer `')

leads to:

File ~/.../python3.10/site-packages/marko/inline.py:107, in LinkOrEmph.__new__(cls, match)
    106 def __new__(cls, match: "_Match") -> "LinkOrEmph":
--> 107     return parser.inline_elements[match.etype](match)

AttributeError: 'NoneType' object has no attribute 'inline_elements'

However:

import marko
marko.parser.Parser().parse('')
marko.parser.Parser().parse_inline('*vbdfgd* dsfjfio sio `dsfs fwer `')

runs properly:

[<marko.inline.Emphasis at 0x7f20ef920d60>,
 <marko.inline.RawText at 0x7f20f51c2140>,
 <marko.inline.CodeSpan at 0x7f20f51c0a90>]

After digging into code it becomes obvious as to why such behavior is observed - marko.inline.parser is indeed set to None (hence the error), but it's overwritten with the Parser() instance when Parser.parse() is run (hence it works in the second snippet above). I'm not entirely sure why this initialization was moved from __init__ to this place, but it seems like it should be done in Parser.parse_inline() as well?

frostming commented 1 year ago

parse_inline() should never be called separately. It should be an internal implementation detail.

bluefish6 commented 1 year ago

This does not seem to be mentioned in the documentation:

image

If this method is not supposed to be used publicly, maybe a good idea would be to rename it to _parse_inline?