-
Notifications
You must be signed in to change notification settings - Fork 1.2k
refactor: deprecate pytz in favor of builtin zoneinfo #2757
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm okay with keeping just the bare minimal changes to be done in here, but since it's mostly noise, I would revert all changes to it - I won't review this file if there are so many lines changed. It's obvious that you didn't know it, but these files are no longer maintained nor we expect them to work with latest pvlib versions (I think, please any maintainer correct me if I'm wrong).
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @echedey-ls ok I'll just modify the line where the outdated pytz property was used. If it doesn't work anymore, maybe we should delete them.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. For the ipython files, whatever is easiest from this point onwards. Since the PR submitter updated the workbook, I don't think we need to revert changes. And I don't recall whether we decided (or just talked about) to not update the notebooks.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
Large diffs are not rendered by default.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -20,7 +20,7 @@ | |
| import requests | ||
| import numpy as np | ||
| import pandas as pd | ||
| import pytz | ||
| import zoneinfo | ||
| from pvlib.iotools import read_epw | ||
|
|
||
| URL = 'https://re.jrc.ec.europa.eu/api/' | ||
|
|
@@ -413,10 +413,10 @@ def _coerce_and_roll_tmy(tmy_data, tz, year): | |
| re-interpreted as zero / UTC. | ||
| """ | ||
| if tz: | ||
| tzname = pytz.timezone(f'Etc/GMT{-tz:+d}') | ||
| tzname = zoneinfo.ZoneInfo(f'Etc/GMT{-tz:+d}') # noqa: E231 | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I can't see the commit history, did you add
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @echedey-ls yes it was a false positive, flake8 insisted on putting a space after the : |
||
| else: | ||
| tz = 0 | ||
| tzname = pytz.timezone('UTC') | ||
| tzname = zoneinfo.ZoneInfo('UTC') | ||
| new_index = pd.DatetimeIndex([ | ||
| timestamp.replace(year=year, tzinfo=tzname) | ||
| for timestamp in tmy_data.index], | ||
|
|
||
| Original file line number | Diff line number | Diff line change | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -14,6 +14,7 @@ | |||||||||
|
|
||||||||||
| from pvlib import solarposition, clearsky, atmosphere, irradiance | ||||||||||
| from pvlib.tools import _degrees_to_index | ||||||||||
| from pvlib._deprecation import warn_deprecated | ||||||||||
|
|
||||||||||
|
|
||||||||||
| class Location: | ||||||||||
|
|
@@ -22,13 +23,11 @@ class Location: | |||||||||
| time zone, and altitude data associated with a particular geographic | ||||||||||
| location. You can also assign a name to a location object. | ||||||||||
|
|
||||||||||
| Location objects have two time-zone attributes: | ||||||||||
| Location objects have a time-zone attribute: | ||||||||||
|
|
||||||||||
| * ``tz`` is an IANA time-zone string. | ||||||||||
|
Comment on lines
+26
to
28
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||
| * ``pytz`` is a pytz-based time-zone object (read only). | ||||||||||
|
|
||||||||||
| The read-only ``pytz`` attribute will stay in sync with any changes made | ||||||||||
| using ``tz``. | ||||||||||
| The ``pytz`` attribute is deprecated. Use ``tz`` instead. | ||||||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
Formatting and decor. |
||||||||||
|
|
||||||||||
| Location objects support the print method. | ||||||||||
|
|
||||||||||
|
|
@@ -47,8 +46,8 @@ class Location: | |||||||||
| list of valid name strings. An `int` or `float` must be a whole-number | ||||||||||
| hour offsets from UTC that can be converted to the IANA-supported | ||||||||||
| 'Etc/GMT-N' format. (Note the limited range of the offset N and its | ||||||||||
| sign-change convention.) Time zones from the pytz and zoneinfo packages | ||||||||||
| may also be passed here, as they are subclasses of datetime.tzinfo. | ||||||||||
| sign-change convention.) Time zones from the zoneinfo packages may also | ||||||||||
| be passed here. | ||||||||||
|
|
||||||||||
| The `tz` attribute is represented as a valid IANA time zone name | ||||||||||
| string. | ||||||||||
|
|
@@ -108,17 +107,19 @@ def tz(self, tz_): | |||||||||
| if isinstance(tz_, str): | ||||||||||
| self._zoneinfo = zoneinfo.ZoneInfo(tz_) | ||||||||||
| elif isinstance(tz_, int): | ||||||||||
| self._zoneinfo = zoneinfo.ZoneInfo(f"Etc/GMT{-tz_:+d}") | ||||||||||
| tz_str = f"Etc/GMT{-tz_:+d}" # noqa: E231 | ||||||||||
| self._zoneinfo = zoneinfo.ZoneInfo(tz_str) | ||||||||||
| elif isinstance(tz_, float): | ||||||||||
| if tz_ % 1 != 0: | ||||||||||
| raise TypeError( | ||||||||||
| "Floating-point tz has non-zero fractional part: " | ||||||||||
| f"{tz_}. Only whole-number offsets are supported." | ||||||||||
| ) | ||||||||||
|
|
||||||||||
| self._zoneinfo = zoneinfo.ZoneInfo(f"Etc/GMT{-int(tz_):+d}") | ||||||||||
| tz_str = f"Etc/GMT{-int(tz_):+d}" # noqa: E231 | ||||||||||
| self._zoneinfo = zoneinfo.ZoneInfo(tz_str) | ||||||||||
| elif isinstance(tz_, datetime.tzinfo): | ||||||||||
| # Includes time zones generated by pytz and zoneinfo packages. | ||||||||||
| # Includes time zones generated by zoneinfo packages. | ||||||||||
| self._zoneinfo = zoneinfo.ZoneInfo(str(tz_)) | ||||||||||
| else: | ||||||||||
| raise TypeError( | ||||||||||
|
|
@@ -128,8 +129,20 @@ def tz(self, tz_): | |||||||||
| ) | ||||||||||
|
|
||||||||||
| @property | ||||||||||
| def pytz(self): | ||||||||||
| """The location's pytz time zone (read only).""" | ||||||||||
| def pytz(self): # pragma: no cover | ||||||||||
| """The location's pytz time zone (read only). | ||||||||||
|
|
||||||||||
| .. deprecated:: | ||||||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||
| The ``pytz`` attribute is deprecated. Use the ``tz`` property | ||||||||||
| instead. | ||||||||||
| """ | ||||||||||
| warn_deprecated( | ||||||||||
| since='0.15.2', | ||||||||||
| removal='0.17.0', | ||||||||||
| name='pytz', | ||||||||||
| obj_type='attribute', | ||||||||||
| alternative='tz', | ||||||||||
| ) | ||||||||||
| return pytz.timezone(str(self._zoneinfo)) | ||||||||||
|
|
||||||||||
| @classmethod | ||||||||||
|
|
||||||||||
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -1360,11 +1360,11 @@ def hour_angle(times, longitude, equation_of_time): | |||||
| Corresponding timestamps, must be localized to the timezone for the | ||||||
| ``longitude``. | ||||||
| A `pytz.exceptions.AmbiguousTimeError` will be raised if any of the | ||||||
| given times are on a day when the local daylight savings transition | ||||||
| happens at midnight. If you're working with such a timezone, | ||||||
| consider converting to a non-DST timezone (e.g. GMT-4) before | ||||||
| calling this function. | ||||||
| An error (AmbiguousTimeError in older pandas, ValueError in newer) | ||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
| will be raised if any of the given times are on a day when the local | ||||||
| daylight savings transition happens at midnight. If you're working | ||||||
| with such a timezone, consider converting to a non-DST timezone | ||||||
| (e.g. GMT-4) before calling this function. | ||||||
| longitude : numeric | ||||||
| Longitude in degrees | ||||||
| equation_of_time : numeric | ||||||
|
|
||||||
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -4,11 +4,12 @@ | |||||
|
|
||||||
| import contextlib | ||||||
| import datetime as dt | ||||||
| from datetime import timezone | ||||||
| import warnings | ||||||
|
|
||||||
| import numpy as np | ||||||
| import pandas as pd | ||||||
| import pytz | ||||||
| import zoneinfo | ||||||
|
|
||||||
|
|
||||||
| def cosd(angle): | ||||||
|
|
@@ -135,8 +136,8 @@ def localize_to_utc(time, location): | |||||
| """ | ||||||
| if isinstance(time, dt.datetime): | ||||||
| if time.tzinfo is None: | ||||||
| time = location.pytz.localize(time) | ||||||
| time_utc = time.astimezone(pytz.utc) | ||||||
| time = time.replace(tzinfo=location._zoneinfo) | ||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can we avoid the access of the private attribute?
Suggested change
Dunno if it can work like that or needs transforming into another object. |
||||||
| time_utc = time.astimezone(timezone.utc) | ||||||
| else: | ||||||
| try: | ||||||
| time_utc = time.tz_convert('UTC') | ||||||
|
|
@@ -162,11 +163,11 @@ def datetime_to_djd(time): | |||||
| """ | ||||||
|
|
||||||
| if time.tzinfo is None: | ||||||
| time_utc = pytz.utc.localize(time) | ||||||
| time_utc = time.replace(tzinfo=timezone.utc) | ||||||
| else: | ||||||
| time_utc = time.astimezone(pytz.utc) | ||||||
| time_utc = time.astimezone(timezone.utc) | ||||||
|
|
||||||
| djd_start = pytz.utc.localize(dt.datetime(1899, 12, 31, 12)) | ||||||
| djd_start = dt.datetime(1899, 12, 31, 12, tzinfo=timezone.utc) | ||||||
| djd = (time_utc - djd_start).total_seconds() * 1.0/(60 * 60 * 24) | ||||||
|
|
||||||
| return djd | ||||||
|
|
@@ -189,10 +190,10 @@ def djd_to_datetime(djd, tz='UTC'): | |||||
| The resultant datetime localized to tz | ||||||
| """ | ||||||
|
|
||||||
| djd_start = pytz.utc.localize(dt.datetime(1899, 12, 31, 12)) | ||||||
| djd_start = dt.datetime(1899, 12, 31, 12, tzinfo=timezone.utc) | ||||||
|
|
||||||
| utc_time = djd_start + dt.timedelta(days=djd) | ||||||
| return utc_time.astimezone(pytz.timezone(tz)) | ||||||
| return utc_time.astimezone(zoneinfo.ZoneInfo(tz)) | ||||||
|
|
||||||
|
|
||||||
| def _pandas_to_doy(pd_object): | ||||||
|
|
||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can you add a test that fails in v0.17.0 that asserts a warning is emitted when reading the deprecated attribute? |
Uh oh!
There was an error while loading. Please reload this page.