Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/main' into wheelpr2
Browse files Browse the repository at this point in the history
  • Loading branch information
hauntsaninja committed Sep 10, 2023
2 parents 87fca59 + 751583a commit f6654ed
Show file tree
Hide file tree
Showing 6 changed files with 56 additions and 12 deletions.
3 changes: 3 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@

<!-- Changes that improve Black's performance. -->

- Store raw tuples instead of NamedTuples in Black's cache, improving performance and
decreasing the size of the cache (#3877)

### Output

<!-- Changes to Black's terminal output and error messages -->
Expand Down
2 changes: 1 addition & 1 deletion docs/requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,4 @@ Sphinx==7.2.3
docutils==0.19
sphinxcontrib-programoutput==0.17
sphinx_copybutton==0.5.2
furo==2023.8.19
furo==2023.9.10
5 changes: 4 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,10 @@ filterwarnings = [
# https://github.com/aio-libs/aiohttp/issues/6905
'''ignore:'cgi' is deprecated and slated for removal in Python 3.13:DeprecationWarning''',
# Work around https://github.com/pytest-dev/pytest/issues/10977 for Python 3.12
'''ignore:(Attribute s|Attribute n|ast.Str|ast.Bytes|ast.NameConstant|ast.Num) is deprecated and will be removed in Python 3.14:DeprecationWarning'''
'''ignore:(Attribute s|Attribute n|ast.Str|ast.Bytes|ast.NameConstant|ast.Num) is deprecated and will be removed in Python 3.14:DeprecationWarning''',
# Will be fixed with aiohttp 3.9.0
# https://github.com/aio-libs/aiohttp/pull/7302
"ignore:datetime.*utcfromtimestamp\\(\\) is deprecated and scheduled for removal:DeprecationWarning",
]
[tool.coverage.report]
omit = [
Expand Down
11 changes: 3 additions & 8 deletions src/black/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,14 +63,9 @@
)
from black.linegen import LN, LineGenerator, transform_line
from black.lines import EmptyLineTracker, LinesBlock
from black.mode import (
FUTURE_FLAG_TO_FEATURE,
VERSION_TO_FEATURES,
Feature,
Mode,
TargetVersion,
supports_feature,
)
from black.mode import FUTURE_FLAG_TO_FEATURE, VERSION_TO_FEATURES, Feature
from black.mode import Mode as Mode # re-exported
from black.mode import TargetVersion, supports_feature
from black.nodes import (
STARS,
is_number_token,
Expand Down
10 changes: 8 additions & 2 deletions src/black/cache.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,8 @@ def read(cls, mode: Mode) -> Self:

with cache_file.open("rb") as fobj:
try:
file_data: Dict[str, FileData] = pickle.load(fobj)
data: Dict[str, Tuple[float, int, str]] = pickle.load(fobj)
file_data = {k: FileData(*v) for k, v in data.items()}
except (pickle.UnpicklingError, ValueError, IndexError):
return cls(mode, cache_file)

Expand Down Expand Up @@ -129,7 +130,12 @@ def write(self, sources: Iterable[Path]) -> None:
with tempfile.NamedTemporaryFile(
dir=str(self.cache_file.parent), delete=False
) as f:
pickle.dump(self.file_data, f, protocol=4)
# We store raw tuples in the cache because pickling NamedTuples
# doesn't work with mypyc on Python 3.8, and because it's faster.
data: Dict[str, Tuple[float, int, str]] = {
k: (*v,) for k, v in self.file_data.items()
}
pickle.dump(data, f, protocol=4)
os.replace(f.name, self.cache_file)
except OSError:
pass
37 changes: 37 additions & 0 deletions tests/test_black.py
Original file line number Diff line number Diff line change
Expand Up @@ -1985,6 +1985,7 @@ def test_cache_multiple_files(self) -> None:
assert not cache.is_changed(one)
assert not cache.is_changed(two)

@pytest.mark.incompatible_with_mypyc
@pytest.mark.parametrize("color", [False, True], ids=["no-color", "with-color"])
def test_no_cache_when_writeback_diff(self, color: bool) -> None:
mode = DEFAULT_MODE
Expand Down Expand Up @@ -2046,6 +2047,7 @@ def test_write_cache_read_cache(self) -> None:
read_cache = black.Cache.read(mode)
assert not read_cache.is_changed(src)

@pytest.mark.incompatible_with_mypyc
def test_filter_cached(self) -> None:
with TemporaryDirectory() as workspace:
path = Path(workspace)
Expand Down Expand Up @@ -2480,6 +2482,41 @@ def test_get_sources_with_stdin_filename_and_force_exclude(self) -> None:
)


class TestDeFactoAPI:
"""Test that certain symbols that are commonly used externally keep working.
We don't (yet) formally expose an API (see issue #779), but we should endeavor to
keep certain functions that external users commonly rely on working.
"""

def test_format_str(self) -> None:
# format_str and Mode should keep working
assert (
black.format_str("print('hello')", mode=black.Mode()) == 'print("hello")\n'
)

# you can pass line length
assert (
black.format_str("print('hello')", mode=black.Mode(line_length=42))
== 'print("hello")\n'
)

# invalid input raises InvalidInput
with pytest.raises(black.InvalidInput):
black.format_str("syntax error", mode=black.Mode())

def test_format_file_contents(self) -> None:
# You probably should be using format_str() instead, but let's keep
# this one around since people do use it
assert (
black.format_file_contents("x=1", fast=True, mode=black.Mode()) == "x = 1\n"
)

with pytest.raises(black.NothingChanged):
black.format_file_contents("x = 1\n", fast=True, mode=black.Mode())


try:
with open(black.__file__, "r", encoding="utf-8") as _bf:
black_source_lines = _bf.readlines()
Expand Down

0 comments on commit f6654ed

Please sign in to comment.