Skip to content

refactor: deprecate pytz in favor of builtin zoneinfo#2757

Open
JoLo90 wants to merge 9 commits into
pvlib:mainfrom
JoLo90:replace_pytz_with_zoneinfo
Open

refactor: deprecate pytz in favor of builtin zoneinfo#2757
JoLo90 wants to merge 9 commits into
pvlib:mainfrom
JoLo90:replace_pytz_with_zoneinfo

Conversation

@JoLo90
Copy link
Copy Markdown
Contributor

@JoLo90 JoLo90 commented May 19, 2026

Description

Replaces pytz with Python's built-in zoneinfo module for all timezone handling in pvlib.
There is an ongoing issue with micromamba that has been solved thanks to mamba-org/setup-micromamba#306. See commit [ci: update micromamba setup and version].

Changes

  • pvlib/tools.py: Replaced all pytz.utc.localize() and pytz.timezone() calls with datetime.timezone.utc and zoneinfo.ZoneInfo
  • pvlib/iotools/pvgis.py: Replaced pytz.timezone() with zoneinfo.ZoneInfo
  • pvlib/solarposition.py: Updated docstring to remove reference to pytz.exceptions.AmbiguousTimeError
  • ci/requirements-py3.1*.yml: updated mamba-org/setup-micromamba from v2 to v3 to fix Windows runner incompatibility with the new windows-2025 GitHub Actions runner
  • docs/tutorials/solarposition.ipynb: Replaced tus.pytz with tus.tz
  • tests/: Updated all test files to use zoneinfo instead of pytz

Checklist

  • Closes Replace pytz with standard library's zoneinfo #2343
  • I am familiar with the contributing guidelines
  • I attest that all AI-generated material has been vetted for accuracy and is in compliance with the pvlib license
  • Tests added
  • Updates entries in docs/sphinx/source/reference for API changes.
  • Adds description and name entries in the appropriate "what's new" file in docs/sphinx/source/whatsnew for all changes. Includes link to the GitHub Issue with :issue:`num` or this Pull Request with :pull:`num`. Includes contributor name and/or GitHub username (link with :ghuser:`user`).
  • New code is fully documented. Includes numpydoc compliant docstrings, examples, and comments where necessary.
  • Pull request is nearly complete and ready for detailed review.
  • Maintainer: Appropriate GitHub Labels (including remote-data) and Milestone are assigned to the Pull Request and linked Issue.

@JoLo90 JoLo90 force-pushed the replace_pytz_with_zoneinfo branch 7 times, most recently from 351a3d7 to 812539d Compare May 19, 2026 13:01
@JoLo90 JoLo90 marked this pull request as ready for review May 19, 2026 13:33
@cwhanse
Copy link
Copy Markdown
Member

cwhanse commented May 19, 2026

@JoLo90 thanks for taking this on. Am I correct in thinking that, other that removing Location.pytz and needing to install pytz on Windows, that the changes are transparent to users?

Since the intent is to remove Location.pytz, we'll want to keep Location.pytz working for a deprecation period and raise a deprecation message if it is accessed or assigned (I think).

@JoLo90
Copy link
Copy Markdown
Contributor Author

JoLo90 commented May 19, 2026

@cwhanse
Yes, the changes are transparent to users, unless they were using the pytz property. As you mentioned, we should first show a warning that the property is deprecated.
Would the following make sense?

    Deprecated since 0.15.2
    Will be removed in 0.16.0 

@cwhanse
Copy link
Copy Markdown
Member

cwhanse commented May 19, 2026

@JoLo90 We'd remove in 0.17.0.

I think we raise a deprecation warning here using the pvlib function warn_deprecated here.

At least I think that's how the deprecation is intended to work for a class attribute.

@RDaxini RDaxini added deprecation Use for issues and PRs which involve deprecations api labels May 19, 2026
@RDaxini RDaxini added this to the v0.15.2 milestone May 19, 2026
@JoLo90 JoLo90 force-pushed the replace_pytz_with_zoneinfo branch from 7793ea6 to 2c4be54 Compare May 20, 2026 13:26
Copy link
Copy Markdown
Member

@cwhanse cwhanse left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Two other items:

  • Thanks for showing how to fix the CI issues with Windows tests. But let's not do that fix in this PR; should be it's own PR. Please revert changes to pytest.yml
  • There are two Warnings in the iPython notebook with a local path. It would help if those messages were suppressed somehow. Also, can you rerun the notebook with the execution counter reset?

Comment thread pvlib/location.py Outdated

The read-only ``pytz`` attribute will stay in sync with any changes made
using ``tz``.
The ``pytz`` attribute is deprecated. Use ``tz`` property instead.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
The ``pytz`` attribute is deprecated. Use ``tz`` property instead.
The ``pytz`` attribute is deprecated. Use ``tz`` instead.

Comment thread docs/sphinx/source/whatsnew/v0.15.2.rst Outdated

Deprecations
~~~~~~~~~~~~
* Deprecated ``Location.pytz`` attribute. Use ``Location.tz`` property instead.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
* Deprecated ``Location.pytz`` attribute. Use ``Location.tz`` property instead.
* ``Location.pytz`` is deprecated. Use ``Location.tz`` instead.

@JoLo90 JoLo90 force-pushed the replace_pytz_with_zoneinfo branch from 2c4be54 to 5e45255 Compare May 21, 2026 07:25
@JoLo90
Copy link
Copy Markdown
Contributor Author

JoLo90 commented May 21, 2026

@cwhanse I implemented your comments and removed the local path warning in the jupyter notebook (note that these local paths appear in the other notebooks). The CI issues with Windows seem to be solved, so I won't open a new PR.

@JoLo90 JoLo90 force-pushed the replace_pytz_with_zoneinfo branch from 5e45255 to ff907e1 Compare May 21, 2026 07:57
Copy link
Copy Markdown
Member

@cwhanse cwhanse left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@pvlib/pvlib-triage I think this should get more looks than only mine - replaces pytz with zoneinfo. @pvlib/pvlib-maintainer

Copy link
Copy Markdown
Member

@RDaxini RDaxini left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm no expert on zoneinfo... I confess I didn't know it existed until this PR, but following @cwhanse's request I have had a quick scan over.

Besides a conventional point on the whatsnew file, and I am unsure about the diff on the notebook, I see the relevant instances of pytz have been replaced and a warning has been added, we have planned a removal version (0.17.0), docs are updated, and all checks pass... so this LGTM.

One question/note: do we need to update pyproject.toml to remove pytz as a dependency? (in 0.17.0)

I would also add on the side that we do need to update #2396 to keep track of the scheduled removal too. @echedey-ls ?

Comment thread docs/sphinx/source/whatsnew/v0.15.2.rst Outdated
Comment thread docs/sphinx/source/whatsnew/v0.15.2.rst
@JoLo90 JoLo90 force-pushed the replace_pytz_with_zoneinfo branch from e5c98a6 to 12e3158 Compare May 21, 2026 20:15
Copy link
Copy Markdown
Member

@echedey-ls echedey-ls left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My first round of comments and thoughts here.

Thanks @cwhanse for the ping and @RDaxini for the deprecation tracker reminder.

@JoLo90 , can you configure your environment to not force push an squashed commit of all your changes? We will squash and merge later, it can help us review to see the progress and small changes between one review and another.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The 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).

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The 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.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The 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.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@cwhanse , yup, it's an overstatement I made. We did remove their reference in docs for being "outdated" thou #2009

I think just cleaning the output of the jupyter execution would be enough to clear the diff and review it.

Comment thread pvlib/iotools/pvgis.py
"""
if tz:
tzname = pytz.timezone(f'Etc/GMT{-tz:+d}')
tzname = zoneinfo.ZoneInfo(f'Etc/GMT{-tz:+d}') # noqa: E231
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can't see the commit history, did you add # noqa: E231 because flake8 was complaining? I may be wrong, but sintax in this line shouldn't raise any flake8 warning. I can't reproduce locally in a reasonable amount of time (flake8 5.0.4 is tech debt at this point...).

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The 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 :

Comment thread pvlib/location.py
Comment thread pvlib/location.py Outdated
Comment thread pvlib/location.py Outdated
Comment thread pvlib/solarposition.py Outdated
Comment thread pvlib/tools.py Outdated
Comment thread tests/test_location.py
@JoLo90 JoLo90 force-pushed the replace_pytz_with_zoneinfo branch 2 times, most recently from af4c3a6 to e85ab50 Compare May 22, 2026 08:21
@JoLo90 JoLo90 force-pushed the replace_pytz_with_zoneinfo branch from e85ab50 to 15e60b0 Compare May 22, 2026 08:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

api deprecation Use for issues and PRs which involve deprecations

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants