Skip to content

Commit 491597c

Browse files
committed
incremental testsuite: don't write subsequent step files until they are needed
This matters with namespace packages - since an empty package with some .2 files in it will be considered a namespace package. This is truer - by only writing the files at the point of the step. This helps unblock python#9636
1 parent 824fa86 commit 491597c

File tree

3 files changed

+20
-11
lines changed

3 files changed

+20
-11
lines changed

mypy/test/data.py

+13-8
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818

1919
# File modify/create operation: copy module contents from source_path.
2020
UpdateFile = NamedTuple('UpdateFile', [('module', str),
21-
('source_path', str),
21+
('content', str),
2222
('target_path', str)])
2323

2424
# File delete operation: delete module file.
@@ -270,23 +270,28 @@ def setup(self) -> None:
270270
self.tmpdir = tempfile.TemporaryDirectory(prefix='mypy-test-')
271271
os.chdir(self.tmpdir.name)
272272
os.mkdir(test_temp_dir)
273-
for path, content in self.files:
274-
dir = os.path.dirname(path)
275-
os.makedirs(dir, exist_ok=True)
276-
with open(path, 'w', encoding='utf8') as f:
277-
f.write(content)
278273

279274
# Precalculate steps for find_steps()
280275
steps: Dict[int, List[FileOperation]] = {}
281-
for path, _ in self.files:
276+
277+
for path, content in self.files:
282278
m = re.match(r'.*\.([0-9]+)$', path)
283279
if m:
280+
# Skip writing subsequent incremental steps - rather
281+
# store them as operations.
284282
num = int(m.group(1))
285283
assert num >= 2
286284
target_path = re.sub(r'\.[0-9]+$', '', path)
287285
module = module_from_path(target_path)
288-
operation = UpdateFile(module, path, target_path)
286+
operation = UpdateFile(module, content, target_path)
289287
steps.setdefault(num, []).append(operation)
288+
else:
289+
# Write the first incremental steps
290+
dir = os.path.dirname(path)
291+
os.makedirs(dir, exist_ok=True)
292+
with open(path, 'w', encoding='utf8') as f:
293+
f.write(content)
294+
290295
for num, paths in self.deleted_paths.items():
291296
assert num >= 2
292297
for path in paths:

mypy/test/helpers.py

+6-3
Original file line numberDiff line numberDiff line change
@@ -406,7 +406,7 @@ def split_lines(*streams: bytes) -> List[str]:
406406
]
407407

408408

409-
def copy_and_fudge_mtime(source_path: str, target_path: str) -> None:
409+
def write_and_fudge_mtime(content: str, target_path: str) -> None:
410410
# In some systems, mtime has a resolution of 1 second which can
411411
# cause annoying-to-debug issues when a file has the same size
412412
# after a change. We manually set the mtime to circumvent this.
@@ -419,7 +419,10 @@ def copy_and_fudge_mtime(source_path: str, target_path: str) -> None:
419419
new_time = os.stat(target_path).st_mtime + 1
420420

421421
# Use retries to work around potential flakiness on Windows (AppVeyor).
422-
retry_on_error(lambda: shutil.copy(source_path, target_path))
422+
dir = os.path.dirname(target_path)
423+
os.makedirs(dir, exist_ok=True)
424+
with open(target_path, "w") as target:
425+
target.write(content)
423426

424427
if new_time:
425428
os.utime(target_path, times=(new_time, new_time))
@@ -430,7 +433,7 @@ def perform_file_operations(
430433
for op in operations:
431434
if isinstance(op, UpdateFile):
432435
# Modify/create file
433-
copy_and_fudge_mtime(op.source_path, op.target_path)
436+
write_and_fudge_mtime(op.content, op.target_path)
434437
else:
435438
# Delete file/directory
436439
if os.path.isdir(op.path):

test-data/unit/fine-grained-follow-imports.test

+1
Original file line numberDiff line numberDiff line change
@@ -638,6 +638,7 @@ import p2.m2
638638
p1/m1.py:1: error: "int" not callable
639639
main.py:2: error: Cannot find implementation or library stub for module named "p2.m2"
640640
main.py:2: note: See https://mypy.readthedocs.io/en/stable/running_mypy.html#missing-imports
641+
main.py:2: error: Cannot find implementation or library stub for module named "p2"
641642
==
642643
p2/m2.py:1: error: "str" not callable
643644
p1/m1.py:1: error: "int" not callable

0 commit comments

Comments
 (0)