Skip to content

Commit

Permalink
Use pyupgrade in pre-commit (#1036)
Browse files Browse the repository at this point in the history
* Immunize `io.open()` from pyupgrade rewrites
* Run `upadup` to update pre-commit additional dependencies
* Run `pre-commit run -a`
* Add pyupgrade as a pre-commit hook
  Because pyupgrade rewrites code, the hook runs before code reformatters.
  • Loading branch information
kurtmckee authored Jul 3, 2024
1 parent 3be5638 commit 9c19d6a
Show file tree
Hide file tree
Showing 8 changed files with 46 additions and 18 deletions.
10 changes: 9 additions & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,14 @@ default_language_version:
python: "3.10"

repos:
- repo: "https://github.com/asottile/pyupgrade"
rev: "v3.15.2"
hooks:
- id: "pyupgrade"
name: "Enforce Python 3.7+ idioms"
args:
- "--py37-plus"

- repo: https://github.com/astral-sh/ruff-pre-commit
rev: "v0.5.0"
hooks:
Expand All @@ -18,7 +26,7 @@ repos:
rev: 1.18.0
hooks:
- id: blacken-docs
additional_dependencies: [ black==22.12.0 ]
additional_dependencies: [ black==24.4.2 ]
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.6.0
hooks:
Expand Down
3 changes: 3 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ The released versions correspond to PyPI releases.
### Fixes
* use real open calls for remaining `pathlib` functions so that it works nice with skippedmodules (see [#1012](../../issues/1012))

### Infrastructure
* Add pyupgrade as a pre-commit hook.

## [Version 5.5.0](https://pypi.python.org/pypi/pyfakefs/5.5.0) (2024-05-12)
Deprecates the usage of `pathlib2` and `scandir`.

Expand Down
2 changes: 1 addition & 1 deletion docs/troubleshooting.rst
Original file line number Diff line number Diff line change
Expand Up @@ -350,7 +350,7 @@ If you want to know if your problem is indeed with the dynamic patcher, you can
def test_something(fs_no_dyn_patch):
... # do the testing
assert foo() # do the testing
If in this case the following tests pass as expected, the dynamic patcher is indeed the problem.
If your ``pyfakefs`` test also works with that setting, you may just use this. Otherwise,
Expand Down
22 changes: 12 additions & 10 deletions docs/usage.rst
Original file line number Diff line number Diff line change
Expand Up @@ -180,13 +180,13 @@ order, as shown here:
@patchfs
@mock.patch("foo.bar")
def test_something(fake_fs, mocked_bar):
...
assert foo()
@mock.patch("foo.bar")
@patchfs
def test_something(mocked_bar, fake_fs):
...
assert foo()
.. note::
Avoid writing the ``patchfs`` decorator *between* ``mock.patch`` operators,
Expand Down Expand Up @@ -257,7 +257,7 @@ In case of ``pytest``, you have two possibilities:
def test_something(fs_no_root):
...
assert foo()
- You can also pass the arguments using ``@pytest.mark.parametrize``. Note that
you have to provide `all Patcher arguments`_ before the needed ones, as
Expand All @@ -272,7 +272,7 @@ In case of ``pytest``, you have two possibilities:
@pytest.mark.parametrize("fs", [[None, None, None, False]], indirect=True)
def test_something(fs):
...
assert foo()
Unittest
........
Expand All @@ -290,7 +290,7 @@ instance:
self.setUpPyfakefs(allow_root_user=False)
def testSomething(self):
...
assert foo()
patchfs
.......
Expand All @@ -304,7 +304,7 @@ the decorator:
@patchfs(allow_root_user=False)
def test_something(fake_fs):
...
assert foo()
List of custom arguments
Expand Down Expand Up @@ -412,6 +412,7 @@ the file ``example/sut.py``, the following code will work (imports are omitted):
import example
# example using unittest
class ReloadModuleTest(fake_filesystem_unittest.TestCase):
def setUp(self):
Expand Down Expand Up @@ -499,27 +500,28 @@ has now been been integrated into ``pyfakefs``):
with Patcher(modules_to_patch={"django.core.files.locks": FakeLocks}):
test_django_stuff()
# test code using unittest
class TestUsingDjango(fake_filesystem_unittest.TestCase):
def setUp(self):
self.setUpPyfakefs(modules_to_patch={"django.core.files.locks": FakeLocks})
def test_django_stuff(self):
...
assert foo()
# test code using pytest
@pytest.mark.parametrize(
"fs", [[None, None, {"django.core.files.locks": FakeLocks}]], indirect=True
)
def test_django_stuff(fs):
...
assert foo()
# test code using patchfs decorator
@patchfs(modules_to_patch={"django.core.files.locks": FakeLocks})
def test_django_stuff(fake_fs):
...
assert foo()
additional_skip_names
.....................
Expand Down Expand Up @@ -583,7 +585,7 @@ set ``patch_open_code`` to ``PatchMode.AUTO``:
@patchfs(patch_open_code=PatchMode.AUTO)
def test_something(fs):
...
assert foo()
.. _patch_default_args:

Expand Down
6 changes: 5 additions & 1 deletion pyfakefs/fake_file.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,10 @@
if TYPE_CHECKING:
from pyfakefs.fake_filesystem import FakeFilesystem


# Work around pyupgrade auto-rewriting `io.open()` to `open()`.
io_open = io.open

AnyFileWrapper = Union[
"FakeFileWrapper",
"FakeDirWrapper",
Expand Down Expand Up @@ -458,7 +462,7 @@ def __init__(
def byte_contents(self) -> Optional[bytes]:
if not self.contents_read:
self.contents_read = True
with io.open(self.file_path, "rb") as f:
with io_open(self.file_path, "rb") as f:
self._byte_contents = f.read()
# On MacOS and BSD, the above io.open() updates atime on the real file
self.st_atime = os.stat(self.file_path).st_atime
Expand Down
9 changes: 6 additions & 3 deletions pyfakefs/fake_open.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,9 @@
from pyfakefs.fake_filesystem import FakeFilesystem


# Work around pyupgrade auto-rewriting `io.open()` to `open()`.
io_open = io.open

_OPEN_MODE_MAP = {
# mode name:(file must exist, can read, can write,
# truncate, append, must not exist)
Expand All @@ -74,7 +77,7 @@ def _real_call_line_no():
global real_call_line_no
if real_call_line_no is None:
fake_io_source = os.path.join(os.path.dirname(__file__), "fake_io.py")
for i, line in enumerate(io.open(fake_io_source)):
for i, line in enumerate(io_open(fake_io_source)):
if "return self._io_module.open_code(path)" in line:
real_call_line_no = i + 1
break
Expand Down Expand Up @@ -105,7 +108,7 @@ def fake_open(
and file.endswith(("fake_open.py", "fake_io.py"))
and os.path.split(os.path.dirname(file))[1] == "pyfakefs"
):
return io.open( # pytype: disable=wrong-arg-count
return io_open( # pytype: disable=wrong-arg-count
file,
mode,
buffering,
Expand Down Expand Up @@ -155,7 +158,7 @@ def fake_open(
if from_open_code or any(
[module_name == sn or module_name.endswith("." + sn) for sn in skip_names]
):
return io.open( # pytype: disable=wrong-arg-count
return io_open( # pytype: disable=wrong-arg-count
file,
mode,
buffering,
Expand Down
6 changes: 5 additions & 1 deletion pyfakefs/tests/example_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,10 @@
from pyfakefs.tests import example # The module under test


# Work around pyupgrade auto-rewriting `io.open()` to `open()`.
io_open = io.open


def load_tests(loader, tests, ignore):
"""Load the pyfakefs/example.py doctest tests into unittest."""
return fake_filesystem_unittest.load_doctests(loader, tests, ignore, example)
Expand All @@ -62,7 +66,7 @@ def setUp(self):

# This is before setUpPyfakefs(), so still using the real file system
self.filepath = os.path.realpath(__file__)
with io.open(self.filepath, "rb") as f:
with io_open(self.filepath, "rb") as f:
self.real_contents = f.read()

self.setUpPyfakefs()
Expand Down
6 changes: 5 additions & 1 deletion pyfakefs/tests/fake_filesystem_unittest_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,10 @@
from distutils.dir_util import copy_tree, remove_tree


# Work around pyupgrade auto-rewriting `io.open()` to `open()`.
io_open = io.open


class TestPatcher(TestCase):
def test_context_manager(self):
with Patcher() as patcher:
Expand Down Expand Up @@ -115,7 +119,7 @@ def test_open(self):
def test_io_open(self):
"""Fake io module is bound"""
self.assertFalse(os.path.exists("/fake_file.txt"))
with io.open("/fake_file.txt", "w", encoding="utf8") as f:
with io_open("/fake_file.txt", "w", encoding="utf8") as f:
f.write("This test file was created using the" " io.open() function.\n")
self.assertTrue(self.fs.exists("/fake_file.txt"))
with open("/fake_file.txt", encoding="utf8") as f:
Expand Down

0 comments on commit 9c19d6a

Please sign in to comment.