python-dateutil 2.9.0.post0__tar.gz → 4.0.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {python-dateutil-2.9.0.post0 → python_dateutil-4.0.0}/.gitignore +1 -0
- {python-dateutil-2.9.0.post0 → python_dateutil-4.0.0}/AUTHORS.md +9 -0
- {python-dateutil-2.9.0.post0 → python_dateutil-4.0.0}/CONTRIBUTING.md +31 -5
- {python-dateutil-2.9.0.post0 → python_dateutil-4.0.0}/NEWS +162 -0
- {python-dateutil-2.9.0.post0/src/python_dateutil.egg-info → python_dateutil-4.0.0}/PKG-INFO +20 -40
- {python-dateutil-2.9.0.post0 → python_dateutil-4.0.0}/README.rst +4 -17
- python_dateutil-4.0.0/ci_tools/run_tz_master_env.sh +97 -0
- {python-dateutil-2.9.0.post0 → python_dateutil-4.0.0}/docs/Makefile +32 -29
- {python-dateutil-2.9.0.post0 → python_dateutil-4.0.0}/docs/conf.py +17 -12
- python_dateutil-4.0.0/docs/tz.rst +108 -0
- python_dateutil-4.0.0/docs/zoneinfo.rst +10 -0
- python_dateutil-4.0.0/pyproject.toml +155 -0
- python_dateutil-4.0.0/requirements-dev.txt +8 -0
- {python-dateutil-2.9.0.post0 → python_dateutil-4.0.0}/src/dateutil/__init__.py +7 -6
- {python-dateutil-2.9.0.post0 → python_dateutil-4.0.0}/src/dateutil/_common.py +1 -4
- python_dateutil-4.0.0/src/dateutil/_tzdata_impl.py +75 -0
- python_dateutil-4.0.0/src/dateutil/_version.py +24 -0
- {python-dateutil-2.9.0.post0 → python_dateutil-4.0.0}/src/dateutil/easter.py +0 -1
- {python-dateutil-2.9.0.post0 → python_dateutil-4.0.0}/src/dateutil/parser/__init__.py +14 -12
- {python-dateutil-2.9.0.post0 → python_dateutil-4.0.0}/src/dateutil/parser/_parser.py +14 -20
- {python-dateutil-2.9.0.post0 → python_dateutil-4.0.0}/src/dateutil/parser/isoparser.py +25 -15
- {python-dateutil-2.9.0.post0 → python_dateutil-4.0.0}/src/dateutil/relativedelta.py +8 -12
- {python-dateutil-2.9.0.post0 → python_dateutil-4.0.0}/src/dateutil/rrule.py +70 -55
- python_dateutil-4.0.0/src/dateutil/tz/__init__.py +44 -0
- {python-dateutil-2.9.0.post0 → python_dateutil-4.0.0}/src/dateutil/tz/_common.py +12 -123
- {python-dateutil-2.9.0.post0 → python_dateutil-4.0.0}/src/dateutil/tz/_factories.py +4 -6
- python_dateutil-4.0.0/src/dateutil/tz/_tzfile.py +1332 -0
- python_dateutil-4.0.0/src/dateutil/tz/_tzpath.py +12 -0
- {python-dateutil-2.9.0.post0 → python_dateutil-4.0.0}/src/dateutil/tz/tz.py +201 -658
- {python-dateutil-2.9.0.post0 → python_dateutil-4.0.0}/src/dateutil/tz/win.py +17 -17
- {python-dateutil-2.9.0.post0 → python_dateutil-4.0.0}/src/dateutil/utils.py +0 -2
- {python-dateutil-2.9.0.post0 → python_dateutil-4.0.0}/src/dateutil/zoneinfo/__init__.py +100 -43
- python_dateutil-4.0.0/src/dateutil/zoneinfo/rebuild.py +42 -0
- {python-dateutil-2.9.0.post0 → python_dateutil-4.0.0}/tests/_common.py +132 -13
- python_dateutil-4.0.0/tests/conftest.py +46 -0
- python_dateutil-4.0.0/tests/property/test_isoparse_prop.py +58 -0
- python_dateutil-4.0.0/tests/property/test_rrule_prop.py +117 -0
- python_dateutil-4.0.0/tests/property/test_tz_prop.py +91 -0
- python_dateutil-4.0.0/tests/resources/data/__init__.py +0 -0
- python_dateutil-4.0.0/tests/resources/data/keys.json +13 -0
- python_dateutil-4.0.0/tests/resources/data/metadata.json +3 -0
- python_dateutil-4.0.0/tests/resources/data/zoneinfo_fat.json +13 -0
- python_dateutil-4.0.0/tests/resources/data/zoneinfo_slim.json +13 -0
- python_dateutil-4.0.0/tests/resources/data/zoneinfo_v1.json +13 -0
- python_dateutil-4.0.0/tests/resources/liliput_tzif +0 -0
- python_dateutil-4.0.0/tests/resources/update_tzif.py +254 -0
- {python-dateutil-2.9.0.post0 → python_dateutil-4.0.0}/tests/test_import_star.py +0 -2
- {python-dateutil-2.9.0.post0 → python_dateutil-4.0.0}/tests/test_imports.py +105 -56
- {python-dateutil-2.9.0.post0 → python_dateutil-4.0.0}/tests/test_internals.py +0 -6
- {python-dateutil-2.9.0.post0 → python_dateutil-4.0.0}/tests/test_isoparser.py +115 -96
- {python-dateutil-2.9.0.post0 → python_dateutil-4.0.0}/tests/test_parser.py +46 -42
- {python-dateutil-2.9.0.post0 → python_dateutil-4.0.0}/tests/test_relativedelta.py +36 -17
- {python-dateutil-2.9.0.post0 → python_dateutil-4.0.0}/tests/test_rrule.py +278 -56
- {python-dateutil-2.9.0.post0 → python_dateutil-4.0.0}/tests/test_tz.py +296 -198
- python_dateutil-4.0.0/tests/test_tzfile.py +2823 -0
- python_dateutil-4.0.0/tests/test_tzpath_data.py +362 -0
- {python-dateutil-2.9.0.post0 → python_dateutil-4.0.0}/tests/test_utils.py +13 -10
- python_dateutil-4.0.0/tests/test_zoneinfo.py +146 -0
- {python-dateutil-2.9.0.post0 → python_dateutil-4.0.0}/tox.ini +38 -56
- python-dateutil-2.9.0.post0/.gitattributes +0 -18
- python-dateutil-2.9.0.post0/.github/pull_request_template.md +0 -12
- python-dateutil-2.9.0.post0/.github/workflows/publish.yml +0 -63
- python-dateutil-2.9.0.post0/.github/workflows/validate.yml +0 -150
- python-dateutil-2.9.0.post0/.pre-commit-config.yaml +0 -14
- python-dateutil-2.9.0.post0/.readthedocs.yml +0 -15
- python-dateutil-2.9.0.post0/.travis.yml +0 -35
- python-dateutil-2.9.0.post0/MANIFEST.in +0 -4
- python-dateutil-2.9.0.post0/PKG-INFO +0 -204
- python-dateutil-2.9.0.post0/RELEASING +0 -79
- python-dateutil-2.9.0.post0/appveyor.yml +0 -38
- python-dateutil-2.9.0.post0/azure-pipelines.yml +0 -79
- python-dateutil-2.9.0.post0/ci_tools/make_zonefile_metadata.py +0 -61
- python-dateutil-2.9.0.post0/ci_tools/retry.bat +0 -18
- python-dateutil-2.9.0.post0/ci_tools/retry.sh +0 -10
- python-dateutil-2.9.0.post0/ci_tools/run_tz_master_env.sh +0 -97
- python-dateutil-2.9.0.post0/codecov.yml +0 -9
- python-dateutil-2.9.0.post0/docs/tz.rst +0 -60
- python-dateutil-2.9.0.post0/docs/zoneinfo.rst +0 -19
- python-dateutil-2.9.0.post0/pyproject.toml +0 -66
- python-dateutil-2.9.0.post0/requirements/3.3/constraints.txt +0 -15
- python-dateutil-2.9.0.post0/requirements/3.3/requirements-dev.txt +0 -8
- python-dateutil-2.9.0.post0/requirements-dev.txt +0 -9
- python-dateutil-2.9.0.post0/setup.cfg +0 -85
- python-dateutil-2.9.0.post0/setup.py +0 -58
- python-dateutil-2.9.0.post0/src/dateutil/_version.py +0 -4
- python-dateutil-2.9.0.post0/src/dateutil/tz/__init__.py +0 -12
- python-dateutil-2.9.0.post0/src/dateutil/zoneinfo/dateutil-zoneinfo.tar.gz +0 -0
- python-dateutil-2.9.0.post0/src/dateutil/zoneinfo/rebuild.py +0 -75
- python-dateutil-2.9.0.post0/src/python_dateutil.egg-info/SOURCES.txt +0 -93
- python-dateutil-2.9.0.post0/src/python_dateutil.egg-info/dependency_links.txt +0 -1
- python-dateutil-2.9.0.post0/src/python_dateutil.egg-info/requires.txt +0 -1
- python-dateutil-2.9.0.post0/src/python_dateutil.egg-info/top_level.txt +0 -1
- python-dateutil-2.9.0.post0/src/python_dateutil.egg-info/zip-safe +0 -1
- python-dateutil-2.9.0.post0/tests/conftest.py +0 -41
- python-dateutil-2.9.0.post0/tests/property/test_isoparse_prop.py +0 -27
- python-dateutil-2.9.0.post0/tests/property/test_tz_prop.py +0 -35
- python-dateutil-2.9.0.post0/updatezinfo.py +0 -71
- python-dateutil-2.9.0.post0/zonefile_metadata.json +0 -22
- {python-dateutil-2.9.0.post0 → python_dateutil-4.0.0}/LICENSE +0 -0
- {python-dateutil-2.9.0.post0 → python_dateutil-4.0.0}/changelog.d/template.rst +0 -0
- {python-dateutil-2.9.0.post0 → python_dateutil-4.0.0}/docs/changelog.rst +0 -0
- {python-dateutil-2.9.0.post0 → python_dateutil-4.0.0}/docs/easter.rst +0 -0
- {python-dateutil-2.9.0.post0 → python_dateutil-4.0.0}/docs/examples.rst +0 -0
- {python-dateutil-2.9.0.post0 → python_dateutil-4.0.0}/docs/exercises/index.rst +0 -0
- {python-dateutil-2.9.0.post0 → python_dateutil-4.0.0}/docs/exercises/solutions/mlk-day-rrule.rst +0 -0
- {python-dateutil-2.9.0.post0 → python_dateutil-4.0.0}/docs/exercises/solutions/mlk_day_rrule_solution.py +0 -0
- {python-dateutil-2.9.0.post0 → python_dateutil-4.0.0}/docs/index.rst +0 -0
- {python-dateutil-2.9.0.post0 → python_dateutil-4.0.0}/docs/make.bat +0 -0
- {python-dateutil-2.9.0.post0 → python_dateutil-4.0.0}/docs/parser.rst +0 -0
- {python-dateutil-2.9.0.post0 → python_dateutil-4.0.0}/docs/relativedelta.rst +0 -0
- {python-dateutil-2.9.0.post0 → python_dateutil-4.0.0}/docs/requirements-docs.txt +0 -0
- {python-dateutil-2.9.0.post0 → python_dateutil-4.0.0}/docs/rrule.rst +0 -0
- {python-dateutil-2.9.0.post0 → python_dateutil-4.0.0}/docs/samples/EST5EDT.ics +0 -0
- {python-dateutil-2.9.0.post0 → python_dateutil-4.0.0}/docs/tzwin.rst +0 -0
- {python-dateutil-2.9.0.post0 → python_dateutil-4.0.0}/docs/utils.rst +0 -0
- {python-dateutil-2.9.0.post0 → python_dateutil-4.0.0}/src/dateutil/tzwin.py +0 -0
- {python-dateutil-2.9.0.post0 → python_dateutil-4.0.0}/tests/__init__.py +0 -0
- {python-dateutil-2.9.0.post0 → python_dateutil-4.0.0}/tests/property/test_parser_prop.py +0 -0
- /python-dateutil-2.9.0.post0/changelog.d/.gitignore → /python_dateutil-4.0.0/tests/resources/__init__.py +0 -0
- {python-dateutil-2.9.0.post0 → python_dateutil-4.0.0}/tests/test_easter.py +0 -0
|
@@ -11,6 +11,7 @@ switch, and thus all their contributions are dual-licensed.
|
|
|
11
11
|
|
|
12
12
|
## Contributors (alphabetical order)
|
|
13
13
|
|
|
14
|
+
- Aarni Koskela <akx@iki.fi> **D**
|
|
14
15
|
- Adam Chainz <adam@MASKED>
|
|
15
16
|
- Adrien Cossa <cossa@MASKED>
|
|
16
17
|
- Alec Nikolas Reiter <alecreiter@MASKED>
|
|
@@ -59,14 +60,18 @@ switch, and thus all their contributions are dual-licensed.
|
|
|
59
60
|
- Igor <mrigor83@MASKED>
|
|
60
61
|
- Ionuț Ciocîrlan <jdxlark@MASKED>
|
|
61
62
|
- Jacqueline Chen <jacqueline415@outlook.com> (gh: @jachen20) **D**
|
|
63
|
+
- Jairo Llopis (gh: @yajo) **D**
|
|
62
64
|
- Jake Chorley (gh: @jakec-github) **D**
|
|
63
65
|
- Jakub Kulík (gh: @kulikjak) **D**
|
|
64
66
|
- Jan Studený <jendas1@MASKED>
|
|
67
|
+
- JAY (gh: @Jay1023CN) **D**
|
|
65
68
|
- Jay Weisskopf <jay@jayschwa.net> (gh: @jayschwa) **D**
|
|
66
69
|
- Jitesh <jitesh@MASKED>
|
|
67
70
|
- John Purviance <jpurviance@MASKED> (gh @jpurviance) **D**
|
|
68
71
|
- Jon Dufresne <jon.dufresne@MASKED> (gh: @jdufresne) **R**
|
|
69
72
|
- Jonas Neubert <jonas@MASKED> (gh: @jonemo) **R**
|
|
73
|
+
- Jordi Masip <jordi@MASKED> (gh: @masipcat)
|
|
74
|
+
- Juan Arias <jdarias3@gmail.com> (gh: @jdarias3) **D**
|
|
70
75
|
- Kevin Nguyen <kvn219@MASKED> **D**
|
|
71
76
|
- Kirit Thadaka <kirit.thadaka@gmail.com> (gh: @kirit93) **D**
|
|
72
77
|
- Kubilay Kocak <koobs@MASKED>
|
|
@@ -87,6 +92,7 @@ switch, and thus all their contributions are dual-licensed.
|
|
|
87
92
|
- Nicholas Herrriot <Nicholas.Herriot@gmail.com> **D**
|
|
88
93
|
- Nicolas Évrard (gh: @nicoe) **D**
|
|
89
94
|
- Nick Smith <nick.smith@MASKED>
|
|
95
|
+
- Nor.na (gh: @Master-Norna) **D**
|
|
90
96
|
- Orson Adams <orson.network@MASKED> (gh: @parsethis) **D**
|
|
91
97
|
- Paul Brown (gh: @pawl) **D**
|
|
92
98
|
- Paul Dickson (gh @prdickson) **D**
|
|
@@ -99,6 +105,7 @@ switch, and thus all their contributions are dual-licensed.
|
|
|
99
105
|
- Raymond Cha (gh: @weatherpattern) **D**
|
|
100
106
|
- Ridhi Mahajan <ridhikmahajan@MASKED> **D**
|
|
101
107
|
- Robin Henriksson Törnström <gh: @MrRawbin> **D**
|
|
108
|
+
- Rowan Walsh (gh: @rowan-walsh) **D**
|
|
102
109
|
- Roy Williams <rwilliams@MASKED>
|
|
103
110
|
- Rustem Saiargaliev (gh: @amureki) **D**
|
|
104
111
|
- Satyabrat Bhol <satyabrat35@MASKED> (gh: @Satyabrat35) **D**
|
|
@@ -116,6 +123,7 @@ switch, and thus all their contributions are dual-licensed.
|
|
|
116
123
|
- Tomasz Kluczkowski (gh: @Tomasz-Kluczkowski) **D**
|
|
117
124
|
- Tomi Pieviläinen <tomi.pievilainen@iki.fi>
|
|
118
125
|
- Unrud <Unrud@MASKED> (gh: @unrud)
|
|
126
|
+
- varun netrakar <varun@security.bugqore.com> (gh: @varun3257) **D**
|
|
119
127
|
- Xavier Lapointe <lapointe.xavier@MASKED> (gh: @lapointexavier) **D**
|
|
120
128
|
- X O <xo@MASKED>
|
|
121
129
|
- Yaron de Leeuw <me@jarondl.net> (gh: @jarondl)
|
|
@@ -124,6 +132,7 @@ switch, and thus all their contributions are dual-licensed.
|
|
|
124
132
|
- Zbigniew Jędrzejewski-Szmek <zbyszek@MASKED>
|
|
125
133
|
- bachmann <bachmann.matt@MASKED>
|
|
126
134
|
- bjv <brandon.vanvaerenbergh@MASKED> (@bjamesvERT)
|
|
135
|
+
- friskysaga (gh: @kevinkt1) **D**
|
|
127
136
|
- gl <gl@MASKED>
|
|
128
137
|
- gfyoung <gfyoung17@gmail.com> **D**
|
|
129
138
|
- Labrys <labrys.git@gmail.com> (gh: @labrys) **R**
|
|
@@ -33,7 +33,8 @@ To keep users abreast of the changes to the module and to give proper credit, `d
|
|
|
33
33
|
- `feature`: A new feature, (e.g. a new function, method, attribute, etc)
|
|
34
34
|
- `bugfix`: A fix to a bug
|
|
35
35
|
- `doc`: A change to the documentation
|
|
36
|
-
- `
|
|
36
|
+
- `deprecations`: Used if deprecating a feature or dropping support for a Python version.
|
|
37
|
+
- `data`: An update to the bundled time zone data.
|
|
37
38
|
- `misc`: A change that has no interesting effect for end users, such as fixes to the test suite or CI.
|
|
38
39
|
|
|
39
40
|
PRs that include a feature or bugfix *and* a deprecation should create a separate entry for the deprecation.
|
|
@@ -93,20 +94,45 @@ pip install -r requirements-dev.txt
|
|
|
93
94
|
|
|
94
95
|
## Testing
|
|
95
96
|
|
|
96
|
-
The best way to test `dateutil` is to run `tox`. By default, `tox` will test against all supported versions of Python installed on your system. To limit the number of tests, run a specific subset of environments. For example, to run only on Python
|
|
97
|
+
The best way to test `dateutil` is to run `tox`. By default, `tox` will test against all supported versions of Python installed on your system. To limit the number of tests, run a specific subset of environments. For example, to run only on Python 3.11 and Python 3.13:
|
|
97
98
|
|
|
98
99
|
```bash
|
|
99
|
-
tox -e
|
|
100
|
+
tox -e py311,py313
|
|
100
101
|
```
|
|
101
102
|
|
|
103
|
+
For faster environment creation and dependency installation, you can install
|
|
104
|
+
`tox` with the `tox-uv` plugin using [uv](https://docs.astral.sh/uv/):
|
|
105
|
+
|
|
106
|
+
```bash
|
|
107
|
+
uv tool install tox --with tox-uv
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
The same `tox` commands work with either the uv plugin or the default installer.
|
|
111
|
+
|
|
102
112
|
You can also pass arguments to `pytest` through `tox` by placing them after `--`:
|
|
103
113
|
|
|
104
114
|
```bash
|
|
105
|
-
tox -e
|
|
115
|
+
tox -e py311 -- -m tzstr
|
|
106
116
|
```
|
|
107
117
|
|
|
108
118
|
This will pass the `-m tzstr` parameter to `pytest`, running only the tests with the `tzstr` mark.
|
|
109
119
|
|
|
120
|
+
`tox` runs the tests in parallel with [pytest-xdist](https://pytest-xdist.readthedocs.io/). To run them in a single process, for example to use `--pdb`, pass `-n 0`:
|
|
121
|
+
|
|
122
|
+
```bash
|
|
123
|
+
tox -e py311 -- -n 0 --pdb
|
|
124
|
+
```
|
|
125
|
+
|
|
110
126
|
The tests can also be run directly by running `pytest` or `python -m pytest` in the root directory. This will be likely be less thorough but is often faster and is a good first pass to check your changes.
|
|
111
127
|
|
|
112
|
-
|
|
128
|
+
The GitHub Actions workflows are checked with [zizmor](https://docs.zizmor.sh/).
|
|
129
|
+
To run the audit locally:
|
|
130
|
+
|
|
131
|
+
```bash
|
|
132
|
+
uvx zizmor .github/workflows
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
This uses the latest zizmor release, which may report different findings from
|
|
136
|
+
the version bundled with the pinned zizmor action in CI.
|
|
137
|
+
|
|
138
|
+
All GitHub pull requests are automatically tested using [GitHub Actions](https://github.com/dateutil/dateutil/actions/).
|
|
@@ -1,3 +1,165 @@
|
|
|
1
|
+
Version 4.0.0 (2026-11-01)
|
|
2
|
+
==========================
|
|
3
|
+
|
|
4
|
+
``dateutil`` 4.0 requires Python 3.11 or later and no longer depends on
|
|
5
|
+
``six``. Apart from that, the changes in this release are bug fixes, but note
|
|
6
|
+
that ``isoparse`` is now stricter about the numeric fields it accepts (see
|
|
7
|
+
below).
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
Deprecations
|
|
11
|
+
------------
|
|
12
|
+
|
|
13
|
+
- Dropped support for Python versions older than 3.11 and removed the dependency
|
|
14
|
+
on ``six``, along with Python 2 compatibility helpers that were never part of
|
|
15
|
+
the public API, such as ``dateutil.tz.tzname_in_python2``. (gh pr #1625)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
Bugfixes
|
|
19
|
+
--------
|
|
20
|
+
|
|
21
|
+
- ``parser.isoparse``, and the ``isoparser`` methods ``parse_isodate``,
|
|
22
|
+
``parse_isotime`` and ``parse_tzstr``, now require each numeric field to be
|
|
23
|
+
exactly the expected number of ASCII digits. Strings that were previously
|
|
24
|
+
accepted, such as ``20200728121240`` (read as 21:24), ``2014- 4-21`` and
|
|
25
|
+
``2_14-04-21``, and offsets such as ``+-1:00``, now raise ``ValueError``.
|
|
26
|
+
``tzical`` applies the same check to ``TZOFFSETFROM`` and ``TZOFFSETTO``.
|
|
27
|
+
Reported by @janos-gonye (gh issue #1074). Fixed by @varun3257 (gh pr #1617).
|
|
28
|
+
- Fixed an issue where iterating over a cached ``rrule`` or ``rruleset`` could
|
|
29
|
+
hang forever if another iterator over the same rule had already completed the
|
|
30
|
+
cache, for example when a cached ``rrule`` was included twice in an
|
|
31
|
+
``rruleset``. Reported by @bysiber (gh pr #1455). Fixed by @pganssle (gh pr
|
|
32
|
+
#1655).
|
|
33
|
+
- Unpickling a ``tzutc`` now gives the ``dateutil.tz.UTC`` singleton, and
|
|
34
|
+
unpickling a ``tzoffset`` gives the same object as calling
|
|
35
|
+
``tzoffset(name, offset)``. Previously unpickling bypassed the
|
|
36
|
+
singleton-generation logic. Reported and fixed by @masipcat (gh issue #1051,
|
|
37
|
+
gh pr #1053).
|
|
38
|
+
- ``relativedelta(yearday=366)`` now resolves to December 31 in leap years.
|
|
39
|
+
Previously it gave December 30, the same date as ``yearday=365``. Reported
|
|
40
|
+
and fixed by @Master-Norna (gh pr #1583).
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
Misc
|
|
44
|
+
----
|
|
45
|
+
|
|
46
|
+
- The build backend is now Hatchling, and the package metadata is in
|
|
47
|
+
``pyproject.toml``. Versions are still derived from Git tags and exposed as
|
|
48
|
+
``dateutil.__version__``. This mainly affects people building ``dateutil``
|
|
49
|
+
from source. (gh pr #1637, #1638)
|
|
50
|
+
- Changes to CI, tests and release tooling that do not affect users of the
|
|
51
|
+
package: gh pr #1636, #1644, #1645, #1646, #1648, #1649, #1650.
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
Version 3.0.0 (2026-10-21)
|
|
55
|
+
==========================
|
|
56
|
+
|
|
57
|
+
**This is the last major version of** ``dateutil`` **that will support any
|
|
58
|
+
version of Python older than 3.11.** The next release will be the 4.x series,
|
|
59
|
+
which will support Python 3.11 and later. We may release fixes for serious bugs
|
|
60
|
+
in the 3.0.x series, but there are no plans for new features there.
|
|
61
|
+
|
|
62
|
+
The biggest change in this release is a rewrite of ``tz.tzfile``, which affects
|
|
63
|
+
nearly every user of ``dateutil.tz`` and changes the UTC offset of
|
|
64
|
+
nonexistent times (see below). ``dateutil`` also now depends on the ``tzdata``
|
|
65
|
+
package, and no longer ships its own time zone database.
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
Data updates
|
|
69
|
+
------------
|
|
70
|
+
|
|
71
|
+
- ``dateutil`` no longer bundles a copy of the IANA time zone database. Time
|
|
72
|
+
zone data now comes from the system (see ``dateutil.tz.TZPATH``) or, failing
|
|
73
|
+
that, from the new ``tzdata`` dependency, so the data version is whatever
|
|
74
|
+
version of ``tzdata`` is installed. (gh pr #1130)
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
Features
|
|
78
|
+
--------
|
|
79
|
+
|
|
80
|
+
- Rewrote ``tz.tzfile`` based on a backport of the ``zoneinfo`` module's pure-Python
|
|
81
|
+
implementation. This adds support for Version 2 and Version 3 ``tzfile(5)`` binaries,
|
|
82
|
+
resolving issues with timestamps beyond 2038 and "slim" format binaries. (gh issues #462, #1059, gh pr #1130)
|
|
83
|
+
- Added ``dateutil.tz.TZPATH`` and ``dateutil.tz.reset_tzpath`` to allow for
|
|
84
|
+
runtime configuration of the IANA time zone data search path. These replace the
|
|
85
|
+
mutable ``dateutil.tz.TZPATHS`` list, which has been removed. (gh pr #1130)
|
|
86
|
+
- ``dateutil`` now depends on the ``tzdata`` package, which ``gettz`` consults after the search
|
|
87
|
+
path and before the Windows registry. On Windows this means that names that are
|
|
88
|
+
both IANA keys and Windows time zone names, such as ``"UTC"``, now return a
|
|
89
|
+
``tzfile`` rather than a ``tzwin``. (gh pr #1130)
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
Bugfixes
|
|
93
|
+
--------
|
|
94
|
+
|
|
95
|
+
- ``tz.tzfile`` now follows PEP 495 for times that fall in a gap: with ``fold=0``
|
|
96
|
+
it uses the offset from before the transition, and with ``fold=1`` the offset
|
|
97
|
+
from after it. Previously it always used the offset from after the transition,
|
|
98
|
+
so for example ``datetime(2003, 4, 6, 2, 30, tzinfo=tz.gettz("America/New_York"))``
|
|
99
|
+
had a UTC offset of -04:00, where it now has -05:00, the same as with
|
|
100
|
+
``zoneinfo``. (gh pr #1130)
|
|
101
|
+
- ``tz.tzfile`` objects for fixed-offset zones, such as ``tz.gettz("UTC")``, now
|
|
102
|
+
return their offset, DST offset and abbreviation when ``utcoffset``, ``dst``
|
|
103
|
+
and ``tzname`` are called with ``None``, as ``tz.tzutc``, ``tz.tzoffset`` and
|
|
104
|
+
``zoneinfo.ZoneInfo`` do. This means that ``datetime.time`` objects with such
|
|
105
|
+
a zone attached are now aware: ``time(12, tzinfo=tz.gettz("UTC")).isoformat()``
|
|
106
|
+
is now ``"12:00:00+00:00"`` rather than ``"12:00:00"``. (gh pr #1130)
|
|
107
|
+
- ``tz.tzfile`` now infers ``dst()`` from the standard time on both sides of
|
|
108
|
+
each DST period, rather than only the one before it, and does so for each
|
|
109
|
+
transition rather than for each local time type. This fixes ``dst()`` for
|
|
110
|
+
double summer time (e.g. in ``Europe/London`` in the 1940s), for half-hour DST
|
|
111
|
+
(e.g. in ``Pacific/Rarotonga``) and where the standard offset changed at the
|
|
112
|
+
same time as a DST transition (e.g. in ``America/Bahia_Banderas`` in 2010).
|
|
113
|
+
Against the standard offsets in the tz database source, the only remaining
|
|
114
|
+
errors are in ``Europe/Paris`` in 1944 and 1945. (gh pr #1130)
|
|
115
|
+
- Fixed ``rrulestr`` raising ``ValueError`` on experimental ``X-`` parameters in
|
|
116
|
+
an ``RRULE`` line (such as GNOME Evolution's ``X-EVOLUTION-ENDDATE``); these are
|
|
117
|
+
now ignored as RFC 5545 permits. Fixed by @yajo (gh pr #1374)
|
|
118
|
+
- Enabled pickling and deepcopy of cached ``rrule`` and ``rruleset`` instances.
|
|
119
|
+
The cache setting is preserved, and cached results are regenerated on demand
|
|
120
|
+
without copying locks or generators. Reported by @niccokunzmann (gh issue #1369).
|
|
121
|
+
Fixed by @Jay1023CN (gh pr #1600).
|
|
122
|
+
- Fixed ``relativedelta.__ne__`` raising ``TypeError`` when comparing against an
|
|
123
|
+
unsupported type such as ``None``; it now returns ``True``. Reported and fixed
|
|
124
|
+
by @kevinkt1 (gh issue #1157, gh pr #1158)
|
|
125
|
+
- Raised the minimum version of ``six`` to 1.6, fixing ``No module named
|
|
126
|
+
'six.moves'`` errors with older versions. Reported by @skytreader (gh issue #1415),
|
|
127
|
+
fixed by @jdarias3 (gh pr #1424).
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
Deprecations
|
|
131
|
+
------------
|
|
132
|
+
|
|
133
|
+
- Deprecated the ``dateutil.zoneinfo`` module. The module now acts as a wrapper
|
|
134
|
+
around the ``tzdata`` package and will be removed in a future version. Users are
|
|
135
|
+
encouraged to migrate to ``dateutil.tz.gettz`` or the standard library's
|
|
136
|
+
``zoneinfo`` module. ``dateutil.zoneinfo.rebuild.rebuild`` no longer does
|
|
137
|
+
anything, and by default raises ``RebuildDeprecationWarning`` as an error;
|
|
138
|
+
filter the warning to call it as a no-op. (gh pr #1130)
|
|
139
|
+
- Deprecated passing ``gettz`` a relative key that refers to a file outside of
|
|
140
|
+
every directory on ``TZPATH``, such as ``"../../etc/localtime"``. By default
|
|
141
|
+
this now raises ``dateutil.tz.DeprecatedTzKeyWarning`` as an error; filter the
|
|
142
|
+
warning to keep the old behavior for now, or pass an absolute path instead.
|
|
143
|
+
(gh pr #1130)
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
Documentation changes
|
|
147
|
+
---------------------
|
|
148
|
+
|
|
149
|
+
- Added intersphinx to the docs build and cleaned up some broken links. (gh pr #1463)
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
Misc
|
|
153
|
+
----
|
|
154
|
+
|
|
155
|
+
- Releases are now uploaded to PyPI using trusted publishing, and the built
|
|
156
|
+
sdist and wheel are tested on all supported platforms before upload.
|
|
157
|
+
(gh pr #1619, #1622)
|
|
158
|
+
- Changes to CI, tests and release tooling that do not affect users of the
|
|
159
|
+
package: gh pr #1417, #1462, #1464, #1465, #1466, #1467, #1468, #1469, #1470,
|
|
160
|
+
#1499, #1501, #1504, #1576, #1577, #1578, #1581, #1585.
|
|
161
|
+
|
|
162
|
+
|
|
1
163
|
Version 2.9.0.post0 (2024-03-01)
|
|
2
164
|
================================
|
|
3
165
|
|
|
@@ -1,38 +1,31 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
2
|
Name: python-dateutil
|
|
3
|
-
Version:
|
|
3
|
+
Version: 4.0.0
|
|
4
4
|
Summary: Extensions to the standard Python datetime module
|
|
5
|
-
|
|
6
|
-
Author: Gustavo Niemeyer
|
|
7
|
-
Author-email: gustavo@niemeyer.net
|
|
8
|
-
Maintainer: Paul Ganssle
|
|
9
|
-
Maintainer-email: dateutil@python.org
|
|
10
|
-
License: Dual License
|
|
5
|
+
Project-URL: Homepage, https://github.com/dateutil/dateutil
|
|
11
6
|
Project-URL: Documentation, https://dateutil.readthedocs.io/en/stable/
|
|
12
7
|
Project-URL: Source, https://github.com/dateutil/dateutil
|
|
8
|
+
Author-email: Gustavo Niemeyer <gustavo@niemeyer.net>
|
|
9
|
+
Maintainer-email: Paul Ganssle <dateutil@python.org>
|
|
10
|
+
License-Expression: BSD-3-Clause
|
|
11
|
+
License-File: AUTHORS.md
|
|
12
|
+
License-File: LICENSE
|
|
13
13
|
Classifier: Development Status :: 5 - Production/Stable
|
|
14
14
|
Classifier: Intended Audience :: Developers
|
|
15
|
-
Classifier: License :: OSI Approved :: BSD License
|
|
16
|
-
Classifier: License :: OSI Approved :: Apache Software License
|
|
17
15
|
Classifier: Programming Language :: Python
|
|
18
|
-
Classifier: Programming Language :: Python :: 2
|
|
19
|
-
Classifier: Programming Language :: Python :: 2.7
|
|
20
16
|
Classifier: Programming Language :: Python :: 3
|
|
21
|
-
Classifier: Programming Language :: Python :: 3.3
|
|
22
|
-
Classifier: Programming Language :: Python :: 3.4
|
|
23
|
-
Classifier: Programming Language :: Python :: 3.5
|
|
24
|
-
Classifier: Programming Language :: Python :: 3.6
|
|
25
|
-
Classifier: Programming Language :: Python :: 3.7
|
|
26
|
-
Classifier: Programming Language :: Python :: 3.8
|
|
27
|
-
Classifier: Programming Language :: Python :: 3.9
|
|
28
|
-
Classifier: Programming Language :: Python :: 3.10
|
|
29
17
|
Classifier: Programming Language :: Python :: 3.11
|
|
30
18
|
Classifier: Programming Language :: Python :: 3.12
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.15
|
|
22
|
+
Classifier: Programming Language :: Python :: Free Threading :: 2 - Beta
|
|
23
|
+
Classifier: Programming Language :: Python :: Implementation :: CPython
|
|
24
|
+
Classifier: Programming Language :: Python :: Implementation :: PyPy
|
|
31
25
|
Classifier: Topic :: Software Development :: Libraries
|
|
32
|
-
Requires-Python:
|
|
26
|
+
Requires-Python: >=3.11
|
|
27
|
+
Requires-Dist: tzdata
|
|
33
28
|
Description-Content-Type: text/x-rst
|
|
34
|
-
License-File: LICENSE
|
|
35
|
-
Requires-Dist: six>=1.5
|
|
36
29
|
|
|
37
30
|
dateutil - powerful extensions to datetime
|
|
38
31
|
==========================================
|
|
@@ -41,7 +34,7 @@ dateutil - powerful extensions to datetime
|
|
|
41
34
|
|
|
42
35
|
|gitter| |readthedocs|
|
|
43
36
|
|
|
44
|
-
|
|
|
37
|
+
|gha| |coverage|
|
|
45
38
|
|
|
46
39
|
.. |pypi| image:: https://img.shields.io/pypi/v/python-dateutil.svg?style=flat-square
|
|
47
40
|
:target: https://pypi.org/project/python-dateutil/
|
|
@@ -51,17 +44,9 @@ dateutil - powerful extensions to datetime
|
|
|
51
44
|
:target: https://pypi.org/project/python-dateutil/
|
|
52
45
|
:alt: supported Python version
|
|
53
46
|
|
|
54
|
-
.. |
|
|
55
|
-
:target: https://
|
|
56
|
-
:alt:
|
|
57
|
-
|
|
58
|
-
.. |appveyor| image:: https://img.shields.io/appveyor/ci/dateutil/dateutil/master.svg?style=flat-square&logo=appveyor
|
|
59
|
-
:target: https://ci.appveyor.com/project/dateutil/dateutil
|
|
60
|
-
:alt: appveyor build status
|
|
61
|
-
|
|
62
|
-
.. |pipelines| image:: https://dev.azure.com/pythondateutilazure/dateutil/_apis/build/status/dateutil.dateutil?branchName=master
|
|
63
|
-
:target: https://dev.azure.com/pythondateutilazure/dateutil/_build/latest?definitionId=1&branchName=master
|
|
64
|
-
:alt: azure pipelines build status
|
|
47
|
+
.. |gha| image:: https://github.com/dateutil/dateutil/actions/workflows/validate.yml/badge.svg
|
|
48
|
+
:target: https://github.com/dateutil/dateutil/actions
|
|
49
|
+
:alt: github actions build status
|
|
65
50
|
|
|
66
51
|
.. |coverage| image:: https://codecov.io/gh/dateutil/dateutil/branch/master/graphs/badge.svg?branch=master
|
|
67
52
|
:target: https://codecov.io/gh/dateutil/dateutil?branch=master
|
|
@@ -189,11 +174,6 @@ Releases Signing key fingerprint
|
|
|
189
174
|
New releases *may* have signed tags, but binary and source distributions
|
|
190
175
|
uploaded to PyPI will no longer have GPG signatures attached.
|
|
191
176
|
|
|
192
|
-
Contact
|
|
193
|
-
=======
|
|
194
|
-
Our mailing list is available at `dateutil@python.org <https://mail.python.org/mailman/listinfo/dateutil>`_. As it is hosted by the PSF, it is subject to the `PSF code of
|
|
195
|
-
conduct <https://www.python.org/psf/conduct/>`_.
|
|
196
|
-
|
|
197
177
|
License
|
|
198
178
|
=======
|
|
199
179
|
|
|
@@ -5,7 +5,7 @@ dateutil - powerful extensions to datetime
|
|
|
5
5
|
|
|
6
6
|
|gitter| |readthedocs|
|
|
7
7
|
|
|
8
|
-
|
|
|
8
|
+
|gha| |coverage|
|
|
9
9
|
|
|
10
10
|
.. |pypi| image:: https://img.shields.io/pypi/v/python-dateutil.svg?style=flat-square
|
|
11
11
|
:target: https://pypi.org/project/python-dateutil/
|
|
@@ -15,17 +15,9 @@ dateutil - powerful extensions to datetime
|
|
|
15
15
|
:target: https://pypi.org/project/python-dateutil/
|
|
16
16
|
:alt: supported Python version
|
|
17
17
|
|
|
18
|
-
.. |
|
|
19
|
-
:target: https://
|
|
20
|
-
:alt:
|
|
21
|
-
|
|
22
|
-
.. |appveyor| image:: https://img.shields.io/appveyor/ci/dateutil/dateutil/master.svg?style=flat-square&logo=appveyor
|
|
23
|
-
:target: https://ci.appveyor.com/project/dateutil/dateutil
|
|
24
|
-
:alt: appveyor build status
|
|
25
|
-
|
|
26
|
-
.. |pipelines| image:: https://dev.azure.com/pythondateutilazure/dateutil/_apis/build/status/dateutil.dateutil?branchName=master
|
|
27
|
-
:target: https://dev.azure.com/pythondateutilazure/dateutil/_build/latest?definitionId=1&branchName=master
|
|
28
|
-
:alt: azure pipelines build status
|
|
18
|
+
.. |gha| image:: https://github.com/dateutil/dateutil/actions/workflows/validate.yml/badge.svg
|
|
19
|
+
:target: https://github.com/dateutil/dateutil/actions
|
|
20
|
+
:alt: github actions build status
|
|
29
21
|
|
|
30
22
|
.. |coverage| image:: https://codecov.io/gh/dateutil/dateutil/branch/master/graphs/badge.svg?branch=master
|
|
31
23
|
:target: https://codecov.io/gh/dateutil/dateutil?branch=master
|
|
@@ -153,11 +145,6 @@ Releases Signing key fingerprint
|
|
|
153
145
|
New releases *may* have signed tags, but binary and source distributions
|
|
154
146
|
uploaded to PyPI will no longer have GPG signatures attached.
|
|
155
147
|
|
|
156
|
-
Contact
|
|
157
|
-
=======
|
|
158
|
-
Our mailing list is available at `dateutil@python.org <https://mail.python.org/mailman/listinfo/dateutil>`_. As it is hosted by the PSF, it is subject to the `PSF code of
|
|
159
|
-
conduct <https://www.python.org/psf/conduct/>`_.
|
|
160
|
-
|
|
161
148
|
License
|
|
162
149
|
=======
|
|
163
150
|
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
|
|
3
|
+
###
|
|
4
|
+
# Runs the 'tz' tox test environment, which builds the repo against the master
|
|
5
|
+
# branch of the upstream tz database project.
|
|
6
|
+
|
|
7
|
+
set -e
|
|
8
|
+
|
|
9
|
+
TMP_DIR=$(readlink -f ${1})
|
|
10
|
+
REPO_DIR=$(readlink -f ${2})
|
|
11
|
+
ORIG_DIR=$(pwd)
|
|
12
|
+
|
|
13
|
+
UPSTREAM_URL="https://github.com/eggert/tz.git"
|
|
14
|
+
|
|
15
|
+
if [ -n "$TF_BUILD" ]; then
|
|
16
|
+
EXTRA_TEST_ARGS=--junitxml=../unittests/TEST-tz.xml
|
|
17
|
+
fi
|
|
18
|
+
|
|
19
|
+
# Work in a temporary directory
|
|
20
|
+
cd $TMP_DIR
|
|
21
|
+
|
|
22
|
+
# Clone or update the repo
|
|
23
|
+
DIR_EXISTS=false
|
|
24
|
+
if [ -d tz ]; then
|
|
25
|
+
cd tz
|
|
26
|
+
if [[ $(git remote get-url origin) == ${UPSTREAM_URL} ]]; then
|
|
27
|
+
git fetch origin main
|
|
28
|
+
git reset --hard origin/main
|
|
29
|
+
DIR_EXISTS=true
|
|
30
|
+
else
|
|
31
|
+
cd ..
|
|
32
|
+
rm -rf tz
|
|
33
|
+
fi
|
|
34
|
+
fi
|
|
35
|
+
|
|
36
|
+
if [ "$DIR_EXISTS" = false ]; then
|
|
37
|
+
git clone ${UPSTREAM_URL}
|
|
38
|
+
cd tz
|
|
39
|
+
fi
|
|
40
|
+
|
|
41
|
+
# Build and install the compiled zoneinfo files, as "fat" TZif files of the
|
|
42
|
+
# "main" data form unless TZ_BLOAT and TZ_DATAFORM say otherwise
|
|
43
|
+
TZ_BLOAT=${TZ_BLOAT:-fat}
|
|
44
|
+
TZ_DATAFORM=${TZ_DATAFORM:-main}
|
|
45
|
+
make ZFLAGS="-b ${TZ_BLOAT}" DATAFORM="${TZ_DATAFORM}" \
|
|
46
|
+
TOPDIR="${TMP_DIR}/tzdir" install
|
|
47
|
+
|
|
48
|
+
cd $ORIG_DIR
|
|
49
|
+
|
|
50
|
+
# Make sure that the tests will actually see the data we just built. The
|
|
51
|
+
# tests that are about the data on TZPATH block the tzdata package
|
|
52
|
+
# themselves (see the tz_source fixture), so that anything missing from or
|
|
53
|
+
# unreadable in this data fails, rather than being answered by tzdata.
|
|
54
|
+
TZ_BLOAT=${TZ_BLOAT} TZ_DATAFORM=${TZ_DATAFORM} python - <<'EOF'
|
|
55
|
+
import os
|
|
56
|
+
import struct
|
|
57
|
+
import sys
|
|
58
|
+
|
|
59
|
+
from dateutil import tz
|
|
60
|
+
|
|
61
|
+
tzpath = os.environ["PYTHONTZPATH"]
|
|
62
|
+
|
|
63
|
+
if tuple(tz.TZPATH) != (tzpath,):
|
|
64
|
+
sys.exit("Expected TZPATH to be (%r,), got %r" % (tzpath, tz.TZPATH))
|
|
65
|
+
|
|
66
|
+
# tzdata.zi starts with a "# version" line, followed by a "# dataform" line
|
|
67
|
+
# for anything other than the main data form.
|
|
68
|
+
with open(os.path.join(tzpath, "tzdata.zi")) as f:
|
|
69
|
+
header = [f.readline().strip() for _ in range(2)]
|
|
70
|
+
print("Testing against: %s" % header[0])
|
|
71
|
+
|
|
72
|
+
dataform = "main"
|
|
73
|
+
if header[1].startswith("# dataform "):
|
|
74
|
+
dataform = header[1].split()[-1]
|
|
75
|
+
if dataform != os.environ["TZ_DATAFORM"]:
|
|
76
|
+
sys.exit(
|
|
77
|
+
"Expected the %s data form, got %s" % (os.environ["TZ_DATAFORM"], dataform)
|
|
78
|
+
)
|
|
79
|
+
print("Using the %s data form" % dataform)
|
|
80
|
+
|
|
81
|
+
zone = tz.gettz("America/New_York")
|
|
82
|
+
if zone is None or not zone._filename.startswith(tzpath):
|
|
83
|
+
sys.exit("America/New_York was not loaded from %s: %r" % (tzpath, zone))
|
|
84
|
+
|
|
85
|
+
# Slim files have an empty version 1 data block, fat files do not.
|
|
86
|
+
with open(zone._filename, "rb") as f:
|
|
87
|
+
v1_timecnt = struct.unpack(">6l", f.read(44)[20:])[3]
|
|
88
|
+
|
|
89
|
+
bloat = "fat" if v1_timecnt else "slim"
|
|
90
|
+
if bloat != os.environ["TZ_BLOAT"]:
|
|
91
|
+
sys.exit("Expected %s TZif files, got %s" % (os.environ["TZ_BLOAT"], bloat))
|
|
92
|
+
print("Using %s TZif files" % bloat)
|
|
93
|
+
EOF
|
|
94
|
+
|
|
95
|
+
# Run the tests
|
|
96
|
+
python -m pytest ${REPO_DIR}/tests $EXTRA_TEST_ARGS -x
|
|
97
|
+
|