Skip to content

Commit 174484a

Browse files
move all the things into _pytest.pathlib
1 parent e7a2b10 commit 174484a

File tree

7 files changed

+19
-195
lines changed

7 files changed

+19
-195
lines changed

src/_pytest/assertion/rewrite.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@
1717
import py
1818

1919
from _pytest.assertion import util
20-
from _pytest.compat import PurePath, spec_from_file_location
20+
from _pytest.pathlib import PurePath
21+
from _pytest.compat import spec_from_file_location
2122
from _pytest.paths import fnmatch_ex
2223

2324
# pytest caches rewritten pycs in __pycache__.

src/_pytest/cacheprovider.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@
1616
import shutil
1717

1818
from . import paths
19-
from .compat import _PY2 as PY2, Path
19+
from .compat import _PY2 as PY2
20+
from .pathlib import Path
2021

2122
README_CONTENT = u"""\
2223
# pytest cache directory #

src/_pytest/compat.py

-7
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,6 @@
2323
# Only available in Python 3.4+ or as a backport
2424
enum = None
2525

26-
__all__ = ["Path", "PurePath"]
27-
2826
_PY3 = sys.version_info > (3, 0)
2927
_PY2 = not _PY3
3028

@@ -41,11 +39,6 @@
4139
PY36 = sys.version_info[:2] >= (3, 6)
4240
MODULE_NOT_FOUND_ERROR = "ModuleNotFoundError" if PY36 else "ImportError"
4341

44-
if PY36:
45-
from pathlib import Path, PurePath
46-
else:
47-
from pathlib2 import Path, PurePath
48-
4942

5043
if _PY3:
5144
from collections.abc import MutableMapping as MappingMixin

src/_pytest/paths.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
import six
77

8-
from .compat import Path, PurePath
8+
from .pathlib import Path, PurePath
99

1010

1111
def resolve_from_str(input, root):

src/_pytest/pytester.py

+4-3
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,14 @@
1717

1818
from _pytest.capture import MultiCapture, SysCapture
1919
from _pytest._code import Source
20-
import py
21-
import pytest
2220
from _pytest.main import Session, EXIT_OK
2321
from _pytest.assertion.rewrite import AssertionRewritingHook
24-
from _pytest.compat import Path
22+
from _pytest.pathlib import Path
2523
from _pytest.compat import safe_str
2624

25+
import py
26+
import pytest
27+
2728
IGNORE_PAM = [ # filenames added when obtaining details about the current user
2829
u"/var/lib/sss/mc/passwd"
2930
]

src/_pytest/tmpdir.py

+1-173
Original file line numberDiff line numberDiff line change
@@ -2,185 +2,13 @@
22
from __future__ import absolute_import, division, print_function
33

44
import re
5-
import os
6-
import errno
7-
import atexit
8-
import operator
9-
import six
10-
from functools import reduce
11-
import uuid
12-
from six.moves import map
135
import pytest
146
import py
157
from _pytest.monkeypatch import MonkeyPatch
16-
from .compat import Path
178
import attr
189
import shutil
1910
import tempfile
20-
import itertools
21-
22-
23-
LOCK_TIMEOUT = 60 * 60 * 3
24-
25-
get_lock_path = operator.methodcaller("joinpath", ".lock")
26-
27-
28-
def find_prefixed(root, prefix):
29-
l_prefix = prefix.lower()
30-
for x in root.iterdir():
31-
if x.name.lower().startswith(l_prefix):
32-
yield x
33-
34-
35-
def extract_suffixes(iter, prefix):
36-
p_len = len(prefix)
37-
for p in iter:
38-
yield p.name[p_len:]
39-
40-
41-
def find_suffixes(root, prefix):
42-
return extract_suffixes(find_prefixed(root, prefix), prefix)
43-
44-
45-
def parse_num(maybe_num):
46-
try:
47-
return int(maybe_num)
48-
except ValueError:
49-
return -1
50-
51-
52-
def _max(iterable, default):
53-
# needed due to python2.7 lacking the default argument for max
54-
return reduce(max, iterable, default)
55-
56-
57-
def make_numbered_dir(root, prefix):
58-
for i in range(10):
59-
# try up to 10 times to create the folder
60-
max_existing = _max(map(parse_num, find_suffixes(root, prefix)), -1)
61-
new_number = max_existing + 1
62-
new_path = root.joinpath("{}{}".format(prefix, new_number))
63-
try:
64-
new_path.mkdir()
65-
except Exception:
66-
pass
67-
else:
68-
return new_path
69-
else:
70-
raise EnvironmentError(
71-
"could not create numbered dir with prefix {prefix} in {root})".format(
72-
prefix=prefix, root=root
73-
)
74-
)
75-
76-
77-
def create_cleanup_lock(p):
78-
lock_path = get_lock_path(p)
79-
try:
80-
fd = os.open(str(lock_path), os.O_WRONLY | os.O_CREAT | os.O_EXCL, 0o644)
81-
except OSError as e:
82-
if e.errno == errno.EEXIST:
83-
six.raise_from(
84-
EnvironmentError("cannot create lockfile in {path}".format(path=p)), e
85-
)
86-
else:
87-
raise
88-
else:
89-
pid = os.getpid()
90-
spid = str(pid)
91-
if not isinstance(spid, six.binary_type):
92-
spid = spid.encode("ascii")
93-
os.write(fd, spid)
94-
os.close(fd)
95-
if not lock_path.is_file():
96-
raise EnvironmentError("lock path got renamed after sucessfull creation")
97-
return lock_path
98-
99-
100-
def register_cleanup_lock_removal(lock_path, register=atexit.register):
101-
pid = os.getpid()
102-
103-
def cleanup_on_exit(lock_path=lock_path, original_pid=pid):
104-
current_pid = os.getpid()
105-
if current_pid != original_pid:
106-
# fork
107-
return
108-
try:
109-
lock_path.unlink()
110-
except (OSError, IOError):
111-
pass
112-
113-
return register(cleanup_on_exit)
114-
115-
116-
def delete_a_numbered_dir(path):
117-
create_cleanup_lock(path)
118-
parent = path.parent
119-
120-
garbage = parent.joinpath("garbage-{}".format(uuid.uuid4()))
121-
path.rename(garbage)
122-
shutil.rmtree(str(garbage), ignore_errors=True)
123-
124-
125-
def ensure_deletable(path, consider_lock_dead_if_created_before):
126-
lock = get_lock_path(path)
127-
if not lock.exists():
128-
return True
129-
try:
130-
lock_time = lock.stat().st_mtime
131-
except Exception:
132-
return False
133-
else:
134-
if lock_time < consider_lock_dead_if_created_before:
135-
lock.unlink()
136-
return True
137-
else:
138-
return False
139-
140-
141-
def try_cleanup(path, consider_lock_dead_if_created_before):
142-
if ensure_deletable(path, consider_lock_dead_if_created_before):
143-
delete_a_numbered_dir(path)
144-
145-
146-
def cleanup_candidates(root, prefix, keep):
147-
max_existing = _max(map(parse_num, find_suffixes(root, prefix)), -1)
148-
max_delete = max_existing - keep
149-
paths = find_prefixed(root, prefix)
150-
paths, paths2 = itertools.tee(paths)
151-
numbers = map(parse_num, extract_suffixes(paths2, prefix))
152-
for path, number in zip(paths, numbers):
153-
if number <= max_delete:
154-
yield path
155-
156-
157-
def cleanup_numbered_dir(root, prefix, keep, consider_lock_dead_if_created_before):
158-
for path in cleanup_candidates(root, prefix, keep):
159-
try_cleanup(path, consider_lock_dead_if_created_before)
160-
for path in root.glob("garbage-*"):
161-
try_cleanup(path, consider_lock_dead_if_created_before)
162-
163-
164-
def make_numbered_dir_with_cleanup(root, prefix, keep, lock_timeout):
165-
e = None
166-
for i in range(10):
167-
try:
168-
p = make_numbered_dir(root, prefix)
169-
lock_path = create_cleanup_lock(p)
170-
register_cleanup_lock_removal(lock_path)
171-
except Exception as e:
172-
pass
173-
else:
174-
consider_lock_dead_if_created_before = p.stat().st_mtime - lock_timeout
175-
cleanup_numbered_dir(
176-
root=root,
177-
prefix=prefix,
178-
keep=keep,
179-
consider_lock_dead_if_created_before=consider_lock_dead_if_created_before,
180-
)
181-
return p
182-
assert e is not None
183-
raise e
11+
from .pathlib import Path, make_numbered_dir, make_numbered_dir_with_cleanup
18412

18513

18614
@attr.s

testing/test_tmpdir.py

+9-9
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,7 @@ class TestNumberedDir(object):
192192
PREFIX = "fun-"
193193

194194
def test_make(self, tmp_path):
195-
from _pytest.tmpdir import make_numbered_dir
195+
from _pytest.pathlib import make_numbered_dir
196196

197197
for i in range(10):
198198
d = make_numbered_dir(root=tmp_path, prefix=self.PREFIX)
@@ -202,7 +202,7 @@ def test_make(self, tmp_path):
202202
def test_cleanup_lock_create(self, tmp_path):
203203
d = tmp_path.joinpath("test")
204204
d.mkdir()
205-
from _pytest.tmpdir import create_cleanup_lock
205+
from _pytest.pathlib import create_cleanup_lock
206206

207207
lockfile = create_cleanup_lock(d)
208208
with pytest.raises(EnvironmentError, match="cannot create lockfile in .*"):
@@ -211,7 +211,7 @@ def test_cleanup_lock_create(self, tmp_path):
211211
lockfile.unlink()
212212

213213
def test_lock_register_cleanup_removal(self, tmp_path):
214-
from _pytest.tmpdir import create_cleanup_lock, register_cleanup_lock_removal
214+
from _pytest.pathlib import create_cleanup_lock, register_cleanup_lock_removal
215215

216216
lock = create_cleanup_lock(tmp_path)
217217

@@ -236,7 +236,7 @@ def test_lock_register_cleanup_removal(self, tmp_path):
236236

237237
def test_cleanup_keep(self, tmp_path):
238238
self.test_make(tmp_path)
239-
from _pytest.tmpdir import cleanup_numbered_dir
239+
from _pytest.pathlib import cleanup_numbered_dir
240240

241241
cleanup_numbered_dir(
242242
root=tmp_path,
@@ -249,15 +249,15 @@ def test_cleanup_keep(self, tmp_path):
249249

250250
def test_cleanup_locked(self, tmp_path):
251251

252-
from _pytest import tmpdir
252+
from _pytest import pathlib
253253

254-
p = tmpdir.make_numbered_dir(root=tmp_path, prefix=self.PREFIX)
254+
p = pathlib.make_numbered_dir(root=tmp_path, prefix=self.PREFIX)
255255

256-
tmpdir.create_cleanup_lock(p)
256+
pathlib.create_cleanup_lock(p)
257257

258-
assert not tmpdir.ensure_deletable(
258+
assert not pathlib.ensure_deletable(
259259
p, consider_lock_dead_if_created_before=p.stat().st_mtime - 1
260260
)
261-
assert tmpdir.ensure_deletable(
261+
assert pathlib.ensure_deletable(
262262
p, consider_lock_dead_if_created_before=p.stat().st_mtime + 1
263263
)

0 commit comments

Comments
 (0)