Skip to content

Commit

Permalink
Clear warnings for each file in comemod cli (#1184)
Browse files Browse the repository at this point in the history
* Clean warnings for each file in comemod cli

* Fix ZeroDivisionError: float division by zero

When codemodding too fast

* Recreate CodemodContext for each file

Keep only context.metadata_manager
Remove wrapper from context defaults on each file
  • Loading branch information
kiri11 authored Aug 5, 2024
1 parent 56cd1f9 commit 45234f1
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 16 deletions.
31 changes: 15 additions & 16 deletions libcst/codemod/_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@

from libcst import parse_module, PartialParserConfig
from libcst.codemod._codemod import Codemod
from libcst.codemod._context import CodemodContext
from libcst.codemod._dummy_pool import DummyPool
from libcst.codemod._runner import (
SkipFile,
Expand Down Expand Up @@ -246,30 +247,28 @@ def _execute_transform( # noqa: C901
),
)

# Somewhat gross hack to provide the filename in the transform's context.
# We do this after the fork so that a context that was initialized with
# some defaults before calling parallel_exec_transform_with_prettyprint
# will be updated per-file.
transformer.context = replace(
transformer.context,
filename=filename,
scratch=deepcopy(scratch),
)

# determine the module and package name for this file
try:
module_name_and_package = calculate_module_and_package(
config.repo_root or ".", filename
)
transformer.context = replace(
transformer.context,
full_module_name=module_name_and_package.name,
full_package_name=module_name_and_package.package,
)
mod_name = module_name_and_package.name
pkg_name = module_name_and_package.package
except ValueError as ex:
print(
f"Failed to determine module name for {filename}: {ex}", file=sys.stderr
)
mod_name = None
pkg_name = None

# Apart from metadata_manager, every field of context should be reset per file
transformer.context = CodemodContext(
scratch=deepcopy(scratch),
filename=filename,
full_module_name=mod_name,
full_package_name=pkg_name,
metadata_manager=transformer.context.metadata_manager,
)

# Run the transform, bail if we failed or if we aren't formatting code
try:
Expand Down Expand Up @@ -420,7 +419,7 @@ def estimate_completion(
operations still to do.
"""

if files_finished <= 0:
if files_finished <= 0 or elapsed_seconds == 0:
# Technically infinite but calculating sounds better.
return "[calculating]"

Expand Down
30 changes: 30 additions & 0 deletions libcst/codemod/tests/test_codemod_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,12 @@
import platform
import subprocess
import sys
import tempfile
from pathlib import Path
from unittest import skipIf

from libcst._parser.entrypoints import is_native
from libcst.codemod import CodemodTest
from libcst.testing.utils import UnitTest


Expand Down Expand Up @@ -63,3 +65,31 @@ def test_codemod_external(self) -> None:
stderr=subprocess.STDOUT,
)
assert "Finished codemodding 1 files!" in output

def test_warning_messages_several_files(self) -> None:
code = """
def baz() -> str:
return "{}: {}".format(*baz)
"""
with tempfile.TemporaryDirectory() as tmpdir:
p = Path(tmpdir)
(p / "mod1.py").write_text(CodemodTest.make_fixture_data(code))
(p / "mod2.py").write_text(CodemodTest.make_fixture_data(code))
(p / "mod3.py").write_text(CodemodTest.make_fixture_data(code))
output = subprocess.run(
[
sys.executable,
"-m",
"libcst.tool",
"codemod",
"convert_format_to_fstring.ConvertFormatStringCommand",
str(p),
],
encoding="utf-8",
stderr=subprocess.PIPE,
)
# Each module will generate a warning, so we should get 3 warnings in total
self.assertIn(
"- 3 warnings were generated.",
output.stderr,
)

0 comments on commit 45234f1

Please sign in to comment.