4
4
import functools
5
5
import itertools
6
6
import operator
7
+ import warnings
7
8
from functools import cached_property
8
9
from typing import IO , TYPE_CHECKING , Any , Iterable , Literal , Mapping , Sequence
9
10
@@ -112,13 +113,13 @@ def __getitem__(self, what):
112
113
return what ._to_semi_join (self )[self ]
113
114
elif isinstance (what , (list , tuple , Table )):
114
115
# Projection case
115
- return self .projection (what )
116
+ return self .select (what )
116
117
elif isinstance (what , BooleanColumn ):
117
118
# Boolean predicate
118
119
return self .filter ([what ])
119
120
elif isinstance (what , Column ):
120
121
# Projection convenience
121
- return self .projection (what )
122
+ return self .select (what )
122
123
else :
123
124
raise NotImplementedError (
124
125
'Selection rows or columns with {} objects is not '
@@ -572,11 +573,12 @@ def mutate(
572
573
exprs .append (value .name (name ))
573
574
574
575
mutation_exprs = an .get_mutation_exprs (exprs , self )
575
- return self .projection (mutation_exprs )
576
+ return self .select (mutation_exprs )
576
577
577
578
def select (
578
579
self ,
579
- exprs : ir .Value | str | Sequence [ir .Value | str ],
580
+ * exprs : ir .Value | str | Iterable [ir .Value | str ],
581
+ ** named_exprs : ir .Value | str ,
580
582
) -> Table :
581
583
"""Compute a new table expression using `exprs`.
582
584
@@ -585,6 +587,10 @@ def select(
585
587
automatically constructs a window function expression. See the examples
586
588
section for more details.
587
589
590
+ For backwards compatibility the keyword argument `exprs` is reserved
591
+ and cannot be used to name an expression. This behavior will be removed
592
+ in v4.
593
+
588
594
Parameters
589
595
----------
590
596
exprs
@@ -601,9 +607,8 @@ def select(
601
607
Simple projection
602
608
603
609
>>> import ibis
604
- >>> fields = [('a', 'int64'), ('b', 'double')]
605
- >>> t = ibis.table(fields, name='t')
606
- >>> proj = t.projection([t.a, (t.b + 1).name('b_plus_1')])
610
+ >>> t = ibis.table(dict(a="int64", b="double"), name='t')
611
+ >>> proj = t.select(t.a, b_plus_1=t.b + 1)
607
612
>>> proj
608
613
r0 := UnboundTable[t]
609
614
a int64
@@ -612,13 +617,13 @@ def select(
612
617
selections:
613
618
a: r0.a
614
619
b_plus_1: r0.b + 1
615
- >>> proj2 = t[t.a, ( t.b + 1).name('b_plus_1')]
620
+ >>> proj2 = t.select("a", b_plus_1= t.b + 1)
616
621
>>> proj.equals(proj2)
617
622
True
618
623
619
624
Aggregate projection
620
625
621
- >>> agg_proj = t[ t.a.sum().name('sum_a'), t.b.mean().name('mean_b')]
626
+ >>> agg_proj = t.select(sum_a= t.a.sum(), mean_b= t.b.mean())
622
627
>>> agg_proj
623
628
r0 := UnboundTable[t]
624
629
a int64
@@ -635,7 +640,7 @@ def select(
635
640
The purpose of this expression rewrite is to make it easy to write
636
641
column/scalar-aggregate operations like
637
642
638
- >>> t[( t.a - t.a.mean()).name('demeaned_a')]
643
+ >>> t.select(demeaned_a= t.a - t.a.mean())
639
644
r0 := UnboundTable[t]
640
645
a int64
641
646
b float64
@@ -645,8 +650,24 @@ def select(
645
650
"""
646
651
import ibis .expr .analysis as an
647
652
648
- if isinstance (exprs , (Expr , str )):
649
- exprs = [exprs ]
653
+ if backcompat_exprs := named_exprs .pop ("exprs" , []):
654
+ warnings .warn (
655
+ "Passing `exprs` as a keyword argument is deprecated"
656
+ " and will be removed in 4.0. Pass the value(s) as"
657
+ " positional arguments." ,
658
+ FutureWarning ,
659
+ )
660
+
661
+ exprs = list (
662
+ itertools .chain (
663
+ itertools .chain .from_iterable (map (util .promote_list , exprs )),
664
+ util .promote_list (backcompat_exprs ),
665
+ (
666
+ self ._ensure_expr (expr ).name (name )
667
+ for name , expr in named_exprs .items ()
668
+ ),
669
+ )
670
+ )
650
671
651
672
projector = an .Projector (self , exprs )
652
673
op = projector .get_result ()
@@ -681,7 +702,7 @@ def relabel(self, substitutions: Mapping[str, str]) -> Table:
681
702
if c not in observed :
682
703
raise KeyError (f'{ c !r} is not an existing column' )
683
704
684
- return self .projection (exprs )
705
+ return self .select (exprs )
685
706
686
707
def drop (self , fields : str | Sequence [str ]) -> Table :
687
708
"""Remove fields from a table.
@@ -905,7 +926,7 @@ def set_column(self, name: str, expr: ir.Value) -> Table:
905
926
else :
906
927
proj_exprs .append (self [key ])
907
928
908
- return self .projection (proj_exprs )
929
+ return self .select (proj_exprs )
909
930
910
931
def join (
911
932
left : Table ,
0 commit comments