From 773daf8e553397d9c84b428563fa0fb60ad4820b Mon Sep 17 00:00:00 2001 From: Julien Enselme Date: Wed, 1 Mar 2023 08:53:37 +0100 Subject: [PATCH] Remove dependency on pytz Starting with Python 3.9 a zoneinfo package is available in the standard library for this feature. There is therefore no need for this dependency and a compatibility layer is available at https://pypi.org/project/backports.zoneinfo/ for older Python versions. --- agate/data_types/date_time.py | 2 +- docs/cookbook/datetime.rst | 18 +++++++++++++----- setup.py | 2 +- tests/test_data_types.py | 15 ++++++++++----- 4 files changed, 25 insertions(+), 12 deletions(-) diff --git a/agate/data_types/date_time.py b/agate/data_types/date_time.py index a0ddaf22..ecd382b9 100644 --- a/agate/data_types/date_time.py +++ b/agate/data_types/date_time.py @@ -18,7 +18,7 @@ class DateTime(DataType): A formatting string for :meth:`datetime.datetime.strptime` to use instead of using regex-based parsing. :param timezone: - A `pytz `_ timezone to apply to each + A ``ZoneInfo`` timezone to apply to each parsed date. :param locale: A locale specification such as :code:`en_US` or :code:`de_DE` to use diff --git a/docs/cookbook/datetime.rst b/docs/cookbook/datetime.rst index 78ffcf0c..5f9f781a 100644 --- a/docs/cookbook/datetime.rst +++ b/docs/cookbook/datetime.rst @@ -34,9 +34,13 @@ The second way is to specify a timezone as an argument to the type constructor: .. code-block:: python - import pytz + try: + from zoneinfo import ZoneInfo + except ImportError: + # Fallback for Python < 3.9 + from backports.zoneinfo import ZoneInfo - eastern = pytz.timezone('US/Eastern') + eastern = ZoneInfo('US/Eastern') datetime_type = agate.DateTime(timezone=eastern) In this case all timezones that are processed will be set to have the Eastern timezone. Note, the timezone will be **set**, not converted. You cannot use this method to convert your timezones from UTC to another timezone. To do that see :ref:`convert_timezones`. @@ -60,9 +64,13 @@ If you load data from a spreadsheet in one timezone and you need to convert it t .. code-block:: python - import pytz + try: + from zoneinfo import ZoneInfo + except ImportError: + # Fallback for Python < 3.9 + from backports.zoneinfo import ZoneInfo - us_eastern = pytz.timezone('US/Eastern') + us_eastern = ZoneInfo('US/Eastern') datetime_type = agate.DateTime(timezone=us_eastern) column_names = ['what', 'when'] @@ -70,7 +78,7 @@ If you load data from a spreadsheet in one timezone and you need to convert it t table = agate.Table.from_csv('events.csv', columns) - rome = timezone('Europe/Rome') + rome = ZoneInfo('Europe/Rome') timezone_shifter = agate.Formula(lambda r: r['when'].astimezone(rome)) table = agate.Table.compute([ diff --git a/setup.py b/setup.py index f6541491..a24d086b 100644 --- a/setup.py +++ b/setup.py @@ -54,7 +54,7 @@ 'PyICU>=2.4.2;sys_platform=="linux"', 'pytest', 'pytest-cov', - 'pytz>=2015.4', + 'backports.zoneinfo;python_version<"3.9"', ], 'docs': [ 'Sphinx>=1.2.2', diff --git a/tests/test_data_types.py b/tests/test_data_types.py index ae4b7de2..7f783ca8 100644 --- a/tests/test_data_types.py +++ b/tests/test_data_types.py @@ -6,7 +6,12 @@ from decimal import Decimal import parsedatetime -import pytz + +try: + from zoneinfo import ZoneInfo +except ImportError: + # Fallback for Python < 3.9 + from backports.zoneinfo import ZoneInfo from agate.data_types import Boolean, Date, DateTime, Number, Text, TimeDelta from agate.exceptions import CastError @@ -350,16 +355,16 @@ def test_cast_parser(self): )) def test_cast_parser_timezone(self): - tzinfo = pytz.timezone('US/Pacific') + tzinfo = ZoneInfo('US/Pacific') datetime_type = DateTime(timezone=tzinfo) values = ('3/1/1994 12:30 PM', '2/17/2011 06:30', None, 'January 5th, 1984 22:37', 'n/a') casted = tuple(datetime_type.cast(v) for v in values) self.assertSequenceEqual(casted, ( - tzinfo.localize(datetime.datetime(1994, 3, 1, 12, 30, 0, 0)), - tzinfo.localize(datetime.datetime(2011, 2, 17, 6, 30, 0, 0)), + datetime.datetime(1994, 3, 1, 12, 30, 0, 0, tzinfo=tzinfo), + datetime.datetime(2011, 2, 17, 6, 30, 0, 0, tzinfo=tzinfo), None, - tzinfo.localize(datetime.datetime(1984, 1, 5, 22, 37, 0, 0)), + datetime.datetime(1984, 1, 5, 22, 37, 0, 0, tzinfo=tzinfo), None ))