Skip to content

Commit fea9686

Browse files
authored
Add Path trait for pathlib.Path values (#941)
1 parent 3646337 commit fea9686

3 files changed

Lines changed: 39 additions & 0 deletions

File tree

‎docs/source/trait_types.rst‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,8 @@ Miscellaneous
109109

110110
.. autoclass:: CRegExp
111111

112+
.. autoclass:: Path
113+
112114
.. autoclass:: Union
113115
:members: __init__
114116

‎tests/test_traitlets.py‎

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
from __future__ import annotations
99

1010
import decimal
11+
import pathlib
1112
import pickle
1213
import re
1314
import typing as t
@@ -44,6 +45,7 @@
4445
Long,
4546
MetaHasTraits,
4647
ObjectName,
48+
Path,
4749
Set,
4850
TCPAddress,
4951
This,
@@ -1643,6 +1645,20 @@ class TestTCPAddress(TraitTestBase):
16431645
_bad_values = [(0, 0), ("localhost", 10.0), ("localhost", -1), None]
16441646

16451647

1648+
class PathTrait(HasTraits):
1649+
value = Path()
1650+
1651+
1652+
class TestPath(TraitTestBase):
1653+
obj = PathTrait()
1654+
1655+
_good_values = ["foo", "foo/bar", pathlib.Path("foo"), pathlib.PurePath("foo")]
1656+
_bad_values = [0, 10.0, None, ["foo"]]
1657+
1658+
def coerce(self, value):
1659+
return pathlib.Path(value)
1660+
1661+
16461662
class ListTrait(HasTraits):
16471663
value = List(Int())
16481664

‎traitlets/traitlets.py‎

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
import inspect
4747
import numbers
4848
import os
49+
import pathlib
4950
import re
5051
import sys
5152
import types
@@ -111,6 +112,7 @@
111112
"MetaHasTraits",
112113
"ObjectName",
113114
"ObserveHandler",
115+
"Path",
114116
"Set",
115117
"TCPAddress",
116118
"This",
@@ -4208,6 +4210,25 @@ def validate(self, obj: t.Any, value: t.Any) -> re.Pattern[t.Any] | None:
42084210
self.error(obj, value)
42094211

42104212

4213+
class Path(TraitType["pathlib.Path", t.Union["pathlib.Path", str, "os.PathLike[str]"]]):
4214+
"""A trait for filesystem paths.
4215+
4216+
Accepts strings and :class:`os.PathLike` objects. The resulting
4217+
attribute will be a :class:`pathlib.Path` instance."""
4218+
4219+
info_text = "a filesystem path"
4220+
4221+
def validate(self, obj: t.Any, value: t.Any) -> pathlib.Path | None:
4222+
if isinstance(value, (str, os.PathLike)):
4223+
return pathlib.Path(value)
4224+
self.error(obj, value)
4225+
4226+
def from_string(self, s: str) -> pathlib.Path | None:
4227+
if self.allow_none and s == "None":
4228+
return None
4229+
return pathlib.Path(s)
4230+
4231+
42114232
class UseEnum(TraitType[t.Any, t.Any]):
42124233
"""Use a Enum class as model for the data type description.
42134234
Note that if no default-value is provided, the first enum-value is used

0 commit comments

Comments
 (0)