Skip to content

Commit

Permalink
chore(python): Clean up some remnants of Python 3.8 support (#20293)
Browse files Browse the repository at this point in the history
  • Loading branch information
stinodego authored Dec 14, 2024
1 parent 84d317a commit b799459
Show file tree
Hide file tree
Showing 25 changed files with 35 additions and 137 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/test-bytecode-parser.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ jobs:
fail-fast: false
matrix:
# Only the versions that are not already run as part of the regular test suite
python-version: ['3.9', '3.10']
python-version: ['3.10', '3.11']

steps:
- uses: actions/checkout@v4
Expand Down
2 changes: 1 addition & 1 deletion docs/source/user-guide/installation.md
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ pip install 'polars[numpy,fsspec]'
| style | Style dataframes through the `style` namespace. |
| timezone | Timezone support[^note]. |

[^note]: Only needed if you are on Python < 3.9 or you are on Windows.
[^note]: Only needed if you are on Windows.

### Rust

Expand Down
26 changes: 5 additions & 21 deletions py-polars/polars/_utils/convert.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@
Any,
Callable,
NoReturn,
no_type_check,
overload,
)
from zoneinfo import ZoneInfo, ZoneInfoNotFoundError

from polars._utils.constants import (
EPOCH,
Expand All @@ -22,7 +22,6 @@
SECONDS_PER_HOUR,
US_PER_SECOND,
)
from polars.dependencies import _ZONEINFO_AVAILABLE, zoneinfo

if TYPE_CHECKING:
from collections.abc import Sequence
Expand Down Expand Up @@ -161,38 +160,23 @@ def to_py_datetime(

if time_zone is None:
return EPOCH + td
elif _ZONEINFO_AVAILABLE:
else:
dt = EPOCH_UTC + td
return _localize_datetime(dt, time_zone)
else:
msg = "install polars[timezone] to handle datetimes with time zone information"
raise ImportError(msg)


def _localize_datetime(dt: datetime, time_zone: str) -> datetime:
# zone info installation should already be checked
tz: ZoneInfo | tzinfo
try:
tz = string_to_zoneinfo(time_zone)
except zoneinfo.ZoneInfoNotFoundError:
tz = ZoneInfo(time_zone)
except ZoneInfoNotFoundError:
# try fixed offset, which is not supported by ZoneInfo
tz = _parse_fixed_tz_offset(time_zone)

return dt.astimezone(tz)


@no_type_check
@lru_cache(None)
def string_to_zoneinfo(key: str) -> Any:
"""
Convert a time zone string to a Python ZoneInfo object.
This is a simple wrapper for the zoneinfo.ZoneInfo constructor.
The wrapper is useful because zoneinfo is not available on Python 3.8
and the backports module may not be installed.
"""
return zoneinfo.ZoneInfo(key)


# cache here as we have a single tz per column
# and this function will be called on every conversion
@lru_cache(16)
Expand Down
9 changes: 0 additions & 9 deletions py-polars/polars/dependencies.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
_PYARROW_AVAILABLE = True
_PYDANTIC_AVAILABLE = True
_PYICEBERG_AVAILABLE = True
_ZONEINFO_AVAILABLE = True


class _LazyModule(ModuleType):
Expand Down Expand Up @@ -150,7 +149,6 @@ def _lazy_import(module_name: str) -> tuple[ModuleType, bool]:
import json
import pickle
import subprocess
import zoneinfo

import altair
import deltalake
Expand Down Expand Up @@ -182,11 +180,6 @@ def _lazy_import(module_name: str) -> tuple[ModuleType, bool]:
pyarrow, _PYARROW_AVAILABLE = _lazy_import("pyarrow")
pydantic, _PYDANTIC_AVAILABLE = _lazy_import("pydantic")
pyiceberg, _PYICEBERG_AVAILABLE = _lazy_import("pyiceberg")
zoneinfo, _ZONEINFO_AVAILABLE = (
_lazy_import("zoneinfo")
if sys.version_info >= (3, 9)
else _lazy_import("backports.zoneinfo")
)
gevent, _GEVENT_AVAILABLE = _lazy_import("gevent")


Expand Down Expand Up @@ -308,7 +301,6 @@ def import_optional(
"pydantic",
"pyiceberg",
"pyarrow",
"zoneinfo",
# lazy utilities
"_check_for_numpy",
"_check_for_pandas",
Expand All @@ -324,5 +316,4 @@ def import_optional(
"_NUMPY_AVAILABLE",
"_PANDAS_AVAILABLE",
"_PYARROW_AVAILABLE",
"_ZONEINFO_AVAILABLE",
]
4 changes: 2 additions & 2 deletions py-polars/polars/testing/parametric/strategies/data.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
from collections.abc import Mapping
from datetime import datetime, timedelta, timezone
from typing import TYPE_CHECKING, Any, Literal
from zoneinfo import ZoneInfo

import hypothesis.strategies as st
from hypothesis.errors import InvalidArgument
Expand All @@ -25,7 +26,6 @@
U32_MAX,
U64_MAX,
)
from polars._utils.convert import string_to_zoneinfo
from polars.datatypes import (
Array,
Binary,
Expand Down Expand Up @@ -167,7 +167,7 @@ def datetimes(
if time_zone is None:
return st.datetimes(min_value, max_value)

time_zone_info = string_to_zoneinfo(time_zone)
time_zone_info = ZoneInfo(time_zone)

# Make sure time zone offsets do not cause out-of-bound datetimes
if time_unit == "ns":
Expand Down
2 changes: 1 addition & 1 deletion py-polars/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ cloudpickle = ["cloudpickle"]
graph = ["matplotlib"]
plot = ["altair >= 5.4.0"]
style = ["great-tables >= 0.8.0"]
timezone = ["backports.zoneinfo; python_version < '3.9'", "tzdata; platform_system == 'Windows'"]
timezone = ["tzdata; platform_system == 'Windows'"]

# GPU Engine
gpu = ["cudf-polars-cu12"]
Expand Down
7 changes: 3 additions & 4 deletions py-polars/requirements-dev.txt
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,11 @@ pyarrow
pydantic>=2.0.0
numba
# Datetime / time zones
backports.zoneinfo; python_version < '3.9'
tzdata; platform_system == 'Windows'
# Database
sqlalchemy
adbc-driver-manager; python_version >= '3.9' and platform_system != 'Windows'
adbc-driver-sqlite; python_version >= '3.9' and platform_system != 'Windows'
adbc-driver-manager; platform_system != 'Windows'
adbc-driver-sqlite; platform_system != 'Windows'
aiosqlite
connectorx
kuzu
Expand All @@ -49,7 +48,7 @@ zstandard
# Plotting
altair>=5.4.0
# Styling
great-tables>=0.8.0; python_version >= '3.9'
great-tables>=0.8.0
# Async
gevent
# Graph
Expand Down
4 changes: 1 addition & 3 deletions py-polars/tests/unit/constructors/test_constructors.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from decimal import Decimal
from random import shuffle
from typing import TYPE_CHECKING, Any, Literal, NamedTuple
from zoneinfo import ZoneInfo

import numpy as np
import pandas as pd
Expand All @@ -23,16 +24,13 @@
if TYPE_CHECKING:
import sys
from collections.abc import Callable
from zoneinfo import ZoneInfo

from polars._typing import PolarsDataType

if sys.version_info >= (3, 11):
from typing import Self
else:
from typing_extensions import Self
else:
from polars._utils.convert import string_to_zoneinfo as ZoneInfo


# -----------------------------------------------------------------------------------
Expand Down
4 changes: 1 addition & 3 deletions py-polars/tests/unit/dataframe/test_df.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
from io import BytesIO
from operator import floordiv, truediv
from typing import TYPE_CHECKING, Any, Callable, cast
from zoneinfo import ZoneInfo

import numpy as np
import pyarrow as pa
Expand All @@ -34,12 +35,9 @@

if TYPE_CHECKING:
from collections.abc import Iterator, Sequence
from zoneinfo import ZoneInfo

from polars import Expr
from polars._typing import JoinStrategy, UniqueKeepStrategy
else:
from polars._utils.convert import string_to_zoneinfo as ZoneInfo


def test_version() -> None:
Expand Down
4 changes: 1 addition & 3 deletions py-polars/tests/unit/dataframe/test_upsample.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

from datetime import datetime
from typing import TYPE_CHECKING
from zoneinfo import ZoneInfo

import pytest

Expand All @@ -11,11 +12,8 @@

if TYPE_CHECKING:
from datetime import timezone
from zoneinfo import ZoneInfo

from polars._typing import FillNullStrategy, PolarsIntegerType
else:
from polars._utils.convert import string_to_zoneinfo as ZoneInfo


@pytest.mark.parametrize(
Expand Down
5 changes: 1 addition & 4 deletions py-polars/tests/unit/datatypes/test_temporal.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import io
from datetime import date, datetime, time, timedelta, timezone
from typing import TYPE_CHECKING, Any, cast
from zoneinfo import ZoneInfo

import hypothesis.strategies as st
import numpy as np
Expand All @@ -27,15 +28,11 @@
from tests.unit.conftest import DATETIME_DTYPES, TEMPORAL_DTYPES

if TYPE_CHECKING:
from zoneinfo import ZoneInfo

from polars._typing import (
Ambiguous,
PolarsTemporalType,
TimeUnit,
)
else:
from polars._utils.convert import string_to_zoneinfo as ZoneInfo


def test_fill_null() -> None:
Expand Down
5 changes: 1 addition & 4 deletions py-polars/tests/unit/expr/test_exprs.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from datetime import date, datetime, timedelta, timezone
from itertools import permutations
from typing import TYPE_CHECKING, Any, cast
from zoneinfo import ZoneInfo

import pytest

Expand All @@ -18,11 +19,7 @@
)

if TYPE_CHECKING:
from zoneinfo import ZoneInfo

from polars._typing import PolarsDataType
else:
from polars._utils.convert import string_to_zoneinfo as ZoneInfo


def test_arg_true() -> None:
Expand Down
5 changes: 1 addition & 4 deletions py-polars/tests/unit/functions/as_datatype/test_datetime.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

from datetime import datetime
from typing import TYPE_CHECKING
from zoneinfo import ZoneInfo

import pytest

Expand All @@ -10,11 +11,7 @@
from polars.testing import assert_series_equal

if TYPE_CHECKING:
from zoneinfo import ZoneInfo

from polars._typing import TimeUnit
else:
from polars._utils.convert import string_to_zoneinfo as ZoneInfo


def test_date_datetime() -> None:
Expand Down
5 changes: 1 addition & 4 deletions py-polars/tests/unit/functions/range/test_datetime_range.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

from datetime import date, datetime, timedelta
from typing import TYPE_CHECKING
from zoneinfo import ZoneInfo

import hypothesis.strategies as st
import pytest
Expand All @@ -13,11 +14,7 @@
from polars.testing import assert_frame_equal, assert_series_equal

if TYPE_CHECKING:
from zoneinfo import ZoneInfo

from polars._typing import ClosedInterval, PolarsDataType, TimeUnit
else:
from polars._utils.convert import string_to_zoneinfo as ZoneInfo


def test_datetime_range() -> None:
Expand Down
Loading

0 comments on commit b799459

Please sign in to comment.