Skip to content

Commit 2932769

Browse files
committed
address comments in PR
1 parent a8d1166 commit 2932769

File tree

3 files changed

+904
-757
lines changed

3 files changed

+904
-757
lines changed

python/datafusion/functions.py

Lines changed: 18 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -278,6 +278,7 @@
278278
"to_timestamp_nanos",
279279
"to_timestamp_seconds",
280280
"to_unixtime",
281+
"today",
281282
"translate",
282283
"trim",
283284
"trunc",
@@ -1013,14 +1014,18 @@ def now() -> Expr:
10131014
return Expr(f.now())
10141015

10151016

1016-
def to_char(arg: Expr, format: Expr) -> Expr:
1017+
def to_char(arg: Expr, formatter: Expr) -> Expr:
10171018
"""Returns a string representation of a date, time, timestamp or duration.
10181019
1019-
For usage of ``format`` see the rust chrono package ``strftime`` package.
1020+
For usage of ``formatter`` see the rust chrono package ``strftime`` package.
10201021
10211022
[Documentation here.](https://docs.rs/chrono/latest/chrono/format/strftime/index.html)
10221023
"""
1023-
return Expr(f.to_char(arg.expr, format.expr))
1024+
return Expr(f.to_char(arg.expr, formatter.expr))
1025+
1026+
1027+
def _unwrap_exprs(args: tuple[Expr, ...]) -> list:
1028+
return [arg.expr for arg in args]
10241029

10251030

10261031
def to_date(arg: Expr, *formatters: Expr) -> Expr:
@@ -1035,18 +1040,15 @@ def to_date(arg: Expr, *formatters: Expr) -> Expr:
10351040
10361041
[Documentation here.](https://docs.rs/chrono/latest/chrono/format/strftime/index.html)
10371042
"""
1038-
if not formatters:
1039-
return Expr(f.to_date(arg.expr))
1040-
formatters = [fmt.expr for fmt in formatters]
1041-
return Expr(f.to_date(arg.expr, *formatters))
1043+
return Expr(f.to_date(arg.expr, *_unwrap_exprs(formatters)))
10421044

10431045

1044-
def to_local_time(arg: Expr) -> Expr:
1046+
def to_local_time(*args: Expr) -> Expr:
10451047
"""Converts a timestamp with a timezone to a timestamp without a timezone.
10461048
10471049
This function handles daylight saving time changes.
10481050
"""
1049-
return Expr(f.to_local_time(arg.expr))
1051+
return Expr(f.to_local_time(*_unwrap_exprs(args)))
10501052

10511053

10521054
def to_time(arg: Expr, *formatters: Expr) -> Expr:
@@ -1059,10 +1061,7 @@ def to_time(arg: Expr, *formatters: Expr) -> Expr:
10591061
10601062
[Documentation here.](https://docs.rs/chrono/latest/chrono/format/strftime/index.html)
10611063
"""
1062-
if not formatters:
1063-
return Expr(f.to_time(arg.expr))
1064-
formatters = [fmt.expr for fmt in formatters]
1065-
return Expr(f.to_time(arg.expr, *formatters))
1064+
return Expr(f.to_time(arg.expr, *_unwrap_exprs(formatters)))
10661065

10671066

10681067
def to_timestamp(arg: Expr, *formatters: Expr) -> Expr:
@@ -1072,53 +1071,44 @@ def to_timestamp(arg: Expr, *formatters: Expr) -> Expr:
10721071
10731072
[Documentation here.](https://docs.rs/chrono/latest/chrono/format/strftime/index.html)
10741073
"""
1075-
if not formatters:
1076-
return Expr(f.to_timestamp(arg.expr))
1077-
1078-
formatters = [fmt.expr for fmt in formatters]
1079-
return Expr(f.to_timestamp(arg.expr, *formatters))
1074+
return Expr(f.to_timestamp(arg.expr, *_unwrap_exprs(formatters)))
10801075

10811076

10821077
def to_timestamp_millis(arg: Expr, *formatters: Expr) -> Expr:
10831078
"""Converts a string and optional formats to a ``Timestamp`` in milliseconds.
10841079
10851080
See :py:func:`to_timestamp` for a description on how to use formatters.
10861081
"""
1087-
formatters = [fmt.expr for fmt in formatters]
1088-
return Expr(f.to_timestamp_millis(arg.expr, *formatters))
1082+
return Expr(f.to_timestamp_millis(arg.expr, *_unwrap_exprs(formatters)))
10891083

10901084

10911085
def to_timestamp_micros(arg: Expr, *formatters: Expr) -> Expr:
10921086
"""Converts a string and optional formats to a ``Timestamp`` in microseconds.
10931087
10941088
See :py:func:`to_timestamp` for a description on how to use formatters.
10951089
"""
1096-
formatters = [fmt.expr for fmt in formatters]
1097-
return Expr(f.to_timestamp_micros(arg.expr, *formatters))
1090+
return Expr(f.to_timestamp_micros(arg.expr, *_unwrap_exprs(formatters)))
10981091

10991092

11001093
def to_timestamp_nanos(arg: Expr, *formatters: Expr) -> Expr:
11011094
"""Converts a string and optional formats to a ``Timestamp`` in nanoseconds.
11021095
11031096
See :py:func:`to_timestamp` for a description on how to use formatters.
11041097
"""
1105-
formatters = [fmt.expr for fmt in formatters]
1106-
return Expr(f.to_timestamp_nanos(arg.expr, *formatters))
1098+
return Expr(f.to_timestamp_nanos(arg.expr, *_unwrap_exprs(formatters)))
11071099

11081100

11091101
def to_timestamp_seconds(arg: Expr, *formatters: Expr) -> Expr:
11101102
"""Converts a string and optional formats to a ``Timestamp`` in seconds.
11111103
11121104
See :py:func:`to_timestamp` for a description on how to use formatters.
11131105
"""
1114-
formatters = [fmt.expr for fmt in formatters]
1115-
return Expr(f.to_timestamp_seconds(arg.expr, *formatters))
1106+
return Expr(f.to_timestamp_seconds(arg.expr, *_unwrap_exprs(formatters)))
11161107

11171108

11181109
def to_unixtime(string: Expr, *format_arguments: Expr) -> Expr:
11191110
"""Converts a string and optional formats to a Unixtime."""
1120-
args = [fmt.expr for fmt in format_arguments]
1121-
return Expr(f.to_unixtime(string.expr, *args))
1111+
return Expr(f.to_unixtime(string.expr, *_unwrap_exprs(format_arguments)))
11221112

11231113

11241114
def current_date() -> Expr:

python/tests/test_functions.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1067,6 +1067,26 @@ def test_temporal_functions(df):
10671067
)
10681068

10691069

1070+
def test_to_time_invalid_input(df):
1071+
with pytest.raises(Exception, match=r"Error parsing 'not-a-time' as time"):
1072+
df.select(f.to_time(literal("not-a-time"))).collect()
1073+
1074+
1075+
def test_to_time_mismatched_formatter(df):
1076+
with pytest.raises(Exception, match=r"Error parsing '12:30:45' as time"):
1077+
df.select(f.to_time(literal("12:30:45"), literal("%Y-%m-%d"))).collect()
1078+
1079+
1080+
def test_to_date_invalid_input(df):
1081+
with pytest.raises(Exception, match=r"Date32"):
1082+
df.select(f.to_date(literal("not-a-date"))).collect()
1083+
1084+
1085+
def test_temporal_formatter_requires_expr():
1086+
with pytest.raises(AttributeError, match="'str' object has no attribute 'expr'"):
1087+
f.to_time(literal("12:30:45"), "not-an-expr")
1088+
1089+
10701090
def test_arrow_cast(df):
10711091
df = df.select(
10721092
# we use `string_literal` to return utf8 instead of `literal` which returns

0 commit comments

Comments
 (0)