fugue 0.9.7.dev2__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.dev2 → fugue-0.9.8}/PKG-INFO +4 -5
  2. {fugue-0.9.7.dev2 → fugue-0.9.8}/README.md +1 -1
  3. {fugue-0.9.7.dev2 → fugue-0.9.8}/fugue.egg-info/PKG-INFO +4 -5
  4. {fugue-0.9.7.dev2 → fugue-0.9.8}/fugue_ray/_utils/io.py +37 -29
  5. {fugue-0.9.7.dev2 → fugue-0.9.8}/fugue_spark/_utils/misc.py +8 -10
  6. {fugue-0.9.7.dev2 → fugue-0.9.8}/fugue_spark/execution_engine.py +11 -4
  7. {fugue-0.9.7.dev2 → fugue-0.9.8}/pyproject.toml +5 -4
  8. {fugue-0.9.7.dev2 → fugue-0.9.8}/LICENSE +0 -0
  9. {fugue-0.9.7.dev2 → fugue-0.9.8}/fugue/__init__.py +0 -0
  10. {fugue-0.9.7.dev2 → fugue-0.9.8}/fugue/_utils/__init__.py +0 -0
  11. {fugue-0.9.7.dev2 → fugue-0.9.8}/fugue/_utils/display.py +0 -0
  12. {fugue-0.9.7.dev2 → fugue-0.9.8}/fugue/_utils/exception.py +0 -0
  13. {fugue-0.9.7.dev2 → fugue-0.9.8}/fugue/_utils/interfaceless.py +0 -0
  14. {fugue-0.9.7.dev2 → fugue-0.9.8}/fugue/_utils/io.py +0 -0
  15. {fugue-0.9.7.dev2 → fugue-0.9.8}/fugue/_utils/misc.py +0 -0
  16. {fugue-0.9.7.dev2 → fugue-0.9.8}/fugue/_utils/registry.py +0 -0
  17. {fugue-0.9.7.dev2 → fugue-0.9.8}/fugue/api.py +0 -0
  18. {fugue-0.9.7.dev2 → fugue-0.9.8}/fugue/bag/__init__.py +0 -0
  19. {fugue-0.9.7.dev2 → fugue-0.9.8}/fugue/bag/array_bag.py +0 -0
  20. {fugue-0.9.7.dev2 → fugue-0.9.8}/fugue/bag/bag.py +0 -0
  21. {fugue-0.9.7.dev2 → fugue-0.9.8}/fugue/collections/__init__.py +0 -0
  22. {fugue-0.9.7.dev2 → fugue-0.9.8}/fugue/collections/partition.py +0 -0
  23. {fugue-0.9.7.dev2 → fugue-0.9.8}/fugue/collections/sql.py +0 -0
  24. {fugue-0.9.7.dev2 → fugue-0.9.8}/fugue/collections/yielded.py +0 -0
  25. {fugue-0.9.7.dev2 → fugue-0.9.8}/fugue/column/__init__.py +0 -0
  26. {fugue-0.9.7.dev2 → fugue-0.9.8}/fugue/column/expressions.py +0 -0
  27. {fugue-0.9.7.dev2 → fugue-0.9.8}/fugue/column/functions.py +0 -0
  28. {fugue-0.9.7.dev2 → fugue-0.9.8}/fugue/column/sql.py +0 -0
  29. {fugue-0.9.7.dev2 → fugue-0.9.8}/fugue/constants.py +0 -0
  30. {fugue-0.9.7.dev2 → fugue-0.9.8}/fugue/dataframe/__init__.py +0 -0
  31. {fugue-0.9.7.dev2 → fugue-0.9.8}/fugue/dataframe/api.py +0 -0
  32. {fugue-0.9.7.dev2 → fugue-0.9.8}/fugue/dataframe/array_dataframe.py +0 -0
  33. {fugue-0.9.7.dev2 → fugue-0.9.8}/fugue/dataframe/arrow_dataframe.py +0 -0
  34. {fugue-0.9.7.dev2 → fugue-0.9.8}/fugue/dataframe/dataframe.py +0 -0
  35. {fugue-0.9.7.dev2 → fugue-0.9.8}/fugue/dataframe/dataframe_iterable_dataframe.py +0 -0
  36. {fugue-0.9.7.dev2 → fugue-0.9.8}/fugue/dataframe/dataframes.py +0 -0
  37. {fugue-0.9.7.dev2 → fugue-0.9.8}/fugue/dataframe/function_wrapper.py +0 -0
  38. {fugue-0.9.7.dev2 → fugue-0.9.8}/fugue/dataframe/iterable_dataframe.py +0 -0
  39. {fugue-0.9.7.dev2 → fugue-0.9.8}/fugue/dataframe/pandas_dataframe.py +0 -0
  40. {fugue-0.9.7.dev2 → fugue-0.9.8}/fugue/dataframe/utils.py +0 -0
  41. {fugue-0.9.7.dev2 → fugue-0.9.8}/fugue/dataset/__init__.py +0 -0
  42. {fugue-0.9.7.dev2 → fugue-0.9.8}/fugue/dataset/api.py +0 -0
  43. {fugue-0.9.7.dev2 → fugue-0.9.8}/fugue/dataset/dataset.py +0 -0
  44. {fugue-0.9.7.dev2 → fugue-0.9.8}/fugue/dev.py +0 -0
  45. {fugue-0.9.7.dev2 → fugue-0.9.8}/fugue/exceptions.py +0 -0
  46. {fugue-0.9.7.dev2 → fugue-0.9.8}/fugue/execution/__init__.py +0 -0
  47. {fugue-0.9.7.dev2 → fugue-0.9.8}/fugue/execution/api.py +0 -0
  48. {fugue-0.9.7.dev2 → fugue-0.9.8}/fugue/execution/execution_engine.py +0 -0
  49. {fugue-0.9.7.dev2 → fugue-0.9.8}/fugue/execution/factory.py +0 -0
  50. {fugue-0.9.7.dev2 → fugue-0.9.8}/fugue/execution/native_execution_engine.py +0 -0
  51. {fugue-0.9.7.dev2 → fugue-0.9.8}/fugue/extensions/__init__.py +0 -0
  52. {fugue-0.9.7.dev2 → fugue-0.9.8}/fugue/extensions/_builtins/__init__.py +0 -0
  53. {fugue-0.9.7.dev2 → fugue-0.9.8}/fugue/extensions/_builtins/creators.py +0 -0
  54. {fugue-0.9.7.dev2 → fugue-0.9.8}/fugue/extensions/_builtins/outputters.py +0 -0
  55. {fugue-0.9.7.dev2 → fugue-0.9.8}/fugue/extensions/_builtins/processors.py +0 -0
  56. {fugue-0.9.7.dev2 → fugue-0.9.8}/fugue/extensions/_utils.py +0 -0
  57. {fugue-0.9.7.dev2 → fugue-0.9.8}/fugue/extensions/context.py +0 -0
  58. {fugue-0.9.7.dev2 → fugue-0.9.8}/fugue/extensions/creator/__init__.py +0 -0
  59. {fugue-0.9.7.dev2 → fugue-0.9.8}/fugue/extensions/creator/convert.py +0 -0
  60. {fugue-0.9.7.dev2 → fugue-0.9.8}/fugue/extensions/creator/creator.py +0 -0
  61. {fugue-0.9.7.dev2 → fugue-0.9.8}/fugue/extensions/outputter/__init__.py +0 -0
  62. {fugue-0.9.7.dev2 → fugue-0.9.8}/fugue/extensions/outputter/convert.py +0 -0
  63. {fugue-0.9.7.dev2 → fugue-0.9.8}/fugue/extensions/outputter/outputter.py +0 -0
  64. {fugue-0.9.7.dev2 → fugue-0.9.8}/fugue/extensions/processor/__init__.py +0 -0
  65. {fugue-0.9.7.dev2 → fugue-0.9.8}/fugue/extensions/processor/convert.py +0 -0
  66. {fugue-0.9.7.dev2 → fugue-0.9.8}/fugue/extensions/processor/processor.py +0 -0
  67. {fugue-0.9.7.dev2 → fugue-0.9.8}/fugue/extensions/transformer/__init__.py +0 -0
  68. {fugue-0.9.7.dev2 → fugue-0.9.8}/fugue/extensions/transformer/constants.py +0 -0
  69. {fugue-0.9.7.dev2 → fugue-0.9.8}/fugue/extensions/transformer/convert.py +0 -0
  70. {fugue-0.9.7.dev2 → fugue-0.9.8}/fugue/extensions/transformer/transformer.py +0 -0
  71. {fugue-0.9.7.dev2 → fugue-0.9.8}/fugue/plugins.py +0 -0
  72. {fugue-0.9.7.dev2 → fugue-0.9.8}/fugue/py.typed +0 -0
  73. {fugue-0.9.7.dev2 → fugue-0.9.8}/fugue/registry.py +0 -0
  74. {fugue-0.9.7.dev2 → fugue-0.9.8}/fugue/rpc/__init__.py +0 -0
  75. {fugue-0.9.7.dev2 → fugue-0.9.8}/fugue/rpc/base.py +0 -0
  76. {fugue-0.9.7.dev2 → fugue-0.9.8}/fugue/rpc/flask.py +0 -0
  77. {fugue-0.9.7.dev2 → fugue-0.9.8}/fugue/sql/__init__.py +0 -0
  78. {fugue-0.9.7.dev2 → fugue-0.9.8}/fugue/sql/_utils.py +0 -0
  79. {fugue-0.9.7.dev2 → fugue-0.9.8}/fugue/sql/_visitors.py +0 -0
  80. {fugue-0.9.7.dev2 → fugue-0.9.8}/fugue/sql/api.py +0 -0
  81. {fugue-0.9.7.dev2 → fugue-0.9.8}/fugue/sql/workflow.py +0 -0
  82. {fugue-0.9.7.dev2 → fugue-0.9.8}/fugue/test/__init__.py +0 -0
  83. {fugue-0.9.7.dev2 → fugue-0.9.8}/fugue/test/pandas_tester.py +0 -0
  84. {fugue-0.9.7.dev2 → fugue-0.9.8}/fugue/test/plugins.py +0 -0
  85. {fugue-0.9.7.dev2 → fugue-0.9.8}/fugue/workflow/__init__.py +0 -0
  86. {fugue-0.9.7.dev2 → fugue-0.9.8}/fugue/workflow/_checkpoint.py +0 -0
  87. {fugue-0.9.7.dev2 → fugue-0.9.8}/fugue/workflow/_tasks.py +0 -0
  88. {fugue-0.9.7.dev2 → fugue-0.9.8}/fugue/workflow/_workflow_context.py +0 -0
  89. {fugue-0.9.7.dev2 → fugue-0.9.8}/fugue/workflow/api.py +0 -0
  90. {fugue-0.9.7.dev2 → fugue-0.9.8}/fugue/workflow/input.py +0 -0
  91. {fugue-0.9.7.dev2 → fugue-0.9.8}/fugue/workflow/module.py +0 -0
  92. {fugue-0.9.7.dev2 → fugue-0.9.8}/fugue/workflow/workflow.py +0 -0
  93. {fugue-0.9.7.dev2 → fugue-0.9.8}/fugue.egg-info/SOURCES.txt +0 -0
  94. {fugue-0.9.7.dev2 → fugue-0.9.8}/fugue.egg-info/dependency_links.txt +0 -0
  95. {fugue-0.9.7.dev2 → fugue-0.9.8}/fugue.egg-info/entry_points.txt +0 -0
  96. {fugue-0.9.7.dev2 → fugue-0.9.8}/fugue.egg-info/requires.txt +0 -0
  97. {fugue-0.9.7.dev2 → fugue-0.9.8}/fugue.egg-info/top_level.txt +0 -0
  98. {fugue-0.9.7.dev2 → fugue-0.9.8}/fugue_contrib/__init__.py +0 -0
  99. {fugue-0.9.7.dev2 → fugue-0.9.8}/fugue_contrib/contrib.py +0 -0
  100. {fugue-0.9.7.dev2 → fugue-0.9.8}/fugue_contrib/seaborn/__init__.py +0 -0
  101. {fugue-0.9.7.dev2 → fugue-0.9.8}/fugue_contrib/viz/__init__.py +0 -0
  102. {fugue-0.9.7.dev2 → fugue-0.9.8}/fugue_contrib/viz/_ext.py +0 -0
  103. {fugue-0.9.7.dev2 → fugue-0.9.8}/fugue_dask/__init__.py +0 -0
  104. {fugue-0.9.7.dev2 → fugue-0.9.8}/fugue_dask/_constants.py +0 -0
  105. {fugue-0.9.7.dev2 → fugue-0.9.8}/fugue_dask/_dask_sql_wrapper.py +0 -0
  106. {fugue-0.9.7.dev2 → fugue-0.9.8}/fugue_dask/_io.py +0 -0
  107. {fugue-0.9.7.dev2 → fugue-0.9.8}/fugue_dask/_utils.py +0 -0
  108. {fugue-0.9.7.dev2 → fugue-0.9.8}/fugue_dask/dataframe.py +0 -0
  109. {fugue-0.9.7.dev2 → fugue-0.9.8}/fugue_dask/execution_engine.py +0 -0
  110. {fugue-0.9.7.dev2 → fugue-0.9.8}/fugue_dask/registry.py +0 -0
  111. {fugue-0.9.7.dev2 → fugue-0.9.8}/fugue_dask/tester.py +0 -0
  112. {fugue-0.9.7.dev2 → fugue-0.9.8}/fugue_duckdb/__init__.py +0 -0
  113. {fugue-0.9.7.dev2 → fugue-0.9.8}/fugue_duckdb/_io.py +0 -0
  114. {fugue-0.9.7.dev2 → fugue-0.9.8}/fugue_duckdb/_utils.py +0 -0
  115. {fugue-0.9.7.dev2 → fugue-0.9.8}/fugue_duckdb/dask.py +0 -0
  116. {fugue-0.9.7.dev2 → fugue-0.9.8}/fugue_duckdb/dataframe.py +0 -0
  117. {fugue-0.9.7.dev2 → fugue-0.9.8}/fugue_duckdb/execution_engine.py +0 -0
  118. {fugue-0.9.7.dev2 → fugue-0.9.8}/fugue_duckdb/registry.py +0 -0
  119. {fugue-0.9.7.dev2 → fugue-0.9.8}/fugue_duckdb/tester.py +0 -0
  120. {fugue-0.9.7.dev2 → fugue-0.9.8}/fugue_ibis/__init__.py +0 -0
  121. {fugue-0.9.7.dev2 → fugue-0.9.8}/fugue_ibis/_compat.py +0 -0
  122. {fugue-0.9.7.dev2 → fugue-0.9.8}/fugue_ibis/_utils.py +0 -0
  123. {fugue-0.9.7.dev2 → fugue-0.9.8}/fugue_ibis/dataframe.py +0 -0
  124. {fugue-0.9.7.dev2 → fugue-0.9.8}/fugue_ibis/execution_engine.py +0 -0
  125. {fugue-0.9.7.dev2 → fugue-0.9.8}/fugue_notebook/__init__.py +0 -0
  126. {fugue-0.9.7.dev2 → fugue-0.9.8}/fugue_notebook/env.py +0 -0
  127. {fugue-0.9.7.dev2 → fugue-0.9.8}/fugue_notebook/nbextension/README.md +0 -0
  128. {fugue-0.9.7.dev2 → fugue-0.9.8}/fugue_notebook/nbextension/__init__.py +0 -0
  129. {fugue-0.9.7.dev2 → fugue-0.9.8}/fugue_notebook/nbextension/description.yaml +0 -0
  130. {fugue-0.9.7.dev2 → fugue-0.9.8}/fugue_notebook/nbextension/main.js +0 -0
  131. {fugue-0.9.7.dev2 → fugue-0.9.8}/fugue_polars/__init__.py +0 -0
  132. {fugue-0.9.7.dev2 → fugue-0.9.8}/fugue_polars/_utils.py +0 -0
  133. {fugue-0.9.7.dev2 → fugue-0.9.8}/fugue_polars/polars_dataframe.py +0 -0
  134. {fugue-0.9.7.dev2 → fugue-0.9.8}/fugue_polars/registry.py +0 -0
  135. {fugue-0.9.7.dev2 → fugue-0.9.8}/fugue_ray/__init__.py +0 -0
  136. {fugue-0.9.7.dev2 → fugue-0.9.8}/fugue_ray/_constants.py +0 -0
  137. {fugue-0.9.7.dev2 → fugue-0.9.8}/fugue_ray/_utils/__init__.py +0 -0
  138. {fugue-0.9.7.dev2 → fugue-0.9.8}/fugue_ray/_utils/cluster.py +0 -0
  139. {fugue-0.9.7.dev2 → fugue-0.9.8}/fugue_ray/_utils/dataframe.py +0 -0
  140. {fugue-0.9.7.dev2 → fugue-0.9.8}/fugue_ray/dataframe.py +0 -0
  141. {fugue-0.9.7.dev2 → fugue-0.9.8}/fugue_ray/execution_engine.py +0 -0
  142. {fugue-0.9.7.dev2 → fugue-0.9.8}/fugue_ray/registry.py +0 -0
  143. {fugue-0.9.7.dev2 → fugue-0.9.8}/fugue_ray/tester.py +0 -0
  144. {fugue-0.9.7.dev2 → fugue-0.9.8}/fugue_spark/__init__.py +0 -0
  145. {fugue-0.9.7.dev2 → fugue-0.9.8}/fugue_spark/_constants.py +0 -0
  146. {fugue-0.9.7.dev2 → fugue-0.9.8}/fugue_spark/_utils/__init__.py +0 -0
  147. {fugue-0.9.7.dev2 → fugue-0.9.8}/fugue_spark/_utils/convert.py +0 -0
  148. {fugue-0.9.7.dev2 → fugue-0.9.8}/fugue_spark/_utils/io.py +0 -0
  149. {fugue-0.9.7.dev2 → fugue-0.9.8}/fugue_spark/_utils/partition.py +0 -0
  150. {fugue-0.9.7.dev2 → fugue-0.9.8}/fugue_spark/dataframe.py +0 -0
  151. {fugue-0.9.7.dev2 → fugue-0.9.8}/fugue_spark/registry.py +0 -0
  152. {fugue-0.9.7.dev2 → fugue-0.9.8}/fugue_spark/tester.py +0 -0
  153. {fugue-0.9.7.dev2 → fugue-0.9.8}/fugue_sql/__init__.py +0 -0
  154. {fugue-0.9.7.dev2 → fugue-0.9.8}/fugue_sql/exceptions.py +0 -0
  155. {fugue-0.9.7.dev2 → fugue-0.9.8}/fugue_test/__init__.py +0 -0
  156. {fugue-0.9.7.dev2 → fugue-0.9.8}/fugue_test/bag_suite.py +0 -0
  157. {fugue-0.9.7.dev2 → fugue-0.9.8}/fugue_test/builtin_suite.py +0 -0
  158. {fugue-0.9.7.dev2 → fugue-0.9.8}/fugue_test/dataframe_suite.py +0 -0
  159. {fugue-0.9.7.dev2 → fugue-0.9.8}/fugue_test/execution_suite.py +0 -0
  160. {fugue-0.9.7.dev2 → fugue-0.9.8}/fugue_test/fixtures.py +0 -0
  161. {fugue-0.9.7.dev2 → fugue-0.9.8}/setup.cfg +0 -0
@@ -1,23 +1,22 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: fugue
3
- Version: 0.9.7.dev2
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
@@ -82,7 +81,7 @@ Dynamic: license-file
82
81
  [![PyPI version](https://badge.fury.io/py/fugue.svg)](https://pypi.python.org/pypi/fugue/)
83
82
  [![PyPI pyversions](https://img.shields.io/pypi/pyversions/fugue.svg)](https://pypi.python.org/pypi/fugue/)
84
83
  [![PyPI license](https://img.shields.io/pypi/l/fugue.svg)](https://pypi.python.org/pypi/fugue/)
85
- [![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)
86
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)
87
86
  [![Downloads](https://static.pepy.tech/badge/fugue)](https://pepy.tech/project/fugue)
88
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
 
@@ -1,23 +1,22 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: fugue
3
- Version: 0.9.7.dev2
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
@@ -82,7 +81,7 @@ Dynamic: license-file
82
81
  [![PyPI version](https://badge.fury.io/py/fugue.svg)](https://pypi.python.org/pypi/fugue/)
83
82
  [![PyPI pyversions](https://img.shields.io/pypi/pyversions/fugue.svg)](https://pypi.python.org/pypi/fugue/)
84
83
  [![PyPI license](https://img.shields.io/pypi/l/fugue.svg)](https://pypi.python.org/pypi/fugue/)
85
- [![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)
86
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)
87
86
  [![Downloads](https://static.pepy.tech/badge/fugue)](https://pepy.tech/project/fugue)
88
87
 
@@ -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()
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "fugue"
7
- version = "0.9.7.dev2"
7
+ version = "0.9.8"
8
8
  description = "An abstraction layer for distributed computing"
9
9
  readme = "README.md"
10
10
  license = { text = "Apache-2.0" }
@@ -14,6 +14,7 @@ keywords = [
14
14
  "spark",
15
15
  "dask",
16
16
  "ray",
17
+ "duckdb",
17
18
  "sql",
18
19
  "dsl",
19
20
  "domain specific language",
@@ -23,14 +24,13 @@ classifiers = [
23
24
  "Intended Audience :: Developers",
24
25
  "Topic :: Software Development :: Libraries :: Python Modules",
25
26
  "Programming Language :: Python :: 3",
26
- "Programming Language :: Python :: 3.10",
27
27
  "Programming Language :: Python :: 3.11",
28
28
  "Programming Language :: Python :: 3.12",
29
29
  "Programming Language :: Python :: 3.13",
30
30
  "Programming Language :: Python :: 3.14",
31
31
  "Programming Language :: Python :: 3 :: Only",
32
32
  ]
33
- requires-python = ">=3.10"
33
+ requires-python = ">=3.11"
34
34
  dependencies = ["triad>=1.0.1", "adagio>=0.2.6", "pandas<3"]
35
35
 
36
36
  [project.urls]
@@ -114,6 +114,7 @@ dev = [
114
114
  "s3fs",
115
115
  # Specific versions for compatibility
116
116
  "pyspark[connect]",
117
+ "pyarrow<23", # pyarrow>=23 needs numpy>=2; pyspark 3.x pins numpy<2
117
118
  "duckdb-engine>=0.6.4",
118
119
  "sqlalchemy==2.0.10",
119
120
  "ray[data]>=2.30.0; python_version<'3.14'",
@@ -202,7 +203,7 @@ max-complexity = 10
202
203
  [tool.tox]
203
204
  legacy_tox_ini = """
204
205
  [tox]
205
- envlist = py39,py310,py311,py312
206
+ envlist = py311,py312,py313,py314
206
207
 
207
208
  [testenv]
208
209
  setenv =
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes