fsspec 2025.7.0__tar.gz → 2025.9.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (90) hide show
  1. {fsspec-2025.7.0 → fsspec-2025.9.0}/PKG-INFO +2 -31
  2. {fsspec-2025.7.0 → fsspec-2025.9.0}/docs/source/changelog.rst +18 -0
  3. {fsspec-2025.7.0 → fsspec-2025.9.0}/fsspec/_version.py +16 -3
  4. {fsspec-2025.7.0 → fsspec-2025.9.0}/fsspec/implementations/asyn_wrapper.py +10 -2
  5. {fsspec-2025.7.0 → fsspec-2025.9.0}/fsspec/implementations/cached.py +2 -1
  6. {fsspec-2025.7.0 → fsspec-2025.9.0}/fsspec/implementations/dbfs.py +31 -3
  7. {fsspec-2025.7.0 → fsspec-2025.9.0}/fsspec/implementations/http.py +1 -1
  8. {fsspec-2025.7.0 → fsspec-2025.9.0}/pyproject.toml +3 -3
  9. {fsspec-2025.7.0 → fsspec-2025.9.0}/.codespellrc +0 -0
  10. {fsspec-2025.7.0 → fsspec-2025.9.0}/.coveragerc +0 -0
  11. {fsspec-2025.7.0 → fsspec-2025.9.0}/.gitattributes +0 -0
  12. {fsspec-2025.7.0 → fsspec-2025.9.0}/.github/workflows/main.yaml +0 -0
  13. {fsspec-2025.7.0 → fsspec-2025.9.0}/.github/workflows/pypipublish.yaml +0 -0
  14. {fsspec-2025.7.0 → fsspec-2025.9.0}/.gitignore +0 -0
  15. {fsspec-2025.7.0 → fsspec-2025.9.0}/.pre-commit-config.yaml +0 -0
  16. {fsspec-2025.7.0 → fsspec-2025.9.0}/LICENSE +0 -0
  17. {fsspec-2025.7.0 → fsspec-2025.9.0}/README.md +0 -0
  18. {fsspec-2025.7.0 → fsspec-2025.9.0}/ci/environment-downstream.yml +0 -0
  19. {fsspec-2025.7.0 → fsspec-2025.9.0}/ci/environment-friends.yml +0 -0
  20. {fsspec-2025.7.0 → fsspec-2025.9.0}/ci/environment-linux.yml +0 -0
  21. {fsspec-2025.7.0 → fsspec-2025.9.0}/ci/environment-win.yml +0 -0
  22. {fsspec-2025.7.0 → fsspec-2025.9.0}/docs/Makefile +0 -0
  23. {fsspec-2025.7.0 → fsspec-2025.9.0}/docs/README.md +0 -0
  24. {fsspec-2025.7.0 → fsspec-2025.9.0}/docs/environment.yml +0 -0
  25. {fsspec-2025.7.0 → fsspec-2025.9.0}/docs/make.bat +0 -0
  26. {fsspec-2025.7.0 → fsspec-2025.9.0}/docs/source/_static/custom.css +0 -0
  27. {fsspec-2025.7.0 → fsspec-2025.9.0}/docs/source/api.rst +0 -0
  28. {fsspec-2025.7.0 → fsspec-2025.9.0}/docs/source/async.rst +0 -0
  29. {fsspec-2025.7.0 → fsspec-2025.9.0}/docs/source/conf.py +0 -0
  30. {fsspec-2025.7.0 → fsspec-2025.9.0}/docs/source/copying.rst +0 -0
  31. {fsspec-2025.7.0 → fsspec-2025.9.0}/docs/source/developer.rst +0 -0
  32. {fsspec-2025.7.0 → fsspec-2025.9.0}/docs/source/features.rst +0 -0
  33. {fsspec-2025.7.0 → fsspec-2025.9.0}/docs/source/img/gui.png +0 -0
  34. {fsspec-2025.7.0 → fsspec-2025.9.0}/docs/source/index.rst +0 -0
  35. {fsspec-2025.7.0 → fsspec-2025.9.0}/docs/source/intro.rst +0 -0
  36. {fsspec-2025.7.0 → fsspec-2025.9.0}/docs/source/usage.rst +0 -0
  37. {fsspec-2025.7.0 → fsspec-2025.9.0}/fsspec/__init__.py +0 -0
  38. {fsspec-2025.7.0 → fsspec-2025.9.0}/fsspec/archive.py +0 -0
  39. {fsspec-2025.7.0 → fsspec-2025.9.0}/fsspec/asyn.py +0 -0
  40. {fsspec-2025.7.0 → fsspec-2025.9.0}/fsspec/caching.py +0 -0
  41. {fsspec-2025.7.0 → fsspec-2025.9.0}/fsspec/callbacks.py +0 -0
  42. {fsspec-2025.7.0 → fsspec-2025.9.0}/fsspec/compression.py +0 -0
  43. {fsspec-2025.7.0 → fsspec-2025.9.0}/fsspec/config.py +0 -0
  44. {fsspec-2025.7.0 → fsspec-2025.9.0}/fsspec/conftest.py +0 -0
  45. {fsspec-2025.7.0 → fsspec-2025.9.0}/fsspec/core.py +0 -0
  46. {fsspec-2025.7.0 → fsspec-2025.9.0}/fsspec/dircache.py +0 -0
  47. {fsspec-2025.7.0 → fsspec-2025.9.0}/fsspec/exceptions.py +0 -0
  48. {fsspec-2025.7.0 → fsspec-2025.9.0}/fsspec/fuse.py +0 -0
  49. {fsspec-2025.7.0 → fsspec-2025.9.0}/fsspec/generic.py +0 -0
  50. {fsspec-2025.7.0 → fsspec-2025.9.0}/fsspec/gui.py +0 -0
  51. {fsspec-2025.7.0 → fsspec-2025.9.0}/fsspec/implementations/__init__.py +0 -0
  52. {fsspec-2025.7.0 → fsspec-2025.9.0}/fsspec/implementations/arrow.py +0 -0
  53. {fsspec-2025.7.0 → fsspec-2025.9.0}/fsspec/implementations/cache_mapper.py +0 -0
  54. {fsspec-2025.7.0 → fsspec-2025.9.0}/fsspec/implementations/cache_metadata.py +0 -0
  55. {fsspec-2025.7.0 → fsspec-2025.9.0}/fsspec/implementations/dask.py +0 -0
  56. {fsspec-2025.7.0 → fsspec-2025.9.0}/fsspec/implementations/data.py +0 -0
  57. {fsspec-2025.7.0 → fsspec-2025.9.0}/fsspec/implementations/dirfs.py +0 -0
  58. {fsspec-2025.7.0 → fsspec-2025.9.0}/fsspec/implementations/ftp.py +0 -0
  59. {fsspec-2025.7.0 → fsspec-2025.9.0}/fsspec/implementations/gist.py +0 -0
  60. {fsspec-2025.7.0 → fsspec-2025.9.0}/fsspec/implementations/git.py +0 -0
  61. {fsspec-2025.7.0 → fsspec-2025.9.0}/fsspec/implementations/github.py +0 -0
  62. {fsspec-2025.7.0 → fsspec-2025.9.0}/fsspec/implementations/http_sync.py +0 -0
  63. {fsspec-2025.7.0 → fsspec-2025.9.0}/fsspec/implementations/jupyter.py +0 -0
  64. {fsspec-2025.7.0 → fsspec-2025.9.0}/fsspec/implementations/libarchive.py +0 -0
  65. {fsspec-2025.7.0 → fsspec-2025.9.0}/fsspec/implementations/local.py +0 -0
  66. {fsspec-2025.7.0 → fsspec-2025.9.0}/fsspec/implementations/memory.py +0 -0
  67. {fsspec-2025.7.0 → fsspec-2025.9.0}/fsspec/implementations/reference.py +0 -0
  68. {fsspec-2025.7.0 → fsspec-2025.9.0}/fsspec/implementations/sftp.py +0 -0
  69. {fsspec-2025.7.0 → fsspec-2025.9.0}/fsspec/implementations/smb.py +0 -0
  70. {fsspec-2025.7.0 → fsspec-2025.9.0}/fsspec/implementations/tar.py +0 -0
  71. {fsspec-2025.7.0 → fsspec-2025.9.0}/fsspec/implementations/webhdfs.py +0 -0
  72. {fsspec-2025.7.0 → fsspec-2025.9.0}/fsspec/implementations/zip.py +0 -0
  73. {fsspec-2025.7.0 → fsspec-2025.9.0}/fsspec/json.py +0 -0
  74. {fsspec-2025.7.0 → fsspec-2025.9.0}/fsspec/mapping.py +0 -0
  75. {fsspec-2025.7.0 → fsspec-2025.9.0}/fsspec/parquet.py +0 -0
  76. {fsspec-2025.7.0 → fsspec-2025.9.0}/fsspec/registry.py +0 -0
  77. {fsspec-2025.7.0 → fsspec-2025.9.0}/fsspec/spec.py +0 -0
  78. {fsspec-2025.7.0 → fsspec-2025.9.0}/fsspec/tests/abstract/__init__.py +0 -0
  79. {fsspec-2025.7.0 → fsspec-2025.9.0}/fsspec/tests/abstract/common.py +0 -0
  80. {fsspec-2025.7.0 → fsspec-2025.9.0}/fsspec/tests/abstract/copy.py +0 -0
  81. {fsspec-2025.7.0 → fsspec-2025.9.0}/fsspec/tests/abstract/get.py +0 -0
  82. {fsspec-2025.7.0 → fsspec-2025.9.0}/fsspec/tests/abstract/mv.py +0 -0
  83. {fsspec-2025.7.0 → fsspec-2025.9.0}/fsspec/tests/abstract/open.py +0 -0
  84. {fsspec-2025.7.0 → fsspec-2025.9.0}/fsspec/tests/abstract/pipe.py +0 -0
  85. {fsspec-2025.7.0 → fsspec-2025.9.0}/fsspec/tests/abstract/put.py +0 -0
  86. {fsspec-2025.7.0 → fsspec-2025.9.0}/fsspec/transaction.py +0 -0
  87. {fsspec-2025.7.0 → fsspec-2025.9.0}/fsspec/utils.py +0 -0
  88. {fsspec-2025.7.0 → fsspec-2025.9.0}/install_s3fs.sh +0 -0
  89. {fsspec-2025.7.0 → fsspec-2025.9.0}/readthedocs.yml +0 -0
  90. {fsspec-2025.7.0 → fsspec-2025.9.0}/setup.cfg +0 -0
@@ -1,45 +1,16 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: fsspec
3
- Version: 2025.7.0
3
+ Version: 2025.9.0
4
4
  Summary: File-system specification
5
5
  Project-URL: Changelog, https://filesystem-spec.readthedocs.io/en/latest/changelog.html
6
6
  Project-URL: Documentation, https://filesystem-spec.readthedocs.io/en/latest/
7
7
  Project-URL: Homepage, https://github.com/fsspec/filesystem_spec
8
8
  Maintainer-email: Martin Durant <mdurant@anaconda.com>
9
- License: BSD 3-Clause License
10
-
11
- Copyright (c) 2018, Martin Durant
12
- All rights reserved.
13
-
14
- Redistribution and use in source and binary forms, with or without
15
- modification, are permitted provided that the following conditions are met:
16
-
17
- * Redistributions of source code must retain the above copyright notice, this
18
- list of conditions and the following disclaimer.
19
-
20
- * Redistributions in binary form must reproduce the above copyright notice,
21
- this list of conditions and the following disclaimer in the documentation
22
- and/or other materials provided with the distribution.
23
-
24
- * Neither the name of the copyright holder nor the names of its
25
- contributors may be used to endorse or promote products derived from
26
- this software without specific prior written permission.
27
-
28
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
29
- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
30
- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
31
- DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
32
- FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
33
- DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
34
- SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
35
- CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
36
- OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
37
- OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
9
+ License-Expression: BSD-3-Clause
38
10
  License-File: LICENSE
39
11
  Keywords: file
40
12
  Classifier: Development Status :: 4 - Beta
41
13
  Classifier: Intended Audience :: Developers
42
- Classifier: License :: OSI Approved :: BSD License
43
14
  Classifier: Operating System :: OS Independent
44
15
  Classifier: Programming Language :: Python :: 3.9
45
16
  Classifier: Programming Language :: Python :: 3.10
@@ -1,6 +1,24 @@
1
1
  Changelog
2
2
  =========
3
3
 
4
+ 2025.9.0
5
+ --------
6
+
7
+ Enhancements
8
+
9
+ - include Last_modified info from HTTP headers to info (#1909)
10
+ - add optional semaphore to async-wrapper (#1908)
11
+
12
+ Fixes
13
+
14
+ - ensure cachingFSs show correct protocol (#1897)
15
+ - fix simplecache cat_ranges (#1892)
16
+
17
+ Other
18
+
19
+ - Style (#1894)
20
+
21
+
4
22
  2025.7.0
5
23
  --------
6
24
 
@@ -1,7 +1,14 @@
1
1
  # file generated by setuptools-scm
2
2
  # don't change, don't track in version control
3
3
 
4
- __all__ = ["__version__", "__version_tuple__", "version", "version_tuple"]
4
+ __all__ = [
5
+ "__version__",
6
+ "__version_tuple__",
7
+ "version",
8
+ "version_tuple",
9
+ "__commit_id__",
10
+ "commit_id",
11
+ ]
5
12
 
6
13
  TYPE_CHECKING = False
7
14
  if TYPE_CHECKING:
@@ -9,13 +16,19 @@ if TYPE_CHECKING:
9
16
  from typing import Union
10
17
 
11
18
  VERSION_TUPLE = Tuple[Union[int, str], ...]
19
+ COMMIT_ID = Union[str, None]
12
20
  else:
13
21
  VERSION_TUPLE = object
22
+ COMMIT_ID = object
14
23
 
15
24
  version: str
16
25
  __version__: str
17
26
  __version_tuple__: VERSION_TUPLE
18
27
  version_tuple: VERSION_TUPLE
28
+ commit_id: COMMIT_ID
29
+ __commit_id__: COMMIT_ID
19
30
 
20
- __version__ = version = '2025.7.0'
21
- __version_tuple__ = version_tuple = (2025, 7, 0)
31
+ __version__ = version = '2025.9.0'
32
+ __version_tuple__ = version_tuple = (2025, 9, 0)
33
+
34
+ __commit_id__ = commit_id = None
@@ -6,7 +6,7 @@ import fsspec
6
6
  from fsspec.asyn import AsyncFileSystem, running_async
7
7
 
8
8
 
9
- def async_wrapper(func, obj=None):
9
+ def async_wrapper(func, obj=None, semaphore=None):
10
10
  """
11
11
  Wraps a synchronous function to make it awaitable.
12
12
 
@@ -16,6 +16,8 @@ def async_wrapper(func, obj=None):
16
16
  The synchronous function to wrap.
17
17
  obj : object, optional
18
18
  The instance to bind the function to, if applicable.
19
+ semaphore : asyncio.Semaphore, optional
20
+ A semaphore to limit concurrent calls.
19
21
 
20
22
  Returns
21
23
  -------
@@ -25,6 +27,9 @@ def async_wrapper(func, obj=None):
25
27
 
26
28
  @functools.wraps(func)
27
29
  async def wrapper(*args, **kwargs):
30
+ if semaphore:
31
+ async with semaphore:
32
+ return await asyncio.to_thread(func, *args, **kwargs)
28
33
  return await asyncio.to_thread(func, *args, **kwargs)
29
34
 
30
35
  return wrapper
@@ -52,6 +57,8 @@ class AsyncFileSystemWrapper(AsyncFileSystem):
52
57
  asynchronous=None,
53
58
  target_protocol=None,
54
59
  target_options=None,
60
+ semaphore=None,
61
+ max_concurrent_tasks=None,
55
62
  **kwargs,
56
63
  ):
57
64
  if asynchronous is None:
@@ -62,6 +69,7 @@ class AsyncFileSystemWrapper(AsyncFileSystem):
62
69
  else:
63
70
  self.sync_fs = fsspec.filesystem(target_protocol, **target_options)
64
71
  self.protocol = self.sync_fs.protocol
72
+ self.semaphore = semaphore
65
73
  self._wrap_all_sync_methods()
66
74
 
67
75
  @property
@@ -83,7 +91,7 @@ class AsyncFileSystemWrapper(AsyncFileSystem):
83
91
 
84
92
  method = getattr(self.sync_fs, method_name)
85
93
  if callable(method) and not inspect.iscoroutinefunction(method):
86
- async_method = async_wrapper(method, obj=self)
94
+ async_method = async_wrapper(method, obj=self, semaphore=self.semaphore)
87
95
  setattr(self, f"_{method_name}", async_method)
88
96
 
89
97
  @classmethod
@@ -478,7 +478,7 @@ class CachingFileSystem(AbstractFileSystem):
478
478
  if item in ["transaction"]:
479
479
  # property
480
480
  return type(self).transaction.__get__(self)
481
- if item in ["_cache", "transaction_type"]:
481
+ if item in {"_cache", "transaction_type", "protocol"}:
482
482
  # class attributes
483
483
  return getattr(type(self), item)
484
484
  if item == "__class__":
@@ -886,6 +886,7 @@ class SimpleCacheFileSystem(WholeFileCacheFileSystem):
886
886
  rpaths = [p for l, p in zip(lpaths, paths) if l is False]
887
887
  lpaths = [l for l, p in zip(lpaths, paths) if l is False]
888
888
  self.fs.get(rpaths, lpaths)
889
+ paths = [self._check_file(p) for p in paths]
889
890
  return LocalFileSystem().cat_ranges(
890
891
  paths, starts, ends, max_gap=max_gap, on_error=on_error, **kwargs
891
892
  )
@@ -1,9 +1,11 @@
1
+ from __future__ import annotations
2
+
1
3
  import base64
2
4
  import urllib
3
5
 
4
6
  import requests
5
- import requests.exceptions
6
7
  from requests.adapters import HTTPAdapter, Retry
8
+ from typing_extensions import override
7
9
 
8
10
  from fsspec import AbstractFileSystem
9
11
  from fsspec.spec import AbstractBufferedFile
@@ -57,6 +59,24 @@ class DatabricksFileSystem(AbstractFileSystem):
57
59
 
58
60
  super().__init__(**kwargs)
59
61
 
62
+ @override
63
+ def _ls_from_cache(self, path) -> list[dict[str, str | int]] | None:
64
+ """Check cache for listing
65
+
66
+ Returns listing, if found (may be empty list for a directory that
67
+ exists but contains nothing), None if not in cache.
68
+ """
69
+ self.dircache.pop(path.rstrip("/"), None)
70
+
71
+ parent = self._parent(path)
72
+ if parent in self.dircache:
73
+ for entry in self.dircache[parent]:
74
+ if entry["name"] == path.rstrip("/"):
75
+ if entry["type"] != "directory":
76
+ return [entry]
77
+ return []
78
+ raise FileNotFoundError(path)
79
+
60
80
  def ls(self, path, detail=True, **kwargs):
61
81
  """
62
82
  List the contents of the given path.
@@ -70,7 +90,15 @@ class DatabricksFileSystem(AbstractFileSystem):
70
90
  but also additional information on file sizes
71
91
  and types.
72
92
  """
73
- out = self._ls_from_cache(path)
93
+ try:
94
+ out = self._ls_from_cache(path)
95
+ except FileNotFoundError:
96
+ # This happens if the `path`'s parent was cached, but `path` is not
97
+ # there. This suggests that `path` is new since the parent was
98
+ # cached. Attempt to invalidate parent's cache before continuing.
99
+ self.dircache.pop(self._parent(path), None)
100
+ out = None
101
+
74
102
  if not out:
75
103
  try:
76
104
  r = self._send_to_api(
@@ -460,7 +488,7 @@ class DatabricksFile(AbstractBufferedFile):
460
488
  return return_buffer
461
489
 
462
490
  def _to_sized_blocks(self, length, start=0):
463
- """Helper function to split a range from 0 to total_length into bloksizes"""
491
+ """Helper function to split a range from 0 to total_length into blocksizes"""
464
492
  end = start + length
465
493
  for data_chunk in range(start, end, self.blocksize):
466
494
  data_start = data_chunk
@@ -873,7 +873,7 @@ async def _file_info(url, session, size_policy="head", **kwargs):
873
873
 
874
874
  info["url"] = str(r.url)
875
875
 
876
- for checksum_field in ["ETag", "Content-MD5", "Digest"]:
876
+ for checksum_field in ["ETag", "Content-MD5", "Digest", "Last-Modified"]:
877
877
  if r.headers.get(checksum_field):
878
878
  info[checksum_field] = r.headers[checksum_field]
879
879
 
@@ -1,5 +1,5 @@
1
1
  [build-system]
2
- requires = ["hatchling", "hatch-vcs"]
2
+ requires = ["hatchling>=1.27.0", "hatch-vcs"]
3
3
  build-backend = "hatchling.build"
4
4
 
5
5
  [project]
@@ -7,14 +7,14 @@ name = "fsspec"
7
7
  dynamic = ["version"]
8
8
  description = "File-system specification"
9
9
  readme = "README.md"
10
- license = { file = "LICENSE" }
10
+ license = "BSD-3-Clause"
11
+ license-files = ["LICENSE"]
11
12
  requires-python = ">=3.9"
12
13
  maintainers = [{ name = "Martin Durant", email = "mdurant@anaconda.com" }]
13
14
  keywords = ["file"]
14
15
  classifiers = [
15
16
  "Development Status :: 4 - Beta",
16
17
  "Intended Audience :: Developers",
17
- "License :: OSI Approved :: BSD License",
18
18
  "Operating System :: OS Independent",
19
19
  "Programming Language :: Python :: 3.9",
20
20
  "Programming Language :: Python :: 3.10",
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes