polars-df 0.20.0 → 0.21.0

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 (88) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +11 -0
  3. data/Cargo.lock +192 -186
  4. data/LICENSE.txt +1 -1
  5. data/ext/polars/Cargo.toml +13 -9
  6. data/ext/polars/src/batched_csv.rs +2 -2
  7. data/ext/polars/src/catalog/mod.rs +1 -0
  8. data/ext/polars/src/catalog/unity.rs +450 -0
  9. data/ext/polars/src/conversion/any_value.rs +9 -19
  10. data/ext/polars/src/conversion/categorical.rs +30 -0
  11. data/ext/polars/src/conversion/chunked_array.rs +8 -8
  12. data/ext/polars/src/conversion/mod.rs +187 -109
  13. data/ext/polars/src/dataframe/construction.rs +2 -2
  14. data/ext/polars/src/dataframe/export.rs +2 -2
  15. data/ext/polars/src/dataframe/general.rs +4 -2
  16. data/ext/polars/src/dataframe/io.rs +2 -2
  17. data/ext/polars/src/exceptions.rs +1 -1
  18. data/ext/polars/src/expr/datatype.rs +14 -0
  19. data/ext/polars/src/expr/general.rs +22 -17
  20. data/ext/polars/src/expr/list.rs +21 -2
  21. data/ext/polars/src/expr/meta.rs +0 -34
  22. data/ext/polars/src/expr/mod.rs +3 -1
  23. data/ext/polars/src/expr/name.rs +2 -2
  24. data/ext/polars/src/expr/rolling.rs +1 -1
  25. data/ext/polars/src/expr/selector.rs +219 -0
  26. data/ext/polars/src/expr/string.rs +14 -6
  27. data/ext/polars/src/file.rs +11 -5
  28. data/ext/polars/src/functions/io.rs +2 -11
  29. data/ext/polars/src/functions/lazy.rs +22 -54
  30. data/ext/polars/src/functions/meta.rs +2 -2
  31. data/ext/polars/src/functions/misc.rs +1 -1
  32. data/ext/polars/src/functions/string_cache.rs +4 -5
  33. data/ext/polars/src/interop/numo/numo_rs.rs +1 -1
  34. data/ext/polars/src/interop/numo/to_numo_series.rs +1 -1
  35. data/ext/polars/src/io/mod.rs +102 -0
  36. data/ext/polars/src/lazyframe/general.rs +74 -112
  37. data/ext/polars/src/lazyframe/serde.rs +1 -1
  38. data/ext/polars/src/lazyframe/sink.rs +6 -6
  39. data/ext/polars/src/lib.rs +98 -20
  40. data/ext/polars/src/map/dataframe.rs +7 -7
  41. data/ext/polars/src/map/lazy.rs +1 -1
  42. data/ext/polars/src/map/mod.rs +31 -19
  43. data/ext/polars/src/map/series.rs +8 -8
  44. data/ext/polars/src/on_startup.rs +5 -2
  45. data/ext/polars/src/rb_modules.rs +1 -1
  46. data/ext/polars/src/series/construction.rs +11 -7
  47. data/ext/polars/src/series/export.rs +6 -4
  48. data/ext/polars/src/series/general.rs +12 -207
  49. data/ext/polars/src/series/import.rs +2 -2
  50. data/ext/polars/src/series/map.rs +227 -0
  51. data/ext/polars/src/series/mod.rs +2 -1
  52. data/ext/polars/src/series/scatter.rs +1 -1
  53. data/ext/polars/src/utils.rs +10 -2
  54. data/lib/polars/cat_name_space.rb +3 -43
  55. data/lib/polars/catalog/unity/catalog_info.rb +20 -0
  56. data/lib/polars/catalog/unity/column_info.rb +31 -0
  57. data/lib/polars/catalog/unity/namespace_info.rb +21 -0
  58. data/lib/polars/catalog/unity/table_info.rb +50 -0
  59. data/lib/polars/catalog.rb +448 -0
  60. data/lib/polars/convert.rb +10 -0
  61. data/lib/polars/data_frame.rb +151 -30
  62. data/lib/polars/data_types.rb +47 -3
  63. data/lib/polars/exceptions.rb +7 -2
  64. data/lib/polars/expr.rb +34 -31
  65. data/lib/polars/functions/col.rb +6 -5
  66. data/lib/polars/functions/lazy.rb +114 -15
  67. data/lib/polars/functions/repeat.rb +4 -0
  68. data/lib/polars/io/csv.rb +18 -0
  69. data/lib/polars/io/json.rb +16 -0
  70. data/lib/polars/io/ndjson.rb +13 -0
  71. data/lib/polars/io/parquet.rb +45 -63
  72. data/lib/polars/io/scan_options.rb +47 -0
  73. data/lib/polars/lazy_frame.rb +163 -75
  74. data/lib/polars/list_expr.rb +204 -7
  75. data/lib/polars/list_name_space.rb +120 -1
  76. data/lib/polars/meta_expr.rb +7 -22
  77. data/lib/polars/scan_cast_options.rb +64 -0
  78. data/lib/polars/schema.rb +6 -1
  79. data/lib/polars/selector.rb +138 -0
  80. data/lib/polars/selectors.rb +931 -202
  81. data/lib/polars/series.rb +34 -11
  82. data/lib/polars/string_expr.rb +24 -3
  83. data/lib/polars/string_name_space.rb +11 -0
  84. data/lib/polars/utils/parse.rb +40 -0
  85. data/lib/polars/utils.rb +5 -1
  86. data/lib/polars/version.rb +1 -1
  87. data/lib/polars.rb +8 -0
  88. metadata +17 -2
@@ -1,9 +1,9 @@
1
- use std::path::{Path, PathBuf};
2
1
  use std::sync::{Arc, Mutex};
3
2
 
4
3
  use magnus::{RHash, TryConvert, Value};
5
4
  use polars::prelude::sync_on_close::SyncOnCloseType;
6
- use polars::prelude::{SinkOptions, SpecialEq};
5
+ use polars::prelude::{PlPath, SinkOptions, SpecialEq};
6
+ use polars_utils::plpath::PlPathRef;
7
7
 
8
8
  use crate::prelude::Wrap;
9
9
  use crate::{RbResult, RbValueError};
@@ -15,8 +15,8 @@ pub enum SinkTarget {
15
15
 
16
16
  impl TryConvert for Wrap<polars_plan::dsl::SinkTarget> {
17
17
  fn try_convert(ob: Value) -> RbResult<Self> {
18
- if let Ok(v) = PathBuf::try_convert(ob) {
19
- Ok(Wrap(polars::prelude::SinkTarget::Path(Arc::new(v))))
18
+ if let Ok(v) = String::try_convert(ob) {
19
+ Ok(Wrap(polars::prelude::SinkTarget::Path(PlPath::new(&v))))
20
20
  } else {
21
21
  let writer = {
22
22
  let rb_f = ob;
@@ -39,10 +39,10 @@ impl TryConvert for SinkTarget {
39
39
  }
40
40
 
41
41
  impl SinkTarget {
42
- pub fn base_path(&self) -> Option<&Path> {
42
+ pub fn base_path(&self) -> Option<PlPathRef<'_>> {
43
43
  match self {
44
44
  Self::File(t) => match t {
45
- polars::prelude::SinkTarget::Path(p) => Some(p.as_path()),
45
+ polars::prelude::SinkTarget::Path(p) => Some(p.as_ref()),
46
46
  polars::prelude::SinkTarget::Dyn(_) => None,
47
47
  },
48
48
  }
@@ -1,5 +1,6 @@
1
1
  mod allocator;
2
2
  mod batched_csv;
3
+ mod catalog;
3
4
  mod conversion;
4
5
  mod dataframe;
5
6
  mod error;
@@ -8,6 +9,7 @@ mod expr;
8
9
  mod file;
9
10
  mod functions;
10
11
  mod interop;
12
+ mod io;
11
13
  mod lazyframe;
12
14
  mod lazygroupby;
13
15
  mod map;
@@ -20,23 +22,25 @@ mod sql;
20
22
  mod utils;
21
23
 
22
24
  use batched_csv::RbBatchedCsv;
25
+ use catalog::unity::RbCatalogClient;
23
26
  use conversion::*;
24
27
  use dataframe::RbDataFrame;
25
28
  use error::RbPolarsErr;
26
29
  use exceptions::{RbTypeError, RbValueError};
27
- use expr::rb_exprs_to_exprs;
28
30
  use expr::RbExpr;
31
+ use expr::rb_exprs_to_exprs;
32
+ use expr::selector::RbSelector;
29
33
  use functions::string_cache::RbStringCacheHolder;
30
34
  use functions::whenthen::{RbChainedThen, RbChainedWhen, RbThen, RbWhen};
31
35
  use interop::arrow::to_ruby::RbArrowArrayStream;
32
36
  use lazyframe::RbLazyFrame;
33
37
  use lazygroupby::RbLazyGroupBy;
34
- use magnus::{define_module, function, method, prelude::*, Ruby};
38
+ use magnus::{Ruby, define_module, function, method, prelude::*};
35
39
  use series::RbSeries;
36
40
  use sql::RbSQLContext;
37
41
 
38
- use magnus::error::Result as RbResult;
39
42
  use magnus::Error as RbErr;
43
+ use magnus::error::Result as RbResult;
40
44
 
41
45
  // TODO move
42
46
  fn re_escape(pattern: String) -> String {
@@ -143,7 +147,7 @@ fn init(ruby: &Ruby) -> RbResult<()> {
143
147
  class.define_method("pivot_expr", method!(RbDataFrame::pivot_expr, 7))?;
144
148
  class.define_method("partition_by", method!(RbDataFrame::partition_by, 3))?;
145
149
  class.define_method("lazy", method!(RbDataFrame::lazy, 0))?;
146
- class.define_method("to_dummies", method!(RbDataFrame::to_dummies, 3))?;
150
+ class.define_method("to_dummies", method!(RbDataFrame::to_dummies, 4))?;
147
151
  class.define_method("null_count", method!(RbDataFrame::null_count, 0))?;
148
152
  class.define_method("map_rows", method!(RbDataFrame::map_rows, 3))?;
149
153
  class.define_method("shrink_to_fit", method!(RbDataFrame::shrink_to_fit, 0))?;
@@ -329,7 +333,7 @@ fn init(ruby: &Ruby) -> RbResult<()> {
329
333
  class.define_method("str_hex_decode", method!(RbExpr::str_hex_decode, 1))?;
330
334
  class.define_method("str_base64_encode", method!(RbExpr::str_base64_encode, 0))?;
331
335
  class.define_method("str_base64_decode", method!(RbExpr::str_base64_decode, 1))?;
332
- class.define_method("str_to_integer", method!(RbExpr::str_to_integer, 2))?;
336
+ class.define_method("str_to_integer", method!(RbExpr::str_to_integer, 3))?;
333
337
  class.define_method("str_json_decode", method!(RbExpr::str_json_decode, 2))?;
334
338
  class.define_method("binary_hex_encode", method!(RbExpr::bin_hex_encode, 0))?;
335
339
  class.define_method("binary_hex_decode", method!(RbExpr::bin_hex_decode, 1))?;
@@ -426,7 +430,6 @@ fn init(ruby: &Ruby) -> RbResult<()> {
426
430
  class.define_method("dot", method!(RbExpr::dot, 1))?;
427
431
  class.define_method("reinterpret", method!(RbExpr::reinterpret, 1))?;
428
432
  class.define_method("mode", method!(RbExpr::mode, 0))?;
429
- class.define_method("exclude", method!(RbExpr::exclude, 1))?;
430
433
  class.define_method("interpolate", method!(RbExpr::interpolate, 1))?;
431
434
  class.define_method("interpolate_by", method!(RbExpr::interpolate_by, 1))?;
432
435
  class.define_method("rolling_sum", method!(RbExpr::rolling_sum, 4))?;
@@ -467,6 +470,7 @@ fn init(ruby: &Ruby) -> RbResult<()> {
467
470
  class.define_method("list_sort", method!(RbExpr::list_sort, 2))?;
468
471
  class.define_method("list_reverse", method!(RbExpr::list_reverse, 0))?;
469
472
  class.define_method("list_unique", method!(RbExpr::list_unique, 1))?;
473
+ class.define_method("list_set_operation", method!(RbExpr::list_set_operation, 2))?;
470
474
  class.define_method("list_get", method!(RbExpr::list_get, 2))?;
471
475
  class.define_method("list_join", method!(RbExpr::list_join, 2))?;
472
476
  class.define_method("list_arg_min", method!(RbExpr::list_arg_min, 0))?;
@@ -477,6 +481,7 @@ fn init(ruby: &Ruby) -> RbResult<()> {
477
481
  class.define_method("list_shift", method!(RbExpr::list_shift, 1))?;
478
482
  class.define_method("list_slice", method!(RbExpr::list_slice, 2))?;
479
483
  class.define_method("list_eval", method!(RbExpr::list_eval, 1))?;
484
+ class.define_method("list_filter", method!(RbExpr::list_filter, 1))?;
480
485
  class.define_method("cumulative_eval", method!(RbExpr::cumulative_eval, 2))?;
481
486
  class.define_method("list_to_struct", method!(RbExpr::list_to_struct, 3))?;
482
487
  class.define_method("rank", method!(RbExpr::rank, 3))?;
@@ -518,6 +523,8 @@ fn init(ruby: &Ruby) -> RbResult<()> {
518
523
  class.define_method("set_sorted_flag", method!(RbExpr::set_sorted_flag, 1))?;
519
524
  class.define_method("replace", method!(RbExpr::replace, 2))?;
520
525
  class.define_method("replace_strict", method!(RbExpr::replace_strict, 4))?;
526
+ class.define_method("into_selector", method!(RbExpr::into_selector, 0))?;
527
+ class.define_singleton_method("new_selector", function!(RbExpr::new_selector, 1))?;
521
528
 
522
529
  // meta
523
530
  class.define_method("meta_pop", method!(RbExpr::meta_pop, 1))?;
@@ -534,10 +541,6 @@ fn init(ruby: &Ruby) -> RbResult<()> {
534
541
  "meta_is_regex_projection",
535
542
  method!(RbExpr::meta_is_regex_projection, 0),
536
543
  )?;
537
- class.define_method("_meta_selector_add", method!(RbExpr::_meta_selector_add, 1))?;
538
- class.define_method("_meta_selector_sub", method!(RbExpr::_meta_selector_sub, 1))?;
539
- class.define_method("_meta_selector_and", method!(RbExpr::_meta_selector_and, 1))?;
540
- class.define_method("_meta_as_selector", method!(RbExpr::_meta_as_selector, 0))?;
541
544
  class.define_method("meta_tree_format", method!(RbExpr::meta_tree_format, 1))?;
542
545
 
543
546
  // name
@@ -550,15 +553,10 @@ fn init(ruby: &Ruby) -> RbResult<()> {
550
553
 
551
554
  // maybe add to different class
552
555
  let class = module.define_module("Plr")?;
553
- class.define_singleton_method("dtype_cols", function!(functions::lazy::dtype_cols, 1))?;
554
- class.define_singleton_method("index_cols", function!(functions::lazy::index_cols, 1))?;
555
556
  class.define_singleton_method("col", function!(functions::lazy::col, 1))?;
556
557
  class.define_singleton_method("len", function!(functions::lazy::len, 0))?;
557
- class.define_singleton_method("first", function!(functions::lazy::first, 0))?;
558
- class.define_singleton_method("last", function!(functions::lazy::last, 0))?;
559
- class.define_singleton_method("cols", function!(functions::lazy::cols, 1))?;
560
558
  class.define_singleton_method("fold", function!(functions::lazy::fold, 5))?;
561
- class.define_singleton_method("cum_fold", function!(functions::lazy::cum_fold, 4))?;
559
+ class.define_singleton_method("cum_fold", function!(functions::lazy::cum_fold, 6))?;
562
560
  class.define_singleton_method("lit", function!(functions::lazy::lit, 3))?;
563
561
  class.define_singleton_method("int_range", function!(functions::range::int_range, 4))?;
564
562
  class.define_singleton_method("int_ranges", function!(functions::range::int_ranges, 4))?;
@@ -729,7 +727,7 @@ fn init(ruby: &Ruby) -> RbResult<()> {
729
727
  class.define_singleton_method("new_from_csv", function!(RbLazyFrame::new_from_csv, -1))?;
730
728
  class.define_singleton_method(
731
729
  "new_from_parquet",
732
- function!(RbLazyFrame::new_from_parquet, -1),
730
+ function!(RbLazyFrame::new_from_parquet, 6),
733
731
  )?;
734
732
  class.define_singleton_method("new_from_ipc", function!(RbLazyFrame::new_from_ipc, 10))?;
735
733
  class.define_method("write_json", method!(RbLazyFrame::write_json, 1))?;
@@ -750,7 +748,6 @@ fn init(ruby: &Ruby) -> RbResult<()> {
750
748
  class.define_method("sink_ipc", method!(RbLazyFrame::sink_ipc, 5))?;
751
749
  class.define_method("sink_csv", method!(RbLazyFrame::sink_csv, -1))?;
752
750
  class.define_method("sink_json", method!(RbLazyFrame::sink_json, 4))?;
753
- class.define_method("fetch", method!(RbLazyFrame::fetch, 1))?;
754
751
  class.define_method("filter", method!(RbLazyFrame::filter, 1))?;
755
752
  class.define_method("select", method!(RbLazyFrame::select, 1))?;
756
753
  class.define_method("select_seq", method!(RbLazyFrame::select_seq, 1))?;
@@ -908,9 +905,9 @@ fn init(ruby: &Ruby) -> RbResult<()> {
908
905
  class.define_method("median", method!(RbSeries::median, 0))?;
909
906
  class.define_method("quantile", method!(RbSeries::quantile, 2))?;
910
907
  class.define_method("_clone", method!(RbSeries::clone, 0))?;
911
- class.define_method("apply_lambda", method!(RbSeries::apply_lambda, 3))?;
908
+ class.define_method("map_elements", method!(RbSeries::map_elements, 3))?;
912
909
  class.define_method("zip_with", method!(RbSeries::zip_with, 2))?;
913
- class.define_method("to_dummies", method!(RbSeries::to_dummies, 2))?;
910
+ class.define_method("to_dummies", method!(RbSeries::to_dummies, 3))?;
914
911
  class.define_method("n_unique", method!(RbSeries::n_unique, 0))?;
915
912
  class.define_method("floor", method!(RbSeries::floor, 0))?;
916
913
  class.define_method("shrink_to_fit", method!(RbSeries::shrink_to_fit, 0))?;
@@ -1111,5 +1108,86 @@ fn init(ruby: &Ruby) -> RbResult<()> {
1111
1108
  let class = module.define_class("ArrowArrayStream", ruby.class_object())?;
1112
1109
  class.define_method("to_i", method!(RbArrowArrayStream::to_i, 0))?;
1113
1110
 
1111
+ // catalog
1112
+ let class = module.define_class("RbCatalogClient", ruby.class_object())?;
1113
+ class.define_singleton_method("new", function!(RbCatalogClient::new, 2))?;
1114
+ class.define_singleton_method(
1115
+ "type_json_to_polars_type",
1116
+ function!(RbCatalogClient::type_json_to_polars_type, 1),
1117
+ )?;
1118
+ class.define_method("list_catalogs", method!(RbCatalogClient::list_catalogs, 0))?;
1119
+ class.define_method(
1120
+ "list_namespaces",
1121
+ method!(RbCatalogClient::list_namespaces, 1),
1122
+ )?;
1123
+ class.define_method("list_tables", method!(RbCatalogClient::list_tables, 2))?;
1124
+ class.define_method(
1125
+ "get_table_info",
1126
+ method!(RbCatalogClient::get_table_info, 3),
1127
+ )?;
1128
+ class.define_method(
1129
+ "create_catalog",
1130
+ method!(RbCatalogClient::create_catalog, 3),
1131
+ )?;
1132
+ class.define_method(
1133
+ "delete_catalog",
1134
+ method!(RbCatalogClient::delete_catalog, 2),
1135
+ )?;
1136
+ class.define_method(
1137
+ "create_namespace",
1138
+ method!(RbCatalogClient::create_namespace, 4),
1139
+ )?;
1140
+ class.define_method(
1141
+ "delete_namespace",
1142
+ method!(RbCatalogClient::delete_namespace, 3),
1143
+ )?;
1144
+ class.define_method("create_table", method!(RbCatalogClient::create_table, 9))?;
1145
+ class.define_method("delete_table", method!(RbCatalogClient::delete_table, 3))?;
1146
+
1147
+ // categories
1148
+ let class = module.define_class("RbCategories", ruby.class_object())?;
1149
+ class.define_singleton_method(
1150
+ "global_categories",
1151
+ function!(RbCategories::global_categories, 0),
1152
+ )?;
1153
+
1154
+ // data type expr
1155
+ let _class = module.define_class("RbDataTypeExpr", ruby.class_object())?;
1156
+
1157
+ // selector
1158
+ let class = module.define_class("RbSelector", ruby.class_object())?;
1159
+ class.define_method("union", method!(RbSelector::union, 1))?;
1160
+ class.define_method("difference", method!(RbSelector::difference, 1))?;
1161
+ class.define_method("exclusive_or", method!(RbSelector::exclusive_or, 1))?;
1162
+ class.define_method("intersect", method!(RbSelector::intersect, 1))?;
1163
+ class.define_singleton_method("by_dtype", function!(RbSelector::by_dtype, 1))?;
1164
+ class.define_singleton_method("by_name", function!(RbSelector::by_name, 2))?;
1165
+ class.define_singleton_method("by_index", function!(RbSelector::by_index, 2))?;
1166
+ class.define_singleton_method("first", function!(RbSelector::first, 1))?;
1167
+ class.define_singleton_method("last", function!(RbSelector::last, 1))?;
1168
+ class.define_singleton_method("matches", function!(RbSelector::matches, 1))?;
1169
+ class.define_singleton_method("enum_", function!(RbSelector::enum_, 0))?;
1170
+ class.define_singleton_method("categorical", function!(RbSelector::categorical, 0))?;
1171
+ class.define_singleton_method("nested", function!(RbSelector::nested, 0))?;
1172
+ class.define_singleton_method("list", function!(RbSelector::list, 1))?;
1173
+ class.define_singleton_method("array", function!(RbSelector::array, 2))?;
1174
+ class.define_singleton_method("struct_", function!(RbSelector::struct_, 0))?;
1175
+ class.define_singleton_method("integer", function!(RbSelector::integer, 0))?;
1176
+ class.define_singleton_method("signed_integer", function!(RbSelector::signed_integer, 0))?;
1177
+ class.define_singleton_method(
1178
+ "unsigned_integer",
1179
+ function!(RbSelector::unsigned_integer, 0),
1180
+ )?;
1181
+ class.define_singleton_method("float", function!(RbSelector::float, 0))?;
1182
+ class.define_singleton_method("decimal", function!(RbSelector::decimal, 0))?;
1183
+ class.define_singleton_method("numeric", function!(RbSelector::numeric, 0))?;
1184
+ class.define_singleton_method("temporal", function!(RbSelector::temporal, 0))?;
1185
+ class.define_singleton_method("datetime", function!(RbSelector::datetime, 2))?;
1186
+ class.define_singleton_method("duration", function!(RbSelector::duration, 1))?;
1187
+ class.define_singleton_method("object", function!(RbSelector::object, 0))?;
1188
+ class.define_singleton_method("empty", function!(RbSelector::empty, 0))?;
1189
+ class.define_singleton_method("all", function!(RbSelector::all, 0))?;
1190
+ class.define_method("_hash", method!(RbSelector::hash, 0))?;
1191
+
1114
1192
  Ok(())
1115
1193
  }
@@ -1,6 +1,6 @@
1
- use magnus::{class, prelude::*, typed_data::Obj, IntoValue, RArray, TryConvert, Value};
1
+ use magnus::{IntoValue, RArray, TryConvert, Value, class, prelude::*, typed_data::Obj};
2
2
  use polars::prelude::*;
3
- use polars_core::frame::row::{rows_to_schema_first_non_null, Row};
3
+ use polars_core::frame::row::{Row, rows_to_schema_first_non_null};
4
4
  use polars_core::series::SeriesIter;
5
5
 
6
6
  use super::*;
@@ -144,7 +144,7 @@ where
144
144
  let tpl = (RArray::from_iter(iter),);
145
145
  match lambda.funcall::<_, _, Value>("call", tpl) {
146
146
  Ok(val) => T::try_convert(val).ok(),
147
- Err(e) => panic!("ruby function failed {}", e),
147
+ Err(e) => panic!("ruby function failed {e}"),
148
148
  }
149
149
  })
150
150
  }
@@ -157,7 +157,7 @@ pub fn apply_lambda_with_primitive_out_type<D>(
157
157
  first_value: Option<D::Native>,
158
158
  ) -> ChunkedArray<D>
159
159
  where
160
- D: RbArrowPrimitiveType,
160
+ D: RbPolarsNumericType,
161
161
  D::Native: IntoValue + TryConvert,
162
162
  {
163
163
  let skip = usize::from(first_value.is_some());
@@ -247,11 +247,11 @@ pub fn apply_lambda_with_list_out_type(
247
247
  if val.is_nil() {
248
248
  None
249
249
  } else {
250
- panic!("should return a Series, got a {:?}", val)
250
+ panic!("should return a Series, got a {val:?}")
251
251
  }
252
252
  }
253
253
  },
254
- Err(e) => panic!("ruby function failed {}", e),
254
+ Err(e) => panic!("ruby function failed {e}"),
255
255
  }
256
256
  });
257
257
  iterator_to_list(
@@ -302,7 +302,7 @@ pub fn apply_lambda_with_rows_output<'a>(
302
302
  None => Ok(&null_row),
303
303
  }
304
304
  }
305
- Err(e) => panic!("ruby function failed {}", e),
305
+ Err(e) => panic!("ruby function failed {e}"),
306
306
  }
307
307
  });
308
308
 
@@ -1,4 +1,4 @@
1
- use magnus::{prelude::*, RArray, Value};
1
+ use magnus::{RArray, Value, prelude::*};
2
2
  use polars::prelude::*;
3
3
 
4
4
  use crate::rb_modules::*;
@@ -2,27 +2,37 @@ pub mod dataframe;
2
2
  pub mod lazy;
3
3
  pub mod series;
4
4
 
5
- use magnus::{prelude::*, RHash, Value};
5
+ use magnus::{RHash, Value, prelude::*};
6
6
  use polars::chunked_array::builder::get_list_builder;
7
7
  use polars::prelude::*;
8
- use polars_core::utils::CustomIterTools;
9
8
  use polars_core::POOL;
9
+ use polars_core::utils::CustomIterTools;
10
10
  use rayon::prelude::*;
11
11
 
12
- use crate::{ObjectValue, RbPolarsErr, RbResult, RbSeries, Wrap};
12
+ use crate::{ObjectValue, RbPolarsErr, RbResult, RbSeries, RbValueError, Wrap};
13
+
14
+ pub trait RbPolarsNumericType: PolarsNumericType {}
13
15
 
14
- pub trait RbArrowPrimitiveType: PolarsNumericType {}
16
+ impl RbPolarsNumericType for UInt8Type {}
17
+ impl RbPolarsNumericType for UInt16Type {}
18
+ impl RbPolarsNumericType for UInt32Type {}
19
+ impl RbPolarsNumericType for UInt64Type {}
20
+ impl RbPolarsNumericType for Int8Type {}
21
+ impl RbPolarsNumericType for Int16Type {}
22
+ impl RbPolarsNumericType for Int32Type {}
23
+ impl RbPolarsNumericType for Int64Type {}
24
+ impl RbPolarsNumericType for Float32Type {}
25
+ impl RbPolarsNumericType for Float64Type {}
15
26
 
16
- impl RbArrowPrimitiveType for UInt8Type {}
17
- impl RbArrowPrimitiveType for UInt16Type {}
18
- impl RbArrowPrimitiveType for UInt32Type {}
19
- impl RbArrowPrimitiveType for UInt64Type {}
20
- impl RbArrowPrimitiveType for Int8Type {}
21
- impl RbArrowPrimitiveType for Int16Type {}
22
- impl RbArrowPrimitiveType for Int32Type {}
23
- impl RbArrowPrimitiveType for Int64Type {}
24
- impl RbArrowPrimitiveType for Float32Type {}
25
- impl RbArrowPrimitiveType for Float64Type {}
27
+ pub(super) fn check_nested_object(dt: &DataType) -> RbResult<()> {
28
+ if dt.contains_objects() {
29
+ Err(RbValueError::new_err(
30
+ "nested objects are not allowed\n\nSet `return_dtype: Polars::Object` to use Ruby's native nesting.",
31
+ ))
32
+ } else {
33
+ Ok(())
34
+ }
35
+ }
26
36
 
27
37
  fn iterator_to_struct(
28
38
  it: impl Iterator<Item = Option<Value>>,
@@ -37,7 +47,7 @@ fn iterator_to_struct(
37
47
  _ => {
38
48
  return Err(crate::exceptions::ComputeError::new_err(format!(
39
49
  "expected struct got {first_value:?}",
40
- )))
50
+ )));
41
51
  }
42
52
  };
43
53
 
@@ -70,9 +80,11 @@ fn iterator_to_struct(
70
80
  Some(dict) => {
71
81
  let dict = RHash::try_convert(dict)?;
72
82
  if dict.len() != struct_width {
73
- return Err(crate::exceptions::ComputeError::new_err(
74
- format!("Cannot create struct type.\n> The struct dtype expects {} fields, but it got a dict with {} fields.", struct_width, dict.len())
75
- ));
83
+ return Err(crate::exceptions::ComputeError::new_err(format!(
84
+ "Cannot create struct type.\n> The struct dtype expects {} fields, but it got a dict with {} fields.",
85
+ struct_width,
86
+ dict.len()
87
+ )));
76
88
  }
77
89
  // we ignore the keys of the rest of the dicts
78
90
  // the first item determines the output name
@@ -109,7 +121,7 @@ fn iterator_to_primitive<T>(
109
121
  capacity: usize,
110
122
  ) -> ChunkedArray<T>
111
123
  where
112
- T: RbArrowPrimitiveType,
124
+ T: RbPolarsNumericType,
113
125
  {
114
126
  // safety: we know the iterators len
115
127
  let mut ca: ChunkedArray<T> = unsafe {
@@ -1,4 +1,4 @@
1
- use magnus::{class, prelude::*, typed_data::Obj, IntoValue, TryConvert, Value};
1
+ use magnus::{IntoValue, TryConvert, Value, class, prelude::*, typed_data::Obj};
2
2
  use polars::prelude::*;
3
3
 
4
4
  use super::*;
@@ -85,7 +85,7 @@ pub trait ApplyLambda<'a> {
85
85
  first_value: Option<D::Native>,
86
86
  ) -> RbResult<ChunkedArray<D>>
87
87
  where
88
- D: RbArrowPrimitiveType,
88
+ D: RbPolarsNumericType,
89
89
  D::Native: IntoValue + TryConvert;
90
90
 
91
91
  /// Apply a lambda with a boolean output type
@@ -143,7 +143,7 @@ where
143
143
  {
144
144
  match call_lambda(lambda, in_val) {
145
145
  Ok(out) => S::try_convert(out),
146
- Err(e) => panic!("ruby function failed {}", e),
146
+ Err(e) => panic!("ruby function failed {e}"),
147
147
  }
148
148
  }
149
149
 
@@ -219,7 +219,7 @@ impl<'a> ApplyLambda<'a> for BooleanChunked {
219
219
  first_value: Option<D::Native>,
220
220
  ) -> RbResult<ChunkedArray<D>>
221
221
  where
222
- D: RbArrowPrimitiveType,
222
+ D: RbPolarsNumericType,
223
223
  D::Native: IntoValue + TryConvert,
224
224
  {
225
225
  let skip = usize::from(first_value.is_some());
@@ -438,7 +438,7 @@ impl<'a> ApplyLambda<'a> for BooleanChunked {
438
438
 
439
439
  impl<'a, T> ApplyLambda<'a> for ChunkedArray<T>
440
440
  where
441
- T: RbArrowPrimitiveType + PolarsNumericType,
441
+ T: RbPolarsNumericType + PolarsNumericType,
442
442
  T::Native: IntoValue + TryConvert,
443
443
  ChunkedArray<T>: IntoSeries,
444
444
  {
@@ -503,7 +503,7 @@ where
503
503
  first_value: Option<D::Native>,
504
504
  ) -> RbResult<ChunkedArray<D>>
505
505
  where
506
- D: RbArrowPrimitiveType,
506
+ D: RbPolarsNumericType,
507
507
  D::Native: IntoValue + TryConvert,
508
508
  {
509
509
  let skip = usize::from(first_value.is_some());
@@ -782,7 +782,7 @@ impl<'a> ApplyLambda<'a> for StringChunked {
782
782
  first_value: Option<D::Native>,
783
783
  ) -> RbResult<ChunkedArray<D>>
784
784
  where
785
- D: RbArrowPrimitiveType,
785
+ D: RbPolarsNumericType,
786
786
  D::Native: IntoValue + TryConvert,
787
787
  {
788
788
  let skip = usize::from(first_value.is_some());
@@ -1047,7 +1047,7 @@ impl<'a> ApplyLambda<'a> for StructChunked {
1047
1047
  first_value: Option<D::Native>,
1048
1048
  ) -> RbResult<ChunkedArray<D>>
1049
1049
  where
1050
- D: RbArrowPrimitiveType,
1050
+ D: RbPolarsNumericType,
1051
1051
  D::Native: IntoValue + TryConvert,
1052
1052
  {
1053
1053
  let skip = usize::from(first_value.is_some());
@@ -9,8 +9,8 @@ use polars_core::chunked_array::object::registry;
9
9
  use polars_core::chunked_array::object::registry::AnonymousObjectBuilder;
10
10
  use polars_core::prelude::AnyValue;
11
11
 
12
- use crate::prelude::ObjectValue;
13
12
  use crate::Wrap;
13
+ use crate::prelude::ObjectValue;
14
14
 
15
15
  static POLARS_REGISTRY_INIT_LOCK: OnceLock<()> = OnceLock::new();
16
16
 
@@ -39,6 +39,9 @@ pub(crate) fn register_startup_deps() {
39
39
  object_converter,
40
40
  rbobject_converter,
41
41
  physical_dtype,
42
- )
42
+ );
43
+ // TODO
44
+ // Register warning function for `polars_warn!`.
45
+ // polars_error::set_warning_function(warning_function);
43
46
  });
44
47
  }
@@ -1,4 +1,4 @@
1
- use magnus::{value::Lazy, ExceptionClass, Module, RClass, RModule, Ruby};
1
+ use magnus::{ExceptionClass, Module, RClass, RModule, Ruby, value::Lazy};
2
2
 
3
3
  static POLARS: Lazy<RModule> = Lazy::new(|ruby| ruby.class_object().const_get("Polars").unwrap());
4
4
 
@@ -1,8 +1,8 @@
1
- use magnus::{prelude::*, RArray, RString};
1
+ use magnus::{RArray, RString, prelude::*};
2
2
  use polars_core::prelude::*;
3
3
 
4
4
  use crate::any_value::rb_object_to_any_value;
5
- use crate::conversion::{slice_extract_wrapped, vec_extract_wrapped, Wrap};
5
+ use crate::conversion::{Wrap, slice_extract_wrapped, vec_extract_wrapped};
6
6
  use crate::prelude::ObjectValue;
7
7
  use crate::series::to_series;
8
8
  use crate::{RbPolarsErr, RbResult, RbSeries, RbTypeError, RbValueError};
@@ -122,13 +122,17 @@ impl RbSeries {
122
122
  .into_iter()
123
123
  .map(|v| rb_object_to_any_value(v, strict))
124
124
  .collect::<RbResult<Vec<AnyValue>>>()?;
125
- let s =
126
- Series::from_any_values_and_dtype(name.into(), any_values.as_slice(), &dtype.0, strict)
127
- .map_err(|e| {
128
- RbTypeError::new_err(format!(
125
+ let s = Series::from_any_values_and_dtype(
126
+ name.into(),
127
+ any_values.as_slice(),
128
+ &dtype.0,
129
+ strict,
130
+ )
131
+ .map_err(|e| {
132
+ RbTypeError::new_err(format!(
129
133
  "{e}\n\nHint: Try setting `strict: false` to allow passing data with mixed types."
130
134
  ))
131
- })?;
135
+ })?;
132
136
  Ok(s.into())
133
137
  }
134
138
 
@@ -1,8 +1,8 @@
1
- use magnus::{value::qnil, IntoValue, RArray, Value};
1
+ use magnus::{IntoValue, RArray, Value, value::qnil};
2
2
  use polars_core::prelude::*;
3
3
 
4
- use crate::prelude::*;
5
4
  use crate::RbSeries;
5
+ use crate::prelude::*;
6
6
 
7
7
  impl RbSeries {
8
8
  /// Convert this Series to a Ruby array.
@@ -25,7 +25,9 @@ impl RbSeries {
25
25
  DataType::Float32 => RArray::from_iter(series.f32().unwrap()).into_value(),
26
26
  DataType::Float64 => RArray::from_iter(series.f64().unwrap()).into_value(),
27
27
  DataType::Categorical(_, _) | DataType::Enum(_, _) => {
28
- RArray::from_iter(series.categorical().unwrap().iter_str()).into_value()
28
+ with_match_categorical_physical_type!(series.dtype().cat_physical().unwrap(), |$C| {
29
+ RArray::from_iter(series.cat::<$C>().unwrap().iter_str()).into_value()
30
+ })
29
31
  }
30
32
  DataType::Object(_) => {
31
33
  let v = RArray::with_capacity(series.len());
@@ -132,7 +134,7 @@ impl RbSeries {
132
134
  unreachable!()
133
135
  }
134
136
  };
135
- rblist
137
+ rblist.into_value()
136
138
  }
137
139
 
138
140
  to_a_recursive(series)