diff --git a/HISTORY.md b/HISTORY.md index 9f0afac4..551c2e96 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,6 +1,7 @@ # cloudpathlib Changelog ## UNRELEASED +- Replaced deprecated pytest `tmpdir` fixture usage with `tmp_path` in the remaining tests. (Issue [#370](https://github.com/drivendataorg/cloudpathlib/issues/370), PR [#554](https://github.com/drivendataorg/cloudpathlib/pull/554)) - Added support for Pydantic serialization (Issue [#537](https://github.com/drivendataorg/cloudpathlib/issues/537), PR [#538](https://github.com/drivendataorg/cloudpathlib/pull/538)) ## v0.23.0 (2025-10-07) diff --git a/tests/test_caching.py b/tests/test_caching.py index 4fce4f6f..20b10381 100644 --- a/tests/test_caching.py +++ b/tests/test_caching.py @@ -1,7 +1,6 @@ import gc import os from time import sleep -from pathlib import Path from google.api_core.exceptions import TooManyRequests import pytest @@ -156,10 +155,10 @@ def test_tmp_dir_mode(rig: CloudProviderTestRig): assert not client_cache_dir.exists() -def test_persistent_mode(rig: CloudProviderTestRig, tmpdir): +def test_persistent_mode(rig: CloudProviderTestRig, tmp_path): client = rig.client_class( file_cache_mode=FileCacheMode.persistent, - local_cache_dir=tmpdir, + local_cache_dir=tmp_path, **rig.required_client_kwargs, ) @@ -190,7 +189,7 @@ def test_persistent_mode(rig: CloudProviderTestRig, tmpdir): assert client_cache_dir.exists() -def test_loc_dir(rig: CloudProviderTestRig, tmpdir, wait_for_mkdir): +def test_loc_dir(rig: CloudProviderTestRig, tmp_path, wait_for_mkdir): """Tests that local cache dir is used when specified and works' with the different cache modes. @@ -204,12 +203,12 @@ def test_loc_dir(rig: CloudProviderTestRig, tmpdir, wait_for_mkdir): ) # automatically set to persistent if not specified - client = rig.client_class(local_cache_dir=tmpdir, **rig.required_client_kwargs) + client = rig.client_class(local_cache_dir=tmp_path, **rig.required_client_kwargs) assert client.file_cache_mode == FileCacheMode.persistent # test setting close_file explicitly works client = rig.client_class( - local_cache_dir=tmpdir, + local_cache_dir=tmp_path, file_cache_mode=FileCacheMode.close_file, **rig.required_client_kwargs, ) @@ -225,7 +224,7 @@ def test_loc_dir(rig: CloudProviderTestRig, tmpdir, wait_for_mkdir): # setting cloudpath_object still works client = rig.client_class( - local_cache_dir=tmpdir, + local_cache_dir=tmp_path, file_cache_mode=FileCacheMode.cloudpath_object, **rig.required_client_kwargs, ) @@ -245,7 +244,9 @@ def test_loc_dir(rig: CloudProviderTestRig, tmpdir, wait_for_mkdir): # setting tmp_dir still works client = rig.client_class( - local_cache_dir=tmpdir, file_cache_mode=FileCacheMode.tmp_dir, **rig.required_client_kwargs + local_cache_dir=tmp_path, + file_cache_mode=FileCacheMode.tmp_dir, + **rig.required_client_kwargs, ) cp = rig.create_cloud_path("dir_0/file0_0.txt", client=client) assert cp.client.file_cache_mode == FileCacheMode.tmp_dir @@ -274,24 +275,24 @@ def test_loc_dir(rig: CloudProviderTestRig, tmpdir, wait_for_mkdir): assert not client_cache_dir.exists() -def test_string_instantiation(rig: CloudProviderTestRig, tmpdir): +def test_string_instantiation(rig: CloudProviderTestRig, tmp_path): # string instantiation for v in FileCacheMode: - local = tmpdir if v == FileCacheMode.persistent else None + local = tmp_path if v == FileCacheMode.persistent else None client = rig.client_class( file_cache_mode=v.value, local_cache_dir=local, **rig.required_client_kwargs ) assert client.file_cache_mode == v -def test_environment_variable_instantiation(rig: CloudProviderTestRig, tmpdir): +def test_environment_variable_instantiation(rig: CloudProviderTestRig, tmp_path): # environment instantiation original_env_setting = os.environ.get("CLOUDPATHLIB_FILE_CACHE_MODE", "") try: for v in FileCacheMode: os.environ["CLOUDPATHLIB_FILE_CACHE_MODE"] = v.value - local = tmpdir if v == FileCacheMode.persistent else None + local = tmp_path if v == FileCacheMode.persistent else None client = rig.client_class(local_cache_dir=local, **rig.required_client_kwargs) assert client.file_cache_mode == v @@ -299,18 +300,18 @@ def test_environment_variable_instantiation(rig: CloudProviderTestRig, tmpdir): os.environ["CLOUDPATHLIB_FILE_CACHE_MODE"] = original_env_setting -def test_environment_variable_local_cache_dir(rig: CloudProviderTestRig, tmpdir): +def test_environment_variable_local_cache_dir(rig: CloudProviderTestRig, tmp_path): # environment instantiation original_env_setting = os.environ.get("CLOUDPATHLIB_LOCAL_CACHE_DIR", "") try: - os.environ["CLOUDPATHLIB_LOCAL_CACHE_DIR"] = tmpdir.strpath + os.environ["CLOUDPATHLIB_LOCAL_CACHE_DIR"] = str(tmp_path) client = rig.client_class(**rig.required_client_kwargs) - assert client._local_cache_dir == Path(tmpdir.strpath) + assert client._local_cache_dir == tmp_path cp = rig.create_cloud_path("dir_0/file0_0.txt", client=client) cp.fspath # download from cloud into the cache - assert (tmpdir / cp._no_prefix).exists() + assert (tmp_path / cp._no_prefix).exists() # "" treated as None; falls back to temp dir for cache os.environ["CLOUDPATHLIB_LOCAL_CACHE_DIR"] = "" @@ -322,7 +323,7 @@ def test_environment_variable_local_cache_dir(rig: CloudProviderTestRig, tmpdir) @pytest.mark.flaky(reruns=3, reruns_delay=1, condition=os.getenv("USE_LIVE_CLOUD") == "1") -def test_environment_variables_force_overwrite_from(rig: CloudProviderTestRig, tmpdir): +def test_environment_variables_force_overwrite_from(rig: CloudProviderTestRig, tmp_path): # environment instantiation original_env_setting = os.environ.get("CLOUDPATHLIB_FORCE_OVERWRITE_FROM_CLOUD", "") @@ -358,7 +359,7 @@ def test_environment_variables_force_overwrite_from(rig: CloudProviderTestRig, t @pytest.mark.flaky(reruns=3, reruns_delay=1, condition=os.getenv("USE_LIVE_CLOUD") == "1") -def test_environment_variables_force_overwrite_to(rig: CloudProviderTestRig, tmpdir): +def test_environment_variables_force_overwrite_to(rig: CloudProviderTestRig, tmp_path): # environment instantiation original_env_setting = os.environ.get("CLOUDPATHLIB_FORCE_OVERWRITE_TO_CLOUD", "") @@ -368,13 +369,16 @@ def test_environment_variables_force_overwrite_to(rig: CloudProviderTestRig, tmp p = rig.create_cloud_path("dir_0/file0_0.txt") - new_local = Path((tmpdir / "new_content.txt").strpath) + new_local = tmp_path / "new_content.txt" new_local.write_text("hello") new_also_cloud = rig.create_cloud_path("dir_0/another_cloud_file.txt") new_also_cloud.write_text("newer") # make cloud newer than local or other cloud file - os.utime(new_local, (new_local.stat().st_mtime - 2, new_local.stat().st_mtime - 2)) + os.utime( + new_local, + (new_local.stat().st_mtime - 2, new_local.stat().st_mtime - 2), + ) p.write_text("updated") diff --git a/tests/test_client.py b/tests/test_client.py index 3eceafc8..dcc624c2 100644 --- a/tests/test_client.py +++ b/tests/test_client.py @@ -56,7 +56,7 @@ def test_different_clients(rig): assert p._local is not p2._local -def test_content_type_setting(rig, tmpdir): +def test_content_type_setting(rig, tmp_path): random.seed(1337) # reproducible file names mimes = [ @@ -74,7 +74,7 @@ def test_content_type_setting(rig, tmpdir): def _test_write_content_type(suffix, expected, rig_ref, check=True): filename = "".join(random.choices(string.ascii_letters, k=8)) + suffix - filepath = Path(tmpdir / filename) + filepath = tmp_path / filename filepath.write_text("testing") cp = rig_ref.create_cloud_path(filename) diff --git a/tests/test_cloudpath_serialize.py b/tests/test_cloudpath_serialize.py index a3e59cec..81e27deb 100644 --- a/tests/test_cloudpath_serialize.py +++ b/tests/test_cloudpath_serialize.py @@ -3,13 +3,13 @@ from cloudpathlib import CloudPath -def test_pickle(rig, tmpdir): +def test_pickle(rig, tmp_path): p = rig.create_cloud_path("dir_0/file0_0.txt") - with (tmpdir / "test.pkl").open("wb") as f: + with (tmp_path / "test.pkl").open("wb") as f: pickle.dump(p, f) - with (tmpdir / "test.pkl").open("rb") as f: + with (tmp_path / "test.pkl").open("rb") as f: pickled = pickle.load(f) # test a call to the network diff --git a/tests/test_cloudpath_upload_copy.py b/tests/test_cloudpath_upload_copy.py index 29471e3f..32f98eac 100644 --- a/tests/test_cloudpath_upload_copy.py +++ b/tests/test_cloudpath_upload_copy.py @@ -15,9 +15,9 @@ @pytest.fixture -def upload_assets_dir(tmpdir): - tmp_assets = tmpdir.mkdir("test_upload_from_dir") - p = Path(tmp_assets) +def upload_assets_dir(tmp_path): + p = tmp_path / "test_upload_from_dir" + p.mkdir() (p / "upload_1.txt").write_text("Hello from 1") (p / "upload_2.txt").write_text("Hello from 2") @@ -29,6 +29,12 @@ def upload_assets_dir(tmpdir): yield p +def _mkdir(base: Path, dirname: str) -> Path: + path = base / dirname + path.mkdir() + return path + + def assert_mirrored(cloud_path, local_path, check_no_extra=True): # file exists and is file if local_path.is_file(): @@ -118,7 +124,7 @@ def test_upload_from_dir(rig, upload_assets_dir): assert assert_mirrored(p, upload_assets_dir) -def test_copy(rig, upload_assets_dir, tmpdir): +def test_copy(rig, upload_assets_dir, tmp_path): to_upload = upload_assets_dir / "upload_1.txt" p = rig.create_cloud_path("upload_test.txt") assert not p.exists() @@ -126,7 +132,7 @@ def test_copy(rig, upload_assets_dir, tmpdir): assert p.exists() # cloud to local dir - dst = Path(tmpdir.mkdir("test_copy_to_local")) + dst = _mkdir(tmp_path, "test_copy_to_local") out_file = p.copy(dst) assert out_file.exists() assert out_file.read_text() == "Hello from 1" @@ -206,7 +212,7 @@ def test_copy(rig, upload_assets_dir, tmpdir): cloud_dir = rig.create_cloud_path("dir_1/") # created by fixtures # Copy cloud directory to local directory - local_dst = Path(tmpdir.mkdir("test_copy_dir_to_local")) + local_dst = _mkdir(tmp_path, "test_copy_dir_to_local") result = cloud_dir.copy(local_dst) assert isinstance(result, Path) assert result.exists() @@ -227,7 +233,7 @@ def test_copy(rig, upload_assets_dir, tmpdir): assert (result / "dir_1_0").exists() # Copy cloud directory to string path - local_dst2 = Path(tmpdir.mkdir("test_copy_dir_to_str")) + local_dst2 = _mkdir(tmp_path, "test_copy_dir_to_str") result = cloud_dir.copy(str(local_dst2)) assert result.exists() assert result.is_dir() @@ -236,11 +242,11 @@ def test_copy(rig, upload_assets_dir, tmpdir): assert (result / "dir_1_0").exists() -def test_copytree(rig, tmpdir): +def test_copytree(rig, tmp_path): # cloud file raises with pytest.raises(CloudPathNotADirectoryError): p = rig.create_cloud_path("dir_0/file0_0.txt") - local_out = Path(tmpdir.mkdir("copytree_fail_on_file")) + local_out = _mkdir(tmp_path, "copytree_fail_on_file") p.copytree(local_out) with pytest.raises(CloudPathFileExistsError): @@ -250,12 +256,12 @@ def test_copytree(rig, tmpdir): # cloud dir to local dir that exists p = rig.create_cloud_path("dir_1/") - local_out = Path(tmpdir.mkdir("copytree_from_cloud")) + local_out = _mkdir(tmp_path, "copytree_from_cloud") p.copytree(local_out) assert assert_mirrored(p, local_out) # str version of path - local_out = Path(tmpdir.mkdir("copytree_to_str_path")) + local_out = _mkdir(tmp_path, "copytree_to_str_path") p.copytree(str(local_out)) assert assert_mirrored(p, local_out) @@ -337,14 +343,14 @@ def test_info(rig): assert info.is_symlink() is False # Cloud paths are never symlinks -def test_copy_into(rig, tmpdir): +def test_copy_into(rig, tmp_path): """Test the copy_into() method.""" # Create a test file p = rig.create_cloud_path("test_file.txt") p.write_text("Hello from copy_into") # Test copying into a local directory - local_dir = Path(tmpdir.mkdir("copy_into_local")) + local_dir = _mkdir(tmp_path, "copy_into_local") result = p.copy_into(local_dir) assert isinstance(result, Path) @@ -362,7 +368,7 @@ def test_copy_into(rig, tmpdir): assert result.read_text() == "Hello from copy_into" # Test copying into a string path - local_dir2 = Path(tmpdir.mkdir("copy_into_str")) + local_dir2 = _mkdir(tmp_path, "copy_into_str") result = p.copy_into(str(local_dir2)) assert result.exists() @@ -373,7 +379,7 @@ def test_copy_into(rig, tmpdir): cloud_dir = rig.create_cloud_path("dir_1/") # created by fixtures # Copy cloud directory into local directory - local_dst = Path(tmpdir.mkdir("copy_into_dir_local")) + local_dst = _mkdir(tmp_path, "copy_into_dir_local") result = cloud_dir.copy_into(local_dst) assert isinstance(result, Path) assert result.exists() @@ -398,7 +404,7 @@ def test_copy_into(rig, tmpdir): assert (result / "dir_1_0").exists() # Copy cloud directory into string path - local_dst2 = Path(tmpdir.mkdir("copy_into_dir_str")) + local_dst2 = _mkdir(tmp_path, "copy_into_dir_str") result = cloud_dir.copy_into(str(local_dst2)) assert result.exists() assert result.is_dir() @@ -408,14 +414,14 @@ def test_copy_into(rig, tmpdir): assert (result / "dir_1_0").exists() -def test_move(rig, tmpdir): +def test_move(rig, tmp_path): """Test the move() method.""" # Create a test file p = rig.create_cloud_path("test_move_file.txt") p.write_text("Hello from move") # Test moving to a local file - local_file = Path(tmpdir) / "moved_file.txt" + local_file = tmp_path / "moved_file.txt" result = p.move(local_file) assert isinstance(result, Path) @@ -438,7 +444,7 @@ def test_move(rig, tmpdir): p3 = rig.create_cloud_path("test_move_file3.txt") p3.write_text("Hello from move 3") - local_file2 = Path(tmpdir) / "moved_file3.txt" + local_file2 = tmp_path / "moved_file3.txt" result = p3.move(str(local_file2)) assert result.exists() @@ -446,14 +452,14 @@ def test_move(rig, tmpdir): # Note: When moving cloud->local, the source may still exist due to download_to behavior -def test_move_into(rig, tmpdir): +def test_move_into(rig, tmp_path): """Test the move_into() method.""" # Create a test file p = rig.create_cloud_path("test_move_into_file.txt") p.write_text("Hello from move_into") # Test moving into a local directory - local_dir = Path(tmpdir.mkdir("move_into_local")) + local_dir = _mkdir(tmp_path, "move_into_local") result = p.move_into(local_dir) assert isinstance(result, Path) @@ -479,7 +485,7 @@ def test_move_into(rig, tmpdir): p3 = rig.create_cloud_path("test_move_into_file3.txt") p3.write_text("Hello from move_into 3") - local_dir2 = Path(tmpdir.mkdir("move_into_str")) + local_dir2 = _mkdir(tmp_path, "move_into_str") result = p3.move_into(str(local_dir2)) assert result.exists() @@ -499,7 +505,7 @@ def test_copy_nonexistent_file_error(rig): p.copy(rig.create_cloud_path("destination.txt")) -def test_copy_with_cloudpath_objects(rig, tmpdir): +def test_copy_with_cloudpath_objects(rig): """Test copy operations using CloudPath objects directly (not strings).""" # Create a test file p = rig.create_cloud_path("test_copy_objects.txt") @@ -529,7 +535,7 @@ def test_copy_with_cloudpath_objects(rig, tmpdir): assert result.read_text() == "Hello from copy objects" -def test_copy_into_with_cloudpath_objects(rig, tmpdir): +def test_copy_into_with_cloudpath_objects(rig): """Test copy_into with CloudPath objects to cover line 1292.""" # Create a test file p = rig.create_cloud_path("test_copy_into_objects.txt") @@ -545,7 +551,7 @@ def test_copy_into_with_cloudpath_objects(rig, tmpdir): assert result.read_text() == "Hello from copy_into objects" -def test_move_into_with_cloudpath_objects(rig, tmpdir): +def test_move_into_with_cloudpath_objects(rig): """Test move_into with CloudPath objects to cover line 1450.""" # Create a test file p = rig.create_cloud_path("test_move_into_objects.txt")