fsspec 2025.9.0__tar.gz → 2025.10.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.
- {fsspec-2025.9.0 → fsspec-2025.10.0}/PKG-INFO +1 -1
- {fsspec-2025.9.0 → fsspec-2025.10.0}/docs/source/api.rst +61 -61
- {fsspec-2025.9.0 → fsspec-2025.10.0}/docs/source/changelog.rst +27 -0
- fsspec-2025.10.0/docs/source/code-of-conduct.rst +126 -0
- {fsspec-2025.9.0 → fsspec-2025.10.0}/docs/source/features.rst +3 -1
- {fsspec-2025.9.0 → fsspec-2025.10.0}/docs/source/index.rst +5 -0
- {fsspec-2025.9.0 → fsspec-2025.10.0}/fsspec/_version.py +2 -2
- fsspec-2025.10.0/fsspec/conftest.py +125 -0
- {fsspec-2025.9.0 → fsspec-2025.10.0}/fsspec/core.py +2 -2
- {fsspec-2025.9.0 → fsspec-2025.10.0}/fsspec/generic.py +2 -0
- {fsspec-2025.9.0 → fsspec-2025.10.0}/fsspec/implementations/arrow.py +7 -4
- {fsspec-2025.9.0 → fsspec-2025.10.0}/fsspec/implementations/cached.py +7 -3
- fsspec-2025.10.0/fsspec/implementations/chained.py +23 -0
- {fsspec-2025.9.0 → fsspec-2025.10.0}/fsspec/implementations/gist.py +25 -16
- {fsspec-2025.9.0 → fsspec-2025.10.0}/fsspec/implementations/http.py +1 -0
- {fsspec-2025.9.0 → fsspec-2025.10.0}/fsspec/implementations/jupyter.py +7 -2
- {fsspec-2025.9.0 → fsspec-2025.10.0}/fsspec/implementations/memory.py +4 -4
- {fsspec-2025.9.0 → fsspec-2025.10.0}/fsspec/implementations/reference.py +14 -8
- {fsspec-2025.9.0 → fsspec-2025.10.0}/fsspec/implementations/sftp.py +7 -0
- {fsspec-2025.9.0 → fsspec-2025.10.0}/fsspec/implementations/webhdfs.py +1 -1
- {fsspec-2025.9.0 → fsspec-2025.10.0}/fsspec/spec.py +17 -6
- {fsspec-2025.9.0 → fsspec-2025.10.0}/fsspec/utils.py +8 -0
- fsspec-2025.9.0/fsspec/conftest.py +0 -55
- {fsspec-2025.9.0 → fsspec-2025.10.0}/.codespellrc +0 -0
- {fsspec-2025.9.0 → fsspec-2025.10.0}/.coveragerc +0 -0
- {fsspec-2025.9.0 → fsspec-2025.10.0}/.gitattributes +0 -0
- {fsspec-2025.9.0 → fsspec-2025.10.0}/.github/workflows/main.yaml +0 -0
- {fsspec-2025.9.0 → fsspec-2025.10.0}/.github/workflows/pypipublish.yaml +0 -0
- {fsspec-2025.9.0 → fsspec-2025.10.0}/.gitignore +0 -0
- {fsspec-2025.9.0 → fsspec-2025.10.0}/.pre-commit-config.yaml +0 -0
- {fsspec-2025.9.0 → fsspec-2025.10.0}/LICENSE +0 -0
- {fsspec-2025.9.0 → fsspec-2025.10.0}/README.md +0 -0
- {fsspec-2025.9.0 → fsspec-2025.10.0}/ci/environment-downstream.yml +0 -0
- {fsspec-2025.9.0 → fsspec-2025.10.0}/ci/environment-friends.yml +0 -0
- {fsspec-2025.9.0 → fsspec-2025.10.0}/ci/environment-linux.yml +0 -0
- {fsspec-2025.9.0 → fsspec-2025.10.0}/ci/environment-win.yml +0 -0
- {fsspec-2025.9.0 → fsspec-2025.10.0}/docs/Makefile +0 -0
- {fsspec-2025.9.0 → fsspec-2025.10.0}/docs/README.md +0 -0
- {fsspec-2025.9.0 → fsspec-2025.10.0}/docs/environment.yml +0 -0
- {fsspec-2025.9.0 → fsspec-2025.10.0}/docs/make.bat +0 -0
- {fsspec-2025.9.0 → fsspec-2025.10.0}/docs/source/_static/custom.css +0 -0
- {fsspec-2025.9.0 → fsspec-2025.10.0}/docs/source/async.rst +0 -0
- {fsspec-2025.9.0 → fsspec-2025.10.0}/docs/source/conf.py +0 -0
- {fsspec-2025.9.0 → fsspec-2025.10.0}/docs/source/copying.rst +0 -0
- {fsspec-2025.9.0 → fsspec-2025.10.0}/docs/source/developer.rst +0 -0
- {fsspec-2025.9.0 → fsspec-2025.10.0}/docs/source/img/gui.png +0 -0
- {fsspec-2025.9.0 → fsspec-2025.10.0}/docs/source/intro.rst +0 -0
- {fsspec-2025.9.0 → fsspec-2025.10.0}/docs/source/usage.rst +0 -0
- {fsspec-2025.9.0 → fsspec-2025.10.0}/fsspec/__init__.py +0 -0
- {fsspec-2025.9.0 → fsspec-2025.10.0}/fsspec/archive.py +0 -0
- {fsspec-2025.9.0 → fsspec-2025.10.0}/fsspec/asyn.py +0 -0
- {fsspec-2025.9.0 → fsspec-2025.10.0}/fsspec/caching.py +0 -0
- {fsspec-2025.9.0 → fsspec-2025.10.0}/fsspec/callbacks.py +0 -0
- {fsspec-2025.9.0 → fsspec-2025.10.0}/fsspec/compression.py +0 -0
- {fsspec-2025.9.0 → fsspec-2025.10.0}/fsspec/config.py +0 -0
- {fsspec-2025.9.0 → fsspec-2025.10.0}/fsspec/dircache.py +0 -0
- {fsspec-2025.9.0 → fsspec-2025.10.0}/fsspec/exceptions.py +0 -0
- {fsspec-2025.9.0 → fsspec-2025.10.0}/fsspec/fuse.py +0 -0
- {fsspec-2025.9.0 → fsspec-2025.10.0}/fsspec/gui.py +0 -0
- {fsspec-2025.9.0 → fsspec-2025.10.0}/fsspec/implementations/__init__.py +0 -0
- {fsspec-2025.9.0 → fsspec-2025.10.0}/fsspec/implementations/asyn_wrapper.py +0 -0
- {fsspec-2025.9.0 → fsspec-2025.10.0}/fsspec/implementations/cache_mapper.py +0 -0
- {fsspec-2025.9.0 → fsspec-2025.10.0}/fsspec/implementations/cache_metadata.py +0 -0
- {fsspec-2025.9.0 → fsspec-2025.10.0}/fsspec/implementations/dask.py +0 -0
- {fsspec-2025.9.0 → fsspec-2025.10.0}/fsspec/implementations/data.py +0 -0
- {fsspec-2025.9.0 → fsspec-2025.10.0}/fsspec/implementations/dbfs.py +0 -0
- {fsspec-2025.9.0 → fsspec-2025.10.0}/fsspec/implementations/dirfs.py +0 -0
- {fsspec-2025.9.0 → fsspec-2025.10.0}/fsspec/implementations/ftp.py +0 -0
- {fsspec-2025.9.0 → fsspec-2025.10.0}/fsspec/implementations/git.py +0 -0
- {fsspec-2025.9.0 → fsspec-2025.10.0}/fsspec/implementations/github.py +0 -0
- {fsspec-2025.9.0 → fsspec-2025.10.0}/fsspec/implementations/http_sync.py +0 -0
- {fsspec-2025.9.0 → fsspec-2025.10.0}/fsspec/implementations/libarchive.py +0 -0
- {fsspec-2025.9.0 → fsspec-2025.10.0}/fsspec/implementations/local.py +0 -0
- {fsspec-2025.9.0 → fsspec-2025.10.0}/fsspec/implementations/smb.py +0 -0
- {fsspec-2025.9.0 → fsspec-2025.10.0}/fsspec/implementations/tar.py +0 -0
- {fsspec-2025.9.0 → fsspec-2025.10.0}/fsspec/implementations/zip.py +0 -0
- {fsspec-2025.9.0 → fsspec-2025.10.0}/fsspec/json.py +0 -0
- {fsspec-2025.9.0 → fsspec-2025.10.0}/fsspec/mapping.py +0 -0
- {fsspec-2025.9.0 → fsspec-2025.10.0}/fsspec/parquet.py +0 -0
- {fsspec-2025.9.0 → fsspec-2025.10.0}/fsspec/registry.py +0 -0
- {fsspec-2025.9.0 → fsspec-2025.10.0}/fsspec/tests/abstract/__init__.py +0 -0
- {fsspec-2025.9.0 → fsspec-2025.10.0}/fsspec/tests/abstract/common.py +0 -0
- {fsspec-2025.9.0 → fsspec-2025.10.0}/fsspec/tests/abstract/copy.py +0 -0
- {fsspec-2025.9.0 → fsspec-2025.10.0}/fsspec/tests/abstract/get.py +0 -0
- {fsspec-2025.9.0 → fsspec-2025.10.0}/fsspec/tests/abstract/mv.py +0 -0
- {fsspec-2025.9.0 → fsspec-2025.10.0}/fsspec/tests/abstract/open.py +0 -0
- {fsspec-2025.9.0 → fsspec-2025.10.0}/fsspec/tests/abstract/pipe.py +0 -0
- {fsspec-2025.9.0 → fsspec-2025.10.0}/fsspec/tests/abstract/put.py +0 -0
- {fsspec-2025.9.0 → fsspec-2025.10.0}/fsspec/transaction.py +0 -0
- {fsspec-2025.9.0 → fsspec-2025.10.0}/install_s3fs.sh +0 -0
- {fsspec-2025.9.0 → fsspec-2025.10.0}/pyproject.toml +0 -0
- {fsspec-2025.9.0 → fsspec-2025.10.0}/readthedocs.yml +0 -0
- {fsspec-2025.9.0 → fsspec-2025.10.0}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: fsspec
|
|
3
|
-
Version: 2025.
|
|
3
|
+
Version: 2025.10.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,17 +7,17 @@ User Functions
|
|
|
7
7
|
--------------
|
|
8
8
|
|
|
9
9
|
.. autosummary::
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
10
|
+
available_compressions
|
|
11
|
+
available_protocols
|
|
12
|
+
filesystem
|
|
13
|
+
fuse.run
|
|
14
|
+
generic.rsync
|
|
15
|
+
get_filesystem_class
|
|
16
|
+
get_mapper
|
|
17
|
+
gui.FileSelector
|
|
18
|
+
open
|
|
19
|
+
open_files
|
|
20
|
+
open_local
|
|
21
21
|
|
|
22
22
|
.. autofunction:: fsspec.available_compressions
|
|
23
23
|
.. autofunction:: fsspec.available_protocols
|
|
@@ -36,24 +36,24 @@ Base Classes
|
|
|
36
36
|
------------
|
|
37
37
|
|
|
38
38
|
.. autosummary::
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
39
|
+
archive.AbstractArchiveFileSystem
|
|
40
|
+
asyn.AsyncFileSystem
|
|
41
|
+
callbacks.Callback
|
|
42
|
+
callbacks.DotPrinterCallback
|
|
43
|
+
callbacks.NoOpCallback
|
|
44
|
+
callbacks.TqdmCallback
|
|
45
|
+
core.BaseCache
|
|
46
|
+
core.OpenFile
|
|
47
|
+
core.OpenFiles
|
|
48
|
+
core.get_fs_token_paths
|
|
49
|
+
core.url_to_fs
|
|
50
|
+
dircache.DirCache
|
|
51
|
+
FSMap
|
|
52
|
+
generic.GenericFileSystem
|
|
53
|
+
registry.register_implementation
|
|
54
|
+
spec.AbstractBufferedFile
|
|
55
|
+
spec.AbstractFileSystem
|
|
56
|
+
spec.Transaction
|
|
57
57
|
|
|
58
58
|
.. autoclass:: fsspec.archive.AbstractArchiveFileSystem
|
|
59
59
|
:members:
|
|
@@ -107,31 +107,31 @@ Built-in Implementations
|
|
|
107
107
|
------------------------
|
|
108
108
|
|
|
109
109
|
.. autosummary::
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
110
|
+
implementations.arrow.ArrowFSWrapper
|
|
111
|
+
implementations.arrow.HadoopFileSystem
|
|
112
|
+
implementations.cached.CachingFileSystem
|
|
113
|
+
implementations.cached.SimpleCacheFileSystem
|
|
114
|
+
implementations.cached.WholeFileCacheFileSystem
|
|
115
|
+
implementations.dask.DaskWorkerFileSystem
|
|
116
|
+
implementations.data.DataFileSystem
|
|
117
|
+
implementations.dbfs.DatabricksFileSystem
|
|
118
|
+
implementations.dirfs.DirFileSystem
|
|
119
|
+
implementations.ftp.FTPFileSystem
|
|
120
|
+
implementations.gist.GistFileSystem
|
|
121
|
+
implementations.git.GitFileSystem
|
|
122
|
+
implementations.github.GithubFileSystem
|
|
123
|
+
implementations.http.HTTPFileSystem
|
|
124
|
+
implementations.jupyter.JupyterFileSystem
|
|
125
|
+
implementations.libarchive.LibArchiveFileSystem
|
|
126
|
+
implementations.local.LocalFileSystem
|
|
127
|
+
implementations.memory.MemoryFileSystem
|
|
128
|
+
implementations.reference.ReferenceFileSystem
|
|
129
|
+
implementations.reference.LazyReferenceMapper
|
|
130
|
+
implementations.sftp.SFTPFileSystem
|
|
131
|
+
implementations.smb.SMBFileSystem
|
|
132
|
+
implementations.tar.TarFileSystem
|
|
133
|
+
implementations.webhdfs.WebHDFS
|
|
134
|
+
implementations.zip.ZipFileSystem
|
|
135
135
|
|
|
136
136
|
.. autoclass:: fsspec.implementations.arrow.ArrowFSWrapper
|
|
137
137
|
:members: __init__
|
|
@@ -296,12 +296,12 @@ Read Buffering
|
|
|
296
296
|
--------------
|
|
297
297
|
|
|
298
298
|
.. autosummary::
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
299
|
+
caching.BlockCache
|
|
300
|
+
caching.BytesCache
|
|
301
|
+
caching.MMapCache
|
|
302
|
+
caching.ReadAheadCache
|
|
303
|
+
caching.FirstChunkCache
|
|
304
|
+
caching.BackgroundBlockCache
|
|
305
305
|
|
|
306
306
|
.. autoclass:: fsspec.caching.BlockCache
|
|
307
307
|
:members:
|
|
@@ -326,7 +326,7 @@ Utilities
|
|
|
326
326
|
|
|
327
327
|
.. autosummary::
|
|
328
328
|
|
|
329
|
-
|
|
329
|
+
utils.read_block
|
|
330
330
|
|
|
331
331
|
.. autofunction:: fsspec.utils.read_block
|
|
332
332
|
|
|
@@ -1,6 +1,33 @@
|
|
|
1
1
|
Changelog
|
|
2
2
|
=========
|
|
3
3
|
|
|
4
|
+
2025.10.0
|
|
5
|
+
---------
|
|
6
|
+
|
|
7
|
+
Enhancements
|
|
8
|
+
|
|
9
|
+
- specify storage_options not use use for tokenising; test instance cache (#1933)
|
|
10
|
+
- base class "chained" for FSs that pass through operations (#1929)
|
|
11
|
+
|
|
12
|
+
Fixes
|
|
13
|
+
|
|
14
|
+
- strip protocol for sftp (#1940)
|
|
15
|
+
- use one-step mv in jupyterfs (#1937)
|
|
16
|
+
- raise errors in jupyterfs, not return (#1936)
|
|
17
|
+
- add protocol attribute to http(#1935)
|
|
18
|
+
- allow ls() on a single file for arrowFS (#1931)
|
|
19
|
+
- support kwargs in webhdfs ls() (#1928)
|
|
20
|
+
- better discrimination for parquet in referenceFS (#1923)
|
|
21
|
+
- accept all mode= types in memoryFS (#1922)
|
|
22
|
+
- pass path list to put() in localtempfile for efficiency (#1920)
|
|
23
|
+
- fix docs errors (#1917)
|
|
24
|
+
|
|
25
|
+
Other
|
|
26
|
+
|
|
27
|
+
- add CoC (#1924)
|
|
28
|
+
- restrict github/gist tests because of rate limiting (#1918)
|
|
29
|
+
|
|
30
|
+
|
|
4
31
|
2025.9.0
|
|
5
32
|
--------
|
|
6
33
|
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
Code of Conduct
|
|
2
|
+
===============
|
|
3
|
+
|
|
4
|
+
All participants in the fsspec community are expected to adhere to a Code of Conduct.
|
|
5
|
+
|
|
6
|
+
As contributors and maintainers of this project, and in the interest of
|
|
7
|
+
fostering an open and welcoming community, we pledge to respect all people who
|
|
8
|
+
contribute through reporting issues, posting feature requests, updating
|
|
9
|
+
documentation, submitting pull requests or patches, and other activities.
|
|
10
|
+
|
|
11
|
+
We are committed to making participation in this project a harassment-free
|
|
12
|
+
experience for everyone, treating everyone as unique humans deserving of
|
|
13
|
+
respect.
|
|
14
|
+
|
|
15
|
+
Examples of unacceptable behaviour by participants include:
|
|
16
|
+
|
|
17
|
+
- The use of sexualized language or imagery
|
|
18
|
+
- Personal attacks
|
|
19
|
+
- Trolling or insulting/derogatory comments
|
|
20
|
+
- Public or private harassment
|
|
21
|
+
- Publishing other's private information, such as physical or electronic
|
|
22
|
+
addresses, without explicit permission
|
|
23
|
+
- Other unethical or unprofessional conduct
|
|
24
|
+
|
|
25
|
+
Project maintainers have the right and responsibility to remove, edit, or
|
|
26
|
+
reject comments, commits, code, wiki edits, issues, and other contributions
|
|
27
|
+
that are not aligned to this Code of Conduct, or to ban temporarily or
|
|
28
|
+
permanently any contributor for other behaviours that they deem inappropriate,
|
|
29
|
+
threatening, offensive, or harmful.
|
|
30
|
+
|
|
31
|
+
By adopting this Code of Conduct, project maintainers commit themselves
|
|
32
|
+
to fairly and consistently applying these principles to every aspect of
|
|
33
|
+
managing this project. Project maintainers who do not follow or enforce
|
|
34
|
+
the Code of Conduct may be permanently removed from the project team.
|
|
35
|
+
|
|
36
|
+
This code of conduct applies both within project spaces and in public
|
|
37
|
+
spaces when an individual is representing the project or its community.
|
|
38
|
+
|
|
39
|
+
If you feel the code of conduct has been violated, please report the
|
|
40
|
+
incident to the fsspec core team.
|
|
41
|
+
|
|
42
|
+
Reporting
|
|
43
|
+
---------
|
|
44
|
+
|
|
45
|
+
If you believe someone is violating theCode of Conduct we ask that you report it
|
|
46
|
+
to the Project by emailing community@anaconda.com. All reports will be kept
|
|
47
|
+
confidential. In some cases we may determine that a public statement will need
|
|
48
|
+
to be made. If that's the case, the identities of all victims and reporters
|
|
49
|
+
will remain confidential unless those individuals instruct us otherwise.
|
|
50
|
+
If you believe anyone is in physical danger, please notify appropriate law
|
|
51
|
+
enforcement first.
|
|
52
|
+
|
|
53
|
+
In your report please include:
|
|
54
|
+
|
|
55
|
+
- Your contact info
|
|
56
|
+
- Names (real, nicknames, or pseudonyms) of any individuals involved.
|
|
57
|
+
If there were other witnesses besides you, please try to include them as well.
|
|
58
|
+
- When and where the incident occurred. Please be as specific as possible.
|
|
59
|
+
- Your account of what occurred. If there is a publicly available record
|
|
60
|
+
please include a link.
|
|
61
|
+
- Any extra context you believe existed for the incident.
|
|
62
|
+
- If you believe this incident is ongoing.
|
|
63
|
+
- If you believe any member of the core team has a conflict of interest
|
|
64
|
+
in adjudicating the incident.
|
|
65
|
+
- What, if any, corrective response you believe would be appropriate.
|
|
66
|
+
- Any other information you believe we should have.
|
|
67
|
+
|
|
68
|
+
Core team members are obligated to maintain confidentiality with regard
|
|
69
|
+
to the reporter and details of an incident.
|
|
70
|
+
|
|
71
|
+
What happens next?
|
|
72
|
+
~~~~~~~~~~~~~~~~~~
|
|
73
|
+
|
|
74
|
+
You will receive an email acknowledging receipt of your complaint.
|
|
75
|
+
The core team will immediately meet to review the incident and determine:
|
|
76
|
+
|
|
77
|
+
- What happened.
|
|
78
|
+
- Whether this event constitutes a code of conduct violation.
|
|
79
|
+
- Who the bad actor was.
|
|
80
|
+
- Whether this is an ongoing situation, or if there is a threat to anyone's
|
|
81
|
+
physical safety.
|
|
82
|
+
- If this is determined to be an ongoing incident or a threat to physical safety,
|
|
83
|
+
the working groups' immediate priority will be to protect everyone involved.
|
|
84
|
+
|
|
85
|
+
If a member of the core team is one of the named parties, they will not be
|
|
86
|
+
included in any discussions, and will not be provided with any confidential
|
|
87
|
+
details from the reporter.
|
|
88
|
+
|
|
89
|
+
If anyone on the core team believes they have a conflict of interest in
|
|
90
|
+
adjudicating on a reported issue, they will inform the other core team
|
|
91
|
+
members, and exempt themselves from any discussion about the issue.
|
|
92
|
+
Following this declaration, they will not be provided with any confidential
|
|
93
|
+
details from the reporter.
|
|
94
|
+
|
|
95
|
+
Once the working group has a complete account of the events they will make a
|
|
96
|
+
decision as to how to response. Responses may include:
|
|
97
|
+
|
|
98
|
+
- Nothing (if we determine no violation occurred).
|
|
99
|
+
- A private reprimand from the working group to the individual(s) involved.
|
|
100
|
+
- A public reprimand.
|
|
101
|
+
- An imposed vacation
|
|
102
|
+
- A permanent or temporary ban from some or all spaces (GitHub repositories, etc.)
|
|
103
|
+
- A request for a public or private apology.
|
|
104
|
+
|
|
105
|
+
We'll respond within one week to the person who filed the report with either a
|
|
106
|
+
resolution or an explanation of why the situation is not yet resolved.
|
|
107
|
+
|
|
108
|
+
Once we've determined our final action, we'll contact the original reporter
|
|
109
|
+
to let them know what action (if any) we'll be taking. We'll take into account
|
|
110
|
+
feedback from the reporter on the appropriateness of our response, but we
|
|
111
|
+
don't guarantee we'll act on it.
|
|
112
|
+
|
|
113
|
+
Acknowledgement
|
|
114
|
+
---------------
|
|
115
|
+
|
|
116
|
+
This CoC is modified from the one by `BeeWare`_, which in turn refers to
|
|
117
|
+
the `Contributor Covenant`_ and the `Django`_ project.
|
|
118
|
+
|
|
119
|
+
.. _BeeWare: https://beeware.org/community/behavior/code-of-conduct/
|
|
120
|
+
.. _Contributor Covenant: https://www.contributor-covenant.org/version/1/3/0/code-of-conduct/
|
|
121
|
+
.. _Django: https://www.djangoproject.com/conduct/reporting/
|
|
122
|
+
|
|
123
|
+
.. raw:: html
|
|
124
|
+
|
|
125
|
+
<script data-goatcounter="https://projspec.goatcounter.com/count"
|
|
126
|
+
async src="//gc.zgo.at/count.js"></script>
|
|
@@ -241,7 +241,9 @@ reads the same zip-file, but extracts the CSV files and stores them locally in t
|
|
|
241
241
|
**For developers**: this "chaining" methods works by formatting the arguments passed to ``open_*``
|
|
242
242
|
into ``target_protocol`` (a simple string) and ``target_options`` (a dict) and also optionally
|
|
243
243
|
``fo`` (target path, if a specific file is required). In order for an implementation to chain
|
|
244
|
-
successfully like this, it must look for exactly those named arguments.
|
|
244
|
+
successfully like this, it must look for exactly those named arguments. Implementations that
|
|
245
|
+
require access to the target path of their nested targets should inherit from ``ChainedFileSystem``,
|
|
246
|
+
which will trigger pass-through of the nested path automatically.
|
|
245
247
|
|
|
246
248
|
Caching Files Locally
|
|
247
249
|
---------------------
|
|
@@ -119,6 +119,11 @@ The current list of known implementations can be found as follows
|
|
|
119
119
|
async.rst
|
|
120
120
|
api.rst
|
|
121
121
|
changelog.rst
|
|
122
|
+
code-of-conduct.rst
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
These docs pages collect anonymous tracking data using goatcounter, and the
|
|
126
|
+
dashboard is available to the public: https://fsspec.goatcounter.com/ .
|
|
122
127
|
|
|
123
128
|
.. raw:: html
|
|
124
129
|
|
|
@@ -28,7 +28,7 @@ version_tuple: VERSION_TUPLE
|
|
|
28
28
|
commit_id: COMMIT_ID
|
|
29
29
|
__commit_id__: COMMIT_ID
|
|
30
30
|
|
|
31
|
-
__version__ = version = '2025.
|
|
32
|
-
__version_tuple__ = version_tuple = (2025,
|
|
31
|
+
__version__ = version = '2025.10.0'
|
|
32
|
+
__version_tuple__ = version_tuple = (2025, 10, 0)
|
|
33
33
|
|
|
34
34
|
__commit_id__ = commit_id = None
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import shutil
|
|
3
|
+
import subprocess
|
|
4
|
+
import sys
|
|
5
|
+
import time
|
|
6
|
+
from collections import deque
|
|
7
|
+
from collections.abc import Generator, Sequence
|
|
8
|
+
|
|
9
|
+
import pytest
|
|
10
|
+
|
|
11
|
+
import fsspec
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
@pytest.fixture()
|
|
15
|
+
def m():
|
|
16
|
+
"""
|
|
17
|
+
Fixture providing a memory filesystem.
|
|
18
|
+
"""
|
|
19
|
+
m = fsspec.filesystem("memory")
|
|
20
|
+
m.store.clear()
|
|
21
|
+
m.pseudo_dirs.clear()
|
|
22
|
+
m.pseudo_dirs.append("")
|
|
23
|
+
try:
|
|
24
|
+
yield m
|
|
25
|
+
finally:
|
|
26
|
+
m.store.clear()
|
|
27
|
+
m.pseudo_dirs.clear()
|
|
28
|
+
m.pseudo_dirs.append("")
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
class InstanceCacheInspector:
|
|
32
|
+
"""
|
|
33
|
+
Helper class to inspect instance caches of filesystem classes in tests.
|
|
34
|
+
"""
|
|
35
|
+
|
|
36
|
+
def clear(self) -> None:
|
|
37
|
+
"""
|
|
38
|
+
Clear instance caches of all currently imported filesystem classes.
|
|
39
|
+
"""
|
|
40
|
+
classes = deque([fsspec.spec.AbstractFileSystem])
|
|
41
|
+
while classes:
|
|
42
|
+
cls = classes.popleft()
|
|
43
|
+
cls.clear_instance_cache()
|
|
44
|
+
classes.extend(cls.__subclasses__())
|
|
45
|
+
|
|
46
|
+
def gather_counts(self, *, omit_zero: bool = True) -> dict[str, int]:
|
|
47
|
+
"""
|
|
48
|
+
Gather counts of filesystem instances in the instance caches
|
|
49
|
+
of all currently imported filesystem classes.
|
|
50
|
+
|
|
51
|
+
Parameters
|
|
52
|
+
----------
|
|
53
|
+
omit_zero:
|
|
54
|
+
Whether to omit instance types with no cached instances.
|
|
55
|
+
"""
|
|
56
|
+
out: dict[str, int] = {}
|
|
57
|
+
classes = deque([fsspec.spec.AbstractFileSystem])
|
|
58
|
+
while classes:
|
|
59
|
+
cls = classes.popleft()
|
|
60
|
+
count = len(cls._cache) # there is no public interface for the cache
|
|
61
|
+
# note: skip intermediate AbstractFileSystem subclasses
|
|
62
|
+
# if they proxy the protocol attribute via a property.
|
|
63
|
+
if isinstance(cls.protocol, (Sequence, str)):
|
|
64
|
+
key = cls.protocol if isinstance(cls.protocol, str) else cls.protocol[0]
|
|
65
|
+
if count or not omit_zero:
|
|
66
|
+
out[key] = count
|
|
67
|
+
classes.extend(cls.__subclasses__())
|
|
68
|
+
return out
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
@pytest.fixture(scope="function", autouse=True)
|
|
72
|
+
def instance_caches() -> Generator[InstanceCacheInspector, None, None]:
|
|
73
|
+
"""
|
|
74
|
+
Fixture to ensure empty filesystem instance caches before and after a test.
|
|
75
|
+
|
|
76
|
+
Used by default for all tests.
|
|
77
|
+
Clears caches of all imported filesystem classes.
|
|
78
|
+
Can be used to write test assertions about instance caches.
|
|
79
|
+
|
|
80
|
+
Usage:
|
|
81
|
+
|
|
82
|
+
def test_something(instance_caches):
|
|
83
|
+
# Test code here
|
|
84
|
+
fsspec.open("file://abc")
|
|
85
|
+
fsspec.open("memory://foo/bar")
|
|
86
|
+
|
|
87
|
+
# Test assertion
|
|
88
|
+
assert instance_caches.gather_counts() == {"file": 1, "memory": 1}
|
|
89
|
+
|
|
90
|
+
Returns
|
|
91
|
+
-------
|
|
92
|
+
instance_caches: An instance cache inspector for clearing and inspecting caches.
|
|
93
|
+
"""
|
|
94
|
+
ic = InstanceCacheInspector()
|
|
95
|
+
|
|
96
|
+
ic.clear()
|
|
97
|
+
try:
|
|
98
|
+
yield ic
|
|
99
|
+
finally:
|
|
100
|
+
ic.clear()
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
@pytest.fixture(scope="function")
|
|
104
|
+
def ftp_writable(tmpdir):
|
|
105
|
+
"""
|
|
106
|
+
Fixture providing a writable FTP filesystem.
|
|
107
|
+
"""
|
|
108
|
+
pytest.importorskip("pyftpdlib")
|
|
109
|
+
|
|
110
|
+
d = str(tmpdir)
|
|
111
|
+
with open(os.path.join(d, "out"), "wb") as f:
|
|
112
|
+
f.write(b"hello" * 10000)
|
|
113
|
+
P = subprocess.Popen(
|
|
114
|
+
[sys.executable, "-m", "pyftpdlib", "-d", d, "-u", "user", "-P", "pass", "-w"]
|
|
115
|
+
)
|
|
116
|
+
try:
|
|
117
|
+
time.sleep(1)
|
|
118
|
+
yield "localhost", 2121, "user", "pass"
|
|
119
|
+
finally:
|
|
120
|
+
P.terminate()
|
|
121
|
+
P.wait()
|
|
122
|
+
try:
|
|
123
|
+
shutil.rmtree(tmpdir)
|
|
124
|
+
except Exception:
|
|
125
|
+
pass
|
|
@@ -330,7 +330,7 @@ def open_files(
|
|
|
330
330
|
|
|
331
331
|
def _un_chain(path, kwargs):
|
|
332
332
|
# Avoid a circular import
|
|
333
|
-
from fsspec.implementations.
|
|
333
|
+
from fsspec.implementations.chained import ChainedFileSystem
|
|
334
334
|
|
|
335
335
|
if "::" in path:
|
|
336
336
|
x = re.compile(".*[^a-z]+.*") # test for non protocol-like single word
|
|
@@ -358,7 +358,7 @@ def _un_chain(path, kwargs):
|
|
|
358
358
|
**kws,
|
|
359
359
|
)
|
|
360
360
|
bit = cls._strip_protocol(bit)
|
|
361
|
-
if "target_protocol" not in kw and issubclass(cls,
|
|
361
|
+
if "target_protocol" not in kw and issubclass(cls, ChainedFileSystem):
|
|
362
362
|
bit = previous_bit
|
|
363
363
|
out.append((bit, protocol, kw))
|
|
364
364
|
previous_bit = bit
|
|
@@ -118,6 +118,8 @@ def rsync(
|
|
|
118
118
|
if otherfile in otherfiles:
|
|
119
119
|
if update_cond == "always":
|
|
120
120
|
allfiles[k] = otherfile
|
|
121
|
+
elif update_cond == "never":
|
|
122
|
+
allfiles.pop(k)
|
|
121
123
|
elif update_cond == "different":
|
|
122
124
|
inf1 = source_field(v) if callable(source_field) else v[source_field]
|
|
123
125
|
v2 = otherfiles[otherfile]
|
|
@@ -75,10 +75,13 @@ class ArrowFSWrapper(AbstractFileSystem):
|
|
|
75
75
|
path = self._strip_protocol(path)
|
|
76
76
|
from pyarrow.fs import FileSelector
|
|
77
77
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
78
|
+
try:
|
|
79
|
+
entries = [
|
|
80
|
+
self._make_entry(entry)
|
|
81
|
+
for entry in self.fs.get_file_info(FileSelector(path))
|
|
82
|
+
]
|
|
83
|
+
except (FileNotFoundError, NotADirectoryError):
|
|
84
|
+
entries = [self.info(path, **kwargs)]
|
|
82
85
|
if detail:
|
|
83
86
|
return entries
|
|
84
87
|
else:
|
|
@@ -9,13 +9,14 @@ import weakref
|
|
|
9
9
|
from shutil import rmtree
|
|
10
10
|
from typing import TYPE_CHECKING, Any, Callable, ClassVar
|
|
11
11
|
|
|
12
|
-
from fsspec import
|
|
12
|
+
from fsspec import filesystem
|
|
13
13
|
from fsspec.callbacks import DEFAULT_CALLBACK
|
|
14
14
|
from fsspec.compression import compr
|
|
15
15
|
from fsspec.core import BaseCache, MMapCache
|
|
16
16
|
from fsspec.exceptions import BlocksizeMismatchError
|
|
17
17
|
from fsspec.implementations.cache_mapper import create_cache_mapper
|
|
18
18
|
from fsspec.implementations.cache_metadata import CacheMetadata
|
|
19
|
+
from fsspec.implementations.chained import ChainedFileSystem
|
|
19
20
|
from fsspec.implementations.local import LocalFileSystem
|
|
20
21
|
from fsspec.spec import AbstractBufferedFile
|
|
21
22
|
from fsspec.transaction import Transaction
|
|
@@ -39,7 +40,7 @@ class WriteCachedTransaction(Transaction):
|
|
|
39
40
|
self.fs = None # break cycle
|
|
40
41
|
|
|
41
42
|
|
|
42
|
-
class CachingFileSystem(
|
|
43
|
+
class CachingFileSystem(ChainedFileSystem):
|
|
43
44
|
"""Locally caching filesystem, layer over any other FS
|
|
44
45
|
|
|
45
46
|
This class implements chunk-wise local storage of remote files, for quick
|
|
@@ -60,6 +61,7 @@ class CachingFileSystem(AbstractFileSystem):
|
|
|
60
61
|
"""
|
|
61
62
|
|
|
62
63
|
protocol: ClassVar[str | tuple[str, ...]] = ("blockcache", "cached")
|
|
64
|
+
_strip_tokenize_options = ("fo",)
|
|
63
65
|
|
|
64
66
|
def __init__(
|
|
65
67
|
self,
|
|
@@ -984,7 +986,9 @@ class LocalTempFile:
|
|
|
984
986
|
os.remove(self.fn)
|
|
985
987
|
|
|
986
988
|
def commit(self):
|
|
987
|
-
|
|
989
|
+
# calling put() with list arguments avoids path expansion and additional operations
|
|
990
|
+
# like isdir()
|
|
991
|
+
self.fs.put([self.fn], [self.path], **self.kwargs)
|
|
988
992
|
# we do not delete the local copy, it's still in the cache.
|
|
989
993
|
|
|
990
994
|
@property
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
from typing import ClassVar
|
|
2
|
+
|
|
3
|
+
from fsspec import AbstractFileSystem
|
|
4
|
+
|
|
5
|
+
__all__ = ("ChainedFileSystem",)
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class ChainedFileSystem(AbstractFileSystem):
|
|
9
|
+
"""Chained filesystem base class.
|
|
10
|
+
|
|
11
|
+
A chained filesystem is designed to be layered over another FS.
|
|
12
|
+
This is useful to implement things like caching.
|
|
13
|
+
|
|
14
|
+
This base class does very little on its own, but is used as a marker
|
|
15
|
+
that the class is designed for chaining.
|
|
16
|
+
|
|
17
|
+
Right now this is only used in `url_to_fs` to provide the path argument
|
|
18
|
+
(`fo`) to the chained filesystem from the underlying filesystem.
|
|
19
|
+
|
|
20
|
+
Additional functionality may be added in the future.
|
|
21
|
+
"""
|
|
22
|
+
|
|
23
|
+
protocol: ClassVar[str] = "chained"
|
|
@@ -14,21 +14,21 @@ class GistFileSystem(AbstractFileSystem):
|
|
|
14
14
|
|
|
15
15
|
Parameters
|
|
16
16
|
----------
|
|
17
|
-
gist_id
|
|
17
|
+
gist_id: str
|
|
18
18
|
The ID of the gist you want to access (the long hex value from the URL).
|
|
19
|
-
filenames
|
|
19
|
+
filenames: list[str] (optional)
|
|
20
20
|
If provided, only make a file system representing these files, and do not fetch
|
|
21
21
|
the list of all files for this gist.
|
|
22
|
-
sha
|
|
22
|
+
sha: str (optional)
|
|
23
23
|
If provided, fetch a particular revision of the gist. If omitted,
|
|
24
24
|
the latest revision is used.
|
|
25
|
-
username
|
|
26
|
-
GitHub username for authentication
|
|
27
|
-
token
|
|
28
|
-
GitHub personal access token (required if username is given).
|
|
29
|
-
timeout
|
|
25
|
+
username: str (optional)
|
|
26
|
+
GitHub username for authentication.
|
|
27
|
+
token: str (optional)
|
|
28
|
+
GitHub personal access token (required if username is given), or.
|
|
29
|
+
timeout: (float, float) or float, optional
|
|
30
30
|
Connect and read timeouts for requests (default 60s each).
|
|
31
|
-
kwargs
|
|
31
|
+
kwargs: dict
|
|
32
32
|
Stored on `self.request_kw` and passed to `requests.get` when fetching Gist
|
|
33
33
|
metadata or reading ("opening") a file.
|
|
34
34
|
"""
|
|
@@ -51,10 +51,8 @@ class GistFileSystem(AbstractFileSystem):
|
|
|
51
51
|
self.gist_id = gist_id
|
|
52
52
|
self.filenames = filenames
|
|
53
53
|
self.sha = sha # revision of the gist (optional)
|
|
54
|
-
if
|
|
55
|
-
|
|
56
|
-
if username or token:
|
|
57
|
-
raise ValueError("Auth requires both username and token, or neither.")
|
|
54
|
+
if username is not None and token is None:
|
|
55
|
+
raise ValueError("User auth requires a token")
|
|
58
56
|
self.username = username
|
|
59
57
|
self.token = token
|
|
60
58
|
self.request_kw = kwargs
|
|
@@ -67,9 +65,18 @@ class GistFileSystem(AbstractFileSystem):
|
|
|
67
65
|
@property
|
|
68
66
|
def kw(self):
|
|
69
67
|
"""Auth parameters passed to 'requests' if we have username/token."""
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
68
|
+
kw = {
|
|
69
|
+
"headers": {
|
|
70
|
+
"Accept": "application/vnd.github+json",
|
|
71
|
+
"X-GitHub-Api-Version": "2022-11-28",
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
kw.update(self.request_kw)
|
|
75
|
+
if self.username and self.token:
|
|
76
|
+
kw["auth"] = (self.username, self.token)
|
|
77
|
+
elif self.token:
|
|
78
|
+
kw["headers"]["Authorization"] = f"Bearer {self.token}"
|
|
79
|
+
return kw
|
|
73
80
|
|
|
74
81
|
def _fetch_gist_metadata(self):
|
|
75
82
|
"""
|
|
@@ -229,4 +236,6 @@ class GistFileSystem(AbstractFileSystem):
|
|
|
229
236
|
pass # skip
|
|
230
237
|
else:
|
|
231
238
|
out[p] = e
|
|
239
|
+
if len(paths) == 1 and paths[0] == path:
|
|
240
|
+
return out[path]
|
|
232
241
|
return out
|