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
11 changes: 10 additions & 1 deletion docxtpl/template.py
Original file line number Diff line number Diff line change
Expand Up @@ -614,7 +614,16 @@ def fix_docpr_ids(self, tree):
elt.attrib["id"] = str(self.docx_ids_index)

def new_subdoc(self, docpath=None) -> Subdoc:
from .subdoc import Subdoc
try:
from .subdoc import Subdoc
except ModuleNotFoundError as exc:
if exc.name == "docxcompose":
raise ModuleNotFoundError(
"new_subdoc() requires the optional docxcompose dependency. "
'Install it with: pip install "docxtpl[subdoc]"',
name="docxcompose",
) from exc
raise

self.init_docx()
return Subdoc(self, docpath)
Expand Down
45 changes: 45 additions & 0 deletions tests/subdoc_optional_dependency.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import importlib.abc
import sys


class BlockDocxcompose(importlib.abc.MetaPathFinder):
missing_name = "docxcompose"

def find_spec(self, fullname, path, target=None):
if fullname == "docxcompose" or fullname.startswith("docxcompose."):
raise ModuleNotFoundError(
"No module named '%s'" % self.missing_name,
name=self.missing_name,
)
return None


blocker = BlockDocxcompose()
sys.meta_path.insert(0, blocker)

try:
from docxtpl import DocxTemplate

template = DocxTemplate("templates/subdoc_tpl.docx")

try:
template.new_subdoc()
except ModuleNotFoundError as exc:
assert exc.name == "docxcompose"
assert "new_subdoc() requires the optional docxcompose dependency" in str(exc)
assert 'pip install "docxtpl[subdoc]"' in str(exc)
assert isinstance(exc.__cause__, ModuleNotFoundError)
else:
raise AssertionError("new_subdoc() did not report the missing dependency")

blocker.missing_name = "some_other_dependency"
try:
template.new_subdoc()
except ModuleNotFoundError as exc:
assert exc.name == "some_other_dependency"
assert str(exc) == "No module named 'some_other_dependency'"
assert "pip install" not in str(exc)
else:
raise AssertionError("an unrelated import failure was masked")
finally:
sys.meta_path.remove(blocker)