fugue 0.9.7.dev2__tar.gz → 0.9.9.dev0__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.
- {fugue-0.9.7.dev2 → fugue-0.9.9.dev0}/PKG-INFO +17 -13
- {fugue-0.9.7.dev2 → fugue-0.9.9.dev0}/README.md +1 -1
- {fugue-0.9.7.dev2 → fugue-0.9.9.dev0}/fugue/dataframe/arrow_dataframe.py +9 -2
- {fugue-0.9.7.dev2 → fugue-0.9.9.dev0}/fugue/dataframe/pandas_dataframe.py +12 -1
- {fugue-0.9.7.dev2 → fugue-0.9.9.dev0}/fugue/execution/native_execution_engine.py +13 -2
- {fugue-0.9.7.dev2 → fugue-0.9.9.dev0}/fugue.egg-info/PKG-INFO +17 -13
- {fugue-0.9.7.dev2 → fugue-0.9.9.dev0}/fugue.egg-info/requires.txt +24 -8
- {fugue-0.9.7.dev2 → fugue-0.9.9.dev0}/fugue_dask/execution_engine.py +2 -2
- {fugue-0.9.7.dev2 → fugue-0.9.9.dev0}/fugue_duckdb/dataframe.py +2 -3
- {fugue-0.9.7.dev2 → fugue-0.9.9.dev0}/fugue_polars/polars_dataframe.py +3 -9
- {fugue-0.9.7.dev2 → fugue-0.9.9.dev0}/fugue_ray/_utils/dataframe.py +3 -2
- {fugue-0.9.7.dev2 → fugue-0.9.9.dev0}/fugue_ray/_utils/io.py +37 -29
- {fugue-0.9.7.dev2 → fugue-0.9.9.dev0}/fugue_ray/dataframe.py +9 -5
- {fugue-0.9.7.dev2 → fugue-0.9.9.dev0}/fugue_spark/_utils/misc.py +8 -10
- {fugue-0.9.7.dev2 → fugue-0.9.9.dev0}/fugue_spark/execution_engine.py +11 -4
- {fugue-0.9.7.dev2 → fugue-0.9.9.dev0}/pyproject.toml +27 -14
- {fugue-0.9.7.dev2 → fugue-0.9.9.dev0}/LICENSE +0 -0
- {fugue-0.9.7.dev2 → fugue-0.9.9.dev0}/fugue/__init__.py +0 -0
- {fugue-0.9.7.dev2 → fugue-0.9.9.dev0}/fugue/_utils/__init__.py +0 -0
- {fugue-0.9.7.dev2 → fugue-0.9.9.dev0}/fugue/_utils/display.py +0 -0
- {fugue-0.9.7.dev2 → fugue-0.9.9.dev0}/fugue/_utils/exception.py +0 -0
- {fugue-0.9.7.dev2 → fugue-0.9.9.dev0}/fugue/_utils/interfaceless.py +0 -0
- {fugue-0.9.7.dev2 → fugue-0.9.9.dev0}/fugue/_utils/io.py +0 -0
- {fugue-0.9.7.dev2 → fugue-0.9.9.dev0}/fugue/_utils/misc.py +0 -0
- {fugue-0.9.7.dev2 → fugue-0.9.9.dev0}/fugue/_utils/registry.py +0 -0
- {fugue-0.9.7.dev2 → fugue-0.9.9.dev0}/fugue/api.py +0 -0
- {fugue-0.9.7.dev2 → fugue-0.9.9.dev0}/fugue/bag/__init__.py +0 -0
- {fugue-0.9.7.dev2 → fugue-0.9.9.dev0}/fugue/bag/array_bag.py +0 -0
- {fugue-0.9.7.dev2 → fugue-0.9.9.dev0}/fugue/bag/bag.py +0 -0
- {fugue-0.9.7.dev2 → fugue-0.9.9.dev0}/fugue/collections/__init__.py +0 -0
- {fugue-0.9.7.dev2 → fugue-0.9.9.dev0}/fugue/collections/partition.py +0 -0
- {fugue-0.9.7.dev2 → fugue-0.9.9.dev0}/fugue/collections/sql.py +0 -0
- {fugue-0.9.7.dev2 → fugue-0.9.9.dev0}/fugue/collections/yielded.py +0 -0
- {fugue-0.9.7.dev2 → fugue-0.9.9.dev0}/fugue/column/__init__.py +0 -0
- {fugue-0.9.7.dev2 → fugue-0.9.9.dev0}/fugue/column/expressions.py +0 -0
- {fugue-0.9.7.dev2 → fugue-0.9.9.dev0}/fugue/column/functions.py +0 -0
- {fugue-0.9.7.dev2 → fugue-0.9.9.dev0}/fugue/column/sql.py +0 -0
- {fugue-0.9.7.dev2 → fugue-0.9.9.dev0}/fugue/constants.py +0 -0
- {fugue-0.9.7.dev2 → fugue-0.9.9.dev0}/fugue/dataframe/__init__.py +0 -0
- {fugue-0.9.7.dev2 → fugue-0.9.9.dev0}/fugue/dataframe/api.py +0 -0
- {fugue-0.9.7.dev2 → fugue-0.9.9.dev0}/fugue/dataframe/array_dataframe.py +0 -0
- {fugue-0.9.7.dev2 → fugue-0.9.9.dev0}/fugue/dataframe/dataframe.py +0 -0
- {fugue-0.9.7.dev2 → fugue-0.9.9.dev0}/fugue/dataframe/dataframe_iterable_dataframe.py +0 -0
- {fugue-0.9.7.dev2 → fugue-0.9.9.dev0}/fugue/dataframe/dataframes.py +0 -0
- {fugue-0.9.7.dev2 → fugue-0.9.9.dev0}/fugue/dataframe/function_wrapper.py +0 -0
- {fugue-0.9.7.dev2 → fugue-0.9.9.dev0}/fugue/dataframe/iterable_dataframe.py +0 -0
- {fugue-0.9.7.dev2 → fugue-0.9.9.dev0}/fugue/dataframe/utils.py +0 -0
- {fugue-0.9.7.dev2 → fugue-0.9.9.dev0}/fugue/dataset/__init__.py +0 -0
- {fugue-0.9.7.dev2 → fugue-0.9.9.dev0}/fugue/dataset/api.py +0 -0
- {fugue-0.9.7.dev2 → fugue-0.9.9.dev0}/fugue/dataset/dataset.py +0 -0
- {fugue-0.9.7.dev2 → fugue-0.9.9.dev0}/fugue/dev.py +0 -0
- {fugue-0.9.7.dev2 → fugue-0.9.9.dev0}/fugue/exceptions.py +0 -0
- {fugue-0.9.7.dev2 → fugue-0.9.9.dev0}/fugue/execution/__init__.py +0 -0
- {fugue-0.9.7.dev2 → fugue-0.9.9.dev0}/fugue/execution/api.py +0 -0
- {fugue-0.9.7.dev2 → fugue-0.9.9.dev0}/fugue/execution/execution_engine.py +0 -0
- {fugue-0.9.7.dev2 → fugue-0.9.9.dev0}/fugue/execution/factory.py +0 -0
- {fugue-0.9.7.dev2 → fugue-0.9.9.dev0}/fugue/extensions/__init__.py +0 -0
- {fugue-0.9.7.dev2 → fugue-0.9.9.dev0}/fugue/extensions/_builtins/__init__.py +0 -0
- {fugue-0.9.7.dev2 → fugue-0.9.9.dev0}/fugue/extensions/_builtins/creators.py +0 -0
- {fugue-0.9.7.dev2 → fugue-0.9.9.dev0}/fugue/extensions/_builtins/outputters.py +0 -0
- {fugue-0.9.7.dev2 → fugue-0.9.9.dev0}/fugue/extensions/_builtins/processors.py +0 -0
- {fugue-0.9.7.dev2 → fugue-0.9.9.dev0}/fugue/extensions/_utils.py +0 -0
- {fugue-0.9.7.dev2 → fugue-0.9.9.dev0}/fugue/extensions/context.py +0 -0
- {fugue-0.9.7.dev2 → fugue-0.9.9.dev0}/fugue/extensions/creator/__init__.py +0 -0
- {fugue-0.9.7.dev2 → fugue-0.9.9.dev0}/fugue/extensions/creator/convert.py +0 -0
- {fugue-0.9.7.dev2 → fugue-0.9.9.dev0}/fugue/extensions/creator/creator.py +0 -0
- {fugue-0.9.7.dev2 → fugue-0.9.9.dev0}/fugue/extensions/outputter/__init__.py +0 -0
- {fugue-0.9.7.dev2 → fugue-0.9.9.dev0}/fugue/extensions/outputter/convert.py +0 -0
- {fugue-0.9.7.dev2 → fugue-0.9.9.dev0}/fugue/extensions/outputter/outputter.py +0 -0
- {fugue-0.9.7.dev2 → fugue-0.9.9.dev0}/fugue/extensions/processor/__init__.py +0 -0
- {fugue-0.9.7.dev2 → fugue-0.9.9.dev0}/fugue/extensions/processor/convert.py +0 -0
- {fugue-0.9.7.dev2 → fugue-0.9.9.dev0}/fugue/extensions/processor/processor.py +0 -0
- {fugue-0.9.7.dev2 → fugue-0.9.9.dev0}/fugue/extensions/transformer/__init__.py +0 -0
- {fugue-0.9.7.dev2 → fugue-0.9.9.dev0}/fugue/extensions/transformer/constants.py +0 -0
- {fugue-0.9.7.dev2 → fugue-0.9.9.dev0}/fugue/extensions/transformer/convert.py +0 -0
- {fugue-0.9.7.dev2 → fugue-0.9.9.dev0}/fugue/extensions/transformer/transformer.py +0 -0
- {fugue-0.9.7.dev2 → fugue-0.9.9.dev0}/fugue/plugins.py +0 -0
- {fugue-0.9.7.dev2 → fugue-0.9.9.dev0}/fugue/py.typed +0 -0
- {fugue-0.9.7.dev2 → fugue-0.9.9.dev0}/fugue/registry.py +0 -0
- {fugue-0.9.7.dev2 → fugue-0.9.9.dev0}/fugue/rpc/__init__.py +0 -0
- {fugue-0.9.7.dev2 → fugue-0.9.9.dev0}/fugue/rpc/base.py +0 -0
- {fugue-0.9.7.dev2 → fugue-0.9.9.dev0}/fugue/rpc/flask.py +0 -0
- {fugue-0.9.7.dev2 → fugue-0.9.9.dev0}/fugue/sql/__init__.py +0 -0
- {fugue-0.9.7.dev2 → fugue-0.9.9.dev0}/fugue/sql/_utils.py +0 -0
- {fugue-0.9.7.dev2 → fugue-0.9.9.dev0}/fugue/sql/_visitors.py +0 -0
- {fugue-0.9.7.dev2 → fugue-0.9.9.dev0}/fugue/sql/api.py +0 -0
- {fugue-0.9.7.dev2 → fugue-0.9.9.dev0}/fugue/sql/workflow.py +0 -0
- {fugue-0.9.7.dev2 → fugue-0.9.9.dev0}/fugue/test/__init__.py +0 -0
- {fugue-0.9.7.dev2 → fugue-0.9.9.dev0}/fugue/test/pandas_tester.py +0 -0
- {fugue-0.9.7.dev2 → fugue-0.9.9.dev0}/fugue/test/plugins.py +0 -0
- {fugue-0.9.7.dev2 → fugue-0.9.9.dev0}/fugue/workflow/__init__.py +0 -0
- {fugue-0.9.7.dev2 → fugue-0.9.9.dev0}/fugue/workflow/_checkpoint.py +0 -0
- {fugue-0.9.7.dev2 → fugue-0.9.9.dev0}/fugue/workflow/_tasks.py +0 -0
- {fugue-0.9.7.dev2 → fugue-0.9.9.dev0}/fugue/workflow/_workflow_context.py +0 -0
- {fugue-0.9.7.dev2 → fugue-0.9.9.dev0}/fugue/workflow/api.py +0 -0
- {fugue-0.9.7.dev2 → fugue-0.9.9.dev0}/fugue/workflow/input.py +0 -0
- {fugue-0.9.7.dev2 → fugue-0.9.9.dev0}/fugue/workflow/module.py +0 -0
- {fugue-0.9.7.dev2 → fugue-0.9.9.dev0}/fugue/workflow/workflow.py +0 -0
- {fugue-0.9.7.dev2 → fugue-0.9.9.dev0}/fugue.egg-info/SOURCES.txt +0 -0
- {fugue-0.9.7.dev2 → fugue-0.9.9.dev0}/fugue.egg-info/dependency_links.txt +0 -0
- {fugue-0.9.7.dev2 → fugue-0.9.9.dev0}/fugue.egg-info/entry_points.txt +0 -0
- {fugue-0.9.7.dev2 → fugue-0.9.9.dev0}/fugue.egg-info/top_level.txt +0 -0
- {fugue-0.9.7.dev2 → fugue-0.9.9.dev0}/fugue_contrib/__init__.py +0 -0
- {fugue-0.9.7.dev2 → fugue-0.9.9.dev0}/fugue_contrib/contrib.py +0 -0
- {fugue-0.9.7.dev2 → fugue-0.9.9.dev0}/fugue_contrib/seaborn/__init__.py +0 -0
- {fugue-0.9.7.dev2 → fugue-0.9.9.dev0}/fugue_contrib/viz/__init__.py +0 -0
- {fugue-0.9.7.dev2 → fugue-0.9.9.dev0}/fugue_contrib/viz/_ext.py +0 -0
- {fugue-0.9.7.dev2 → fugue-0.9.9.dev0}/fugue_dask/__init__.py +0 -0
- {fugue-0.9.7.dev2 → fugue-0.9.9.dev0}/fugue_dask/_constants.py +0 -0
- {fugue-0.9.7.dev2 → fugue-0.9.9.dev0}/fugue_dask/_dask_sql_wrapper.py +0 -0
- {fugue-0.9.7.dev2 → fugue-0.9.9.dev0}/fugue_dask/_io.py +0 -0
- {fugue-0.9.7.dev2 → fugue-0.9.9.dev0}/fugue_dask/_utils.py +0 -0
- {fugue-0.9.7.dev2 → fugue-0.9.9.dev0}/fugue_dask/dataframe.py +0 -0
- {fugue-0.9.7.dev2 → fugue-0.9.9.dev0}/fugue_dask/registry.py +0 -0
- {fugue-0.9.7.dev2 → fugue-0.9.9.dev0}/fugue_dask/tester.py +0 -0
- {fugue-0.9.7.dev2 → fugue-0.9.9.dev0}/fugue_duckdb/__init__.py +0 -0
- {fugue-0.9.7.dev2 → fugue-0.9.9.dev0}/fugue_duckdb/_io.py +0 -0
- {fugue-0.9.7.dev2 → fugue-0.9.9.dev0}/fugue_duckdb/_utils.py +0 -0
- {fugue-0.9.7.dev2 → fugue-0.9.9.dev0}/fugue_duckdb/dask.py +0 -0
- {fugue-0.9.7.dev2 → fugue-0.9.9.dev0}/fugue_duckdb/execution_engine.py +0 -0
- {fugue-0.9.7.dev2 → fugue-0.9.9.dev0}/fugue_duckdb/registry.py +0 -0
- {fugue-0.9.7.dev2 → fugue-0.9.9.dev0}/fugue_duckdb/tester.py +0 -0
- {fugue-0.9.7.dev2 → fugue-0.9.9.dev0}/fugue_ibis/__init__.py +0 -0
- {fugue-0.9.7.dev2 → fugue-0.9.9.dev0}/fugue_ibis/_compat.py +0 -0
- {fugue-0.9.7.dev2 → fugue-0.9.9.dev0}/fugue_ibis/_utils.py +0 -0
- {fugue-0.9.7.dev2 → fugue-0.9.9.dev0}/fugue_ibis/dataframe.py +0 -0
- {fugue-0.9.7.dev2 → fugue-0.9.9.dev0}/fugue_ibis/execution_engine.py +0 -0
- {fugue-0.9.7.dev2 → fugue-0.9.9.dev0}/fugue_notebook/__init__.py +0 -0
- {fugue-0.9.7.dev2 → fugue-0.9.9.dev0}/fugue_notebook/env.py +0 -0
- {fugue-0.9.7.dev2 → fugue-0.9.9.dev0}/fugue_notebook/nbextension/README.md +0 -0
- {fugue-0.9.7.dev2 → fugue-0.9.9.dev0}/fugue_notebook/nbextension/__init__.py +0 -0
- {fugue-0.9.7.dev2 → fugue-0.9.9.dev0}/fugue_notebook/nbextension/description.yaml +0 -0
- {fugue-0.9.7.dev2 → fugue-0.9.9.dev0}/fugue_notebook/nbextension/main.js +0 -0
- {fugue-0.9.7.dev2 → fugue-0.9.9.dev0}/fugue_polars/__init__.py +0 -0
- {fugue-0.9.7.dev2 → fugue-0.9.9.dev0}/fugue_polars/_utils.py +0 -0
- {fugue-0.9.7.dev2 → fugue-0.9.9.dev0}/fugue_polars/registry.py +0 -0
- {fugue-0.9.7.dev2 → fugue-0.9.9.dev0}/fugue_ray/__init__.py +0 -0
- {fugue-0.9.7.dev2 → fugue-0.9.9.dev0}/fugue_ray/_constants.py +0 -0
- {fugue-0.9.7.dev2 → fugue-0.9.9.dev0}/fugue_ray/_utils/__init__.py +0 -0
- {fugue-0.9.7.dev2 → fugue-0.9.9.dev0}/fugue_ray/_utils/cluster.py +0 -0
- {fugue-0.9.7.dev2 → fugue-0.9.9.dev0}/fugue_ray/execution_engine.py +0 -0
- {fugue-0.9.7.dev2 → fugue-0.9.9.dev0}/fugue_ray/registry.py +0 -0
- {fugue-0.9.7.dev2 → fugue-0.9.9.dev0}/fugue_ray/tester.py +0 -0
- {fugue-0.9.7.dev2 → fugue-0.9.9.dev0}/fugue_spark/__init__.py +0 -0
- {fugue-0.9.7.dev2 → fugue-0.9.9.dev0}/fugue_spark/_constants.py +0 -0
- {fugue-0.9.7.dev2 → fugue-0.9.9.dev0}/fugue_spark/_utils/__init__.py +0 -0
- {fugue-0.9.7.dev2 → fugue-0.9.9.dev0}/fugue_spark/_utils/convert.py +0 -0
- {fugue-0.9.7.dev2 → fugue-0.9.9.dev0}/fugue_spark/_utils/io.py +0 -0
- {fugue-0.9.7.dev2 → fugue-0.9.9.dev0}/fugue_spark/_utils/partition.py +0 -0
- {fugue-0.9.7.dev2 → fugue-0.9.9.dev0}/fugue_spark/dataframe.py +0 -0
- {fugue-0.9.7.dev2 → fugue-0.9.9.dev0}/fugue_spark/registry.py +0 -0
- {fugue-0.9.7.dev2 → fugue-0.9.9.dev0}/fugue_spark/tester.py +0 -0
- {fugue-0.9.7.dev2 → fugue-0.9.9.dev0}/fugue_sql/__init__.py +0 -0
- {fugue-0.9.7.dev2 → fugue-0.9.9.dev0}/fugue_sql/exceptions.py +0 -0
- {fugue-0.9.7.dev2 → fugue-0.9.9.dev0}/fugue_test/__init__.py +0 -0
- {fugue-0.9.7.dev2 → fugue-0.9.9.dev0}/fugue_test/bag_suite.py +0 -0
- {fugue-0.9.7.dev2 → fugue-0.9.9.dev0}/fugue_test/builtin_suite.py +0 -0
- {fugue-0.9.7.dev2 → fugue-0.9.9.dev0}/fugue_test/dataframe_suite.py +0 -0
- {fugue-0.9.7.dev2 → fugue-0.9.9.dev0}/fugue_test/execution_suite.py +0 -0
- {fugue-0.9.7.dev2 → fugue-0.9.9.dev0}/fugue_test/fixtures.py +0 -0
- {fugue-0.9.7.dev2 → fugue-0.9.9.dev0}/setup.cfg +0 -0
|
@@ -1,28 +1,30 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: fugue
|
|
3
|
-
Version: 0.9.
|
|
3
|
+
Version: 0.9.9.dev0
|
|
4
4
|
Summary: An abstraction layer for distributed computing
|
|
5
5
|
Author-email: The Fugue Development Team <hello@fugue.ai>
|
|
6
6
|
License: Apache-2.0
|
|
7
7
|
Project-URL: Homepage, http://github.com/fugue-project/fugue
|
|
8
8
|
Project-URL: Repository, http://github.com/fugue-project/fugue
|
|
9
|
-
Keywords: distributed,spark,dask,ray,sql,dsl,domain specific language
|
|
9
|
+
Keywords: distributed,spark,dask,ray,duckdb,sql,dsl,domain specific language
|
|
10
10
|
Classifier: Development Status :: 5 - Production/Stable
|
|
11
11
|
Classifier: Intended Audience :: Developers
|
|
12
12
|
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
13
13
|
Classifier: Programming Language :: Python :: 3
|
|
14
|
-
Classifier: Programming Language :: Python :: 3.10
|
|
15
14
|
Classifier: Programming Language :: Python :: 3.11
|
|
16
15
|
Classifier: Programming Language :: Python :: 3.12
|
|
17
16
|
Classifier: Programming Language :: Python :: 3.13
|
|
18
17
|
Classifier: Programming Language :: Python :: 3.14
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.15
|
|
19
19
|
Classifier: Programming Language :: Python :: 3 :: Only
|
|
20
|
-
Requires-Python: >=3.
|
|
20
|
+
Requires-Python: >=3.11
|
|
21
21
|
Description-Content-Type: text/markdown
|
|
22
22
|
License-File: LICENSE
|
|
23
|
-
Requires-Dist: triad>=1.0.
|
|
23
|
+
Requires-Dist: triad>=1.0.4
|
|
24
24
|
Requires-Dist: adagio>=0.2.6
|
|
25
|
-
Requires-Dist: pandas<3
|
|
25
|
+
Requires-Dist: pandas; python_version < "3.15"
|
|
26
|
+
Requires-Dist: pandas>=3; python_version >= "3.15"
|
|
27
|
+
Requires-Dist: packaging
|
|
26
28
|
Provides-Extra: sql
|
|
27
29
|
Requires-Dist: duckdb>=0.5.0; extra == "sql"
|
|
28
30
|
Requires-Dist: fugue-sql-antlr>=0.2.4; extra == "sql"
|
|
@@ -31,10 +33,11 @@ Requires-Dist: jinja2; extra == "sql"
|
|
|
31
33
|
Provides-Extra: cpp-sql-parser
|
|
32
34
|
Requires-Dist: fugue-sql-antlr[cpp]>=0.2.4; extra == "cpp-sql-parser"
|
|
33
35
|
Provides-Extra: spark
|
|
34
|
-
Requires-Dist: pyspark>=3.
|
|
36
|
+
Requires-Dist: pyspark>=3.5; python_version < "3.12" and extra == "spark"
|
|
37
|
+
Requires-Dist: pyspark>=4.0; python_version >= "3.12" and extra == "spark"
|
|
35
38
|
Requires-Dist: zstandard>=0.25.0; extra == "spark"
|
|
36
39
|
Provides-Extra: dask
|
|
37
|
-
Requires-Dist: dask[dataframe,distributed]>=
|
|
40
|
+
Requires-Dist: dask[dataframe,distributed]>=2025.12.0; extra == "dask"
|
|
38
41
|
Requires-Dist: pyarrow>=7.0.0; extra == "dask"
|
|
39
42
|
Requires-Dist: pandas>=2.0.2; extra == "dask"
|
|
40
43
|
Provides-Extra: ray
|
|
@@ -54,7 +57,7 @@ Provides-Extra: ibis
|
|
|
54
57
|
Requires-Dist: fugue-sql-antlr>=0.2.4; extra == "ibis"
|
|
55
58
|
Requires-Dist: sqlglot<28; extra == "ibis"
|
|
56
59
|
Requires-Dist: jinja2; extra == "ibis"
|
|
57
|
-
Requires-Dist: ibis-framework
|
|
60
|
+
Requires-Dist: ibis-framework; extra == "ibis"
|
|
58
61
|
Provides-Extra: notebook
|
|
59
62
|
Requires-Dist: notebook; extra == "notebook"
|
|
60
63
|
Requires-Dist: jupyterlab; extra == "notebook"
|
|
@@ -63,8 +66,9 @@ Provides-Extra: all
|
|
|
63
66
|
Requires-Dist: fugue-sql-antlr>=0.2.4; extra == "all"
|
|
64
67
|
Requires-Dist: sqlglot<28; extra == "all"
|
|
65
68
|
Requires-Dist: jinja2; extra == "all"
|
|
66
|
-
Requires-Dist: pyspark>=3.
|
|
67
|
-
Requires-Dist:
|
|
69
|
+
Requires-Dist: pyspark>=3.5; python_version < "3.12" and extra == "all"
|
|
70
|
+
Requires-Dist: pyspark>=4.0; python_version >= "3.12" and extra == "all"
|
|
71
|
+
Requires-Dist: dask[dataframe,distributed]>=2025.12.0; extra == "all"
|
|
68
72
|
Requires-Dist: dask-sql; extra == "all"
|
|
69
73
|
Requires-Dist: ray[data]>=2.30.0; python_version < "3.14" and extra == "all"
|
|
70
74
|
Requires-Dist: notebook; extra == "all"
|
|
@@ -73,7 +77,7 @@ Requires-Dist: ipython>=7.10.0; extra == "all"
|
|
|
73
77
|
Requires-Dist: duckdb>=0.5.0; extra == "all"
|
|
74
78
|
Requires-Dist: pyarrow>=6.0.1; extra == "all"
|
|
75
79
|
Requires-Dist: pandas>=2.0.2; extra == "all"
|
|
76
|
-
Requires-Dist: ibis-framework[duckdb
|
|
80
|
+
Requires-Dist: ibis-framework[duckdb]; extra == "all"
|
|
77
81
|
Requires-Dist: polars; extra == "all"
|
|
78
82
|
Dynamic: license-file
|
|
79
83
|
|
|
@@ -82,7 +86,7 @@ Dynamic: license-file
|
|
|
82
86
|
[](https://pypi.python.org/pypi/fugue/)
|
|
83
87
|
[](https://pypi.python.org/pypi/fugue/)
|
|
84
88
|
[](https://pypi.python.org/pypi/fugue/)
|
|
85
|
-
[](https://codecov.io/gh/fugue-project/fugue)
|
|
86
90
|
[](https://www.codacy.com/gh/fugue-project/fugue/dashboard?utm_source=github.com&utm_medium=referral&utm_content=fugue-project/fugue&utm_campaign=Badge_Grade)
|
|
87
91
|
[](https://pepy.tech/project/fugue)
|
|
88
92
|
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
[](https://pypi.python.org/pypi/fugue/)
|
|
4
4
|
[](https://pypi.python.org/pypi/fugue/)
|
|
5
5
|
[](https://pypi.python.org/pypi/fugue/)
|
|
6
|
-
[](https://codecov.io/gh/fugue-project/fugue)
|
|
7
7
|
[](https://www.codacy.com/gh/fugue-project/fugue/dashboard?utm_source=github.com&utm_medium=referral&utm_content=fugue-project/fugue&utm_campaign=Badge_Grade)
|
|
8
8
|
[](https://pepy.tech/project/fugue)
|
|
9
9
|
|
|
@@ -5,7 +5,12 @@ import pyarrow as pa
|
|
|
5
5
|
from triad.collections.schema import Schema
|
|
6
6
|
from triad.exceptions import InvalidOperationError
|
|
7
7
|
from triad.utils.assertion import assert_or_throw
|
|
8
|
-
from triad.utils.pyarrow import
|
|
8
|
+
from triad.utils.pyarrow import (
|
|
9
|
+
cast_pa_table,
|
|
10
|
+
normalize_large_types,
|
|
11
|
+
normalize_large_types_in_table,
|
|
12
|
+
pa_table_to_pandas,
|
|
13
|
+
)
|
|
9
14
|
|
|
10
15
|
from fugue.dataset.api import (
|
|
11
16
|
as_fugue_dataset,
|
|
@@ -73,6 +78,7 @@ class ArrowDataFrame(LocalBoundedDataFrame):
|
|
|
73
78
|
schema is None,
|
|
74
79
|
InvalidOperationError("can't reset schema for pa.Table"),
|
|
75
80
|
)
|
|
81
|
+
df = normalize_large_types_in_table(df)
|
|
76
82
|
self._native = df
|
|
77
83
|
super().__init__(Schema(df.schema))
|
|
78
84
|
return
|
|
@@ -253,6 +259,7 @@ def _pa_table_as_dict_iterable(
|
|
|
253
259
|
def _pa_table_alter_columns(
|
|
254
260
|
df: pa.Table, columns: Any, as_fugue: bool = False
|
|
255
261
|
) -> pa.Table:
|
|
262
|
+
df = normalize_large_types_in_table(df)
|
|
256
263
|
schema = Schema(df.schema)
|
|
257
264
|
new_schema = schema.alter(columns)
|
|
258
265
|
if schema != new_schema:
|
|
@@ -302,7 +309,7 @@ def _get_pyarrow_table_columns(df: pa.Table) -> List[Any]:
|
|
|
302
309
|
|
|
303
310
|
@get_schema.candidate(lambda df: isinstance(df, pa.Table))
|
|
304
311
|
def _get_pyarrow_table_schema(df: pa.Table) -> Schema:
|
|
305
|
-
return Schema(df.schema)
|
|
312
|
+
return Schema(normalize_large_types(df.schema))
|
|
306
313
|
|
|
307
314
|
|
|
308
315
|
@rename.candidate(lambda df, *args, **kwargs: isinstance(df, pa.Table))
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import math
|
|
1
2
|
from typing import Any, Dict, Iterable, List, Optional, Tuple
|
|
2
3
|
|
|
3
4
|
import pandas as pd
|
|
@@ -109,7 +110,17 @@ class PandasDataFrame(LocalBoundedDataFrame):
|
|
|
109
110
|
|
|
110
111
|
def peek_array(self) -> List[Any]:
|
|
111
112
|
self.assert_not_empty()
|
|
112
|
-
|
|
113
|
+
arr = self.native.iloc[0].values.tolist()
|
|
114
|
+
# missing non-float values may come back as nan / pd.NA
|
|
115
|
+
return [
|
|
116
|
+
(
|
|
117
|
+
None
|
|
118
|
+
if (v is pd.NA or (isinstance(v, float) and math.isnan(v)))
|
|
119
|
+
and not pa.types.is_floating(t)
|
|
120
|
+
else v
|
|
121
|
+
)
|
|
122
|
+
for v, t in zip(arr, self.schema.types)
|
|
123
|
+
]
|
|
113
124
|
|
|
114
125
|
def count(self) -> int:
|
|
115
126
|
return self.native.shape[0]
|
|
@@ -2,7 +2,6 @@ import logging
|
|
|
2
2
|
import os
|
|
3
3
|
from typing import Any, Callable, Dict, List, Optional, Type, Union
|
|
4
4
|
|
|
5
|
-
import numpy as np
|
|
6
5
|
import pandas as pd
|
|
7
6
|
from triad import Schema
|
|
8
7
|
from triad.collections.dict import IndexedOrderedDict
|
|
@@ -149,7 +148,7 @@ class PandasMapEngine(MapEngine):
|
|
|
149
148
|
)
|
|
150
149
|
dfs: List[DataFrame] = []
|
|
151
150
|
for p, subdf in enumerate(
|
|
152
|
-
|
|
151
|
+
_split_pandas(input_df.as_pandas(), partitions)
|
|
153
152
|
):
|
|
154
153
|
if len(subdf) > 0:
|
|
155
154
|
tdf = PandasDataFrame(subdf, df.schema, pandas_df_wrapper=True)
|
|
@@ -443,3 +442,15 @@ class _NativeExecutionEngineParam(ExecutionEngineParam):
|
|
|
443
442
|
def _to_native_execution_engine_df(df: AnyDataFrame, schema: Any = None) -> DataFrame:
|
|
444
443
|
fdf = as_fugue_df(df) if schema is None else as_fugue_df(df, schema=schema)
|
|
445
444
|
return fdf.as_local_bounded()
|
|
445
|
+
|
|
446
|
+
|
|
447
|
+
def _split_pandas(df: pd.DataFrame, n: int) -> List[pd.DataFrame]:
|
|
448
|
+
# same chunk sizes as np.array_split, which returns ndarrays on pandas 3
|
|
449
|
+
size, extra = divmod(len(df), n)
|
|
450
|
+
res: List[pd.DataFrame] = []
|
|
451
|
+
start = 0
|
|
452
|
+
for i in range(n):
|
|
453
|
+
end = start + size + (1 if i < extra else 0)
|
|
454
|
+
res.append(df.iloc[start:end].reset_index(drop=True))
|
|
455
|
+
start = end
|
|
456
|
+
return res
|
|
@@ -1,28 +1,30 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: fugue
|
|
3
|
-
Version: 0.9.
|
|
3
|
+
Version: 0.9.9.dev0
|
|
4
4
|
Summary: An abstraction layer for distributed computing
|
|
5
5
|
Author-email: The Fugue Development Team <hello@fugue.ai>
|
|
6
6
|
License: Apache-2.0
|
|
7
7
|
Project-URL: Homepage, http://github.com/fugue-project/fugue
|
|
8
8
|
Project-URL: Repository, http://github.com/fugue-project/fugue
|
|
9
|
-
Keywords: distributed,spark,dask,ray,sql,dsl,domain specific language
|
|
9
|
+
Keywords: distributed,spark,dask,ray,duckdb,sql,dsl,domain specific language
|
|
10
10
|
Classifier: Development Status :: 5 - Production/Stable
|
|
11
11
|
Classifier: Intended Audience :: Developers
|
|
12
12
|
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
13
13
|
Classifier: Programming Language :: Python :: 3
|
|
14
|
-
Classifier: Programming Language :: Python :: 3.10
|
|
15
14
|
Classifier: Programming Language :: Python :: 3.11
|
|
16
15
|
Classifier: Programming Language :: Python :: 3.12
|
|
17
16
|
Classifier: Programming Language :: Python :: 3.13
|
|
18
17
|
Classifier: Programming Language :: Python :: 3.14
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.15
|
|
19
19
|
Classifier: Programming Language :: Python :: 3 :: Only
|
|
20
|
-
Requires-Python: >=3.
|
|
20
|
+
Requires-Python: >=3.11
|
|
21
21
|
Description-Content-Type: text/markdown
|
|
22
22
|
License-File: LICENSE
|
|
23
|
-
Requires-Dist: triad>=1.0.
|
|
23
|
+
Requires-Dist: triad>=1.0.4
|
|
24
24
|
Requires-Dist: adagio>=0.2.6
|
|
25
|
-
Requires-Dist: pandas<3
|
|
25
|
+
Requires-Dist: pandas; python_version < "3.15"
|
|
26
|
+
Requires-Dist: pandas>=3; python_version >= "3.15"
|
|
27
|
+
Requires-Dist: packaging
|
|
26
28
|
Provides-Extra: sql
|
|
27
29
|
Requires-Dist: duckdb>=0.5.0; extra == "sql"
|
|
28
30
|
Requires-Dist: fugue-sql-antlr>=0.2.4; extra == "sql"
|
|
@@ -31,10 +33,11 @@ Requires-Dist: jinja2; extra == "sql"
|
|
|
31
33
|
Provides-Extra: cpp-sql-parser
|
|
32
34
|
Requires-Dist: fugue-sql-antlr[cpp]>=0.2.4; extra == "cpp-sql-parser"
|
|
33
35
|
Provides-Extra: spark
|
|
34
|
-
Requires-Dist: pyspark>=3.
|
|
36
|
+
Requires-Dist: pyspark>=3.5; python_version < "3.12" and extra == "spark"
|
|
37
|
+
Requires-Dist: pyspark>=4.0; python_version >= "3.12" and extra == "spark"
|
|
35
38
|
Requires-Dist: zstandard>=0.25.0; extra == "spark"
|
|
36
39
|
Provides-Extra: dask
|
|
37
|
-
Requires-Dist: dask[dataframe,distributed]>=
|
|
40
|
+
Requires-Dist: dask[dataframe,distributed]>=2025.12.0; extra == "dask"
|
|
38
41
|
Requires-Dist: pyarrow>=7.0.0; extra == "dask"
|
|
39
42
|
Requires-Dist: pandas>=2.0.2; extra == "dask"
|
|
40
43
|
Provides-Extra: ray
|
|
@@ -54,7 +57,7 @@ Provides-Extra: ibis
|
|
|
54
57
|
Requires-Dist: fugue-sql-antlr>=0.2.4; extra == "ibis"
|
|
55
58
|
Requires-Dist: sqlglot<28; extra == "ibis"
|
|
56
59
|
Requires-Dist: jinja2; extra == "ibis"
|
|
57
|
-
Requires-Dist: ibis-framework
|
|
60
|
+
Requires-Dist: ibis-framework; extra == "ibis"
|
|
58
61
|
Provides-Extra: notebook
|
|
59
62
|
Requires-Dist: notebook; extra == "notebook"
|
|
60
63
|
Requires-Dist: jupyterlab; extra == "notebook"
|
|
@@ -63,8 +66,9 @@ Provides-Extra: all
|
|
|
63
66
|
Requires-Dist: fugue-sql-antlr>=0.2.4; extra == "all"
|
|
64
67
|
Requires-Dist: sqlglot<28; extra == "all"
|
|
65
68
|
Requires-Dist: jinja2; extra == "all"
|
|
66
|
-
Requires-Dist: pyspark>=3.
|
|
67
|
-
Requires-Dist:
|
|
69
|
+
Requires-Dist: pyspark>=3.5; python_version < "3.12" and extra == "all"
|
|
70
|
+
Requires-Dist: pyspark>=4.0; python_version >= "3.12" and extra == "all"
|
|
71
|
+
Requires-Dist: dask[dataframe,distributed]>=2025.12.0; extra == "all"
|
|
68
72
|
Requires-Dist: dask-sql; extra == "all"
|
|
69
73
|
Requires-Dist: ray[data]>=2.30.0; python_version < "3.14" and extra == "all"
|
|
70
74
|
Requires-Dist: notebook; extra == "all"
|
|
@@ -73,7 +77,7 @@ Requires-Dist: ipython>=7.10.0; extra == "all"
|
|
|
73
77
|
Requires-Dist: duckdb>=0.5.0; extra == "all"
|
|
74
78
|
Requires-Dist: pyarrow>=6.0.1; extra == "all"
|
|
75
79
|
Requires-Dist: pandas>=2.0.2; extra == "all"
|
|
76
|
-
Requires-Dist: ibis-framework[duckdb
|
|
80
|
+
Requires-Dist: ibis-framework[duckdb]; extra == "all"
|
|
77
81
|
Requires-Dist: polars; extra == "all"
|
|
78
82
|
Dynamic: license-file
|
|
79
83
|
|
|
@@ -82,7 +86,7 @@ Dynamic: license-file
|
|
|
82
86
|
[](https://pypi.python.org/pypi/fugue/)
|
|
83
87
|
[](https://pypi.python.org/pypi/fugue/)
|
|
84
88
|
[](https://pypi.python.org/pypi/fugue/)
|
|
85
|
-
[](https://codecov.io/gh/fugue-project/fugue)
|
|
86
90
|
[](https://www.codacy.com/gh/fugue-project/fugue/dashboard?utm_source=github.com&utm_medium=referral&utm_content=fugue-project/fugue&utm_campaign=Badge_Grade)
|
|
87
91
|
[](https://pepy.tech/project/fugue)
|
|
88
92
|
|
|
@@ -1,13 +1,18 @@
|
|
|
1
|
-
triad>=1.0.
|
|
1
|
+
triad>=1.0.4
|
|
2
2
|
adagio>=0.2.6
|
|
3
|
-
|
|
3
|
+
packaging
|
|
4
|
+
|
|
5
|
+
[:python_version < "3.15"]
|
|
6
|
+
pandas
|
|
7
|
+
|
|
8
|
+
[:python_version >= "3.15"]
|
|
9
|
+
pandas>=3
|
|
4
10
|
|
|
5
11
|
[all]
|
|
6
12
|
fugue-sql-antlr>=0.2.4
|
|
7
13
|
sqlglot<28
|
|
8
14
|
jinja2
|
|
9
|
-
|
|
10
|
-
dask[dataframe,distributed]>=2024.4.0
|
|
15
|
+
dask[dataframe,distributed]>=2025.12.0
|
|
11
16
|
dask-sql
|
|
12
17
|
notebook
|
|
13
18
|
jupyterlab
|
|
@@ -15,17 +20,23 @@ ipython>=7.10.0
|
|
|
15
20
|
duckdb>=0.5.0
|
|
16
21
|
pyarrow>=6.0.1
|
|
17
22
|
pandas>=2.0.2
|
|
18
|
-
ibis-framework[duckdb
|
|
23
|
+
ibis-framework[duckdb]
|
|
19
24
|
polars
|
|
20
25
|
|
|
26
|
+
[all:python_version < "3.12"]
|
|
27
|
+
pyspark>=3.5
|
|
28
|
+
|
|
21
29
|
[all:python_version < "3.14"]
|
|
22
30
|
ray[data]>=2.30.0
|
|
23
31
|
|
|
32
|
+
[all:python_version >= "3.12"]
|
|
33
|
+
pyspark>=4.0
|
|
34
|
+
|
|
24
35
|
[cpp_sql_parser]
|
|
25
36
|
fugue-sql-antlr[cpp]>=0.2.4
|
|
26
37
|
|
|
27
38
|
[dask]
|
|
28
|
-
dask[dataframe,distributed]>=
|
|
39
|
+
dask[dataframe,distributed]>=2025.12.0
|
|
29
40
|
pyarrow>=7.0.0
|
|
30
41
|
pandas>=2.0.2
|
|
31
42
|
|
|
@@ -40,7 +51,7 @@ numpy
|
|
|
40
51
|
fugue-sql-antlr>=0.2.4
|
|
41
52
|
sqlglot<28
|
|
42
53
|
jinja2
|
|
43
|
-
ibis-framework
|
|
54
|
+
ibis-framework
|
|
44
55
|
|
|
45
56
|
[notebook]
|
|
46
57
|
notebook
|
|
@@ -59,9 +70,14 @@ pandas
|
|
|
59
70
|
ray[data]>=2.30.0
|
|
60
71
|
|
|
61
72
|
[spark]
|
|
62
|
-
pyspark>=3.1.1
|
|
63
73
|
zstandard>=0.25.0
|
|
64
74
|
|
|
75
|
+
[spark:python_version < "3.12"]
|
|
76
|
+
pyspark>=3.5
|
|
77
|
+
|
|
78
|
+
[spark:python_version >= "3.12"]
|
|
79
|
+
pyspark>=4.0
|
|
80
|
+
|
|
65
81
|
[sql]
|
|
66
82
|
duckdb>=0.5.0
|
|
67
83
|
fugue-sql-antlr>=0.2.4
|
|
@@ -169,7 +169,7 @@ class DaskMapEngine(MapEngine):
|
|
|
169
169
|
sort=False,
|
|
170
170
|
group_keys=False,
|
|
171
171
|
dropna=False,
|
|
172
|
-
).apply(_map, meta=output_dtypes)
|
|
172
|
+
)[list(df.native.columns)].apply(_map, meta=output_dtypes)
|
|
173
173
|
elif partition_spec.algo == "coarse":
|
|
174
174
|
result = pdf.native.map_partitions( # type: ignore
|
|
175
175
|
_map, meta=output_dtypes
|
|
@@ -515,7 +515,7 @@ class DaskExecutionEngine(ExecutionEngine):
|
|
|
515
515
|
)
|
|
516
516
|
|
|
517
517
|
d = (
|
|
518
|
-
d.groupby(partition_spec.partition_by, dropna=False)
|
|
518
|
+
d.groupby(partition_spec.partition_by, dropna=False)[list(d.columns)]
|
|
519
519
|
.apply(_partition_take, n=n, presort=_presort, meta=meta)
|
|
520
520
|
.reset_index(drop=True)
|
|
521
521
|
)
|
|
@@ -4,7 +4,7 @@ import pandas as pd
|
|
|
4
4
|
import pyarrow as pa
|
|
5
5
|
from duckdb import DuckDBPyRelation
|
|
6
6
|
from triad import Schema, assert_or_throw
|
|
7
|
-
from triad.utils.pyarrow import
|
|
7
|
+
from triad.utils.pyarrow import normalize_large_types_in_table
|
|
8
8
|
|
|
9
9
|
from fugue import ArrowDataFrame, DataFrame, LocalBoundedDataFrame
|
|
10
10
|
from fugue.dataframe.arrow_dataframe import _pa_table_as_pandas
|
|
@@ -166,8 +166,7 @@ def _duck_as_local(df: DuckDBPyRelation) -> DuckDBPyRelation:
|
|
|
166
166
|
@as_arrow.candidate(lambda df: isinstance(df, DuckDBPyRelation))
|
|
167
167
|
def _duck_as_arrow(df: DuckDBPyRelation) -> pa.Table:
|
|
168
168
|
_df = df.fetch_arrow_table()
|
|
169
|
-
|
|
170
|
-
return _df
|
|
169
|
+
return normalize_large_types_in_table(_df)
|
|
171
170
|
|
|
172
171
|
|
|
173
172
|
@as_pandas.candidate(lambda df: isinstance(df, DuckDBPyRelation))
|
|
@@ -6,11 +6,7 @@ import pyarrow as pa
|
|
|
6
6
|
from triad.collections.schema import Schema
|
|
7
7
|
from triad.exceptions import InvalidOperationError
|
|
8
8
|
from triad.utils.assertion import assert_or_throw
|
|
9
|
-
from triad.utils.pyarrow import
|
|
10
|
-
LARGE_TYPES_REPLACEMENT,
|
|
11
|
-
replace_types_in_schema,
|
|
12
|
-
replace_types_in_table,
|
|
13
|
-
)
|
|
9
|
+
from triad.utils.pyarrow import normalize_large_types, normalize_large_types_in_table
|
|
14
10
|
|
|
15
11
|
from fugue import ArrowDataFrame
|
|
16
12
|
from fugue.api import (
|
|
@@ -157,8 +153,7 @@ def _pl_as_local_bounded(df: pl.DataFrame) -> pl.DataFrame:
|
|
|
157
153
|
@as_arrow.candidate(lambda df: isinstance(df, pl.DataFrame))
|
|
158
154
|
def _pl_as_arrow(df: pl.DataFrame) -> pa.Table:
|
|
159
155
|
adf = df.to_arrow()
|
|
160
|
-
|
|
161
|
-
return adf
|
|
156
|
+
return normalize_large_types_in_table(adf)
|
|
162
157
|
|
|
163
158
|
|
|
164
159
|
@is_df.candidate(lambda df: isinstance(df, pl.DataFrame))
|
|
@@ -199,8 +194,7 @@ def _get_pl_columns(df: pl.DataFrame) -> List[Any]:
|
|
|
199
194
|
@get_schema.candidate(lambda df: isinstance(df, pl.DataFrame))
|
|
200
195
|
def _get_pl_schema(df: pl.DataFrame) -> Schema:
|
|
201
196
|
adf = df.to_arrow()
|
|
202
|
-
|
|
203
|
-
return Schema(schema)
|
|
197
|
+
return Schema(normalize_large_types(adf.schema))
|
|
204
198
|
|
|
205
199
|
|
|
206
200
|
@rename.candidate(lambda df, *args, **kwargs: isinstance(df, pl.DataFrame))
|
|
@@ -5,6 +5,7 @@ import pandas as pd
|
|
|
5
5
|
import pyarrow as pa
|
|
6
6
|
import ray.data as rd
|
|
7
7
|
from triad import Schema
|
|
8
|
+
from triad.utils.pyarrow import normalize_large_types
|
|
8
9
|
|
|
9
10
|
from .._constants import _ZERO_COPY
|
|
10
11
|
|
|
@@ -40,10 +41,10 @@ def get_dataset_format(df: rd.Dataset) -> Tuple[Optional[str], rd.Dataset]:
|
|
|
40
41
|
|
|
41
42
|
def to_schema(schema: Any) -> Schema: # pragma: no cover
|
|
42
43
|
if isinstance(schema, pa.Schema):
|
|
43
|
-
return Schema(schema)
|
|
44
|
+
return Schema(normalize_large_types(schema))
|
|
44
45
|
if isinstance(schema, rd.Schema):
|
|
45
46
|
if hasattr(schema, "base_schema") and isinstance(schema.base_schema, pa.Schema):
|
|
46
|
-
return Schema(schema.base_schema)
|
|
47
|
+
return Schema(normalize_large_types(schema.base_schema))
|
|
47
48
|
return Schema(list(zip(schema.names, schema.types)))
|
|
48
49
|
raise ValueError(f"{schema} is not supported")
|
|
49
50
|
|
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
import os
|
|
2
2
|
import pathlib
|
|
3
|
-
from
|
|
3
|
+
from collections.abc import Callable, Iterable
|
|
4
|
+
from typing import Any
|
|
4
5
|
|
|
5
6
|
import pyarrow as pa
|
|
6
7
|
import ray.data as rd
|
|
7
8
|
from packaging import version
|
|
8
9
|
from pyarrow import csv as pacsv
|
|
9
10
|
from pyarrow import json as pajson
|
|
10
|
-
|
|
11
11
|
from triad.collections import Schema
|
|
12
12
|
from triad.collections.dict import ParamDict
|
|
13
13
|
from triad.utils.assertion import assert_or_throw
|
|
14
|
-
from triad.utils.io import exists, makedirs, rm
|
|
14
|
+
from triad.utils.io import exists, isfile, makedirs, rm
|
|
15
15
|
|
|
16
16
|
from fugue import ExecutionEngine
|
|
17
17
|
from fugue._utils.io import FileParser, save_df
|
|
@@ -25,9 +25,7 @@ try:
|
|
|
25
25
|
from ray.data.datasource import FileExtensionFilter
|
|
26
26
|
|
|
27
27
|
class _FileFiler(FileExtensionFilter): # pragma: no cover
|
|
28
|
-
def __init__(
|
|
29
|
-
self, file_extensions: Union[str, List[str]], exclude: Iterable[str]
|
|
30
|
-
):
|
|
28
|
+
def __init__(self, file_extensions: str | list[str], exclude: Iterable[str]):
|
|
31
29
|
super().__init__(file_extensions, allow_if_no_extension=True)
|
|
32
30
|
self._exclude = set(exclude)
|
|
33
31
|
|
|
@@ -36,23 +34,23 @@ try:
|
|
|
36
34
|
path
|
|
37
35
|
).name not in self._exclude and self._file_has_extension(path)
|
|
38
36
|
|
|
39
|
-
def __call__(self, paths:
|
|
37
|
+
def __call__(self, paths: list[str]) -> list[str]:
|
|
40
38
|
return [path for path in paths if self._is_valid(path)]
|
|
41
39
|
|
|
42
40
|
except ImportError: # pragma: no cover
|
|
43
41
|
pass # ray >=2.10
|
|
44
42
|
|
|
45
43
|
|
|
46
|
-
class RayIO
|
|
44
|
+
class RayIO:
|
|
47
45
|
def __init__(self, engine: ExecutionEngine):
|
|
48
46
|
self._engine = engine
|
|
49
47
|
self._logger = engine.log
|
|
50
|
-
self._loads:
|
|
48
|
+
self._loads: dict[str, Callable[..., DataFrame]] = {
|
|
51
49
|
"csv": self._load_csv,
|
|
52
50
|
"parquet": self._load_parquet,
|
|
53
51
|
"json": self._load_json,
|
|
54
52
|
}
|
|
55
|
-
self._saves:
|
|
53
|
+
self._saves: dict[str, Callable[..., None]] = {
|
|
56
54
|
"csv": self._save_csv,
|
|
57
55
|
"parquet": self._save_parquet,
|
|
58
56
|
"json": self._save_json,
|
|
@@ -60,8 +58,8 @@ class RayIO(object):
|
|
|
60
58
|
|
|
61
59
|
def load_df(
|
|
62
60
|
self,
|
|
63
|
-
uri:
|
|
64
|
-
format_hint:
|
|
61
|
+
uri: str | list[str],
|
|
62
|
+
format_hint: str | None = None,
|
|
65
63
|
columns: Any = None,
|
|
66
64
|
**kwargs: Any,
|
|
67
65
|
) -> DataFrame:
|
|
@@ -81,8 +79,8 @@ class RayIO(object):
|
|
|
81
79
|
self,
|
|
82
80
|
df: RayDataFrame,
|
|
83
81
|
uri: str,
|
|
84
|
-
format_hint:
|
|
85
|
-
partition_spec:
|
|
82
|
+
format_hint: str | None = None,
|
|
83
|
+
partition_spec: PartitionSpec | None = None,
|
|
86
84
|
mode: str = "overwrite",
|
|
87
85
|
force_single: bool = False,
|
|
88
86
|
**kwargs: Any,
|
|
@@ -122,7 +120,7 @@ class RayIO(object):
|
|
|
122
120
|
if "header" in kw:
|
|
123
121
|
kw["include_header"] = kw.pop("header")
|
|
124
122
|
|
|
125
|
-
def _fn() ->
|
|
123
|
+
def _fn() -> dict[str, Any]: # pragma: no cover
|
|
126
124
|
return dict(write_options=pacsv.WriteOptions(**kw))
|
|
127
125
|
|
|
128
126
|
df.native.write_csv(
|
|
@@ -152,13 +150,25 @@ class RayIO(object):
|
|
|
152
150
|
)
|
|
153
151
|
|
|
154
152
|
def _load_parquet(
|
|
155
|
-
self, p:
|
|
153
|
+
self, p: list[str], columns: Any = None, **kwargs: Any
|
|
156
154
|
) -> DataFrame:
|
|
157
155
|
# in 2.52.0 the default changes to ["parquet"]
|
|
158
156
|
if "file_extensions" not in kwargs:
|
|
159
157
|
kwargs = kwargs.copy()
|
|
160
158
|
kwargs["file_extensions"] = None
|
|
161
|
-
|
|
159
|
+
# ray>=2.60 routes read_parquet to the V2 datasource by default, which
|
|
160
|
+
# (1) forces file_extensions=None to ["parquet"], so single files without
|
|
161
|
+
# extension can't be read, and (2) may raise ImportError from a threaded
|
|
162
|
+
# fsspec HTTPFileSystem import when listing multiple paths. Use V1.
|
|
163
|
+
ctx = rd.DataContext.get_current()
|
|
164
|
+
use_v2 = getattr(ctx, "use_datasource_v2", None)
|
|
165
|
+
if use_v2: # pragma: no cover
|
|
166
|
+
ctx.use_datasource_v2 = False
|
|
167
|
+
try:
|
|
168
|
+
sdf = rd.read_parquet(p, ray_remote_args=self._remote_args(), **kwargs)
|
|
169
|
+
finally:
|
|
170
|
+
if use_v2: # pragma: no cover
|
|
171
|
+
ctx.use_datasource_v2 = use_v2
|
|
162
172
|
if columns is None:
|
|
163
173
|
return RayDataFrame(sdf)
|
|
164
174
|
if isinstance(columns, list): # column names
|
|
@@ -166,20 +176,18 @@ class RayIO(object):
|
|
|
166
176
|
schema = Schema(columns)
|
|
167
177
|
return RayDataFrame(sdf)[schema.names].alter_columns(schema)
|
|
168
178
|
|
|
169
|
-
def _load_csv(
|
|
170
|
-
self, p: List[str], columns: Any = None, **kwargs: Any
|
|
171
|
-
) -> DataFrame:
|
|
179
|
+
def _load_csv(self, p: list[str], columns: Any = None, **kwargs: Any) -> DataFrame:
|
|
172
180
|
kw = ParamDict(kwargs)
|
|
173
181
|
infer_schema = kw.get("infer_schema", False)
|
|
174
|
-
read_options:
|
|
175
|
-
parse_options:
|
|
176
|
-
convert_options:
|
|
182
|
+
read_options: dict[str, Any] = {"use_threads": False}
|
|
183
|
+
parse_options: dict[str, Any] = {}
|
|
184
|
+
convert_options: dict[str, Any] = {}
|
|
177
185
|
if infer_schema and columns is not None and not isinstance(columns, list):
|
|
178
186
|
raise ValueError("can't set columns as a schema when infer schema is true")
|
|
179
187
|
|
|
180
188
|
if RAY_VERSION >= version.parse("2.10"):
|
|
181
189
|
if len(p) == 1 and isfile(p[0]): # TODO: very hacky
|
|
182
|
-
params:
|
|
190
|
+
params: dict[str, Any] = {}
|
|
183
191
|
else:
|
|
184
192
|
params = {"file_extensions": ["csv"]}
|
|
185
193
|
else: # pragma: no cover
|
|
@@ -230,14 +238,14 @@ class RayIO(object):
|
|
|
230
238
|
else: # pragma: no cover
|
|
231
239
|
raise NotImplementedError(f"{header} is not supported")
|
|
232
240
|
|
|
233
|
-
def _load_json(self, p:
|
|
234
|
-
read_options:
|
|
235
|
-
parse_options:
|
|
241
|
+
def _load_json(self, p: list[str], columns: Any = None, **kwargs: Any) -> DataFrame:
|
|
242
|
+
read_options: dict[str, Any] = {"use_threads": False}
|
|
243
|
+
parse_options: dict[str, Any] = {}
|
|
236
244
|
|
|
237
245
|
def _read_json() -> RayDataFrame: # pragma: no cover
|
|
238
246
|
if RAY_VERSION >= version.parse("2.10"):
|
|
239
247
|
if len(p) == 1 and isfile(p[0]): # TODO: very hacky
|
|
240
|
-
params:
|
|
248
|
+
params: dict[str, Any] = {"file_extensions": None}
|
|
241
249
|
else:
|
|
242
250
|
params = {"file_extensions": ["json"]}
|
|
243
251
|
elif RAY_VERSION >= version.parse("2.9"): # pragma: no cover
|
|
@@ -272,5 +280,5 @@ class RayIO(object):
|
|
|
272
280
|
schema = Schema(columns)
|
|
273
281
|
return _read_json()[schema.names].alter_columns(schema)
|
|
274
282
|
|
|
275
|
-
def _remote_args(self) ->
|
|
283
|
+
def _remote_args(self) -> dict[str, Any]:
|
|
276
284
|
return {"num_cpus": 1}
|
|
@@ -6,11 +6,14 @@ import ray
|
|
|
6
6
|
import ray.data as rd
|
|
7
7
|
from triad import assert_or_throw
|
|
8
8
|
from triad.collections.schema import Schema
|
|
9
|
-
from triad.utils.pyarrow import cast_pa_table
|
|
9
|
+
from triad.utils.pyarrow import cast_pa_table, normalize_large_types_in_table
|
|
10
10
|
|
|
11
11
|
from fugue.dataframe import ArrowDataFrame, DataFrame, LocalBoundedDataFrame
|
|
12
12
|
from fugue.dataframe.dataframe import _input_schema
|
|
13
|
-
from fugue.dataframe.utils import
|
|
13
|
+
from fugue.dataframe.utils import (
|
|
14
|
+
pa_table_as_array,
|
|
15
|
+
pa_table_as_dicts,
|
|
16
|
+
)
|
|
14
17
|
from fugue.exceptions import FugueDataFrameOperationError, FugueDatasetEmptyError
|
|
15
18
|
from fugue.plugins import (
|
|
16
19
|
as_array,
|
|
@@ -140,7 +143,8 @@ class RayDataFrame(DataFrame):
|
|
|
140
143
|
|
|
141
144
|
@property
|
|
142
145
|
def num_partitions(self) -> int:
|
|
143
|
-
|
|
146
|
+
self._native = materialize(self._native)
|
|
147
|
+
return self._native.num_blocks()
|
|
144
148
|
|
|
145
149
|
def _drop_cols(self, cols: List[str]) -> DataFrame:
|
|
146
150
|
cols = (self.schema - cols).names
|
|
@@ -263,7 +267,7 @@ def _rd_is_df(df: rd.Dataset) -> bool:
|
|
|
263
267
|
|
|
264
268
|
@get_num_partitions.candidate(lambda df: isinstance(df, rd.Dataset))
|
|
265
269
|
def _rd_num_partitions(df: rd.Dataset) -> int:
|
|
266
|
-
return df.num_blocks()
|
|
270
|
+
return materialize(df).num_blocks()
|
|
267
271
|
|
|
268
272
|
|
|
269
273
|
@as_local_bounded.candidate(lambda df: isinstance(df, rd.Dataset))
|
|
@@ -305,7 +309,7 @@ def _rd_as_pandas(df: rd.Dataset) -> pd.DataFrame:
|
|
|
305
309
|
|
|
306
310
|
@as_arrow.candidate(lambda df: isinstance(df, rd.Dataset))
|
|
307
311
|
def _rd_as_arrow(df: rd.Dataset) -> pa.Table:
|
|
308
|
-
return pa.concat_tables(_get_arrow_tables(df))
|
|
312
|
+
return normalize_large_types_in_table(pa.concat_tables(_get_arrow_tables(df)))
|
|
309
313
|
|
|
310
314
|
|
|
311
315
|
@as_array.candidate(lambda df, *args, **kwargs: isinstance(df, rd.Dataset))
|