fugue 0.9.7.dev1__tar.gz → 0.9.8__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (161) hide show
  1. {fugue-0.9.7.dev1 → fugue-0.9.8}/PKG-INFO +10 -14
  2. {fugue-0.9.7.dev1 → fugue-0.9.8}/README.md +1 -1
  3. {fugue-0.9.7.dev1 → fugue-0.9.8}/fugue/__init__.py +1 -1
  4. {fugue-0.9.7.dev1 → fugue-0.9.8}/fugue/_utils/misc.py +1 -3
  5. {fugue-0.9.7.dev1 → fugue-0.9.8}/fugue/constants.py +1 -1
  6. {fugue-0.9.7.dev1 → fugue-0.9.8}/fugue/dev.py +1 -1
  7. {fugue-0.9.7.dev1 → fugue-0.9.8}/fugue/execution/__init__.py +1 -1
  8. {fugue-0.9.7.dev1 → fugue-0.9.8}/fugue/execution/native_execution_engine.py +41 -18
  9. {fugue-0.9.7.dev1 → fugue-0.9.8}/fugue/registry.py +2 -5
  10. {fugue-0.9.7.dev1 → fugue-0.9.8}/fugue.egg-info/PKG-INFO +10 -14
  11. {fugue-0.9.7.dev1 → fugue-0.9.8}/fugue.egg-info/requires.txt +6 -9
  12. {fugue-0.9.7.dev1 → fugue-0.9.8}/fugue_ray/_utils/io.py +37 -29
  13. {fugue-0.9.7.dev1 → fugue-0.9.8}/fugue_spark/_utils/misc.py +8 -10
  14. {fugue-0.9.7.dev1 → fugue-0.9.8}/fugue_spark/execution_engine.py +11 -4
  15. {fugue-0.9.7.dev1 → fugue-0.9.8}/fugue_test/builtin_suite.py +29 -16
  16. {fugue-0.9.7.dev1 → fugue-0.9.8}/fugue_test/execution_suite.py +16 -9
  17. {fugue-0.9.7.dev1 → fugue-0.9.8}/pyproject.toml +27 -38
  18. {fugue-0.9.7.dev1 → fugue-0.9.8}/LICENSE +0 -0
  19. {fugue-0.9.7.dev1 → fugue-0.9.8}/fugue/_utils/__init__.py +0 -0
  20. {fugue-0.9.7.dev1 → fugue-0.9.8}/fugue/_utils/display.py +0 -0
  21. {fugue-0.9.7.dev1 → fugue-0.9.8}/fugue/_utils/exception.py +0 -0
  22. {fugue-0.9.7.dev1 → fugue-0.9.8}/fugue/_utils/interfaceless.py +0 -0
  23. {fugue-0.9.7.dev1 → fugue-0.9.8}/fugue/_utils/io.py +0 -0
  24. {fugue-0.9.7.dev1 → fugue-0.9.8}/fugue/_utils/registry.py +0 -0
  25. {fugue-0.9.7.dev1 → fugue-0.9.8}/fugue/api.py +0 -0
  26. {fugue-0.9.7.dev1 → fugue-0.9.8}/fugue/bag/__init__.py +0 -0
  27. {fugue-0.9.7.dev1 → fugue-0.9.8}/fugue/bag/array_bag.py +0 -0
  28. {fugue-0.9.7.dev1 → fugue-0.9.8}/fugue/bag/bag.py +0 -0
  29. {fugue-0.9.7.dev1 → fugue-0.9.8}/fugue/collections/__init__.py +0 -0
  30. {fugue-0.9.7.dev1 → fugue-0.9.8}/fugue/collections/partition.py +0 -0
  31. {fugue-0.9.7.dev1 → fugue-0.9.8}/fugue/collections/sql.py +0 -0
  32. {fugue-0.9.7.dev1 → fugue-0.9.8}/fugue/collections/yielded.py +0 -0
  33. {fugue-0.9.7.dev1 → fugue-0.9.8}/fugue/column/__init__.py +0 -0
  34. {fugue-0.9.7.dev1 → fugue-0.9.8}/fugue/column/expressions.py +0 -0
  35. {fugue-0.9.7.dev1 → fugue-0.9.8}/fugue/column/functions.py +0 -0
  36. {fugue-0.9.7.dev1 → fugue-0.9.8}/fugue/column/sql.py +0 -0
  37. {fugue-0.9.7.dev1 → fugue-0.9.8}/fugue/dataframe/__init__.py +0 -0
  38. {fugue-0.9.7.dev1 → fugue-0.9.8}/fugue/dataframe/api.py +0 -0
  39. {fugue-0.9.7.dev1 → fugue-0.9.8}/fugue/dataframe/array_dataframe.py +0 -0
  40. {fugue-0.9.7.dev1 → fugue-0.9.8}/fugue/dataframe/arrow_dataframe.py +0 -0
  41. {fugue-0.9.7.dev1 → fugue-0.9.8}/fugue/dataframe/dataframe.py +0 -0
  42. {fugue-0.9.7.dev1 → fugue-0.9.8}/fugue/dataframe/dataframe_iterable_dataframe.py +0 -0
  43. {fugue-0.9.7.dev1 → fugue-0.9.8}/fugue/dataframe/dataframes.py +0 -0
  44. {fugue-0.9.7.dev1 → fugue-0.9.8}/fugue/dataframe/function_wrapper.py +0 -0
  45. {fugue-0.9.7.dev1 → fugue-0.9.8}/fugue/dataframe/iterable_dataframe.py +0 -0
  46. {fugue-0.9.7.dev1 → fugue-0.9.8}/fugue/dataframe/pandas_dataframe.py +0 -0
  47. {fugue-0.9.7.dev1 → fugue-0.9.8}/fugue/dataframe/utils.py +0 -0
  48. {fugue-0.9.7.dev1 → fugue-0.9.8}/fugue/dataset/__init__.py +0 -0
  49. {fugue-0.9.7.dev1 → fugue-0.9.8}/fugue/dataset/api.py +0 -0
  50. {fugue-0.9.7.dev1 → fugue-0.9.8}/fugue/dataset/dataset.py +0 -0
  51. {fugue-0.9.7.dev1 → fugue-0.9.8}/fugue/exceptions.py +0 -0
  52. {fugue-0.9.7.dev1 → fugue-0.9.8}/fugue/execution/api.py +0 -0
  53. {fugue-0.9.7.dev1 → fugue-0.9.8}/fugue/execution/execution_engine.py +0 -0
  54. {fugue-0.9.7.dev1 → fugue-0.9.8}/fugue/execution/factory.py +0 -0
  55. {fugue-0.9.7.dev1 → fugue-0.9.8}/fugue/extensions/__init__.py +0 -0
  56. {fugue-0.9.7.dev1 → fugue-0.9.8}/fugue/extensions/_builtins/__init__.py +0 -0
  57. {fugue-0.9.7.dev1 → fugue-0.9.8}/fugue/extensions/_builtins/creators.py +0 -0
  58. {fugue-0.9.7.dev1 → fugue-0.9.8}/fugue/extensions/_builtins/outputters.py +0 -0
  59. {fugue-0.9.7.dev1 → fugue-0.9.8}/fugue/extensions/_builtins/processors.py +0 -0
  60. {fugue-0.9.7.dev1 → fugue-0.9.8}/fugue/extensions/_utils.py +0 -0
  61. {fugue-0.9.7.dev1 → fugue-0.9.8}/fugue/extensions/context.py +0 -0
  62. {fugue-0.9.7.dev1 → fugue-0.9.8}/fugue/extensions/creator/__init__.py +0 -0
  63. {fugue-0.9.7.dev1 → fugue-0.9.8}/fugue/extensions/creator/convert.py +0 -0
  64. {fugue-0.9.7.dev1 → fugue-0.9.8}/fugue/extensions/creator/creator.py +0 -0
  65. {fugue-0.9.7.dev1 → fugue-0.9.8}/fugue/extensions/outputter/__init__.py +0 -0
  66. {fugue-0.9.7.dev1 → fugue-0.9.8}/fugue/extensions/outputter/convert.py +0 -0
  67. {fugue-0.9.7.dev1 → fugue-0.9.8}/fugue/extensions/outputter/outputter.py +0 -0
  68. {fugue-0.9.7.dev1 → fugue-0.9.8}/fugue/extensions/processor/__init__.py +0 -0
  69. {fugue-0.9.7.dev1 → fugue-0.9.8}/fugue/extensions/processor/convert.py +0 -0
  70. {fugue-0.9.7.dev1 → fugue-0.9.8}/fugue/extensions/processor/processor.py +0 -0
  71. {fugue-0.9.7.dev1 → fugue-0.9.8}/fugue/extensions/transformer/__init__.py +0 -0
  72. {fugue-0.9.7.dev1 → fugue-0.9.8}/fugue/extensions/transformer/constants.py +0 -0
  73. {fugue-0.9.7.dev1 → fugue-0.9.8}/fugue/extensions/transformer/convert.py +0 -0
  74. {fugue-0.9.7.dev1 → fugue-0.9.8}/fugue/extensions/transformer/transformer.py +0 -0
  75. {fugue-0.9.7.dev1 → fugue-0.9.8}/fugue/plugins.py +0 -0
  76. {fugue-0.9.7.dev1 → fugue-0.9.8}/fugue/py.typed +0 -0
  77. {fugue-0.9.7.dev1 → fugue-0.9.8}/fugue/rpc/__init__.py +0 -0
  78. {fugue-0.9.7.dev1 → fugue-0.9.8}/fugue/rpc/base.py +0 -0
  79. {fugue-0.9.7.dev1 → fugue-0.9.8}/fugue/rpc/flask.py +0 -0
  80. {fugue-0.9.7.dev1 → fugue-0.9.8}/fugue/sql/__init__.py +0 -0
  81. {fugue-0.9.7.dev1 → fugue-0.9.8}/fugue/sql/_utils.py +0 -0
  82. {fugue-0.9.7.dev1 → fugue-0.9.8}/fugue/sql/_visitors.py +0 -0
  83. {fugue-0.9.7.dev1 → fugue-0.9.8}/fugue/sql/api.py +0 -0
  84. {fugue-0.9.7.dev1 → fugue-0.9.8}/fugue/sql/workflow.py +0 -0
  85. {fugue-0.9.7.dev1 → fugue-0.9.8}/fugue/test/__init__.py +0 -0
  86. {fugue-0.9.7.dev1 → fugue-0.9.8}/fugue/test/pandas_tester.py +0 -0
  87. {fugue-0.9.7.dev1 → fugue-0.9.8}/fugue/test/plugins.py +0 -0
  88. {fugue-0.9.7.dev1 → fugue-0.9.8}/fugue/workflow/__init__.py +0 -0
  89. {fugue-0.9.7.dev1 → fugue-0.9.8}/fugue/workflow/_checkpoint.py +0 -0
  90. {fugue-0.9.7.dev1 → fugue-0.9.8}/fugue/workflow/_tasks.py +0 -0
  91. {fugue-0.9.7.dev1 → fugue-0.9.8}/fugue/workflow/_workflow_context.py +0 -0
  92. {fugue-0.9.7.dev1 → fugue-0.9.8}/fugue/workflow/api.py +0 -0
  93. {fugue-0.9.7.dev1 → fugue-0.9.8}/fugue/workflow/input.py +0 -0
  94. {fugue-0.9.7.dev1 → fugue-0.9.8}/fugue/workflow/module.py +0 -0
  95. {fugue-0.9.7.dev1 → fugue-0.9.8}/fugue/workflow/workflow.py +0 -0
  96. {fugue-0.9.7.dev1 → fugue-0.9.8}/fugue.egg-info/SOURCES.txt +0 -0
  97. {fugue-0.9.7.dev1 → fugue-0.9.8}/fugue.egg-info/dependency_links.txt +0 -0
  98. {fugue-0.9.7.dev1 → fugue-0.9.8}/fugue.egg-info/entry_points.txt +0 -0
  99. {fugue-0.9.7.dev1 → fugue-0.9.8}/fugue.egg-info/top_level.txt +0 -0
  100. {fugue-0.9.7.dev1 → fugue-0.9.8}/fugue_contrib/__init__.py +0 -0
  101. {fugue-0.9.7.dev1 → fugue-0.9.8}/fugue_contrib/contrib.py +0 -0
  102. {fugue-0.9.7.dev1 → fugue-0.9.8}/fugue_contrib/seaborn/__init__.py +0 -0
  103. {fugue-0.9.7.dev1 → fugue-0.9.8}/fugue_contrib/viz/__init__.py +0 -0
  104. {fugue-0.9.7.dev1 → fugue-0.9.8}/fugue_contrib/viz/_ext.py +0 -0
  105. {fugue-0.9.7.dev1 → fugue-0.9.8}/fugue_dask/__init__.py +0 -0
  106. {fugue-0.9.7.dev1 → fugue-0.9.8}/fugue_dask/_constants.py +0 -0
  107. {fugue-0.9.7.dev1 → fugue-0.9.8}/fugue_dask/_dask_sql_wrapper.py +0 -0
  108. {fugue-0.9.7.dev1 → fugue-0.9.8}/fugue_dask/_io.py +0 -0
  109. {fugue-0.9.7.dev1 → fugue-0.9.8}/fugue_dask/_utils.py +0 -0
  110. {fugue-0.9.7.dev1 → fugue-0.9.8}/fugue_dask/dataframe.py +0 -0
  111. {fugue-0.9.7.dev1 → fugue-0.9.8}/fugue_dask/execution_engine.py +0 -0
  112. {fugue-0.9.7.dev1 → fugue-0.9.8}/fugue_dask/registry.py +0 -0
  113. {fugue-0.9.7.dev1 → fugue-0.9.8}/fugue_dask/tester.py +0 -0
  114. {fugue-0.9.7.dev1 → fugue-0.9.8}/fugue_duckdb/__init__.py +0 -0
  115. {fugue-0.9.7.dev1 → fugue-0.9.8}/fugue_duckdb/_io.py +0 -0
  116. {fugue-0.9.7.dev1 → fugue-0.9.8}/fugue_duckdb/_utils.py +0 -0
  117. {fugue-0.9.7.dev1 → fugue-0.9.8}/fugue_duckdb/dask.py +0 -0
  118. {fugue-0.9.7.dev1 → fugue-0.9.8}/fugue_duckdb/dataframe.py +0 -0
  119. {fugue-0.9.7.dev1 → fugue-0.9.8}/fugue_duckdb/execution_engine.py +0 -0
  120. {fugue-0.9.7.dev1 → fugue-0.9.8}/fugue_duckdb/registry.py +0 -0
  121. {fugue-0.9.7.dev1 → fugue-0.9.8}/fugue_duckdb/tester.py +0 -0
  122. {fugue-0.9.7.dev1 → fugue-0.9.8}/fugue_ibis/__init__.py +0 -0
  123. {fugue-0.9.7.dev1 → fugue-0.9.8}/fugue_ibis/_compat.py +0 -0
  124. {fugue-0.9.7.dev1 → fugue-0.9.8}/fugue_ibis/_utils.py +0 -0
  125. {fugue-0.9.7.dev1 → fugue-0.9.8}/fugue_ibis/dataframe.py +0 -0
  126. {fugue-0.9.7.dev1 → fugue-0.9.8}/fugue_ibis/execution_engine.py +0 -0
  127. {fugue-0.9.7.dev1 → fugue-0.9.8}/fugue_notebook/__init__.py +0 -0
  128. {fugue-0.9.7.dev1 → fugue-0.9.8}/fugue_notebook/env.py +0 -0
  129. {fugue-0.9.7.dev1 → fugue-0.9.8}/fugue_notebook/nbextension/README.md +0 -0
  130. {fugue-0.9.7.dev1 → fugue-0.9.8}/fugue_notebook/nbextension/__init__.py +0 -0
  131. {fugue-0.9.7.dev1 → fugue-0.9.8}/fugue_notebook/nbextension/description.yaml +0 -0
  132. {fugue-0.9.7.dev1 → fugue-0.9.8}/fugue_notebook/nbextension/main.js +0 -0
  133. {fugue-0.9.7.dev1 → fugue-0.9.8}/fugue_polars/__init__.py +0 -0
  134. {fugue-0.9.7.dev1 → fugue-0.9.8}/fugue_polars/_utils.py +0 -0
  135. {fugue-0.9.7.dev1 → fugue-0.9.8}/fugue_polars/polars_dataframe.py +0 -0
  136. {fugue-0.9.7.dev1 → fugue-0.9.8}/fugue_polars/registry.py +0 -0
  137. {fugue-0.9.7.dev1 → fugue-0.9.8}/fugue_ray/__init__.py +0 -0
  138. {fugue-0.9.7.dev1 → fugue-0.9.8}/fugue_ray/_constants.py +0 -0
  139. {fugue-0.9.7.dev1 → fugue-0.9.8}/fugue_ray/_utils/__init__.py +0 -0
  140. {fugue-0.9.7.dev1 → fugue-0.9.8}/fugue_ray/_utils/cluster.py +0 -0
  141. {fugue-0.9.7.dev1 → fugue-0.9.8}/fugue_ray/_utils/dataframe.py +0 -0
  142. {fugue-0.9.7.dev1 → fugue-0.9.8}/fugue_ray/dataframe.py +0 -0
  143. {fugue-0.9.7.dev1 → fugue-0.9.8}/fugue_ray/execution_engine.py +0 -0
  144. {fugue-0.9.7.dev1 → fugue-0.9.8}/fugue_ray/registry.py +0 -0
  145. {fugue-0.9.7.dev1 → fugue-0.9.8}/fugue_ray/tester.py +0 -0
  146. {fugue-0.9.7.dev1 → fugue-0.9.8}/fugue_spark/__init__.py +0 -0
  147. {fugue-0.9.7.dev1 → fugue-0.9.8}/fugue_spark/_constants.py +0 -0
  148. {fugue-0.9.7.dev1 → fugue-0.9.8}/fugue_spark/_utils/__init__.py +0 -0
  149. {fugue-0.9.7.dev1 → fugue-0.9.8}/fugue_spark/_utils/convert.py +0 -0
  150. {fugue-0.9.7.dev1 → fugue-0.9.8}/fugue_spark/_utils/io.py +0 -0
  151. {fugue-0.9.7.dev1 → fugue-0.9.8}/fugue_spark/_utils/partition.py +0 -0
  152. {fugue-0.9.7.dev1 → fugue-0.9.8}/fugue_spark/dataframe.py +0 -0
  153. {fugue-0.9.7.dev1 → fugue-0.9.8}/fugue_spark/registry.py +0 -0
  154. {fugue-0.9.7.dev1 → fugue-0.9.8}/fugue_spark/tester.py +0 -0
  155. {fugue-0.9.7.dev1 → fugue-0.9.8}/fugue_sql/__init__.py +0 -0
  156. {fugue-0.9.7.dev1 → fugue-0.9.8}/fugue_sql/exceptions.py +0 -0
  157. {fugue-0.9.7.dev1 → fugue-0.9.8}/fugue_test/__init__.py +0 -0
  158. {fugue-0.9.7.dev1 → fugue-0.9.8}/fugue_test/bag_suite.py +0 -0
  159. {fugue-0.9.7.dev1 → fugue-0.9.8}/fugue_test/dataframe_suite.py +0 -0
  160. {fugue-0.9.7.dev1 → fugue-0.9.8}/fugue_test/fixtures.py +0 -0
  161. {fugue-0.9.7.dev1 → fugue-0.9.8}/setup.cfg +0 -0
@@ -1,35 +1,34 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: fugue
3
- Version: 0.9.7.dev1
3
+ Version: 0.9.8
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
19
18
  Classifier: Programming Language :: Python :: 3 :: Only
20
- Requires-Python: >=3.10
19
+ Requires-Python: >=3.11
21
20
  Description-Content-Type: text/markdown
22
21
  License-File: LICENSE
23
22
  Requires-Dist: triad>=1.0.1
24
23
  Requires-Dist: adagio>=0.2.6
25
24
  Requires-Dist: pandas<3
26
25
  Provides-Extra: sql
27
- Requires-Dist: qpd>=0.4.4; extra == "sql"
28
- Requires-Dist: fugue-sql-antlr>=0.2.0; extra == "sql"
26
+ Requires-Dist: duckdb>=0.5.0; extra == "sql"
27
+ Requires-Dist: fugue-sql-antlr>=0.2.4; extra == "sql"
29
28
  Requires-Dist: sqlglot<28; extra == "sql"
30
29
  Requires-Dist: jinja2; extra == "sql"
31
30
  Provides-Extra: cpp-sql-parser
32
- Requires-Dist: fugue-sql-antlr[cpp]>=0.2.0; extra == "cpp-sql-parser"
31
+ Requires-Dist: fugue-sql-antlr[cpp]>=0.2.4; extra == "cpp-sql-parser"
33
32
  Provides-Extra: spark
34
33
  Requires-Dist: pyspark>=3.1.1; extra == "spark"
35
34
  Requires-Dist: zstandard>=0.25.0; extra == "spark"
@@ -43,8 +42,7 @@ Requires-Dist: duckdb>=0.5.0; extra == "ray"
43
42
  Requires-Dist: pyarrow>=7.0.0; extra == "ray"
44
43
  Requires-Dist: pandas; extra == "ray"
45
44
  Provides-Extra: duckdb
46
- Requires-Dist: qpd>=0.4.4; extra == "duckdb"
47
- Requires-Dist: fugue-sql-antlr>=0.2.0; extra == "duckdb"
45
+ Requires-Dist: fugue-sql-antlr>=0.2.4; extra == "duckdb"
48
46
  Requires-Dist: sqlglot<28; extra == "duckdb"
49
47
  Requires-Dist: jinja2; extra == "duckdb"
50
48
  Requires-Dist: duckdb>=0.5.0; extra == "duckdb"
@@ -52,8 +50,7 @@ Requires-Dist: numpy; extra == "duckdb"
52
50
  Provides-Extra: polars
53
51
  Requires-Dist: polars; extra == "polars"
54
52
  Provides-Extra: ibis
55
- Requires-Dist: qpd>=0.4.4; extra == "ibis"
56
- Requires-Dist: fugue-sql-antlr>=0.2.0; extra == "ibis"
53
+ Requires-Dist: fugue-sql-antlr>=0.2.4; extra == "ibis"
57
54
  Requires-Dist: sqlglot<28; extra == "ibis"
58
55
  Requires-Dist: jinja2; extra == "ibis"
59
56
  Requires-Dist: ibis-framework[pandas]; extra == "ibis"
@@ -62,8 +59,7 @@ Requires-Dist: notebook; extra == "notebook"
62
59
  Requires-Dist: jupyterlab; extra == "notebook"
63
60
  Requires-Dist: ipython>=7.10.0; extra == "notebook"
64
61
  Provides-Extra: all
65
- Requires-Dist: qpd>=0.4.4; extra == "all"
66
- Requires-Dist: fugue-sql-antlr>=0.2.0; extra == "all"
62
+ Requires-Dist: fugue-sql-antlr>=0.2.4; extra == "all"
67
63
  Requires-Dist: sqlglot<28; extra == "all"
68
64
  Requires-Dist: jinja2; extra == "all"
69
65
  Requires-Dist: pyspark>=3.1.1; extra == "all"
@@ -85,7 +81,7 @@ Dynamic: license-file
85
81
  [![PyPI version](https://badge.fury.io/py/fugue.svg)](https://pypi.python.org/pypi/fugue/)
86
82
  [![PyPI pyversions](https://img.shields.io/pypi/pyversions/fugue.svg)](https://pypi.python.org/pypi/fugue/)
87
83
  [![PyPI license](https://img.shields.io/pypi/l/fugue.svg)](https://pypi.python.org/pypi/fugue/)
88
- [![codecov](https://codecov.io/gh/fugue-project/fugue/branch/main/graph/badge.svg?token=ZO9YD5N3IA)](https://codecov.io/gh/fugue-project/fugue)
84
+ [![codecov](https://codecov.io/gh/fugue-project/fugue/graph/badge.svg?token=ZO9YD5N3IA)](https://codecov.io/gh/fugue-project/fugue)
89
85
  [![Codacy Badge](https://app.codacy.com/project/badge/Grade/4fa5f2f53e6f48aaa1218a89f4808b91)](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)
90
86
  [![Downloads](https://static.pepy.tech/badge/fugue)](https://pepy.tech/project/fugue)
91
87
 
@@ -3,7 +3,7 @@
3
3
  [![PyPI version](https://badge.fury.io/py/fugue.svg)](https://pypi.python.org/pypi/fugue/)
4
4
  [![PyPI pyversions](https://img.shields.io/pypi/pyversions/fugue.svg)](https://pypi.python.org/pypi/fugue/)
5
5
  [![PyPI license](https://img.shields.io/pypi/l/fugue.svg)](https://pypi.python.org/pypi/fugue/)
6
- [![codecov](https://codecov.io/gh/fugue-project/fugue/branch/main/graph/badge.svg?token=ZO9YD5N3IA)](https://codecov.io/gh/fugue-project/fugue)
6
+ [![codecov](https://codecov.io/gh/fugue-project/fugue/graph/badge.svg?token=ZO9YD5N3IA)](https://codecov.io/gh/fugue-project/fugue)
7
7
  [![Codacy Badge](https://app.codacy.com/project/badge/Grade/4fa5f2f53e6f48aaa1218a89f4808b91)](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
  [![Downloads](https://static.pepy.tech/badge/fugue)](https://pepy.tech/project/fugue)
9
9
 
@@ -55,7 +55,7 @@ from fugue.execution.factory import (
55
55
  from fugue.execution.native_execution_engine import (
56
56
  NativeExecutionEngine,
57
57
  PandasMapEngine,
58
- QPDPandasEngine,
58
+ DefaultSQLEngine,
59
59
  )
60
60
  from fugue.extensions.creator import Creator, creator, register_creator
61
61
  from fugue.extensions.outputter import Outputter, outputter, register_outputter
@@ -23,6 +23,4 @@ def import_or_throw(package_name: str, message: str) -> Any:
23
23
 
24
24
 
25
25
  def import_fsql_dependency(package_name: str) -> Any:
26
- return import_or_throw(
27
- package_name, "Please try to install the package by `pip install fugue[sql]`."
28
- )
26
+ return import_or_throw(package_name, "Please pip install with extra `fugue[sql]`.")
@@ -37,7 +37,7 @@ _FUGUE_GLOBAL_CONF = ParamDict(
37
37
  FUGUE_CONF_WORKFLOW_CONCURRENCY: 1,
38
38
  FUGUE_CONF_WORKFLOW_AUTO_PERSIST: False,
39
39
  FUGUE_CONF_WORKFLOW_EXCEPTION_HIDE: "fugue.,six,adagio.,pandas,"
40
- "fugue_dask.,dask.,fugue_spark.,pyspark.,antlr4,_qpd_antlr,qpd,triad,"
40
+ "fugue_dask.,dask.,fugue_spark.,pyspark.,antlr4,triad,"
41
41
  "fugue_notebook.,ipython.,jupyter.,ipykernel,_pytest,pytest,fugue_ibis.",
42
42
  FUGUE_CONF_WORKFLOW_EXCEPTION_INJECT: 3,
43
43
  FUGUE_CONF_WORKFLOW_EXCEPTION_OPTIMIZE: True,
@@ -32,7 +32,7 @@ from fugue.execution.factory import (
32
32
  register_execution_engine,
33
33
  register_sql_engine,
34
34
  )
35
- from fugue.execution.native_execution_engine import PandasMapEngine, QPDPandasEngine
35
+ from fugue.execution.native_execution_engine import PandasMapEngine, DefaultSQLEngine
36
36
  from fugue.rpc import (
37
37
  EmptyRPCHandler,
38
38
  RPCClient,
@@ -10,4 +10,4 @@ from .factory import (
10
10
  register_execution_engine,
11
11
  register_sql_engine,
12
12
  )
13
- from .native_execution_engine import NativeExecutionEngine, QPDPandasEngine
13
+ from .native_execution_engine import NativeExecutionEngine, DefaultSQLEngine
@@ -11,7 +11,6 @@ from triad.utils.io import makedirs
11
11
  from triad.utils.pandas_like import PandasUtils
12
12
 
13
13
  from fugue._utils.io import load_df, save_df
14
- from fugue._utils.misc import import_fsql_dependency
15
14
  from fugue.collections.partition import (
16
15
  PartitionCursor,
17
16
  PartitionSpec,
@@ -21,6 +20,7 @@ from fugue.collections.sql import StructuredRawSQL
21
20
  from fugue.constants import KEYWORD_PARALLELISM, KEYWORD_ROWCOUNT
22
21
  from fugue.dataframe import (
23
22
  AnyDataFrame,
23
+ ArrowDataFrame,
24
24
  DataFrame,
25
25
  DataFrames,
26
26
  LocalBoundedDataFrame,
@@ -39,31 +39,53 @@ from .execution_engine import (
39
39
  )
40
40
 
41
41
 
42
- class QPDPandasEngine(SQLEngine):
43
- """QPD execution implementation.
42
+ class DefaultSQLEngine(SQLEngine):
43
+ """DuckDB SQL backend implementation.
44
44
 
45
45
  :param execution_engine: the execution engine this sql engine will run on
46
46
  """
47
47
 
48
48
  @property
49
49
  def dialect(self) -> Optional[str]:
50
- return "spark"
51
-
52
- def to_df(self, df: AnyDataFrame, schema: Any = None) -> DataFrame:
53
- return _to_native_execution_engine_df(df, schema)
54
-
55
- @property
56
- def is_distributed(self) -> bool:
57
- return False
50
+ return "duckdb"
58
51
 
59
52
  def select(self, dfs: DataFrames, statement: StructuredRawSQL) -> DataFrame:
60
- qpd_pandas = import_fsql_dependency("qpd_pandas")
53
+ import duckdb
54
+
55
+ from fugue_duckdb.dataframe import _duck_as_arrow
61
56
 
62
57
  _dfs, _sql = self.encode(dfs, statement)
63
- _dd = {k: self.to_df(v).as_pandas() for k, v in _dfs.items()} # type: ignore
64
58
 
65
- df = qpd_pandas.run_sql_on_pandas(_sql, _dd, ignore_case=True)
66
- return self.to_df(df)
59
+ with duckdb.connect() as conn:
60
+ for k, v in _dfs.items():
61
+ duckdb.from_arrow(v.as_arrow(), connection=conn).create_view(k)
62
+ return ArrowDataFrame(_duck_as_arrow(conn.sql(_sql)))
63
+
64
+ def table_exists(self, table: str) -> bool: # pragma: no cover
65
+ raise NotImplementedError(
66
+ "table_exists can only be used with DuckExecutionEngine"
67
+ )
68
+
69
+ def save_table(
70
+ self,
71
+ df: DataFrame,
72
+ table: str,
73
+ mode: str = "overwrite",
74
+ partition_spec: Optional[PartitionSpec] = None,
75
+ **kwargs: Any,
76
+ ) -> None: # pragma: no cover
77
+ raise NotImplementedError(
78
+ "save_table can only be used with DuckExecutionEngine"
79
+ )
80
+
81
+ def load_table(self, table: str, **kwargs: Any) -> DataFrame: # pragma: no cover
82
+ raise NotImplementedError(
83
+ "load_table can only be used with DuckExecutionEngine"
84
+ )
85
+
86
+ @property
87
+ def is_distributed(self) -> bool:
88
+ return False
67
89
 
68
90
 
69
91
  class PandasMapEngine(MapEngine):
@@ -148,8 +170,9 @@ class PandasMapEngine(MapEngine):
148
170
  output_df = PandasDataFrame(output_df.native, output_schema)
149
171
  assert_or_throw(
150
172
  output_df.schema == output_schema,
151
- lambda: f"map output {output_df.schema} "
152
- f"mismatches given {output_schema}",
173
+ lambda: (
174
+ f"map output {output_df.schema} mismatches given {output_schema}"
175
+ ),
153
176
  )
154
177
  return self.to_df(output_df) # type: ignore
155
178
 
@@ -194,7 +217,7 @@ class NativeExecutionEngine(ExecutionEngine):
194
217
  return False
195
218
 
196
219
  def create_default_sql_engine(self) -> SQLEngine:
197
- return QPDPandasEngine(self)
220
+ return DefaultSQLEngine(self)
198
221
 
199
222
  def create_default_map_engine(self) -> MapEngine:
200
223
  return PandasMapEngine(self)
@@ -1,7 +1,7 @@
1
1
  from fugue.execution.factory import register_execution_engine, register_sql_engine
2
2
  from fugue.execution.native_execution_engine import (
3
+ DefaultSQLEngine,
3
4
  NativeExecutionEngine,
4
- QPDPandasEngine,
5
5
  )
6
6
 
7
7
 
@@ -25,8 +25,5 @@ def _register_engines() -> None:
25
25
  "pandas", lambda conf: NativeExecutionEngine(conf), on_dup="ignore"
26
26
  )
27
27
  register_sql_engine(
28
- "qpdpandas", lambda engine: QPDPandasEngine(engine), on_dup="ignore"
29
- )
30
- register_sql_engine(
31
- "qpd_pandas", lambda engine: QPDPandasEngine(engine), on_dup="ignore"
28
+ "default", lambda engine: DefaultSQLEngine(engine), on_dup="ignore"
32
29
  )
@@ -1,35 +1,34 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: fugue
3
- Version: 0.9.7.dev1
3
+ Version: 0.9.8
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
19
18
  Classifier: Programming Language :: Python :: 3 :: Only
20
- Requires-Python: >=3.10
19
+ Requires-Python: >=3.11
21
20
  Description-Content-Type: text/markdown
22
21
  License-File: LICENSE
23
22
  Requires-Dist: triad>=1.0.1
24
23
  Requires-Dist: adagio>=0.2.6
25
24
  Requires-Dist: pandas<3
26
25
  Provides-Extra: sql
27
- Requires-Dist: qpd>=0.4.4; extra == "sql"
28
- Requires-Dist: fugue-sql-antlr>=0.2.0; extra == "sql"
26
+ Requires-Dist: duckdb>=0.5.0; extra == "sql"
27
+ Requires-Dist: fugue-sql-antlr>=0.2.4; extra == "sql"
29
28
  Requires-Dist: sqlglot<28; extra == "sql"
30
29
  Requires-Dist: jinja2; extra == "sql"
31
30
  Provides-Extra: cpp-sql-parser
32
- Requires-Dist: fugue-sql-antlr[cpp]>=0.2.0; extra == "cpp-sql-parser"
31
+ Requires-Dist: fugue-sql-antlr[cpp]>=0.2.4; extra == "cpp-sql-parser"
33
32
  Provides-Extra: spark
34
33
  Requires-Dist: pyspark>=3.1.1; extra == "spark"
35
34
  Requires-Dist: zstandard>=0.25.0; extra == "spark"
@@ -43,8 +42,7 @@ Requires-Dist: duckdb>=0.5.0; extra == "ray"
43
42
  Requires-Dist: pyarrow>=7.0.0; extra == "ray"
44
43
  Requires-Dist: pandas; extra == "ray"
45
44
  Provides-Extra: duckdb
46
- Requires-Dist: qpd>=0.4.4; extra == "duckdb"
47
- Requires-Dist: fugue-sql-antlr>=0.2.0; extra == "duckdb"
45
+ Requires-Dist: fugue-sql-antlr>=0.2.4; extra == "duckdb"
48
46
  Requires-Dist: sqlglot<28; extra == "duckdb"
49
47
  Requires-Dist: jinja2; extra == "duckdb"
50
48
  Requires-Dist: duckdb>=0.5.0; extra == "duckdb"
@@ -52,8 +50,7 @@ Requires-Dist: numpy; extra == "duckdb"
52
50
  Provides-Extra: polars
53
51
  Requires-Dist: polars; extra == "polars"
54
52
  Provides-Extra: ibis
55
- Requires-Dist: qpd>=0.4.4; extra == "ibis"
56
- Requires-Dist: fugue-sql-antlr>=0.2.0; extra == "ibis"
53
+ Requires-Dist: fugue-sql-antlr>=0.2.4; extra == "ibis"
57
54
  Requires-Dist: sqlglot<28; extra == "ibis"
58
55
  Requires-Dist: jinja2; extra == "ibis"
59
56
  Requires-Dist: ibis-framework[pandas]; extra == "ibis"
@@ -62,8 +59,7 @@ Requires-Dist: notebook; extra == "notebook"
62
59
  Requires-Dist: jupyterlab; extra == "notebook"
63
60
  Requires-Dist: ipython>=7.10.0; extra == "notebook"
64
61
  Provides-Extra: all
65
- Requires-Dist: qpd>=0.4.4; extra == "all"
66
- Requires-Dist: fugue-sql-antlr>=0.2.0; extra == "all"
62
+ Requires-Dist: fugue-sql-antlr>=0.2.4; extra == "all"
67
63
  Requires-Dist: sqlglot<28; extra == "all"
68
64
  Requires-Dist: jinja2; extra == "all"
69
65
  Requires-Dist: pyspark>=3.1.1; extra == "all"
@@ -85,7 +81,7 @@ Dynamic: license-file
85
81
  [![PyPI version](https://badge.fury.io/py/fugue.svg)](https://pypi.python.org/pypi/fugue/)
86
82
  [![PyPI pyversions](https://img.shields.io/pypi/pyversions/fugue.svg)](https://pypi.python.org/pypi/fugue/)
87
83
  [![PyPI license](https://img.shields.io/pypi/l/fugue.svg)](https://pypi.python.org/pypi/fugue/)
88
- [![codecov](https://codecov.io/gh/fugue-project/fugue/branch/main/graph/badge.svg?token=ZO9YD5N3IA)](https://codecov.io/gh/fugue-project/fugue)
84
+ [![codecov](https://codecov.io/gh/fugue-project/fugue/graph/badge.svg?token=ZO9YD5N3IA)](https://codecov.io/gh/fugue-project/fugue)
89
85
  [![Codacy Badge](https://app.codacy.com/project/badge/Grade/4fa5f2f53e6f48aaa1218a89f4808b91)](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)
90
86
  [![Downloads](https://static.pepy.tech/badge/fugue)](https://pepy.tech/project/fugue)
91
87
 
@@ -3,8 +3,7 @@ adagio>=0.2.6
3
3
  pandas<3
4
4
 
5
5
  [all]
6
- qpd>=0.4.4
7
- fugue-sql-antlr>=0.2.0
6
+ fugue-sql-antlr>=0.2.4
8
7
  sqlglot<28
9
8
  jinja2
10
9
  pyspark>=3.1.1
@@ -23,7 +22,7 @@ polars
23
22
  ray[data]>=2.30.0
24
23
 
25
24
  [cpp_sql_parser]
26
- fugue-sql-antlr[cpp]>=0.2.0
25
+ fugue-sql-antlr[cpp]>=0.2.4
27
26
 
28
27
  [dask]
29
28
  dask[dataframe,distributed]>=2024.4.0
@@ -31,16 +30,14 @@ pyarrow>=7.0.0
31
30
  pandas>=2.0.2
32
31
 
33
32
  [duckdb]
34
- qpd>=0.4.4
35
- fugue-sql-antlr>=0.2.0
33
+ fugue-sql-antlr>=0.2.4
36
34
  sqlglot<28
37
35
  jinja2
38
36
  duckdb>=0.5.0
39
37
  numpy
40
38
 
41
39
  [ibis]
42
- qpd>=0.4.4
43
- fugue-sql-antlr>=0.2.0
40
+ fugue-sql-antlr>=0.2.4
44
41
  sqlglot<28
45
42
  jinja2
46
43
  ibis-framework[pandas]
@@ -66,7 +63,7 @@ pyspark>=3.1.1
66
63
  zstandard>=0.25.0
67
64
 
68
65
  [sql]
69
- qpd>=0.4.4
70
- fugue-sql-antlr>=0.2.0
66
+ duckdb>=0.5.0
67
+ fugue-sql-antlr>=0.2.4
71
68
  sqlglot<28
72
69
  jinja2
@@ -1,17 +1,17 @@
1
1
  import os
2
2
  import pathlib
3
- from typing import Any, Callable, Dict, Iterable, List, Optional, Union
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, isfile
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: List[str]) -> List[str]:
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(object):
44
+ class RayIO:
47
45
  def __init__(self, engine: ExecutionEngine):
48
46
  self._engine = engine
49
47
  self._logger = engine.log
50
- self._loads: Dict[str, Callable[..., DataFrame]] = {
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: Dict[str, Callable[..., None]] = {
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: Union[str, List[str]],
64
- format_hint: Optional[str] = None,
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: Optional[str] = None,
85
- partition_spec: Optional[PartitionSpec] = None,
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() -> Dict[str, Any]: # pragma: no cover
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: List[str], columns: Any = None, **kwargs: Any
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
- sdf = rd.read_parquet(p, ray_remote_args=self._remote_args(), **kwargs)
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( # noqa: C901
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: Dict[str, Any] = {"use_threads": False}
175
- parse_options: Dict[str, Any] = {}
176
- convert_options: Dict[str, Any] = {}
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: Dict[str, Any] = {}
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: List[str], columns: Any = None, **kwargs: Any) -> DataFrame:
234
- read_options: Dict[str, Any] = {"use_threads": False}
235
- parse_options: Dict[str, Any] = {}
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: Dict[str, Any] = {"file_extensions": None}
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) -> Dict[str, Any]:
283
+ def _remote_args(self) -> dict[str, Any]:
276
284
  return {"num_cpus": 1}
@@ -1,25 +1,23 @@
1
1
  import pyspark.sql as ps
2
- import pyspark
3
2
  from typing import Any
4
3
 
5
4
 
6
- SPARK_VERSION = pyspark.__version__.split(".")
5
+ try:
6
+ from pyspark.sql import is_remote as _is_remote
7
+ except ImportError: # pragma: no cover
8
+ _is_remote = None
7
9
 
8
10
  try:
9
- if int(SPARK_VERSION[0]) >= 4:
10
- from pyspark.sql import SparkSession as SparkConnectSession
11
- from pyspark.sql import DataFrame as SparkConnectDataFrame
12
- else: # pragma: no cover
13
- from pyspark.sql.connect.session import SparkSession as SparkConnectSession
14
- from pyspark.sql.connect.dataframe import DataFrame as SparkConnectDataFrame
11
+ from pyspark.sql.connect.session import SparkSession as SparkConnectSession
12
+ from pyspark.sql.connect.dataframe import DataFrame as SparkConnectDataFrame
15
13
  except Exception: # pragma: no cover
16
14
  SparkConnectSession = None
17
15
  SparkConnectDataFrame = None
18
16
 
19
17
 
20
18
  def is_spark_connect(session: Any) -> bool: # pragma: no cover
21
- if int(SPARK_VERSION[0]) >= 4:
22
- return False
19
+ if _is_remote is not None:
20
+ return _is_remote()
23
21
  return SparkConnectSession is not None and isinstance(
24
22
  session, (SparkConnectSession, SparkConnectDataFrame)
25
23
  )
@@ -403,10 +403,17 @@ class SparkExecutionEngine(ExecutionEngine):
403
403
  def get_current_parallelism(self) -> int:
404
404
  spark = self.spark_session
405
405
  if self.is_spark_connect: # pragma: no cover
406
- num = spark.conf.get("spark.default.parallelism", "")
407
- if num != "":
408
- return int(num)
409
- return int(spark.conf.get("spark.sql.shuffle.partitions", "200"))
406
+ for key in (
407
+ "spark.default.parallelism",
408
+ "spark.sql.shuffle.partitions",
409
+ ):
410
+ try:
411
+ value = spark.conf.get(key, "")
412
+ except Exception:
413
+ continue
414
+ if value != "":
415
+ return int(value)
416
+ return 200
410
417
  e_cores = int(spark.conf.get("spark.executor.cores", "1"))
411
418
  tc = int(spark.conf.get("spark.task.cpus", "1"))
412
419
  sc = spark._jsc.sc()