diff --git a/pyproject.toml b/pyproject.toml index 158b0be0a..912e35fdb 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -171,6 +171,7 @@ markers = [ ] xfail_strict = true testpaths = ["tests"] +filterwarnings = ["error::pytest_mock.PytestMockWarning"] [tool.coverage.run] branch = true diff --git a/tests/func/test_import.py b/tests/func/test_import.py index cedcf231c..92ef03cdf 100644 --- a/tests/func/test_import.py +++ b/tests/func/test_import.py @@ -1,6 +1,5 @@ import filecmp import os -from unittest.mock import patch import pytest from funcy import first @@ -49,7 +48,7 @@ def test_import_git_file(tmp_dir, scm, dvc, git_dir, src_is_dvc): } -def test_import_cached_file(erepo_dir, tmp_dir, dvc, scm, monkeypatch): +def test_import_cached_file(mocker, erepo_dir, tmp_dir, dvc, scm, monkeypatch): src = "some_file" dst = "some_file_imported" @@ -60,10 +59,10 @@ def test_import_cached_file(erepo_dir, tmp_dir, dvc, scm, monkeypatch): (tmp_dir / dst).unlink() remote_exception = NoRemoteError("dvc import") - with patch.object( + mocker.patch.object( dvc.cloud, "get_remote_odb", side_effect=remote_exception - ): - tmp_dir.dvc.imp(os.fspath(erepo_dir), src, dst) + ) + tmp_dir.dvc.imp(os.fspath(erepo_dir), src, dst) assert (tmp_dir / dst).is_file() assert filecmp.cmp(erepo_dir / src, tmp_dir / dst, shallow=False) @@ -357,7 +356,9 @@ def test_push_wildcard_from_bare_git_repo( dvc_repo.dvc.imp(os.fspath(tmp_dir), "dir123") -def test_download_error_pulling_imported_stage(tmp_dir, dvc, erepo_dir): +def test_download_error_pulling_imported_stage( + mocker, tmp_dir, dvc, erepo_dir +): with erepo_dir.chdir(): erepo_dir.dvc_gen("foo", "foo content", commit="create foo") dvc.imp(os.fspath(erepo_dir), "foo", "foo_imported") @@ -368,9 +369,8 @@ def test_download_error_pulling_imported_stage(tmp_dir, dvc, erepo_dir): remove("foo_imported") remove(dst_cache) - with patch( - "dvc_objects.fs.generic.transfer", side_effect=Exception - ), pytest.raises(DownloadError): + mocker.patch("dvc_objects.fs.generic.transfer", side_effect=Exception) + with pytest.raises(DownloadError): dvc.pull(["foo_imported.dvc"]) diff --git a/tests/func/test_repro.py b/tests/func/test_repro.py index 612512c9c..627f6ce68 100644 --- a/tests/func/test_repro.py +++ b/tests/func/test_repro.py @@ -3,7 +3,6 @@ import os import re import shutil from pathlib import Path -from unittest.mock import patch import pytest @@ -130,7 +129,7 @@ class TestReproWorkingDirectoryAsOutput: with pytest.raises(StagePathAsOutputError): dvc.reproduce(faulty_stage_path) - def test_nested(self, dvc): + def test_nested(self, mocker, dvc): # . # |-- a # | |__ nested @@ -175,9 +174,9 @@ class TestReproWorkingDirectoryAsOutput: ] ) - with patch.object(dvc, "_reset"): # to prevent `stages` resetting - with pytest.raises(StagePathAsOutputError): - dvc.reproduce(error_stage_path) + mocker.patch.object(dvc, "_reset") # to prevent `stages` resetting + with pytest.raises(StagePathAsOutputError): + dvc.reproduce(error_stage_path) def test_similar_paths(self, dvc): # File structure: diff --git a/tests/unit/dependency/test_dependency.py b/tests/unit/dependency/test_dependency.py index 6f7501bb6..6748311da 100644 --- a/tests/unit/dependency/test_dependency.py +++ b/tests/unit/dependency/test_dependency.py @@ -7,6 +7,6 @@ from dvc.stage import Stage def test_save_missing(dvc, mocker): stage = Stage(dvc) dep = Dependency(stage, "path") - with mocker.patch.object(dep.fs, "exists", return_value=False): - with pytest.raises(dep.DoesNotExistError): - dep.save() + mocker.patch.object(dep.fs, "exists", return_value=False) + with pytest.raises(dep.DoesNotExistError): + dep.save() diff --git a/tests/unit/output/test_output.py b/tests/unit/output/test_output.py index bcf821098..740605e6f 100644 --- a/tests/unit/output/test_output.py +++ b/tests/unit/output/test_output.py @@ -15,9 +15,9 @@ from dvc.utils.fs import remove def test_save_missing(dvc, mocker): stage = Stage(dvc) out = Output(stage, "path", cache=False) - with mocker.patch.object(out.fs, "exists", return_value=False): - with pytest.raises(out.DoesNotExistError): - out.save() + mocker.patch.object(out.fs, "exists", return_value=False) + with pytest.raises(out.DoesNotExistError): + out.save() @pytest.mark.parametrize( @@ -115,9 +115,9 @@ def test_remote_missing_dependency_on_dir_pull(tmp_dir, scm, dvc, mocker): remove("dir") remove(dvc.odb.local.path) - with mocker.patch( + mocker.patch( "dvc.data_cloud.DataCloud.get_remote_odb", side_effect=RemoteMissingDepsError(dvc.fs, "azure", "azure://", []), - ): - with pytest.raises(RemoteMissingDepsError): - dvc.pull() + ) + with pytest.raises(RemoteMissingDepsError): + dvc.pull() diff --git a/tests/unit/remote/test_base.py b/tests/unit/remote/test_base.py index aa1ebfc59..d935cf85a 100644 --- a/tests/unit/remote/test_base.py +++ b/tests/unit/remote/test_base.py @@ -1,6 +1,5 @@ import math import posixpath -from unittest import mock from dvc.fs import FileSystem from dvc_data.hashfile.db import ObjectDB @@ -16,59 +15,54 @@ class _CallableOrNone: CallableOrNone = _CallableOrNone() -@mock.patch.object(ObjectDB, "_list_oids_traverse") -@mock.patch.object(ObjectDB, "list_oids_exists") -def test_oids_exist(object_exists, traverse, dvc): +def test_oids_exist(mocker, dvc): + traverse = mocker.patch.object(ObjectDB, "_list_oids_traverse") + object_exists = mocker.patch.object(ObjectDB, "list_oids_exists") odb = ObjectDB(FileSystem(), None) # remote does not support traverse odb.fs.CAN_TRAVERSE = False - with mock.patch.object(odb, "_list_oids", return_value=list(range(256))): - oids = set(range(1000)) - odb.oids_exist(oids) - object_exists.assert_called_with(oids, None) - traverse.assert_not_called() + mocker.patch.object(odb, "_list_oids", return_value=list(range(256))) + oids = set(range(1000)) + odb.oids_exist(oids) + object_exists.assert_called_with(oids, None) + traverse.assert_not_called() odb.fs.CAN_TRAVERSE = True # large remote, small local object_exists.reset_mock() traverse.reset_mock() - with mock.patch.object(odb, "_list_oids", return_value=list(range(2048))): - oids = list(range(1000)) - odb.oids_exist(oids) - # verify that _odb_paths_with_max() short circuits - # before returning all 2048 remote oids - max_oids = math.ceil( - odb._max_estimation_size(oids) - / pow(16, odb.fs.TRAVERSE_PREFIX_LEN) - ) - assert max_oids < 2048 - object_exists.assert_called_with( - frozenset(range(max_oids, 1000)), None - ) - traverse.assert_not_called() + + mocker.patch.object(odb, "_list_oids", return_value=list(range(2048))) + oids = list(range(1000)) + odb.oids_exist(oids) + # verify that _odb_paths_with_max() short circuits + # before returning all 2048 remote oids + max_oids = math.ceil( + odb._max_estimation_size(oids) / pow(16, odb.fs.TRAVERSE_PREFIX_LEN) + ) + assert max_oids < 2048 + object_exists.assert_called_with(frozenset(range(max_oids, 1000)), None) + traverse.assert_not_called() # large remote, large local object_exists.reset_mock() traverse.reset_mock() odb.fs._JOBS = 16 - with mock.patch.object(odb, "_list_oids", return_value=list(range(256))): - oids = list(range(1000000)) - odb.oids_exist(oids) - object_exists.assert_not_called() - traverse.assert_called_with( - 256 * pow(16, odb.fs.TRAVERSE_PREFIX_LEN), - set(range(256)), - jobs=None, - ) + mocker.patch.object(odb, "_list_oids", return_value=list(range(256))) + oids = list(range(1000000)) + odb.oids_exist(oids) + object_exists.assert_not_called() + traverse.assert_called_with( + 256 * pow(16, odb.fs.TRAVERSE_PREFIX_LEN), + set(range(256)), + jobs=None, + ) -@mock.patch.object(ObjectDB, "_list_oids", return_value=[]) -@mock.patch.object(ObjectDB, "path_to_oid", side_effect=lambda x: x) -def test_list_oids_traverse( - path_to_oid, list_oids, dvc # pylint: disable=unused-argument -): +def test_list_oids_traverse(mocker, dvc): # pylint: disable=unused-argument + list_oids = mocker.patch.object(ObjectDB, "_list_oids", return_value=[]) odb = ObjectDB(FileSystem(), None) odb.fs_path = "foo" @@ -87,28 +81,24 @@ def test_list_oids_traverse( list_oids.assert_called_with(None) -def test_list_oids(dvc): +def test_list_oids(mocker, dvc): odb = ObjectDB(FileSystem(), None) odb.fs_path = "foo" - with mock.patch.object( - odb, "_list_paths", return_value=["12/3456", "bar"] - ): - oids = list(odb._list_oids()) - assert oids == ["123456"] + mocker.patch.object(odb, "_list_paths", return_value=["12/3456", "bar"]) + oids = list(odb._list_oids()) + assert oids == ["123456"] -def test_list_paths(dvc): +def test_list_paths(mocker, dvc): path = "foo" odb = ObjectDB(FileSystem(), path) - with mock.patch.object(odb.fs, "find", return_value=[]) as walk_mock: - for _ in odb._list_paths(): - pass - walk_mock.assert_called_with(path, prefix=False) + walk_mock = mocker.patch.object(odb.fs, "find", return_value=[]) + for _ in odb._list_paths(): + pass + walk_mock.assert_called_with(path, prefix=False) - for _ in odb._list_paths(prefix="000"): - pass - walk_mock.assert_called_with( - posixpath.join(path, "00", "0"), prefix=True - ) + for _ in odb._list_paths(prefix="000"): + pass + walk_mock.assert_called_with(posixpath.join(path, "00", "0"), prefix=True) diff --git a/tests/unit/remote/test_http.py b/tests/unit/remote/test_http.py index 22ffd904f..0c10df584 100644 --- a/tests/unit/remote/test_http.py +++ b/tests/unit/remote/test_http.py @@ -1,5 +1,4 @@ import ssl -from unittest.mock import patch from dvc.fs import HTTPFileSystem @@ -64,8 +63,8 @@ def test_ssl_verify_disable(dvc): assert not fs.fs_args["client_kwargs"]["connector"]._ssl -@patch("ssl.SSLContext.load_verify_locations") def test_ssl_verify_custom_cert(dvc, mocker): + mocker.patch("ssl.SSLContext.load_verify_locations") config = { "url": "http://example.com/", "path": "file.html", diff --git a/tests/unit/remote/test_webdav.py b/tests/unit/remote/test_webdav.py index 2f328101d..cd8c188e3 100644 --- a/tests/unit/remote/test_webdav.py +++ b/tests/unit/remote/test_webdav.py @@ -1,5 +1,3 @@ -from unittest.mock import patch - import pytest from dvc_webdav import WebDAVFileSystem, WebDAVSFileSystem @@ -66,9 +64,10 @@ def test_token(): ) -@patch("dvc_webdav.ask_password") -def test_ask_password(ask_password_mocked): - ask_password_mocked.return_value = "pass" +def test_ask_password(mocker): + ask_password_mocked = mocker.patch( + "dvc_webdav.ask_password", return_value="pass" + ) host = "host" # it should not ask for password as password is set diff --git a/tests/unit/remote/test_webhdfs.py b/tests/unit/remote/test_webhdfs.py index db5da387f..a9a508874 100644 --- a/tests/unit/remote/test_webhdfs.py +++ b/tests/unit/remote/test_webhdfs.py @@ -1,5 +1,3 @@ -from unittest.mock import Mock, create_autospec - import pytest import requests from dvc_webhdfs import WebHDFSFileSystem @@ -42,9 +40,11 @@ def test_init(dvc, webhdfs_config): assert fs.fs_args["use_https"] == use_https -def test_verify_ssl(dvc, webhdfs_config, monkeypatch): - mock_session = create_autospec(requests.Session) - monkeypatch.setattr(requests, "Session", Mock(return_value=mock_session)) +def test_verify_ssl(dvc, webhdfs_config, monkeypatch, mocker): + mock_session = mocker.create_autospec(requests.Session) + monkeypatch.setattr( + requests, "Session", mocker.Mock(return_value=mock_session) + ) # can't have token at the same time as user or proxy_to del webhdfs_config["token"] fs = WebHDFSFileSystem(**webhdfs_config) diff --git a/tests/unit/test_analytics.py b/tests/unit/test_analytics.py index eaa86eec7..d31a0b3d1 100644 --- a/tests/unit/test_analytics.py +++ b/tests/unit/test_analytics.py @@ -1,6 +1,5 @@ import json import platform -from unittest import mock import pytest from voluptuous import Any, Schema @@ -57,8 +56,9 @@ def test_runtime_info(tmp_global_dir): assert schema(analytics._runtime_info()) -@mock.patch("requests.post") -def test_send(mock_post, tmp_path): +def test_send(mocker, tmp_path): + mock_post = mocker.patch("requests.post") + import requests url = "https://analytics.dvc.org" diff --git a/tests/unit/utils/test_collections.py b/tests/unit/utils/test_collections.py index 1a4918e72..e065ba3fb 100644 --- a/tests/unit/utils/test_collections.py +++ b/tests/unit/utils/test_collections.py @@ -1,6 +1,5 @@ # pylint: disable=unidiomatic-typecheck import json -from unittest.mock import create_autospec import pytest @@ -83,7 +82,7 @@ def _test_func(x, y, *args, j=3, k=5, **kwargs): def test_pre_validate_decorator_required_args(mocker): mock = mocker.MagicMock() - func_mock = create_autospec(_test_func) + func_mock = mocker.create_autospec(_test_func) func = validate(mock)(func_mock) func("x", "y") @@ -102,7 +101,7 @@ def test_pre_validate_decorator_required_args(mocker): def test_pre_validate_decorator_kwargs_args(mocker): mock = mocker.MagicMock() - func_mock = create_autospec(_test_func) + func_mock = mocker.create_autospec(_test_func) func = validate(mock)(func_mock) func("x", "y", "part", "of", "args", j=1, k=10, m=100, n=1000) @@ -120,7 +119,7 @@ def test_pre_validate_decorator_kwargs_args(mocker): assert args.kwargs == {"m": 100, "n": 1000} -def test_pre_validate_update_args(): +def test_pre_validate_update_args(mocker): def test_validator(args): args.w += 50 del args.x @@ -129,7 +128,7 @@ def test_pre_validate_update_args(): def test_func(w=1, x=5, y=10, z=15): pass - mock = create_autospec(test_func) + mock = mocker.create_autospec(test_func) func = validate(test_validator)(mock) func(100, 100)