fsspec 2024.5.0__tar.gz → 2024.6.1__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-2024.5.0 → fsspec-2024.6.1}/.pre-commit-config.yaml +1 -1
- {fsspec-2024.5.0 → fsspec-2024.6.1}/PKG-INFO +10 -5
- {fsspec-2024.5.0 → fsspec-2024.6.1}/README.md +3 -4
- fsspec-2024.6.1/docs/environment.yml +5 -0
- {fsspec-2024.5.0 → fsspec-2024.6.1}/docs/source/changelog.rst +34 -0
- {fsspec-2024.5.0 → fsspec-2024.6.1}/docs/source/developer.rst +2 -2
- {fsspec-2024.5.0 → fsspec-2024.6.1}/docs/source/index.rst +1 -1
- {fsspec-2024.5.0 → fsspec-2024.6.1}/fsspec/_version.py +2 -2
- {fsspec-2024.5.0 → fsspec-2024.6.1}/fsspec/caching.py +3 -2
- {fsspec-2024.5.0 → fsspec-2024.6.1}/fsspec/compression.py +1 -1
- {fsspec-2024.5.0 → fsspec-2024.6.1}/fsspec/generic.py +3 -0
- {fsspec-2024.5.0 → fsspec-2024.6.1}/fsspec/implementations/cached.py +6 -16
- {fsspec-2024.5.0 → fsspec-2024.6.1}/fsspec/implementations/dirfs.py +2 -0
- {fsspec-2024.5.0 → fsspec-2024.6.1}/fsspec/implementations/github.py +12 -0
- {fsspec-2024.5.0 → fsspec-2024.6.1}/fsspec/implementations/http.py +2 -1
- {fsspec-2024.5.0 → fsspec-2024.6.1}/fsspec/implementations/reference.py +9 -0
- {fsspec-2024.5.0 → fsspec-2024.6.1}/fsspec/implementations/smb.py +10 -0
- fsspec-2024.6.1/fsspec/json.py +121 -0
- {fsspec-2024.5.0 → fsspec-2024.6.1}/fsspec/registry.py +24 -18
- {fsspec-2024.5.0 → fsspec-2024.6.1}/fsspec/spec.py +119 -33
- {fsspec-2024.5.0 → fsspec-2024.6.1}/fsspec/utils.py +1 -1
- {fsspec-2024.5.0 → fsspec-2024.6.1}/pyproject.toml +33 -1
- {fsspec-2024.5.0 → fsspec-2024.6.1}/readthedocs.yml +2 -0
- fsspec-2024.5.0/docs/environment.yml +0 -11
- fsspec-2024.5.0/fsspec/implementations/tests/__init__.py +0 -0
- fsspec-2024.5.0/fsspec/implementations/tests/cassettes/test_dbfs/test_dbfs_file_listing.yaml +0 -112
- fsspec-2024.5.0/fsspec/implementations/tests/cassettes/test_dbfs/test_dbfs_mkdir.yaml +0 -582
- fsspec-2024.5.0/fsspec/implementations/tests/cassettes/test_dbfs/test_dbfs_read_pyarrow_non_partitioned.yaml +0 -873
- fsspec-2024.5.0/fsspec/implementations/tests/cassettes/test_dbfs/test_dbfs_read_range.yaml +0 -458
- fsspec-2024.5.0/fsspec/implementations/tests/cassettes/test_dbfs/test_dbfs_read_range_chunked.yaml +0 -1355
- fsspec-2024.5.0/fsspec/implementations/tests/cassettes/test_dbfs/test_dbfs_write_and_read.yaml +0 -795
- fsspec-2024.5.0/fsspec/implementations/tests/cassettes/test_dbfs/test_dbfs_write_pyarrow_non_partitioned.yaml +0 -613
- fsspec-2024.5.0/fsspec/implementations/tests/conftest.py +0 -39
- fsspec-2024.5.0/fsspec/implementations/tests/local/__init__.py +0 -0
- fsspec-2024.5.0/fsspec/implementations/tests/local/local_fixtures.py +0 -18
- fsspec-2024.5.0/fsspec/implementations/tests/local/local_test.py +0 -14
- fsspec-2024.5.0/fsspec/implementations/tests/memory/__init__.py +0 -0
- fsspec-2024.5.0/fsspec/implementations/tests/memory/memory_fixtures.py +0 -27
- fsspec-2024.5.0/fsspec/implementations/tests/memory/memory_test.py +0 -14
- fsspec-2024.5.0/fsspec/implementations/tests/out.zip +0 -0
- fsspec-2024.5.0/fsspec/implementations/tests/test_archive.py +0 -382
- fsspec-2024.5.0/fsspec/implementations/tests/test_arrow.py +0 -259
- fsspec-2024.5.0/fsspec/implementations/tests/test_cached.py +0 -1306
- fsspec-2024.5.0/fsspec/implementations/tests/test_common.py +0 -35
- fsspec-2024.5.0/fsspec/implementations/tests/test_dask.py +0 -29
- fsspec-2024.5.0/fsspec/implementations/tests/test_data.py +0 -20
- fsspec-2024.5.0/fsspec/implementations/tests/test_dbfs.py +0 -268
- fsspec-2024.5.0/fsspec/implementations/tests/test_dirfs.py +0 -588
- fsspec-2024.5.0/fsspec/implementations/tests/test_ftp.py +0 -178
- fsspec-2024.5.0/fsspec/implementations/tests/test_git.py +0 -76
- fsspec-2024.5.0/fsspec/implementations/tests/test_http.py +0 -577
- fsspec-2024.5.0/fsspec/implementations/tests/test_jupyter.py +0 -57
- fsspec-2024.5.0/fsspec/implementations/tests/test_libarchive.py +0 -33
- fsspec-2024.5.0/fsspec/implementations/tests/test_local.py +0 -1285
- fsspec-2024.5.0/fsspec/implementations/tests/test_memory.py +0 -382
- fsspec-2024.5.0/fsspec/implementations/tests/test_reference.py +0 -720
- fsspec-2024.5.0/fsspec/implementations/tests/test_sftp.py +0 -233
- fsspec-2024.5.0/fsspec/implementations/tests/test_smb.py +0 -139
- fsspec-2024.5.0/fsspec/implementations/tests/test_tar.py +0 -243
- fsspec-2024.5.0/fsspec/implementations/tests/test_webhdfs.py +0 -197
- fsspec-2024.5.0/fsspec/implementations/tests/test_zip.py +0 -134
- fsspec-2024.5.0/fsspec/tests/__init__.py +0 -0
- fsspec-2024.5.0/fsspec/tests/conftest.py +0 -188
- fsspec-2024.5.0/fsspec/tests/data/listing.html +0 -1
- fsspec-2024.5.0/fsspec/tests/test_api.py +0 -498
- fsspec-2024.5.0/fsspec/tests/test_async.py +0 -230
- fsspec-2024.5.0/fsspec/tests/test_caches.py +0 -255
- fsspec-2024.5.0/fsspec/tests/test_callbacks.py +0 -89
- fsspec-2024.5.0/fsspec/tests/test_compression.py +0 -164
- fsspec-2024.5.0/fsspec/tests/test_config.py +0 -129
- fsspec-2024.5.0/fsspec/tests/test_core.py +0 -466
- fsspec-2024.5.0/fsspec/tests/test_downstream.py +0 -40
- fsspec-2024.5.0/fsspec/tests/test_file.py +0 -200
- fsspec-2024.5.0/fsspec/tests/test_fuse.py +0 -147
- fsspec-2024.5.0/fsspec/tests/test_generic.py +0 -90
- fsspec-2024.5.0/fsspec/tests/test_gui.py +0 -23
- fsspec-2024.5.0/fsspec/tests/test_mapping.py +0 -228
- fsspec-2024.5.0/fsspec/tests/test_parquet.py +0 -140
- fsspec-2024.5.0/fsspec/tests/test_registry.py +0 -134
- fsspec-2024.5.0/fsspec/tests/test_spec.py +0 -1167
- fsspec-2024.5.0/fsspec/tests/test_utils.py +0 -478
- {fsspec-2024.5.0 → fsspec-2024.6.1}/.codespellrc +0 -0
- {fsspec-2024.5.0 → fsspec-2024.6.1}/.coveragerc +0 -0
- {fsspec-2024.5.0 → fsspec-2024.6.1}/.gitattributes +0 -0
- {fsspec-2024.5.0 → fsspec-2024.6.1}/.github/workflows/codespell.yml +0 -0
- {fsspec-2024.5.0 → fsspec-2024.6.1}/.github/workflows/main.yaml +0 -0
- {fsspec-2024.5.0 → fsspec-2024.6.1}/.github/workflows/pypipublish.yaml +0 -0
- {fsspec-2024.5.0 → fsspec-2024.6.1}/.gitignore +0 -0
- {fsspec-2024.5.0 → fsspec-2024.6.1}/LICENSE +0 -0
- {fsspec-2024.5.0 → fsspec-2024.6.1}/ci/environment-downstream.yml +0 -0
- {fsspec-2024.5.0 → fsspec-2024.6.1}/ci/environment-friends.yml +0 -0
- {fsspec-2024.5.0 → fsspec-2024.6.1}/ci/environment-py38.yml +0 -0
- {fsspec-2024.5.0 → fsspec-2024.6.1}/ci/environment-typecheck.yml +0 -0
- {fsspec-2024.5.0 → fsspec-2024.6.1}/ci/environment-win.yml +0 -0
- {fsspec-2024.5.0 → fsspec-2024.6.1}/docs/Makefile +0 -0
- {fsspec-2024.5.0 → fsspec-2024.6.1}/docs/README.md +0 -0
- {fsspec-2024.5.0 → fsspec-2024.6.1}/docs/make.bat +0 -0
- {fsspec-2024.5.0 → fsspec-2024.6.1}/docs/source/_static/custom.css +0 -0
- {fsspec-2024.5.0 → fsspec-2024.6.1}/docs/source/api.rst +0 -0
- {fsspec-2024.5.0 → fsspec-2024.6.1}/docs/source/async.rst +0 -0
- {fsspec-2024.5.0 → fsspec-2024.6.1}/docs/source/conf.py +0 -0
- {fsspec-2024.5.0 → fsspec-2024.6.1}/docs/source/copying.rst +0 -0
- {fsspec-2024.5.0 → fsspec-2024.6.1}/docs/source/features.rst +0 -0
- {fsspec-2024.5.0 → fsspec-2024.6.1}/docs/source/img/gui.png +0 -0
- {fsspec-2024.5.0 → fsspec-2024.6.1}/docs/source/intro.rst +0 -0
- {fsspec-2024.5.0 → fsspec-2024.6.1}/docs/source/usage.rst +0 -0
- {fsspec-2024.5.0 → fsspec-2024.6.1}/fsspec/__init__.py +0 -0
- {fsspec-2024.5.0 → fsspec-2024.6.1}/fsspec/archive.py +0 -0
- {fsspec-2024.5.0 → fsspec-2024.6.1}/fsspec/asyn.py +0 -0
- {fsspec-2024.5.0 → fsspec-2024.6.1}/fsspec/callbacks.py +0 -0
- {fsspec-2024.5.0 → fsspec-2024.6.1}/fsspec/config.py +0 -0
- {fsspec-2024.5.0 → fsspec-2024.6.1}/fsspec/conftest.py +0 -0
- {fsspec-2024.5.0 → fsspec-2024.6.1}/fsspec/core.py +0 -0
- {fsspec-2024.5.0 → fsspec-2024.6.1}/fsspec/dircache.py +0 -0
- {fsspec-2024.5.0 → fsspec-2024.6.1}/fsspec/exceptions.py +0 -0
- {fsspec-2024.5.0 → fsspec-2024.6.1}/fsspec/fuse.py +0 -0
- {fsspec-2024.5.0 → fsspec-2024.6.1}/fsspec/gui.py +0 -0
- {fsspec-2024.5.0 → fsspec-2024.6.1}/fsspec/implementations/__init__.py +0 -0
- {fsspec-2024.5.0 → fsspec-2024.6.1}/fsspec/implementations/arrow.py +0 -0
- {fsspec-2024.5.0 → fsspec-2024.6.1}/fsspec/implementations/cache_mapper.py +0 -0
- {fsspec-2024.5.0 → fsspec-2024.6.1}/fsspec/implementations/cache_metadata.py +0 -0
- {fsspec-2024.5.0 → fsspec-2024.6.1}/fsspec/implementations/dask.py +0 -0
- {fsspec-2024.5.0 → fsspec-2024.6.1}/fsspec/implementations/data.py +0 -0
- {fsspec-2024.5.0 → fsspec-2024.6.1}/fsspec/implementations/dbfs.py +0 -0
- {fsspec-2024.5.0 → fsspec-2024.6.1}/fsspec/implementations/ftp.py +0 -0
- {fsspec-2024.5.0 → fsspec-2024.6.1}/fsspec/implementations/git.py +0 -0
- {fsspec-2024.5.0 → fsspec-2024.6.1}/fsspec/implementations/jupyter.py +0 -0
- {fsspec-2024.5.0 → fsspec-2024.6.1}/fsspec/implementations/libarchive.py +0 -0
- {fsspec-2024.5.0 → fsspec-2024.6.1}/fsspec/implementations/local.py +0 -0
- {fsspec-2024.5.0 → fsspec-2024.6.1}/fsspec/implementations/memory.py +0 -0
- {fsspec-2024.5.0 → fsspec-2024.6.1}/fsspec/implementations/sftp.py +0 -0
- {fsspec-2024.5.0 → fsspec-2024.6.1}/fsspec/implementations/tar.py +0 -0
- {fsspec-2024.5.0 → fsspec-2024.6.1}/fsspec/implementations/webhdfs.py +0 -0
- {fsspec-2024.5.0 → fsspec-2024.6.1}/fsspec/implementations/zip.py +0 -0
- {fsspec-2024.5.0 → fsspec-2024.6.1}/fsspec/mapping.py +0 -0
- {fsspec-2024.5.0 → fsspec-2024.6.1}/fsspec/parquet.py +0 -0
- {fsspec-2024.5.0 → fsspec-2024.6.1}/fsspec/tests/abstract/__init__.py +0 -0
- {fsspec-2024.5.0 → fsspec-2024.6.1}/fsspec/tests/abstract/common.py +0 -0
- {fsspec-2024.5.0 → fsspec-2024.6.1}/fsspec/tests/abstract/copy.py +0 -0
- {fsspec-2024.5.0 → fsspec-2024.6.1}/fsspec/tests/abstract/get.py +0 -0
- {fsspec-2024.5.0 → fsspec-2024.6.1}/fsspec/tests/abstract/mv.py +0 -0
- {fsspec-2024.5.0 → fsspec-2024.6.1}/fsspec/tests/abstract/put.py +0 -0
- {fsspec-2024.5.0 → fsspec-2024.6.1}/fsspec/transaction.py +0 -0
- {fsspec-2024.5.0 → fsspec-2024.6.1}/install_s3fs.sh +0 -0
- {fsspec-2024.5.0 → fsspec-2024.6.1}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: fsspec
|
|
3
|
-
Version: 2024.
|
|
3
|
+
Version: 2024.6.1
|
|
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/
|
|
@@ -59,6 +59,12 @@ Requires-Dist: distributed; extra == 'dask'
|
|
|
59
59
|
Provides-Extra: dev
|
|
60
60
|
Requires-Dist: pre-commit; extra == 'dev'
|
|
61
61
|
Requires-Dist: ruff; extra == 'dev'
|
|
62
|
+
Provides-Extra: doc
|
|
63
|
+
Requires-Dist: numpydoc; extra == 'doc'
|
|
64
|
+
Requires-Dist: sphinx; extra == 'doc'
|
|
65
|
+
Requires-Dist: sphinx-design; extra == 'doc'
|
|
66
|
+
Requires-Dist: sphinx-rtd-theme; extra == 'doc'
|
|
67
|
+
Requires-Dist: yarl; extra == 'doc'
|
|
62
68
|
Provides-Extra: dropbox
|
|
63
69
|
Requires-Dist: dropbox; extra == 'dropbox'
|
|
64
70
|
Requires-Dist: dropboxdrivefs; extra == 'dropbox'
|
|
@@ -178,7 +184,6 @@ Description-Content-Type: text/markdown
|
|
|
178
184
|
[](https://anaconda.org/conda-forge/fsspec)
|
|
179
185
|

|
|
180
186
|
[](https://filesystem-spec.readthedocs.io/en/latest/?badge=latest)
|
|
181
|
-
[](https://pepy.tech/project/fsspec)
|
|
182
187
|
|
|
183
188
|
A specification for pythonic filesystems.
|
|
184
189
|
|
|
@@ -225,13 +230,13 @@ CI runtime. For local use, pick a version suitable for you.
|
|
|
225
230
|
mamba create -n fsspec -c conda-forge python=3.9 -y
|
|
226
231
|
conda activate fsspec
|
|
227
232
|
|
|
228
|
-
# Standard dev
|
|
229
|
-
pip install -e ".[dev,test]"
|
|
233
|
+
# Standard dev install with docs and tests.
|
|
234
|
+
pip install -e ".[dev,doc,test]"
|
|
230
235
|
|
|
231
236
|
# Full tests except for downstream
|
|
232
237
|
pip install s3fs
|
|
233
238
|
pip uninstall s3fs
|
|
234
|
-
pip install -e .[dev,test_full]
|
|
239
|
+
pip install -e .[dev,doc,test_full]
|
|
235
240
|
pip install s3fs --no-deps
|
|
236
241
|
pytest -v
|
|
237
242
|
|
|
@@ -4,7 +4,6 @@
|
|
|
4
4
|
[](https://anaconda.org/conda-forge/fsspec)
|
|
5
5
|

|
|
6
6
|
[](https://filesystem-spec.readthedocs.io/en/latest/?badge=latest)
|
|
7
|
-
[](https://pepy.tech/project/fsspec)
|
|
8
7
|
|
|
9
8
|
A specification for pythonic filesystems.
|
|
10
9
|
|
|
@@ -51,13 +50,13 @@ CI runtime. For local use, pick a version suitable for you.
|
|
|
51
50
|
mamba create -n fsspec -c conda-forge python=3.9 -y
|
|
52
51
|
conda activate fsspec
|
|
53
52
|
|
|
54
|
-
# Standard dev
|
|
55
|
-
pip install -e ".[dev,test]"
|
|
53
|
+
# Standard dev install with docs and tests.
|
|
54
|
+
pip install -e ".[dev,doc,test]"
|
|
56
55
|
|
|
57
56
|
# Full tests except for downstream
|
|
58
57
|
pip install s3fs
|
|
59
58
|
pip uninstall s3fs
|
|
60
|
-
pip install -e .[dev,test_full]
|
|
59
|
+
pip install -e .[dev,doc,test_full]
|
|
61
60
|
pip install s3fs --no-deps
|
|
62
61
|
pytest -v
|
|
63
62
|
|
|
@@ -1,6 +1,40 @@
|
|
|
1
1
|
Changelog
|
|
2
2
|
=========
|
|
3
3
|
|
|
4
|
+
2024.6.1
|
|
5
|
+
--------
|
|
6
|
+
|
|
7
|
+
Fixes
|
|
8
|
+
|
|
9
|
+
- fix appending to non-dict reference sets (#1634)
|
|
10
|
+
- don't let generic edit info dicts (#1633)
|
|
11
|
+
- set https's loop before calling super (#1633)
|
|
12
|
+
- cached write file doesn't need to update it's size on close (#1633)
|
|
13
|
+
- fix JSON serialize for FSs with interior FSs (#1628, 1627)
|
|
14
|
+
- option to strip "password" when pickling (#1625)
|
|
15
|
+
- fix filecache write (#1622)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
2024.6.0
|
|
19
|
+
--------
|
|
20
|
+
|
|
21
|
+
Enhancements
|
|
22
|
+
|
|
23
|
+
- allow dicts (not just bytes) for referenceFS (#1616
|
|
24
|
+
- make filesystems JSON serializeable (#1612)
|
|
25
|
+
- implement multifile cat() for github (#1620)
|
|
26
|
+
|
|
27
|
+
Fixes
|
|
28
|
+
|
|
29
|
+
- implement auto_mkdir for SMB (#1604)
|
|
30
|
+
|
|
31
|
+
Other
|
|
32
|
+
|
|
33
|
+
- add doc deps to pyproject (#1613)
|
|
34
|
+
- re-remove test from package (#1611)
|
|
35
|
+
- formatting (#1610, 1608, 1602)
|
|
36
|
+
- change monthly download badge (#1607)
|
|
37
|
+
|
|
4
38
|
2024.5.0
|
|
5
39
|
--------
|
|
6
40
|
|
|
@@ -107,9 +107,9 @@ The following can be used to install ``fsspec`` in development mode
|
|
|
107
107
|
|
|
108
108
|
git clone https://github.com/fsspec/filesystem_spec
|
|
109
109
|
cd filesystem_spec
|
|
110
|
-
pip install -e .
|
|
110
|
+
pip install -e .[dev,doc,test]
|
|
111
111
|
|
|
112
|
-
A number of additional dependencies are required to run tests, see "ci/environment*.yml", as
|
|
112
|
+
A number of additional dependencies are required to run tests in full, see "ci/environment*.yml", as
|
|
113
113
|
well as Docker. Most implementation-specific tests should skip if their requirements are
|
|
114
114
|
not met.
|
|
115
115
|
|
|
@@ -69,7 +69,7 @@ The following libraries use ``fsspec`` internally for path and file handling:
|
|
|
69
69
|
.. _xarray: https://docs.xarray.dev/
|
|
70
70
|
.. _zarr: https://zarr.readthedocs.io/
|
|
71
71
|
.. _DVC: https://dvc.org/
|
|
72
|
-
.. _kedro: https://kedro.
|
|
72
|
+
.. _kedro: https://docs.kedro.org/en/stable/tutorial/set_up_data.html#supported-data-locations
|
|
73
73
|
.. _pyxet: https://github.com/xetdata/pyxet
|
|
74
74
|
.. _Huggingface🤗 Datasets: https://github.com/huggingface/datasets
|
|
75
75
|
.. _pyarrow: https://arrow.apache.org/docs/python/
|
|
@@ -12,5 +12,5 @@ __version__: str
|
|
|
12
12
|
__version_tuple__: VERSION_TUPLE
|
|
13
13
|
version_tuple: VERSION_TUPLE
|
|
14
14
|
|
|
15
|
-
__version__ = version = '2024.
|
|
16
|
-
__version_tuple__ = version_tuple = (2024,
|
|
15
|
+
__version__ = version = '2024.6.1'
|
|
16
|
+
__version_tuple__ = version_tuple = (2024, 6, 1)
|
|
@@ -15,6 +15,7 @@ from typing import (
|
|
|
15
15
|
ClassVar,
|
|
16
16
|
Generic,
|
|
17
17
|
NamedTuple,
|
|
18
|
+
Optional,
|
|
18
19
|
OrderedDict,
|
|
19
20
|
TypeVar,
|
|
20
21
|
)
|
|
@@ -574,7 +575,7 @@ class KnownPartsOfAFile(BaseCache):
|
|
|
574
575
|
blocksize: int,
|
|
575
576
|
fetcher: Fetcher,
|
|
576
577
|
size: int,
|
|
577
|
-
data: dict[tuple[int, int], bytes] =
|
|
578
|
+
data: Optional[dict[tuple[int, int], bytes]] = None,
|
|
578
579
|
strict: bool = True,
|
|
579
580
|
**_: Any,
|
|
580
581
|
):
|
|
@@ -597,7 +598,7 @@ class KnownPartsOfAFile(BaseCache):
|
|
|
597
598
|
|
|
598
599
|
self.data = dict(zip(offsets, blocks))
|
|
599
600
|
else:
|
|
600
|
-
self.data =
|
|
601
|
+
self.data = {}
|
|
601
602
|
|
|
602
603
|
def _fetch(self, start: int | None, stop: int | None) -> bytes:
|
|
603
604
|
if start is None:
|
|
@@ -139,7 +139,7 @@ class SnappyFile(AbstractBufferedFile):
|
|
|
139
139
|
try:
|
|
140
140
|
import snappy
|
|
141
141
|
|
|
142
|
-
snappy.compress
|
|
142
|
+
snappy.compress(b"")
|
|
143
143
|
# Snappy may use the .sz file extension, but this is not part of the
|
|
144
144
|
# standard implementation.
|
|
145
145
|
register_compression("snappy", SnappyFile, [])
|
|
@@ -197,6 +197,7 @@ class GenericFileSystem(AsyncFileSystem):
|
|
|
197
197
|
)
|
|
198
198
|
result = {}
|
|
199
199
|
for k, v in out.items():
|
|
200
|
+
v = v.copy() # don't corrupt target FS dircache
|
|
200
201
|
name = fs.unstrip_protocol(k)
|
|
201
202
|
v["name"] = name
|
|
202
203
|
result[name] = v
|
|
@@ -210,6 +211,7 @@ class GenericFileSystem(AsyncFileSystem):
|
|
|
210
211
|
out = await fs._info(url, **kwargs)
|
|
211
212
|
else:
|
|
212
213
|
out = fs.info(url, **kwargs)
|
|
214
|
+
out = out.copy() # don't edit originals
|
|
213
215
|
out["name"] = fs.unstrip_protocol(out["name"])
|
|
214
216
|
return out
|
|
215
217
|
|
|
@@ -224,6 +226,7 @@ class GenericFileSystem(AsyncFileSystem):
|
|
|
224
226
|
out = await fs._ls(url, detail=True, **kwargs)
|
|
225
227
|
else:
|
|
226
228
|
out = fs.ls(url, detail=True, **kwargs)
|
|
229
|
+
out = [o.copy() for o in out] # don't edit originals
|
|
227
230
|
for o in out:
|
|
228
231
|
o["name"] = fs.unstrip_protocol(o["name"])
|
|
229
232
|
if detail:
|
|
@@ -425,7 +425,6 @@ class CachingFileSystem(AbstractFileSystem):
|
|
|
425
425
|
"clear_cache",
|
|
426
426
|
"clear_expired_cache",
|
|
427
427
|
"pop_from_cache",
|
|
428
|
-
"_mkcache",
|
|
429
428
|
"local_file",
|
|
430
429
|
"_paths_from_path",
|
|
431
430
|
"get_mapper",
|
|
@@ -435,12 +434,10 @@ class CachingFileSystem(AbstractFileSystem):
|
|
|
435
434
|
"__hash__",
|
|
436
435
|
"__eq__",
|
|
437
436
|
"to_json",
|
|
437
|
+
"to_dict",
|
|
438
438
|
"cache_size",
|
|
439
439
|
"pipe_file",
|
|
440
440
|
"pipe",
|
|
441
|
-
"isdir",
|
|
442
|
-
"isfile",
|
|
443
|
-
"exists",
|
|
444
441
|
"start_transaction",
|
|
445
442
|
"end_transaction",
|
|
446
443
|
}:
|
|
@@ -510,15 +507,6 @@ class CachingFileSystem(AbstractFileSystem):
|
|
|
510
507
|
^ hash(self.target_protocol)
|
|
511
508
|
)
|
|
512
509
|
|
|
513
|
-
def to_json(self):
|
|
514
|
-
"""Calculate JSON representation.
|
|
515
|
-
|
|
516
|
-
Not implemented yet for CachingFileSystem.
|
|
517
|
-
"""
|
|
518
|
-
raise NotImplementedError(
|
|
519
|
-
"CachingFileSystem JSON representation not implemented"
|
|
520
|
-
)
|
|
521
|
-
|
|
522
510
|
|
|
523
511
|
class WholeFileCacheFileSystem(CachingFileSystem):
|
|
524
512
|
"""Caches whole remote files on first access
|
|
@@ -663,7 +651,8 @@ class WholeFileCacheFileSystem(CachingFileSystem):
|
|
|
663
651
|
def _open(self, path, mode="rb", **kwargs):
|
|
664
652
|
path = self._strip_protocol(path)
|
|
665
653
|
if "r" not in mode:
|
|
666
|
-
|
|
654
|
+
hash = self._mapper(path)
|
|
655
|
+
fn = os.path.join(self.storage[-1], hash)
|
|
667
656
|
user_specified_kwargs = {
|
|
668
657
|
k: v
|
|
669
658
|
for k, v in kwargs.items()
|
|
@@ -806,7 +795,8 @@ class SimpleCacheFileSystem(WholeFileCacheFileSystem):
|
|
|
806
795
|
if self._intrans:
|
|
807
796
|
f = [_ for _ in self.transaction.files if _.path == path]
|
|
808
797
|
if f:
|
|
809
|
-
|
|
798
|
+
size = os.path.getsize(f[0].fn) if f[0].closed else f[0].tell()
|
|
799
|
+
return {"name": path, "size": size, "type": "file"}
|
|
810
800
|
f = any(_.path.startswith(path + "/") for _ in self.transaction.files)
|
|
811
801
|
if f:
|
|
812
802
|
return {"name": path, "size": 0, "type": "directory"}
|
|
@@ -912,7 +902,7 @@ class LocalTempFile:
|
|
|
912
902
|
self.close()
|
|
913
903
|
|
|
914
904
|
def close(self):
|
|
915
|
-
self.size = self.fh.tell()
|
|
905
|
+
# self.size = self.fh.tell()
|
|
916
906
|
if self.closed:
|
|
917
907
|
return
|
|
918
908
|
self.fh.close()
|
|
@@ -56,6 +56,8 @@ class DirFileSystem(AsyncFileSystem):
|
|
|
56
56
|
if not path:
|
|
57
57
|
return self.path
|
|
58
58
|
return self.fs.sep.join((self.path, self._strip_protocol(path)))
|
|
59
|
+
if isinstance(path, dict):
|
|
60
|
+
return {self._join(_path): value for _path, value in path.items()}
|
|
59
61
|
return [self._join(_path) for _path in path]
|
|
60
62
|
|
|
61
63
|
def _relpath(self, path):
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import requests
|
|
2
2
|
|
|
3
|
+
import fsspec
|
|
4
|
+
|
|
3
5
|
from ..spec import AbstractFileSystem
|
|
4
6
|
from ..utils import infer_storage_options
|
|
5
7
|
from .memory import MemoryFile
|
|
@@ -225,3 +227,13 @@ class GithubFileSystem(AbstractFileSystem):
|
|
|
225
227
|
raise FileNotFoundError(path)
|
|
226
228
|
r.raise_for_status()
|
|
227
229
|
return MemoryFile(None, None, r.content)
|
|
230
|
+
|
|
231
|
+
def cat(self, path, recursive=False, on_error="raise", **kwargs):
|
|
232
|
+
paths = self.expand_path(path, recursive=recursive)
|
|
233
|
+
urls = [
|
|
234
|
+
self.rurl.format(org=self.org, repo=self.repo, path=u, sha=self.root)
|
|
235
|
+
for u, sh in paths
|
|
236
|
+
]
|
|
237
|
+
fs = fsspec.filesystem("http")
|
|
238
|
+
data = fs.cat(urls, on_error="return")
|
|
239
|
+
return {u: v for ((k, v), u) in zip(data.items(), urls)}
|
|
@@ -560,6 +560,7 @@ class HTTPFile(AbstractBufferedFile):
|
|
|
560
560
|
if mode != "rb":
|
|
561
561
|
raise NotImplementedError("File mode not supported")
|
|
562
562
|
self.asynchronous = asynchronous
|
|
563
|
+
self.loop = loop
|
|
563
564
|
self.url = url
|
|
564
565
|
self.session = session
|
|
565
566
|
self.details = {"name": url, "size": size, "type": "file"}
|
|
@@ -572,7 +573,6 @@ class HTTPFile(AbstractBufferedFile):
|
|
|
572
573
|
cache_options=cache_options,
|
|
573
574
|
**kwargs,
|
|
574
575
|
)
|
|
575
|
-
self.loop = loop
|
|
576
576
|
|
|
577
577
|
def read(self, length=-1):
|
|
578
578
|
"""Read bytes from file
|
|
@@ -736,6 +736,7 @@ class HTTPStreamFile(AbstractBufferedFile):
|
|
|
736
736
|
return r
|
|
737
737
|
|
|
738
738
|
self.r = sync(self.loop, cor)
|
|
739
|
+
self.loop = fs.loop
|
|
739
740
|
|
|
740
741
|
def seek(self, loc, whence=0):
|
|
741
742
|
if loc == 0 and whence == 1:
|
|
@@ -935,6 +935,13 @@ class ReferenceFileSystem(AsyncFileSystem):
|
|
|
935
935
|
|
|
936
936
|
def _process_references0(self, references):
|
|
937
937
|
"""Make reference dict for Spec Version 0"""
|
|
938
|
+
if isinstance(references, dict):
|
|
939
|
+
# do not do this for lazy/parquet backend, which will not make dicts,
|
|
940
|
+
# but must remain writable in the original object
|
|
941
|
+
references = {
|
|
942
|
+
key: json.dumps(val) if isinstance(val, dict) else val
|
|
943
|
+
for key, val in references.items()
|
|
944
|
+
}
|
|
938
945
|
self.references = references
|
|
939
946
|
|
|
940
947
|
def _process_references1(self, references, template_overrides=None):
|
|
@@ -952,6 +959,8 @@ class ReferenceFileSystem(AsyncFileSystem):
|
|
|
952
959
|
if v.startswith("base64:"):
|
|
953
960
|
self.references[k] = base64.b64decode(v[7:])
|
|
954
961
|
self.references[k] = v
|
|
962
|
+
elif isinstance(v, dict):
|
|
963
|
+
self.references[k] = json.dumps(v)
|
|
955
964
|
elif self.templates:
|
|
956
965
|
u = v[0]
|
|
957
966
|
if "{{" in u:
|
|
@@ -68,6 +68,7 @@ class SMBFileSystem(AbstractFileSystem):
|
|
|
68
68
|
encrypt=None,
|
|
69
69
|
share_access=None,
|
|
70
70
|
register_session_retries=5,
|
|
71
|
+
auto_mkdir=False,
|
|
71
72
|
**kwargs,
|
|
72
73
|
):
|
|
73
74
|
"""
|
|
@@ -102,6 +103,10 @@ class SMBFileSystem(AbstractFileSystem):
|
|
|
102
103
|
- 'r': Allow other handles to be opened with read access.
|
|
103
104
|
- 'w': Allow other handles to be opened with write access.
|
|
104
105
|
- 'd': Allow other handles to be opened with delete access.
|
|
106
|
+
auto_mkdir: bool
|
|
107
|
+
Whether, when opening a file, the directory containing it should
|
|
108
|
+
be created (if it doesn't already exist). This is assumed by pyarrow
|
|
109
|
+
and zarr-python code.
|
|
105
110
|
"""
|
|
106
111
|
super().__init__(**kwargs)
|
|
107
112
|
self.host = host
|
|
@@ -113,6 +118,7 @@ class SMBFileSystem(AbstractFileSystem):
|
|
|
113
118
|
self.temppath = kwargs.pop("temppath", "")
|
|
114
119
|
self.share_access = share_access
|
|
115
120
|
self.register_session_retries = register_session_retries
|
|
121
|
+
self.auto_mkdir = auto_mkdir
|
|
116
122
|
self._connect()
|
|
117
123
|
|
|
118
124
|
@property
|
|
@@ -224,6 +230,8 @@ class SMBFileSystem(AbstractFileSystem):
|
|
|
224
230
|
By specifying 'share_access' in 'kwargs' it is possible to override the
|
|
225
231
|
default shared access setting applied in the constructor of this object.
|
|
226
232
|
"""
|
|
233
|
+
if self.auto_mkdir and "w" in mode:
|
|
234
|
+
self.makedirs(self._parent(path), exist_ok=True)
|
|
227
235
|
bls = block_size if block_size is not None and block_size >= 0 else -1
|
|
228
236
|
wpath = _as_unc_path(self.host, path)
|
|
229
237
|
share_access = kwargs.pop("share_access", self.share_access)
|
|
@@ -245,6 +253,8 @@ class SMBFileSystem(AbstractFileSystem):
|
|
|
245
253
|
"""Copy within two locations in the same filesystem"""
|
|
246
254
|
wpath1 = _as_unc_path(self.host, path1)
|
|
247
255
|
wpath2 = _as_unc_path(self.host, path2)
|
|
256
|
+
if self.auto_mkdir:
|
|
257
|
+
self.makedirs(self._parent(path2), exist_ok=True)
|
|
248
258
|
smbclient.copyfile(wpath1, wpath2, port=self._port, **kwargs)
|
|
249
259
|
|
|
250
260
|
def _rm(self, path):
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import json
|
|
2
|
+
from contextlib import suppress
|
|
3
|
+
from pathlib import PurePath
|
|
4
|
+
from typing import (
|
|
5
|
+
Any,
|
|
6
|
+
Callable,
|
|
7
|
+
ClassVar,
|
|
8
|
+
Dict,
|
|
9
|
+
List,
|
|
10
|
+
Mapping,
|
|
11
|
+
Optional,
|
|
12
|
+
Sequence,
|
|
13
|
+
Tuple,
|
|
14
|
+
)
|
|
15
|
+
|
|
16
|
+
from .registry import _import_class, get_filesystem_class
|
|
17
|
+
from .spec import AbstractFileSystem
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class FilesystemJSONEncoder(json.JSONEncoder):
|
|
21
|
+
include_password: ClassVar[bool] = True
|
|
22
|
+
|
|
23
|
+
def default(self, o: Any) -> Any:
|
|
24
|
+
if isinstance(o, AbstractFileSystem):
|
|
25
|
+
return o.to_dict(include_password=self.include_password)
|
|
26
|
+
if isinstance(o, PurePath):
|
|
27
|
+
cls = type(o)
|
|
28
|
+
return {"cls": f"{cls.__module__}.{cls.__name__}", "str": str(o)}
|
|
29
|
+
|
|
30
|
+
return super().default(o)
|
|
31
|
+
|
|
32
|
+
def make_serializable(self, obj: Any) -> Any:
|
|
33
|
+
"""
|
|
34
|
+
Recursively converts an object so that it can be JSON serialized via
|
|
35
|
+
:func:`json.dumps` and :func:`json.dump`, without actually calling
|
|
36
|
+
said functions.
|
|
37
|
+
"""
|
|
38
|
+
if isinstance(obj, (str, int, float, bool)):
|
|
39
|
+
return obj
|
|
40
|
+
if isinstance(obj, Mapping):
|
|
41
|
+
return {k: self.make_serializable(v) for k, v in obj.items()}
|
|
42
|
+
if isinstance(obj, Sequence):
|
|
43
|
+
return [self.make_serializable(v) for v in obj]
|
|
44
|
+
|
|
45
|
+
return self.default(obj)
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
class FilesystemJSONDecoder(json.JSONDecoder):
|
|
49
|
+
def __init__(
|
|
50
|
+
self,
|
|
51
|
+
*,
|
|
52
|
+
object_hook: Optional[Callable[[Dict[str, Any]], Any]] = None,
|
|
53
|
+
parse_float: Optional[Callable[[str], Any]] = None,
|
|
54
|
+
parse_int: Optional[Callable[[str], Any]] = None,
|
|
55
|
+
parse_constant: Optional[Callable[[str], Any]] = None,
|
|
56
|
+
strict: bool = True,
|
|
57
|
+
object_pairs_hook: Optional[Callable[[List[Tuple[str, Any]]], Any]] = None,
|
|
58
|
+
) -> None:
|
|
59
|
+
self.original_object_hook = object_hook
|
|
60
|
+
|
|
61
|
+
super().__init__(
|
|
62
|
+
object_hook=self.custom_object_hook,
|
|
63
|
+
parse_float=parse_float,
|
|
64
|
+
parse_int=parse_int,
|
|
65
|
+
parse_constant=parse_constant,
|
|
66
|
+
strict=strict,
|
|
67
|
+
object_pairs_hook=object_pairs_hook,
|
|
68
|
+
)
|
|
69
|
+
|
|
70
|
+
@classmethod
|
|
71
|
+
def try_resolve_path_cls(cls, dct: Dict[str, Any]):
|
|
72
|
+
with suppress(Exception):
|
|
73
|
+
fqp = dct["cls"]
|
|
74
|
+
|
|
75
|
+
path_cls = _import_class(fqp)
|
|
76
|
+
|
|
77
|
+
if issubclass(path_cls, PurePath):
|
|
78
|
+
return path_cls
|
|
79
|
+
|
|
80
|
+
return None
|
|
81
|
+
|
|
82
|
+
@classmethod
|
|
83
|
+
def try_resolve_fs_cls(cls, dct: Dict[str, Any]):
|
|
84
|
+
with suppress(Exception):
|
|
85
|
+
if "cls" in dct:
|
|
86
|
+
try:
|
|
87
|
+
fs_cls = _import_class(dct["cls"])
|
|
88
|
+
if issubclass(fs_cls, AbstractFileSystem):
|
|
89
|
+
return fs_cls
|
|
90
|
+
except Exception:
|
|
91
|
+
if "protocol" in dct: # Fallback if cls cannot be imported
|
|
92
|
+
return get_filesystem_class(dct["protocol"])
|
|
93
|
+
|
|
94
|
+
raise
|
|
95
|
+
|
|
96
|
+
return None
|
|
97
|
+
|
|
98
|
+
def custom_object_hook(self, dct: Dict[str, Any]):
|
|
99
|
+
if "cls" in dct:
|
|
100
|
+
if (obj_cls := self.try_resolve_fs_cls(dct)) is not None:
|
|
101
|
+
return AbstractFileSystem.from_dict(dct)
|
|
102
|
+
if (obj_cls := self.try_resolve_path_cls(dct)) is not None:
|
|
103
|
+
return obj_cls(dct["str"])
|
|
104
|
+
|
|
105
|
+
if self.original_object_hook is not None:
|
|
106
|
+
return self.original_object_hook(dct)
|
|
107
|
+
|
|
108
|
+
return dct
|
|
109
|
+
|
|
110
|
+
def unmake_serializable(self, obj: Any) -> Any:
|
|
111
|
+
"""
|
|
112
|
+
Inverse function of :meth:`FilesystemJSONEncoder.make_serializable`.
|
|
113
|
+
"""
|
|
114
|
+
if isinstance(obj, dict):
|
|
115
|
+
obj = self.custom_object_hook(obj)
|
|
116
|
+
if isinstance(obj, dict):
|
|
117
|
+
return {k: self.unmake_serializable(v) for k, v in obj.items()}
|
|
118
|
+
if isinstance(obj, (list, tuple)):
|
|
119
|
+
return [self.unmake_serializable(v) for v in obj]
|
|
120
|
+
|
|
121
|
+
return obj
|
|
@@ -257,27 +257,33 @@ update the current installation.
|
|
|
257
257
|
"""
|
|
258
258
|
|
|
259
259
|
|
|
260
|
-
def _import_class(
|
|
261
|
-
"""Take a
|
|
260
|
+
def _import_class(fqp: str):
|
|
261
|
+
"""Take a fully-qualified path and return the imported class or identifier.
|
|
262
262
|
|
|
263
|
-
|
|
263
|
+
``fqp`` is of the form "package.module.klass" or
|
|
264
|
+
"package.module:subobject.klass".
|
|
265
|
+
|
|
266
|
+
Warnings
|
|
267
|
+
--------
|
|
268
|
+
This can import arbitrary modules. Make sure you haven't installed any modules
|
|
269
|
+
that may execute malicious code at import time.
|
|
264
270
|
"""
|
|
265
|
-
if ":" in
|
|
266
|
-
mod, name =
|
|
267
|
-
s3 = mod == "s3fs"
|
|
268
|
-
mod = importlib.import_module(mod)
|
|
269
|
-
if s3 and mod.__version__.split(".") < ["0", "5"]:
|
|
270
|
-
warnings.warn(s3_msg)
|
|
271
|
-
for part in name.split("."):
|
|
272
|
-
mod = getattr(mod, part)
|
|
273
|
-
return mod
|
|
271
|
+
if ":" in fqp:
|
|
272
|
+
mod, name = fqp.rsplit(":", 1)
|
|
274
273
|
else:
|
|
275
|
-
mod, name =
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
274
|
+
mod, name = fqp.rsplit(".", 1)
|
|
275
|
+
|
|
276
|
+
is_s3 = mod == "s3fs"
|
|
277
|
+
mod = importlib.import_module(mod)
|
|
278
|
+
if is_s3 and mod.__version__.split(".") < ["0", "5"]:
|
|
279
|
+
warnings.warn(s3_msg)
|
|
280
|
+
for part in name.split("."):
|
|
281
|
+
mod = getattr(mod, part)
|
|
282
|
+
|
|
283
|
+
if not isinstance(mod, type):
|
|
284
|
+
raise TypeError(f"{fqp} is not a class")
|
|
285
|
+
|
|
286
|
+
return mod
|
|
281
287
|
|
|
282
288
|
|
|
283
289
|
def filesystem(protocol, **storage_options):
|