@@ -58,6 +58,22 @@ def lineno_from_content_start(content: str, start: int) -> int:
5858 return content [:start ].count ('\n ' ) + 1
5959
6060
61+ def safe_os_path_relpath (path : str , start : str ) -> str :
62+ """Return the relative path of a file from a start directory.
63+
64+ Safe version of `os.path.relpath` that catches `ValueError` exceptions
65+ on Windows and returns the original path in case of error.
66+ On Windows, `ValueError` is raised when `path` and `start` are on
67+ different drives.
68+ """
69+ if os .name != 'nt' : # pragma: nt no cover
70+ return os .path .relpath (path , start )
71+ try : # pragma: nt cover
72+ return os .path .relpath (path , start )
73+ except ValueError : # pragma: no cover
74+ return path
75+
76+
6177def file_lineno_message (
6278 page_src_path : str | None ,
6379 docs_dir : str ,
@@ -67,7 +83,7 @@ def file_lineno_message(
6783 if page_src_path is None : # pragma: no cover
6884 return f'generated page content (line { lineno } )'
6985 return (
70- f'{ os . path . relpath (page_src_path , docs_dir )} '
86+ f'{ safe_os_path_relpath (page_src_path , docs_dir )} '
7187 f':{ lineno } '
7288 )
7389
@@ -287,7 +303,7 @@ def found_include_tag( # noqa: PLR0912, PLR0915
287303 if expected_but_any_found [i ]:
288304 delimiter_value = locals ()[delimiter_name ]
289305 readable_files_to_include = ', ' .join ([
290- os . path . relpath (fpath , docs_dir )
306+ safe_os_path_relpath (fpath , docs_dir )
291307 for fpath in file_paths_to_include
292308 ])
293309 plural_suffix = 's' if len (file_paths_to_include ) > 1 else ''
@@ -593,7 +609,7 @@ def found_include_markdown_tag( # noqa: PLR0912, PLR0915
593609 if expected_but_any_found [i ]:
594610 delimiter_value = locals ()[delimiter_name ]
595611 readable_files_to_include = ', ' .join ([
596- os . path . relpath (fpath , docs_dir )
612+ safe_os_path_relpath (fpath , docs_dir )
597613 for fpath in file_paths_to_include
598614 ])
599615 plural_suffix = 's' if len (file_paths_to_include ) > 1 else ''
0 commit comments