From 5cb462fbd264c9f23a46196554ae0bdb46d5c091 Mon Sep 17 00:00:00 2001 From: Marco Gorelli <33491632+MarcoGorelli@users.noreply.github.com> Date: Thu, 30 May 2024 15:19:39 +0100 Subject: [PATCH 1/4] deprecate upstreamed functions --- .github/workflows/CI.yml | 2 +- Makefile | 22 +++++++++++----------- polars_xdt/functions.py | 6 +++++- 3 files changed, 17 insertions(+), 13 deletions(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index f8c2d45..467cc1c 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -63,7 +63,7 @@ jobs: run: rustup show - uses: mozilla-actions/sccache-action@v0.0.3 - run: make venv - - run: venv/bin/python -m pip install polars==0.20.6 # min version + - run: .venv/bin/python -m pip install polars==0.20.6 # min version - run: make install - run: make test diff --git a/Makefile b/Makefile index 326f012..e4bc835 100644 --- a/Makefile +++ b/Makefile @@ -2,29 +2,29 @@ SHELL=/bin/bash venv: ## Set up virtual environment - python3 -m venv venv - venv/bin/pip install -r requirements.txt -r docs/requirements-docs.txt + python3 -m venv .venv + .venv/bin/pip install -r requirements.txt -r docs/requirements-docs.txt install: venv unset CONDA_PREFIX && \ - source venv/bin/activate && maturin develop + source .venv/bin/activate && maturin develop install-release: venv unset CONDA_PREFIX && \ - source venv/bin/activate && maturin develop --release + source .venv/bin/activate && maturin develop --release pre-commit: venv cargo fmt --all && cargo clippy --all-features - venv/bin/python -m ruff check . --fix --exit-non-zero-on-fix - venv/bin/python -m ruff format polars_xdt tests - venv/bin/python -m mypy polars_xdt tests + .venv/bin/python -m ruff check . --fix --exit-non-zero-on-fix + .venv/bin/python -m ruff format polars_xdt tests + .venv/bin/python -m mypy polars_xdt tests test: venv - venv/bin/python -m pytest tests - venv/bin/python -m pytest polars_xdt --doctest-modules + .venv/bin/python -m pytest tests + .venv/bin/python -m pytest polars_xdt --doctest-modules run: install - source venv/bin/activate && python run.py + source .venv/bin/activate && python run.py run-release: install-release - source venv/bin/activate && python run.py + source .venv/bin/activate && python run.py diff --git a/polars_xdt/functions.py b/polars_xdt/functions.py index 00e1801..24115c2 100644 --- a/polars_xdt/functions.py +++ b/polars_xdt/functions.py @@ -1,4 +1,5 @@ from __future__ import annotations +import warnings import re import sys @@ -153,6 +154,7 @@ def offset_by( └────────────┴──────┴──────────────┘ """ + warnings.warn("`offset_by` is deprecated, as it has been upstreamed. Please use `polars.add_business_days` instead.", DeprecationWarning, stacklevel=2) expr = parse_into_expr(expr) if ( isinstance(by, str) @@ -160,7 +162,7 @@ def offset_by( and (len(match.group(1)) == len(by)) ): # Fast path - do we have a business day offset, and nothing else? - n: int | pl.Expr = int(by[:-2]) + n: int | pl.Expr = pl.lit(int(by[:-2]), dtype=pl.Int32) fastpath = True else: if not isinstance(by, pl.Expr): @@ -717,6 +719,7 @@ def workday_count( └────────────┴────────────┴─────────────────┘ """ + warnings.warn("`workday_count` is deprecated, as it has been upstreamed. Please use `polars.business_day_count` instead.", DeprecationWarning, stacklevel=2) start_dates = parse_into_expr(start_dates) end_dates = parse_into_expr(end_dates) weekmask = get_weekmask(weekend) @@ -976,6 +979,7 @@ def ewma_by_time( └────────┴────────────┴──────────┘ """ + warnings.warn("`ewma_by_time` is deprecated, as it has been upstreamed. Please use `polars.ewm_mean_by` instead.", DeprecationWarning, stacklevel=2) values = parse_into_expr(values) half_life_us = ( int(half_life.total_seconds()) * 1_000_000 + half_life.microseconds From 294dbaa963d5e7996f0640632b5846a6a24491bf Mon Sep 17 00:00:00 2001 From: Marco Gorelli <33491632+MarcoGorelli@users.noreply.github.com> Date: Thu, 30 May 2024 18:13:10 +0100 Subject: [PATCH 2/4] Bump version to 0.14.13 --- Cargo.toml | 18 +++--- polars_xdt/functions.py | 12 ++++ src/business_days.rs | 6 +- src/lib.rs | 4 +- src/timezone.rs | 6 +- tests/test_business_offsets.py | 100 ++++++++++++++++++--------------- tests/test_ewma_by_time.py | 7 ++- tests/test_sub.py | 52 +++++++++-------- 8 files changed, 116 insertions(+), 89 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 63315e0..3a2936c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "polars_xdt" -version = "0.14.12" +version = "0.14.13" edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html @@ -9,15 +9,15 @@ name = "polars_xdt" crate-type = ["cdylib"] [dependencies] -pyo3 = { version = "0.20.0", features = ["extension-module", "abi3-py38"] } -pyo3-polars = { version = "0.12.0", features = ["derive"] } +pyo3 = { version = "0.21.2", features = ["extension-module", "abi3-py38"] } +pyo3-polars = { version = "0.14.0", features = ["derive"] } serde = { version = "1", features = ["derive"] } -chrono = { version = "0.4.31", default-features = false, features = ["std", "unstable-locales"] } -chrono-tz = "0.8.5" -polars = { version = "0.38.2", features = ["strings", "dtype-date"], default-features = false } -polars-time = { version = "0.38.2", features = ["timezones"], default-features = false } -polars-ops = { version = "0.38.2", default-features = false } -polars-arrow = { version = "0.38.2", default-features = false } +chrono = { version = "0.4.38", default-features = false, features = ["std", "unstable-locales"] } +chrono-tz = "0.9.0" +polars = { version = "0.40.0", features = ["strings", "dtype-date"], default-features = false } +polars-time = { version = "0.40.0", features = ["timezones"], default-features = false } +polars-ops = { version = "0.40.0", default-features = false } +polars-arrow = { version = "0.40.0", default-features = false } [target.'cfg(target_os = "linux")'.dependencies] jemallocator = { version = "0.5", features = ["disable_initial_exec_tls"] } diff --git a/polars_xdt/functions.py b/polars_xdt/functions.py index 24115c2..ef797d6 100644 --- a/polars_xdt/functions.py +++ b/polars_xdt/functions.py @@ -59,6 +59,10 @@ def offset_by( """ Offset this date by a relative time offset. + .. deprecated:: 0.14.13 + + This is deprecated, please use `polars.add_business_days` instead. + Parameters ---------- expr @@ -679,6 +683,10 @@ def workday_count( """ Count the number of workdays between two columns of dates. + .. deprecated:: 0.14.13 + + This is deprecated, please use `polars.business_day_count` instead. + Parameters ---------- start_dates @@ -929,6 +937,10 @@ def ewma_by_time( where :math:`\lambda` equals :math:`\ln(2) / \text{half_life}`. + .. deprecated:: 0.14.13 + + This is deprecated, please use `polars.ewm_mean_by` instead. + Parameters ---------- values diff --git a/src/business_days.rs b/src/business_days.rs index c40ca0a..8da23cf 100644 --- a/src/business_days.rs +++ b/src/business_days.rs @@ -151,7 +151,7 @@ pub(crate) fn impl_advance_n_days( let out = match n.len() { 1 => { if let Some(n) = n.get(0) { - ca.try_apply(|x_date| { + ca.try_apply_nonnull_values_generic(|x_date| { let x_weekday = weekday(x_date); calculate_advance( x_date, n, x_weekday, weekmask, n_weekdays, &holidays, roll, @@ -188,10 +188,10 @@ pub(crate) fn impl_advance_n_days( let out = match n.len() { 1 => { if let Some(n) = n.get(0) { - ca.try_apply(|x| { + ca.try_apply_nonnull_values_generic(|x| { let x_date = (x / multiplier) as i32; let x_weekday = weekday(x_date); - Ok(x + ((calculate_advance( + Ok::(x + ((calculate_advance( x_date, n, x_weekday, weekmask, n_weekdays, &holidays, roll, )? - x_date) as i64 * multiplier)) diff --git a/src/lib.rs b/src/lib.rs index 77531f0..1d2d7e8 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -11,7 +11,7 @@ mod to_julian; mod utc_offsets; use pyo3::types::PyModule; -use pyo3::{pymodule, PyResult, Python}; +use pyo3::{pymodule, PyResult, Bound}; #[cfg(target_os = "linux")] use jemallocator::Jemalloc; @@ -21,7 +21,7 @@ use jemallocator::Jemalloc; static ALLOC: Jemalloc = Jemalloc; #[pymodule] -fn _internal(_py: Python, m: &PyModule) -> PyResult<()> { +fn _internal(m: &Bound<'_, PyModule>) -> PyResult<()> { m.add("__version__", env!("CARGO_PKG_VERSION"))?; Ok(()) } diff --git a/src/timezone.rs b/src/timezone.rs index def3a13..50477d3 100644 --- a/src/timezone.rs +++ b/src/timezone.rs @@ -1,6 +1,6 @@ use arity::try_binary_elementwise; use chrono::{LocalResult, NaiveDateTime, TimeZone}; -use chrono_tz::Tz; +use polars_arrow::legacy::time_zone::Tz; use polars::chunked_array::temporal::parse_time_zone; use polars::prelude::*; use pyo3_polars::export::polars_core::utils::arrow::legacy::kernels::Ambiguous; @@ -117,9 +117,9 @@ pub fn elementwise_from_local_datetime( 1 => match unsafe { from_tz.get_unchecked(0) } { Some(from_tz) => { let from_tz = parse_time_zone(from_tz)?; - datetime.0.try_apply(|timestamp| { + datetime.0.try_apply_nonnull_values_generic(|timestamp| { let ndt = timestamp_to_datetime(timestamp); - Ok(datetime_to_timestamp( + Ok::(datetime_to_timestamp( naive_local_to_naive_utc_in_new_time_zone(&from_tz, &to_tz, ndt, &ambig)?, )) }) diff --git a/tests/test_business_offsets.py b/tests/test_business_offsets.py index e504329..5c9ceb8 100644 --- a/tests/test_business_offsets.py +++ b/tests/test_business_offsets.py @@ -92,14 +92,15 @@ def test_against_np_busday_offset( assume(date.strftime("%a") not in weekend) assume(date not in holidays) roll = "raise" - result = get_result( - date, - dtype, - by=function(f"{n}bd"), - weekend=weekend, - holidays=holidays, - roll=roll, - ) + with pytest.deprecated_call(): + result = get_result( + date, + dtype, + by=function(f"{n}bd"), + weekend=weekend, + holidays=holidays, + roll=roll, + ) weekmask = [0 if reverse_mapping[i] in weekend else 1 for i in range(1, 8)] expected = np.busday_offset(date, n, weekmask=weekmask, holidays=holidays) assert np.datetime64(result) == expected @@ -143,14 +144,15 @@ def test_against_np_busday_offset_with_roll( function: Callable[[str], str | pl.Series], roll: Literal["forward", "backward"], ) -> None: - result = get_result( - date, - dtype, - by=function(f"{n}bd"), - weekend=weekend, - holidays=holidays, - roll=roll, # type: ignore[arg-type] - ) + with pytest.deprecated_call(): + result = get_result( + date, + dtype, + by=function(f"{n}bd"), + weekend=weekend, + holidays=holidays, + roll=roll, # type: ignore[arg-type] + ) weekmask = [0 if reverse_mapping[i] in weekend else 1 for i in range(1, 8)] expected = np.busday_offset( date, n, weekmask=weekmask, holidays=holidays, roll=roll @@ -176,22 +178,24 @@ def test_against_np_busday_offset_with_roll( def test_extra_args(by: str, expected: dt.datetime) -> None: start = dt.datetime(2000, 1, 3) df = pl.DataFrame({"dates": [start]}) - result = ( - df.with_columns( - dates_shifted=xdt.offset_by("dates", by=by) - ).with_columns(end_wday=pl.col("dates_shifted").dt.strftime("%a")) - )["dates_shifted"].item() + with pytest.deprecated_call(): + result = ( + df.with_columns( + dates_shifted=xdt.offset_by("dates", by=by) + ).with_columns(end_wday=pl.col("dates_shifted").dt.strftime("%a")) + )["dates_shifted"].item() assert result == expected def test_extra_args_w_series() -> None: start = dt.datetime(2000, 1, 3) df = pl.DataFrame({"dates": [start] * 2, "by": ["1bd2h", "-1bd1h"]}) - result = ( - df.with_columns( - dates_shifted=xdt.offset_by("dates", by=pl.col("by")) - ).with_columns(end_wday=pl.col("dates_shifted").dt.strftime("%a")) - )["dates_shifted"] + with pytest.deprecated_call(): + result = ( + df.with_columns( + dates_shifted=xdt.offset_by("dates", by=pl.col("by")) + ).with_columns(end_wday=pl.col("dates_shifted").dt.strftime("%a")) + )["dates_shifted"] assert result[0] == dt.datetime(2000, 1, 4, 2) assert result[1] == dt.datetime(1999, 12, 30, 23) @@ -202,26 +206,28 @@ def test_starting_on_non_business() -> None: weekend = ["Sat", "Sun"] df = pl.DataFrame({"dates": [start]}) with pytest.raises(pl.ComputeError): - df.with_columns( - dates_shifted=xdt.offset_by( - "dates", - by=f"{n}bd", - weekend=weekend, + with pytest.deprecated_call(): + df.with_columns( + dates_shifted=xdt.offset_by( + "dates", + by=f"{n}bd", + weekend=weekend, + ) ) - ) df = pl.DataFrame({"dates": [start]}) weekend = [] holidays = [start] with pytest.raises(pl.ComputeError): - df.with_columns( - dates_shifted=xdt.offset_by( - "dates", - by=f"{n}bd", - holidays=holidays, - weekend=weekend, + with pytest.deprecated_call(): + df.with_columns( + dates_shifted=xdt.offset_by( + "dates", + by=f"{n}bd", + holidays=holidays, + weekend=weekend, + ) ) - ) def test_within_group_by() -> None: @@ -231,12 +237,13 @@ def test_within_group_by() -> None: } df = pl.DataFrame(data) - result = ( - df.group_by(["a"]).agg( - minDate=xdt.offset_by(pl.col.date.min(), "-3bd"), # type: ignore[attr-defined] - maxDate=xdt.offset_by(pl.col.date.max(), "3bd"), # type: ignore[attr-defined] - ) - ).sort("a", descending=True) + with pytest.deprecated_call(): + result = ( + df.group_by(["a"]).agg( + minDate=xdt.offset_by(pl.col.date.min(), "-3bd"), # type: ignore[attr-defined] + maxDate=xdt.offset_by(pl.col.date.max(), "3bd"), # type: ignore[attr-defined] + ) + ).sort("a", descending=True) expected = pl.DataFrame( { "a": [2, 1], @@ -256,4 +263,5 @@ def test_invalid_roll_strategy() -> None: } ) with pytest.raises(pl.ComputeError): - df.with_columns(xdt.offset_by("date", "1bd", roll="cabbage")) # type: ignore[arg-type] + with pytest.deprecated_call(): + df.with_columns(xdt.offset_by("date", "1bd", roll="cabbage")) # type: ignore[arg-type] diff --git a/tests/test_ewma_by_time.py b/tests/test_ewma_by_time.py index 55a36cd..4d4280d 100644 --- a/tests/test_ewma_by_time.py +++ b/tests/test_ewma_by_time.py @@ -29,9 +29,10 @@ def test_ewma_by_time(start_null): ], } ) - result = df.select( - xdt.ewma_by_time("values", times="times", half_life=timedelta(days=2)), - ) + with pytest.deprecated_call(): + result = df.select( + xdt.ewma_by_time("values", times="times", half_life=timedelta(days=2)), + ) expected = pl.DataFrame( { diff --git a/tests/test_sub.py b/tests/test_sub.py index d0fd4ce..154214a 100644 --- a/tests/test_sub.py +++ b/tests/test_sub.py @@ -21,15 +21,16 @@ def get_result( weekend: list[str], holidays: list[dt.date], ) -> int: - return ( # type: ignore[no-any-return] - pl.DataFrame({"end_date": [end_date]}) - .select( - n=xdt.workday_count( - start_date, "end_date", weekend=weekend, holidays=holidays - ) - )["n"] # type: ignore[arg-type] - .item() - ) + with pytest.deprecated_call(): + return ( # type: ignore[no-any-return] + pl.DataFrame({"end_date": [end_date]}) + .select( + n=xdt.workday_count( + start_date, "end_date", weekend=weekend, holidays=holidays + ) + )["n"] # type: ignore[arg-type] + .item() + ) @given( @@ -129,13 +130,14 @@ def test_empty_weekmask() -> None: } ) with pytest.raises(ValueError): - df.select( - xdt.workday_count( - "start", - "end", - weekend=["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"], + with pytest.deprecated_call(): + df.select( + xdt.workday_count( + "start", + "end", + weekend=["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"], + ) ) - ) def test_sub_lit() -> None: @@ -144,7 +146,8 @@ def test_sub_lit() -> None: "end": [dt.date(2020, 1, 3), dt.date(2020, 1, 5)], } ) - result = df.select(xdt.workday_count(pl.lit(dt.date(2020, 1, 1)), "end")) + with pytest.deprecated_call(): + result = df.select(xdt.workday_count(pl.lit(dt.date(2020, 1, 1)), "end")) assert result["literal"][0] == 2 assert result["literal"][1] == 3 @@ -156,16 +159,19 @@ def test_workday_count() -> None: "end": [dt.date(2020, 1, 8), dt.date(2020, 1, 20)], } ) - result = df.with_columns(workday_count=xdt.workday_count("start", "end")) + with pytest.deprecated_call(): + result = df.with_columns(workday_count=xdt.workday_count("start", "end")) assert result["workday_count"][0] == 3 assert result["workday_count"][1] == 10 - result = df.with_columns( - workday_count=xdt.workday_count("start", dt.date(2020, 1, 8)) - ) + with pytest.deprecated_call(): + result = df.with_columns( + workday_count=xdt.workday_count("start", dt.date(2020, 1, 8)) + ) assert result["workday_count"][0] == 3 assert result["workday_count"][1] == 2 - result = df.with_columns( - workday_count=xdt.workday_count(dt.date(2020, 1, 5), pl.col("end")) - ) + with pytest.deprecated_call(): + result = df.with_columns( + workday_count=xdt.workday_count(dt.date(2020, 1, 5), pl.col("end")) + ) assert result["workday_count"][0] == 2 assert result["workday_count"][1] == 10 From 37a9ea03587db87a39be206e05fd9ebb3d7ac819 Mon Sep 17 00:00:00 2001 From: Marco Gorelli <33491632+MarcoGorelli@users.noreply.github.com> Date: Thu, 30 May 2024 18:23:54 +0100 Subject: [PATCH 3/4] lint --- Makefile | 2 +- polars_xdt/functions.py | 20 ++++++++++--- polars_xdt/ranges.py | 9 ++---- src/business_days.rs | 10 ++++--- src/ewma_by_time.rs | 6 ++-- src/expressions.rs | 2 +- src/lib.rs | 2 +- src/timezone.rs | 2 +- tests/ceil_test.py | 2 ++ tests/julian_date_test.py | 5 ++-- tests/test_business_offsets.py | 55 +++++++++++++++++----------------- tests/test_date_range.py | 7 +++-- tests/test_ewma_by_time.py | 28 ++++++++++------- tests/test_format_localized.py | 6 ++-- tests/test_is_busday.py | 4 +-- tests/test_sub.py | 18 ++++++----- tests/test_timezone.py | 6 ++-- 17 files changed, 106 insertions(+), 78 deletions(-) diff --git a/Makefile b/Makefile index e4bc835..b2573d4 100644 --- a/Makefile +++ b/Makefile @@ -15,7 +15,7 @@ install-release: venv pre-commit: venv cargo fmt --all && cargo clippy --all-features - .venv/bin/python -m ruff check . --fix --exit-non-zero-on-fix + .venv/bin/python -m ruff check polars_xdt tests --fix --exit-non-zero-on-fix .venv/bin/python -m ruff format polars_xdt tests .venv/bin/python -m mypy polars_xdt tests diff --git a/polars_xdt/functions.py b/polars_xdt/functions.py index ef797d6..3084b41 100644 --- a/polars_xdt/functions.py +++ b/polars_xdt/functions.py @@ -1,8 +1,8 @@ from __future__ import annotations -import warnings import re import sys +import warnings from datetime import date, timedelta from pathlib import Path from typing import TYPE_CHECKING, Literal, Sequence @@ -158,7 +158,11 @@ def offset_by( └────────────┴──────┴──────────────┘ """ - warnings.warn("`offset_by` is deprecated, as it has been upstreamed. Please use `polars.add_business_days` instead.", DeprecationWarning, stacklevel=2) + warnings.warn( + "`offset_by` is deprecated, as it has been upstreamed. Please use `polars.add_business_days` instead.", + DeprecationWarning, + stacklevel=2, + ) expr = parse_into_expr(expr) if ( isinstance(by, str) @@ -727,7 +731,11 @@ def workday_count( └────────────┴────────────┴─────────────────┘ """ - warnings.warn("`workday_count` is deprecated, as it has been upstreamed. Please use `polars.business_day_count` instead.", DeprecationWarning, stacklevel=2) + warnings.warn( + "`workday_count` is deprecated, as it has been upstreamed. Please use `polars.business_day_count` instead.", + DeprecationWarning, + stacklevel=2, + ) start_dates = parse_into_expr(start_dates) end_dates = parse_into_expr(end_dates) weekmask = get_weekmask(weekend) @@ -991,7 +999,11 @@ def ewma_by_time( └────────┴────────────┴──────────┘ """ - warnings.warn("`ewma_by_time` is deprecated, as it has been upstreamed. Please use `polars.ewm_mean_by` instead.", DeprecationWarning, stacklevel=2) + warnings.warn( + "`ewma_by_time` is deprecated, as it has been upstreamed. Please use `polars.ewm_mean_by` instead.", + DeprecationWarning, + stacklevel=2, + ) values = parse_into_expr(values) half_life_us = ( int(half_life.total_seconds()) * 1_000_000 + half_life.microseconds diff --git a/polars_xdt/ranges.py b/polars_xdt/ranges.py index 1d820c2..1a3d852 100644 --- a/polars_xdt/ranges.py +++ b/polars_xdt/ranges.py @@ -25,8 +25,7 @@ def date_range( eager: Literal[False] = ..., weekend: Sequence[str] = ..., holidays: Sequence[date] | None = ..., -) -> pl.Expr: - ... +) -> pl.Expr: ... @overload @@ -41,8 +40,7 @@ def date_range( eager: Literal[True], weekend: Sequence[str] = ..., holidays: Sequence[date] | None = ..., -) -> pl.Series: - ... +) -> pl.Series: ... @overload @@ -57,8 +55,7 @@ def date_range( eager: bool = ..., weekend: Sequence[str] = ..., holidays: Sequence[date] | None = ..., -) -> pl.Series | pl.Expr: - ... +) -> pl.Series | pl.Expr: ... def date_range( # noqa: PLR0913 diff --git a/src/business_days.rs b/src/business_days.rs index 8da23cf..0a5bed7 100644 --- a/src/business_days.rs +++ b/src/business_days.rs @@ -191,10 +191,12 @@ pub(crate) fn impl_advance_n_days( ca.try_apply_nonnull_values_generic(|x| { let x_date = (x / multiplier) as i32; let x_weekday = weekday(x_date); - Ok::(x + ((calculate_advance( - x_date, n, x_weekday, weekmask, n_weekdays, &holidays, roll, - )? - x_date) as i64 - * multiplier)) + Ok::( + x + ((calculate_advance( + x_date, n, x_weekday, weekmask, n_weekdays, &holidays, roll, + )? - x_date) as i64 + * multiplier), + ) }) } else { Ok(Int64Chunked::full_null(ca.name(), ca.len())) diff --git a/src/ewma_by_time.rs b/src/ewma_by_time.rs index fc242fd..3268935 100644 --- a/src/ewma_by_time.rs +++ b/src/ewma_by_time.rs @@ -5,7 +5,7 @@ pub(crate) fn impl_ewma_by_time_float( times: &Int64Chunked, values: &Float64Chunked, half_life: i64, - time_unit: TimeUnit + time_unit: TimeUnit, ) -> Float64Chunked { let mut out = Vec::with_capacity(times.len()); if values.is_empty() { @@ -29,7 +29,7 @@ pub(crate) fn impl_ewma_by_time_float( out.push(Some(prev_result)); skip_rows = idx + 1; break; - }, + } _ => { out.push(None); } @@ -50,7 +50,7 @@ pub(crate) fn impl_ewma_by_time_float( prev_time = time; prev_result = result; out.push(Some(result)); - }, + } _ => out.push(None), } }); diff --git a/src/expressions.rs b/src/expressions.rs index fb096e0..ab71e33 100644 --- a/src/expressions.rs +++ b/src/expressions.rs @@ -178,7 +178,7 @@ fn arg_previous_greater(inputs: &[Series]) -> PolarsResult { #[derive(Deserialize)] struct EwmTimeKwargs { - half_life: i64 + half_life: i64, } #[polars_expr(output_type=Float64)] diff --git a/src/lib.rs b/src/lib.rs index 1d2d7e8..bf6c212 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -11,7 +11,7 @@ mod to_julian; mod utc_offsets; use pyo3::types::PyModule; -use pyo3::{pymodule, PyResult, Bound}; +use pyo3::{pymodule, Bound, PyResult}; #[cfg(target_os = "linux")] use jemallocator::Jemalloc; diff --git a/src/timezone.rs b/src/timezone.rs index 50477d3..c0e0c66 100644 --- a/src/timezone.rs +++ b/src/timezone.rs @@ -1,8 +1,8 @@ use arity::try_binary_elementwise; use chrono::{LocalResult, NaiveDateTime, TimeZone}; -use polars_arrow::legacy::time_zone::Tz; use polars::chunked_array::temporal::parse_time_zone; use polars::prelude::*; +use polars_arrow::legacy::time_zone::Tz; use pyo3_polars::export::polars_core::utils::arrow::legacy::kernels::Ambiguous; use pyo3_polars::export::polars_core::utils::arrow::temporal_conversions::{ timestamp_ms_to_datetime, timestamp_ns_to_datetime, timestamp_us_to_datetime, diff --git a/tests/ceil_test.py b/tests/ceil_test.py index 4aecbe4..56181bf 100644 --- a/tests/ceil_test.py +++ b/tests/ceil_test.py @@ -1,5 +1,7 @@ from datetime import datetime + import polars as pl + import polars_xdt as xdt diff --git a/tests/julian_date_test.py b/tests/julian_date_test.py index 67ede9a..416f9ea 100644 --- a/tests/julian_date_test.py +++ b/tests/julian_date_test.py @@ -1,11 +1,12 @@ from __future__ import annotations + import datetime as dt import hypothesis.strategies as st +import pandas as pd +import polars as pl from hypothesis import given -import polars as pl -import pandas as pd import polars_xdt as xdt diff --git a/tests/test_business_offsets.py b/tests/test_business_offsets.py index 5c9ceb8..596b74b 100644 --- a/tests/test_business_offsets.py +++ b/tests/test_business_offsets.py @@ -1,18 +1,19 @@ from __future__ import annotations import datetime as dt -from polars.testing import assert_frame_equal -import pytest -from typing import Mapping, Any, Callable, Literal +from typing import TYPE_CHECKING, Any, Callable, Literal import hypothesis.strategies as st import numpy as np -from hypothesis import given, assume, reject - import polars as pl +import pytest +from hypothesis import assume, given, reject +from polars.testing import assert_frame_equal + import polars_xdt as xdt -from polars.type_aliases import PolarsDataType +if TYPE_CHECKING: + from polars.type_aliases import PolarsDataType mapping = {"Mon": 1, "Tue": 2, "Wed": 3, "Thu": 4, "Fri": 5, "Sat": 6, "Sun": 7} reverse_mapping = {value: key for key, value in mapping.items()} @@ -47,8 +48,8 @@ def get_result( )["ts"] .item() ) - except Exception as exp: - assert "non-existent" in str(exp) or "ambiguous" in str(exp) + except Exception as exp: # noqa: BLE001 + assert "non-existent" in str(exp) or "ambiguous" in str(exp) # noqa: PT017 reject() return result # type: ignore[no-any-return] @@ -81,7 +82,7 @@ def get_result( ), function=st.sampled_from([lambda x: x, lambda x: pl.Series([x])]), ) -def test_against_np_busday_offset( +def test_against_np_busday_offset( # noqa: PLR0913 date: dt.date, n: int, weekend: list[str], @@ -135,7 +136,7 @@ def test_against_np_busday_offset( function=st.sampled_from([lambda x: x, lambda x: pl.Series([x])]), roll=st.sampled_from(["forward", "backward"]), ) -def test_against_np_busday_offset_with_roll( +def test_against_np_busday_offset_with_roll( # noqa:PLR0913 date: dt.date, n: int, weekend: list[str], @@ -205,29 +206,27 @@ def test_starting_on_non_business() -> None: n = -7 weekend = ["Sat", "Sun"] df = pl.DataFrame({"dates": [start]}) - with pytest.raises(pl.ComputeError): - with pytest.deprecated_call(): - df.with_columns( - dates_shifted=xdt.offset_by( - "dates", - by=f"{n}bd", - weekend=weekend, - ) + with pytest.raises(pl.ComputeError), pytest.deprecated_call(): + df.with_columns( + dates_shifted=xdt.offset_by( + "dates", + by=f"{n}bd", + weekend=weekend, ) + ) df = pl.DataFrame({"dates": [start]}) weekend = [] holidays = [start] - with pytest.raises(pl.ComputeError): - with pytest.deprecated_call(): - df.with_columns( - dates_shifted=xdt.offset_by( - "dates", - by=f"{n}bd", - holidays=holidays, - weekend=weekend, - ) + with pytest.raises(pl.ComputeError), pytest.deprecated_call(): + df.with_columns( + dates_shifted=xdt.offset_by( + "dates", + by=f"{n}bd", + holidays=holidays, + weekend=weekend, ) + ) def test_within_group_by() -> None: @@ -262,6 +261,6 @@ def test_invalid_roll_strategy() -> None: ) } ) - with pytest.raises(pl.ComputeError): + with pytest.raises(pl.ComputeError): # noqa: SIM117 with pytest.deprecated_call(): df.with_columns(xdt.offset_by("date", "1bd", roll="cabbage")) # type: ignore[arg-type] diff --git a/tests/test_date_range.py b/tests/test_date_range.py index 510da86..31cf550 100644 --- a/tests/test_date_range.py +++ b/tests/test_date_range.py @@ -1,10 +1,13 @@ from __future__ import annotations + +from datetime import date + import polars as pl import pytest -from datetime import date -import polars_xdt as xdt # noqa: F401 from polars.testing import assert_series_equal +import polars_xdt as xdt + def test_eager() -> None: result = xdt.date_range(date(2023, 1, 1), date(2023, 1, 10), eager=True) diff --git a/tests/test_ewma_by_time.py b/tests/test_ewma_by_time.py index 4d4280d..60079fc 100644 --- a/tests/test_ewma_by_time.py +++ b/tests/test_ewma_by_time.py @@ -1,26 +1,29 @@ +import os +from datetime import datetime, timedelta + import polars as pl -from polars.testing import assert_frame_equal -import polars_xdt as xdt import pytest -from datetime import datetime, timedelta +from polars.testing import assert_frame_equal -import os +import polars_xdt as xdt os.environ["POLARS_VERBOSE"] = "1" + @pytest.mark.parametrize("start_null", [True, False]) -def test_ewma_by_time(start_null): +def test_ewma_by_time(*, start_null: bool) -> None: if start_null: values = [None] times = [datetime(2020, 1, 1)] else: values = [] times = [] - + df = pl.DataFrame( { - "values": values + [0.0, 1., 2., None, 4.], - "times": times + [ + "values": [*values, 0.0, 1.0, 2.0, None, 4.0], + "times": [ + *times, datetime(2020, 1, 2), datetime(2020, 1, 4), datetime(2020, 1, 11), @@ -31,12 +34,15 @@ def test_ewma_by_time(start_null): ) with pytest.deprecated_call(): result = df.select( - xdt.ewma_by_time("values", times="times", half_life=timedelta(days=2)), + xdt.ewma_by_time( + "values", times="times", half_life=timedelta(days=2) + ), ) - + expected = pl.DataFrame( { - "values": values + [ + "values": [ + *values, 0.0, 0.5, 1.8674174785275222, diff --git a/tests/test_format_localized.py b/tests/test_format_localized.py index 50997b3..ead01f2 100644 --- a/tests/test_format_localized.py +++ b/tests/test_format_localized.py @@ -1,9 +1,9 @@ -import pytest - -from datetime import datetime, date +from datetime import date, datetime import polars as pl +import pytest from polars.type_aliases import TimeUnit + import polars_xdt as xdt diff --git a/tests/test_is_busday.py b/tests/test_is_busday.py index 4df5d78..2d58f3e 100644 --- a/tests/test_is_busday.py +++ b/tests/test_is_busday.py @@ -1,14 +1,14 @@ from __future__ import annotations + import datetime as dt import hypothesis.strategies as st import numpy as np +import polars as pl from hypothesis import given -import polars as pl import polars_xdt as xdt - mapping = {"Mon": 1, "Tue": 2, "Wed": 3, "Thu": 4, "Fri": 5, "Sat": 6, "Sun": 7} reverse_mapping = {value: key for key, value in mapping.items()} diff --git a/tests/test_sub.py b/tests/test_sub.py index 154214a..6cc4ad7 100644 --- a/tests/test_sub.py +++ b/tests/test_sub.py @@ -1,15 +1,15 @@ from __future__ import annotations + import datetime as dt -import pytest from typing import Callable import hypothesis.strategies as st import numpy as np -from hypothesis import given, assume, reject - import polars as pl -import polars_xdt as xdt +import pytest +from hypothesis import assume, given, reject +import polars_xdt as xdt mapping = {"Mon": 1, "Tue": 2, "Wed": 3, "Thu": 4, "Fri": 5, "Sat": 6, "Sun": 7} reverse_mapping = {value: key for key, value in mapping.items()} @@ -129,7 +129,7 @@ def test_empty_weekmask() -> None: "end": [dt.date(2020, 1, 5)], } ) - with pytest.raises(ValueError): + with pytest.raises(ValueError): # noqa: SIM117 with pytest.deprecated_call(): df.select( xdt.workday_count( @@ -147,7 +147,9 @@ def test_sub_lit() -> None: } ) with pytest.deprecated_call(): - result = df.select(xdt.workday_count(pl.lit(dt.date(2020, 1, 1)), "end")) + result = df.select( + xdt.workday_count(pl.lit(dt.date(2020, 1, 1)), "end") + ) assert result["literal"][0] == 2 assert result["literal"][1] == 3 @@ -160,7 +162,9 @@ def test_workday_count() -> None: } ) with pytest.deprecated_call(): - result = df.with_columns(workday_count=xdt.workday_count("start", "end")) + result = df.with_columns( + workday_count=xdt.workday_count("start", "end") + ) assert result["workday_count"][0] == 3 assert result["workday_count"][1] == 10 with pytest.deprecated_call(): diff --git a/tests/test_timezone.py b/tests/test_timezone.py index 12034bb..91f6ed6 100644 --- a/tests/test_timezone.py +++ b/tests/test_timezone.py @@ -1,11 +1,13 @@ from __future__ import annotations -import pytest + from datetime import datetime, timezone +import polars as pl +import pytest from polars.testing import ( assert_frame_equal, ) -import polars as pl + import polars_xdt as xdt From 910abaa950c8b95d0c84638365789ffb28d15723 Mon Sep 17 00:00:00 2001 From: Marco Gorelli <33491632+MarcoGorelli@users.noreply.github.com> Date: Thu, 30 May 2024 18:27:34 +0100 Subject: [PATCH 4/4] missing file --- tests/__init__.py | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 tests/__init__.py diff --git a/tests/__init__.py b/tests/__init__.py new file mode 100644 index 0000000..e69de29