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
8 changes: 7 additions & 1 deletion docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,13 @@ Install
# local development, with uv
uv sync

To read or write TOML front matter, install the optional dependency::

pip install 'python-frontmatter[toml]'

Without it, parsing a document with TOML delimiters emits a warning and leaves
the document as content, without extracting its metadata.

Usage
------

Expand Down Expand Up @@ -152,4 +159,3 @@ Indices and tables
* :ref:`genindex`
* :ref:`modindex`
* :ref:`search`

9 changes: 9 additions & 0 deletions frontmatter/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@

import io
import pathlib
import re
import warnings
from os import PathLike
from typing import TYPE_CHECKING, Iterable, TextIO

Expand Down Expand Up @@ -80,6 +82,13 @@ def parse(
# this will only run if a handler hasn't been set higher up
handler = handler or detect_format(text, handlers)
if handler is None:
if TOMLHandler is None and re.match(r"^\+{3,}\s*$", text, re.MULTILINE):
warnings.warn(
"TOML front matter detected, but TOML support is not installed. "
"Install 'python-frontmatter[toml]' to parse it.",
UserWarning,
stacklevel=2,
)
return metadata, text

# split on the delimiters
Expand Down
35 changes: 35 additions & 0 deletions tests/test_missing_toml.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
"""Exercise optional TOML support in an interpreter without the dependency."""

import subprocess
import sys
import textwrap


def test_missing_toml_warning():
result = subprocess.run(
[sys.executable, "-c", textwrap.dedent('''
import sys
import warnings
sys.modules["toml"] = None
import frontmatter

text = '+++\\ntitle = "Hello"\\n+++\\nBody'
with warnings.catch_warnings(record=True) as caught:
warnings.simplefilter("always")
post = frontmatter.loads(text)
assert len(caught) == 1
assert "python-frontmatter[toml]" in str(caught[0].message)
assert post.content == text
assert post.metadata == {}

with warnings.catch_warnings(record=True) as caught:
warnings.simplefilter("always")
assert frontmatter.loads('---\\ntitle: Hello\\n---\\nBody')["title"] == "Hello"
assert frontmatter.loads('Body\\n+++').content == 'Body\\n+++'
assert frontmatter.loads('++++ text').content == '++++ text'
assert not caught
''')],
capture_output=True,
text=True,
)
assert result.returncode == 0, result.stderr
Loading