Skip to content

Commit 768c6b7

Browse files
committed
Create a _StrPath proxy type
1 parent d178a53 commit 768c6b7

File tree

1 file changed

+36
-1
lines changed

1 file changed

+36
-1
lines changed

sphinx/util/_pathlib.py

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
import sys
1818
import warnings
1919
from pathlib import Path, PosixPath, PurePath, WindowsPath
20-
from typing import Any
20+
from typing import Any, overload
2121

2222
from sphinx.deprecation import RemovedInSphinx90Warning
2323

@@ -133,3 +133,38 @@ def __getitem__(self, item: int | slice) -> str:
133133
def __len__(self) -> int:
134134
warnings.warn(_MSG, RemovedInSphinx90Warning, stacklevel=2)
135135
return len(self.__str__())
136+
137+
138+
class _StrPathProperty:
139+
def __init__(self) -> None:
140+
self.instance_attr: str = ''
141+
142+
def __set_name__(self, owner: object, name: str) -> None:
143+
self.instance_attr = f'_{name}' # i.e. '_srcdir'
144+
145+
@overload
146+
def __get__(self, obj: None, objtype: None) -> _StrPathProperty: ... # NoQA: E704
147+
148+
@overload
149+
def __get__(self, obj: object, objtype: type[object]) -> _StrPath: ... # NoQA: E704
150+
151+
def __get__(
152+
self, obj: object | None, objtype: type[object] | None = None
153+
) -> _StrPathProperty | _StrPath:
154+
if obj is None:
155+
return self
156+
if not self.instance_attr:
157+
raise AttributeError
158+
return getattr(obj, self.instance_attr)
159+
160+
def __set__(self, obj: Any, value: _StrPath | Path) -> None:
161+
try:
162+
setattr(obj, self.instance_attr, _StrPath(value))
163+
except TypeError as err:
164+
cls_name = type(obj).__qualname__
165+
name = self.instance_attr.removeprefix('_')
166+
msg = f'{cls_name}.{name} may only be set to path-like objects'
167+
raise TypeError(msg) from err
168+
169+
def __delete__(self, obj: Any) -> None:
170+
delattr(obj, self.instance_attr)

0 commit comments

Comments
 (0)