Skip to content

Commit 6abd966

Browse files
committed
Added .is_dir and .is_file for parity with pathlib.
Ref #214
1 parent 8f325dc commit 6abd966

File tree

4 files changed

+52
-35
lines changed

4 files changed

+52
-35
lines changed

newsfragments/214.feature.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Added .is_dir and .is_file for parity with pathlib. Deprecates .isdir and .isfile.

path/__init__.py

Lines changed: 26 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ class Traversal:
125125
Directories beginning with `.` will appear in the results, but
126126
their children will not.
127127
128-
>>> dot_dir = next(item for item in items if item.isdir() and item.startswith('.'))
128+
>>> dot_dir = next(item for item in items if item.is_dir() and item.startswith('.'))
129129
>>> any(item.parent == dot_dir for item in items)
130130
False
131131
"""
@@ -566,7 +566,7 @@ def dirs(self, *args, **kwargs):
566566
567567
Accepts parameters to :meth:`iterdir`.
568568
"""
569-
return [p for p in self.iterdir(*args, **kwargs) if p.isdir()]
569+
return [p for p in self.iterdir(*args, **kwargs) if p.is_dir()]
570570

571571
def files(self, *args, **kwargs):
572572
"""List of the files in self.
@@ -577,14 +577,14 @@ def files(self, *args, **kwargs):
577577
Accepts parameters to :meth:`iterdir`.
578578
"""
579579

580-
return [p for p in self.iterdir(*args, **kwargs) if p.isfile()]
580+
return [p for p in self.iterdir(*args, **kwargs) if p.is_file()]
581581

582582
def walk(self, match=None, errors='strict'):
583583
"""Iterator over files and subdirs, recursively.
584584
585585
The iterator yields Path objects naming each child item of
586586
this directory and its descendants. This requires that
587-
``D.isdir()``.
587+
``D.is_dir()``.
588588
589589
This performs a depth-first traversal of the directory tree.
590590
Each directory is returned just before all its children.
@@ -609,7 +609,7 @@ def walk(self, match=None, errors='strict'):
609609
traverse = None
610610
if match(child):
611611
traverse = yield child
612-
traverse = traverse or child.isdir
612+
traverse = traverse or child.is_dir
613613
try:
614614
do_traverse = traverse()
615615
except Exception as exc:
@@ -621,11 +621,11 @@ def walk(self, match=None, errors='strict'):
621621

622622
def walkdirs(self, *args, **kwargs):
623623
"""Iterator over subdirs, recursively."""
624-
return (item for item in self.walk(*args, **kwargs) if item.isdir())
624+
return (item for item in self.walk(*args, **kwargs) if item.is_dir())
625625

626626
def walkfiles(self, *args, **kwargs):
627627
"""Iterator over files, recursively."""
628-
return (item for item in self.walk(*args, **kwargs) if item.isfile())
628+
return (item for item in self.walk(*args, **kwargs) if item.is_file())
629629

630630
def fnmatch(self, pattern, normcase=None):
631631
"""Return ``True`` if `self.name` matches the given `pattern`.
@@ -1097,10 +1097,24 @@ def exists(self):
10971097
return self.module.exists(self)
10981098

10991099
def isdir(self):
1100+
warnings.warn(
1101+
"isdir is deprecated; use is_dir",
1102+
DeprecationWarning,
1103+
stacklevel=2,
1104+
)
1105+
1106+
def is_dir(self):
11001107
""".. seealso:: :func:`os.path.isdir`"""
11011108
return self.module.isdir(self)
11021109

11031110
def isfile(self):
1111+
warnings.warn(
1112+
"isfile is deprecated; use is_file",
1113+
DeprecationWarning,
1114+
stacklevel=2,
1115+
)
1116+
1117+
def is_file(self):
11041118
""".. seealso:: :func:`os.path.isfile`"""
11051119
return self.module.isfile(self)
11061120

@@ -1556,7 +1570,7 @@ def ignored(item):
15561570
if symlinks and source.islink():
15571571
target = source.readlink()
15581572
target.symlink(dest)
1559-
elif source.isdir():
1573+
elif source.is_dir():
15601574
source.merge_tree(
15611575
dest,
15621576
symlinks=symlinks,
@@ -1613,7 +1627,7 @@ def in_place(
16131627
For example, to add line numbers to a file::
16141628
16151629
p = Path(filename)
1616-
assert p.isfile()
1630+
assert p.is_file()
16171631
with p.in_place() as (reader, writer):
16181632
for number, line in enumerate(reader, 1):
16191633
writer.write('{0:3}: '.format(number)))
@@ -1747,7 +1761,7 @@ class ExtantFile(Path):
17471761
"""
17481762

17491763
def _validate(self):
1750-
if not self.isfile():
1764+
if not self.is_file():
17511765
raise FileNotFoundError(f"{self} does not exist as a file.")
17521766

17531767

@@ -1818,12 +1832,12 @@ class TempDir(Path):
18181832
For example:
18191833
18201834
>>> with TempDir() as d:
1821-
... d.isdir() and isinstance(d, Path)
1835+
... d.is_dir() and isinstance(d, Path)
18221836
True
18231837
18241838
The directory is deleted automatically.
18251839
1826-
>>> d.isdir()
1840+
>>> d.is_dir()
18271841
False
18281842
18291843
.. seealso:: :func:`tempfile.mkdtemp`

path/__init__.pyi

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,9 @@ class Path(str):
154154
def isabs(self) -> bool: ...
155155
def exists(self) -> bool: ...
156156
def isdir(self) -> bool: ...
157+
def is_dir(self) -> bool: ...
157158
def isfile(self) -> bool: ...
159+
def is_file(self) -> bool: ...
158160
def islink(self) -> bool: ...
159161
def ismount(self) -> bool: ...
160162
def samefile(self, other: str) -> bool: ...

test_path.py

Lines changed: 23 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -300,10 +300,10 @@ def test_removedirs_p(self, tmpdir):
300300
(dir / 'file').touch()
301301
(dir / 'sub').mkdir()
302302
dir.removedirs_p()
303-
assert dir.isdir()
304-
assert (dir / 'file').isfile()
303+
assert dir.is_dir()
304+
assert (dir / 'file').is_file()
305305
# TODO: shouldn't sub get removed?
306-
# assert not (dir / 'sub').isdir()
306+
# assert not (dir / 'sub').is_dir()
307307

308308

309309
class TestReadWriteText:
@@ -360,7 +360,7 @@ def test_symlink_none(self, tmpdir):
360360
with root:
361361
file = (Path('dir').mkdir() / 'file').touch()
362362
file.symlink()
363-
assert Path('file').isfile()
363+
assert Path('file').is_file()
364364

365365
def test_readlinkabs_passthrough(self, tmpdir):
366366
link = Path(tmpdir) / 'link'
@@ -383,7 +383,7 @@ def test_skip_symlinks(self, tmpdir):
383383
assert len(list(root.walk())) == 4
384384

385385
skip_links = path.Traversal(
386-
lambda item: item.isdir() and not item.islink(),
386+
lambda item: item.is_dir() and not item.islink(),
387387
)
388388
assert len(list(skip_links(root.walk()))) == 3
389389

@@ -474,7 +474,7 @@ def test_touch(self, tmpdir):
474474
t1 = time.time() + threshold
475475

476476
assert f.exists()
477-
assert f.isfile()
477+
assert f.is_file()
478478
assert f.size == 0
479479
assert t0 <= f.mtime <= t1
480480
if hasattr(os.path, 'getctime'):
@@ -493,7 +493,7 @@ def test_touch(self, tmpdir):
493493
assert t0 <= t1 < t2 <= t3 # sanity check
494494

495495
assert f.exists()
496-
assert f.isfile()
496+
assert f.is_file()
497497
assert f.size == 10
498498
assert t2 <= f.mtime <= t3
499499
if hasattr(os.path, 'getctime'):
@@ -593,7 +593,7 @@ def test_makedirs(self, tmpdir):
593593
boz = foo / 'bar' / 'baz' / 'boz'
594594
boz.makedirs()
595595
try:
596-
assert boz.isdir()
596+
assert boz.is_dir()
597597
finally:
598598
boz.removedirs()
599599
assert not foo.exists()
@@ -602,7 +602,7 @@ def test_makedirs(self, tmpdir):
602602
foo.mkdir(0o750)
603603
boz.makedirs(0o700)
604604
try:
605-
assert boz.isdir()
605+
assert boz.is_dir()
606606
finally:
607607
boz.removedirs()
608608
assert not foo.exists()
@@ -648,21 +648,21 @@ def test_shutil(self, tmpdir):
648648

649649
# Test simple file copying.
650650
testFile.copyfile(testCopy)
651-
assert testCopy.isfile()
651+
assert testCopy.is_file()
652652
assert testFile.bytes() == testCopy.bytes()
653653

654654
# Test copying into a directory.
655655
testCopy2 = testA / testFile.name
656656
testFile.copy(testA)
657-
assert testCopy2.isfile()
657+
assert testCopy2.is_file()
658658
assert testFile.bytes() == testCopy2.bytes()
659659

660660
# Make a link for the next test to use.
661661
testFile.symlink(testLink)
662662

663663
# Test copying directory tree.
664664
testA.copytree(testC)
665-
assert testC.isdir()
665+
assert testC.is_dir()
666666
self.assertSetsEqual(
667667
testC.iterdir(),
668668
[testC / testCopy.name, testC / testFile.name, testCopyOfLink],
@@ -675,7 +675,7 @@ def test_shutil(self, tmpdir):
675675

676676
# Copy again, preserving symlinks.
677677
testA.copytree(testC, True)
678-
assert testC.isdir()
678+
assert testC.is_dir()
679679
self.assertSetsEqual(
680680
testC.iterdir(),
681681
[testC / testCopy.name, testC / testFile.name, testCopyOfLink],
@@ -698,7 +698,7 @@ def test_patterns(self, tmpdir):
698698
dirs = [d, d / 'xdir', d / 'xdir.tmp', d / 'xdir.tmp' / 'xsubdir']
699699

700700
for e in dirs:
701-
if not e.isdir():
701+
if not e.is_dir():
702702
e.makedirs()
703703

704704
for name in names:
@@ -913,12 +913,12 @@ def testing_structure(self, tmpdir):
913913

914914
def check_link(self):
915915
target = Path(self.subdir_b / self.test_link.name)
916-
check = target.islink if hasattr(os, 'symlink') else target.isfile
916+
check = target.islink if hasattr(os, 'symlink') else target.is_file
917917
assert check()
918918

919919
def test_with_nonexisting_dst_kwargs(self):
920920
self.subdir_a.merge_tree(self.subdir_b, symlinks=True)
921-
assert self.subdir_b.isdir()
921+
assert self.subdir_b.is_dir()
922922
expected = {
923923
self.subdir_b / self.test_file.name,
924924
self.subdir_b / self.test_link.name,
@@ -928,7 +928,7 @@ def test_with_nonexisting_dst_kwargs(self):
928928

929929
def test_with_nonexisting_dst_args(self):
930930
self.subdir_a.merge_tree(self.subdir_b, True)
931-
assert self.subdir_b.isdir()
931+
assert self.subdir_b.is_dir()
932932
expected = {
933933
self.subdir_b / self.test_file.name,
934934
self.subdir_b / self.test_link.name,
@@ -948,7 +948,7 @@ def test_with_existing_dst(self):
948948

949949
self.subdir_a.merge_tree(self.subdir_b, True)
950950

951-
assert self.subdir_b.isdir()
951+
assert self.subdir_b.is_dir()
952952
expected = {
953953
self.subdir_b / self.test_file.name,
954954
self.subdir_b / self.test_link.name,
@@ -965,7 +965,7 @@ def test_copytree_parameters(self):
965965
ignore = shutil.ignore_patterns('testlink*')
966966
self.subdir_a.merge_tree(self.subdir_b, ignore=ignore)
967967

968-
assert self.subdir_b.isdir()
968+
assert self.subdir_b.is_dir()
969969
assert list(self.subdir_b.iterdir()) == [self.subdir_b / self.test_file.name]
970970

971971
def test_only_newer(self):
@@ -984,7 +984,7 @@ def test_only_newer(self):
984984
def test_nested(self):
985985
self.subdir_a.joinpath('subsub').mkdir()
986986
self.subdir_a.merge_tree(self.subdir_b)
987-
assert self.subdir_b.joinpath('subsub').isdir()
987+
assert self.subdir_b.joinpath('subsub').is_dir()
988988

989989
def test_listdir(self):
990990
with pytest.deprecated_call():
@@ -1040,7 +1040,7 @@ def test_constructor(self):
10401040
d = TempDir()
10411041
assert isinstance(d, path.Path)
10421042
assert d.exists()
1043-
assert d.isdir()
1043+
assert d.is_dir()
10441044
d.rmdir()
10451045
assert not d.exists()
10461046

@@ -1074,8 +1074,8 @@ def test_context_manager_using_with(self):
10741074
"""
10751075

10761076
with TempDir() as d:
1077-
assert d.isdir()
1078-
assert not d.isdir()
1077+
assert d.is_dir()
1078+
assert not d.is_dir()
10791079

10801080
def test_cleaned_up_on_interrupt(self):
10811081
with contextlib.suppress(KeyboardInterrupt):

0 commit comments

Comments
 (0)