python-dateutil 3.0.0__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-3.0.0 → python_dateutil-4.0.0}/AUTHORS.md +3 -0
- {python_dateutil-3.0.0 → python_dateutil-4.0.0}/CONTRIBUTING.md +31 -5
- {python_dateutil-3.0.0 → python_dateutil-4.0.0}/NEWS +53 -0
- {python_dateutil-3.0.0/src/python_dateutil.egg-info → python_dateutil-4.0.0}/PKG-INFO +11 -31
- {python_dateutil-3.0.0 → python_dateutil-4.0.0}/README.rst +1 -5
- {python_dateutil-3.0.0 → python_dateutil-4.0.0}/docs/conf.py +1 -3
- {python_dateutil-3.0.0 → python_dateutil-4.0.0}/docs/tz.rst +6 -7
- python_dateutil-4.0.0/pyproject.toml +155 -0
- python_dateutil-4.0.0/requirements-dev.txt +8 -0
- {python_dateutil-3.0.0 → python_dateutil-4.0.0}/src/dateutil/__init__.py +0 -1
- {python_dateutil-3.0.0 → 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-3.0.0 → python_dateutil-4.0.0}/src/dateutil/easter.py +0 -1
- {python_dateutil-3.0.0 → python_dateutil-4.0.0}/src/dateutil/parser/__init__.py +14 -12
- {python_dateutil-3.0.0 → python_dateutil-4.0.0}/src/dateutil/parser/_parser.py +14 -20
- {python_dateutil-3.0.0 → python_dateutil-4.0.0}/src/dateutil/parser/isoparser.py +25 -15
- {python_dateutil-3.0.0 → python_dateutil-4.0.0}/src/dateutil/relativedelta.py +8 -9
- {python_dateutil-3.0.0 → python_dateutil-4.0.0}/src/dateutil/rrule.py +43 -55
- python_dateutil-4.0.0/src/dateutil/tz/__init__.py +44 -0
- {python_dateutil-3.0.0 → python_dateutil-4.0.0}/src/dateutil/tz/_common.py +12 -123
- {python_dateutil-3.0.0 → python_dateutil-4.0.0}/src/dateutil/tz/_factories.py +4 -6
- {python_dateutil-3.0.0 → python_dateutil-4.0.0}/src/dateutil/tz/_tzfile.py +27 -123
- python_dateutil-4.0.0/src/dateutil/tz/_tzpath.py +12 -0
- {python_dateutil-3.0.0 → python_dateutil-4.0.0}/src/dateutil/tz/tz.py +34 -114
- {python_dateutil-3.0.0 → python_dateutil-4.0.0}/src/dateutil/tz/win.py +17 -17
- {python_dateutil-3.0.0 → python_dateutil-4.0.0}/src/dateutil/utils.py +0 -2
- {python_dateutil-3.0.0 → python_dateutil-4.0.0}/src/dateutil/zoneinfo/__init__.py +5 -14
- {python_dateutil-3.0.0 → python_dateutil-4.0.0}/tests/_common.py +13 -46
- {python_dateutil-3.0.0 → python_dateutil-4.0.0}/tests/conftest.py +1 -7
- {python_dateutil-3.0.0 → python_dateutil-4.0.0}/tests/property/test_isoparse_prop.py +3 -7
- {python_dateutil-3.0.0 → python_dateutil-4.0.0}/tests/property/test_tz_prop.py +0 -4
- {python_dateutil-3.0.0 → python_dateutil-4.0.0}/tests/resources/update_tzif.py +0 -2
- {python_dateutil-3.0.0 → python_dateutil-4.0.0}/tests/test_imports.py +25 -20
- {python_dateutil-3.0.0 → python_dateutil-4.0.0}/tests/test_internals.py +0 -6
- {python_dateutil-3.0.0 → python_dateutil-4.0.0}/tests/test_isoparser.py +106 -90
- {python_dateutil-3.0.0 → python_dateutil-4.0.0}/tests/test_parser.py +45 -42
- {python_dateutil-3.0.0 → python_dateutil-4.0.0}/tests/test_relativedelta.py +31 -17
- {python_dateutil-3.0.0 → python_dateutil-4.0.0}/tests/test_rrule.py +45 -47
- {python_dateutil-3.0.0 → python_dateutil-4.0.0}/tests/test_tz.py +44 -81
- {python_dateutil-3.0.0 → python_dateutil-4.0.0}/tests/test_tzfile.py +70 -336
- {python_dateutil-3.0.0 → python_dateutil-4.0.0}/tests/test_tzpath_data.py +4 -19
- {python_dateutil-3.0.0 → python_dateutil-4.0.0}/tests/test_utils.py +0 -3
- {python_dateutil-3.0.0 → python_dateutil-4.0.0}/tox.ini +20 -38
- python_dateutil-3.0.0/.gitattributes +0 -21
- python_dateutil-3.0.0/.github/pull_request_template.md +0 -12
- python_dateutil-3.0.0/.github/workflows/publish.yml +0 -56
- python_dateutil-3.0.0/.github/workflows/validate.yml +0 -328
- python_dateutil-3.0.0/.pre-commit-config.yaml +0 -15
- python_dateutil-3.0.0/.readthedocs.yml +0 -15
- python_dateutil-3.0.0/MANIFEST.in +0 -4
- python_dateutil-3.0.0/PKG-INFO +0 -204
- python_dateutil-3.0.0/RELEASING +0 -87
- python_dateutil-3.0.0/appveyor.yml +0 -34
- python_dateutil-3.0.0/changelog.d/.gitignore +0 -0
- python_dateutil-3.0.0/codecov.yml +0 -9
- python_dateutil-3.0.0/pyproject.toml +0 -65
- python_dateutil-3.0.0/requirements/3.3/constraints.txt +0 -15
- python_dateutil-3.0.0/requirements/3.3/requirements-dev.txt +0 -8
- python_dateutil-3.0.0/requirements-dev.txt +0 -9
- python_dateutil-3.0.0/setup.cfg +0 -90
- python_dateutil-3.0.0/setup.py +0 -31
- python_dateutil-3.0.0/src/dateutil/_tzdata_impl.py +0 -147
- python_dateutil-3.0.0/src/dateutil/_version.py +0 -4
- python_dateutil-3.0.0/src/dateutil/tz/__init__.py +0 -60
- python_dateutil-3.0.0/src/dateutil/tz/_tzpath.py +0 -104
- python_dateutil-3.0.0/src/python_dateutil.egg-info/SOURCES.txt +0 -101
- python_dateutil-3.0.0/src/python_dateutil.egg-info/dependency_links.txt +0 -1
- python_dateutil-3.0.0/src/python_dateutil.egg-info/requires.txt +0 -2
- python_dateutil-3.0.0/src/python_dateutil.egg-info/top_level.txt +0 -1
- python_dateutil-3.0.0/src/python_dateutil.egg-info/zip-safe +0 -1
- {python_dateutil-3.0.0 → python_dateutil-4.0.0}/.gitignore +0 -0
- {python_dateutil-3.0.0 → python_dateutil-4.0.0}/LICENSE +0 -0
- {python_dateutil-3.0.0 → python_dateutil-4.0.0}/changelog.d/template.rst +0 -0
- {python_dateutil-3.0.0 → python_dateutil-4.0.0}/ci_tools/run_tz_master_env.sh +0 -0
- {python_dateutil-3.0.0 → python_dateutil-4.0.0}/docs/Makefile +0 -0
- {python_dateutil-3.0.0 → python_dateutil-4.0.0}/docs/changelog.rst +0 -0
- {python_dateutil-3.0.0 → python_dateutil-4.0.0}/docs/easter.rst +0 -0
- {python_dateutil-3.0.0 → python_dateutil-4.0.0}/docs/examples.rst +0 -0
- {python_dateutil-3.0.0 → python_dateutil-4.0.0}/docs/exercises/index.rst +0 -0
- {python_dateutil-3.0.0 → python_dateutil-4.0.0}/docs/exercises/solutions/mlk-day-rrule.rst +0 -0
- {python_dateutil-3.0.0 → python_dateutil-4.0.0}/docs/exercises/solutions/mlk_day_rrule_solution.py +0 -0
- {python_dateutil-3.0.0 → python_dateutil-4.0.0}/docs/index.rst +0 -0
- {python_dateutil-3.0.0 → python_dateutil-4.0.0}/docs/make.bat +0 -0
- {python_dateutil-3.0.0 → python_dateutil-4.0.0}/docs/parser.rst +0 -0
- {python_dateutil-3.0.0 → python_dateutil-4.0.0}/docs/relativedelta.rst +0 -0
- {python_dateutil-3.0.0 → python_dateutil-4.0.0}/docs/requirements-docs.txt +0 -0
- {python_dateutil-3.0.0 → python_dateutil-4.0.0}/docs/rrule.rst +0 -0
- {python_dateutil-3.0.0 → python_dateutil-4.0.0}/docs/samples/EST5EDT.ics +0 -0
- {python_dateutil-3.0.0 → python_dateutil-4.0.0}/docs/tzwin.rst +0 -0
- {python_dateutil-3.0.0 → python_dateutil-4.0.0}/docs/utils.rst +0 -0
- {python_dateutil-3.0.0 → python_dateutil-4.0.0}/docs/zoneinfo.rst +0 -0
- {python_dateutil-3.0.0 → python_dateutil-4.0.0}/src/dateutil/tzwin.py +0 -0
- {python_dateutil-3.0.0 → python_dateutil-4.0.0}/src/dateutil/zoneinfo/rebuild.py +0 -0
- {python_dateutil-3.0.0 → python_dateutil-4.0.0}/tests/__init__.py +0 -0
- {python_dateutil-3.0.0 → python_dateutil-4.0.0}/tests/property/test_parser_prop.py +0 -0
- {python_dateutil-3.0.0 → python_dateutil-4.0.0}/tests/property/test_rrule_prop.py +0 -0
- {python_dateutil-3.0.0 → python_dateutil-4.0.0}/tests/resources/__init__.py +0 -0
- {python_dateutil-3.0.0 → python_dateutil-4.0.0}/tests/resources/data/__init__.py +0 -0
- {python_dateutil-3.0.0 → python_dateutil-4.0.0}/tests/resources/data/keys.json +0 -0
- {python_dateutil-3.0.0 → python_dateutil-4.0.0}/tests/resources/data/metadata.json +0 -0
- {python_dateutil-3.0.0 → python_dateutil-4.0.0}/tests/resources/data/zoneinfo_fat.json +0 -0
- {python_dateutil-3.0.0 → python_dateutil-4.0.0}/tests/resources/data/zoneinfo_slim.json +0 -0
- {python_dateutil-3.0.0 → python_dateutil-4.0.0}/tests/resources/data/zoneinfo_v1.json +0 -0
- {python_dateutil-3.0.0 → python_dateutil-4.0.0}/tests/resources/liliput_tzif +0 -0
- {python_dateutil-3.0.0 → python_dateutil-4.0.0}/tests/test_easter.py +0 -0
- {python_dateutil-3.0.0 → python_dateutil-4.0.0}/tests/test_import_star.py +0 -0
- {python_dateutil-3.0.0 → python_dateutil-4.0.0}/tests/test_zoneinfo.py +0 -0
|
@@ -70,6 +70,7 @@ switch, and thus all their contributions are dual-licensed.
|
|
|
70
70
|
- John Purviance <jpurviance@MASKED> (gh @jpurviance) **D**
|
|
71
71
|
- Jon Dufresne <jon.dufresne@MASKED> (gh: @jdufresne) **R**
|
|
72
72
|
- Jonas Neubert <jonas@MASKED> (gh: @jonemo) **R**
|
|
73
|
+
- Jordi Masip <jordi@MASKED> (gh: @masipcat)
|
|
73
74
|
- Juan Arias <jdarias3@gmail.com> (gh: @jdarias3) **D**
|
|
74
75
|
- Kevin Nguyen <kvn219@MASKED> **D**
|
|
75
76
|
- Kirit Thadaka <kirit.thadaka@gmail.com> (gh: @kirit93) **D**
|
|
@@ -91,6 +92,7 @@ switch, and thus all their contributions are dual-licensed.
|
|
|
91
92
|
- Nicholas Herrriot <Nicholas.Herriot@gmail.com> **D**
|
|
92
93
|
- Nicolas Évrard (gh: @nicoe) **D**
|
|
93
94
|
- Nick Smith <nick.smith@MASKED>
|
|
95
|
+
- Nor.na (gh: @Master-Norna) **D**
|
|
94
96
|
- Orson Adams <orson.network@MASKED> (gh: @parsethis) **D**
|
|
95
97
|
- Paul Brown (gh: @pawl) **D**
|
|
96
98
|
- Paul Dickson (gh @prdickson) **D**
|
|
@@ -121,6 +123,7 @@ switch, and thus all their contributions are dual-licensed.
|
|
|
121
123
|
- Tomasz Kluczkowski (gh: @Tomasz-Kluczkowski) **D**
|
|
122
124
|
- Tomi Pieviläinen <tomi.pievilainen@iki.fi>
|
|
123
125
|
- Unrud <Unrud@MASKED> (gh: @unrud)
|
|
126
|
+
- varun netrakar <varun@security.bugqore.com> (gh: @varun3257) **D**
|
|
124
127
|
- Xavier Lapointe <lapointe.xavier@MASKED> (gh: @lapointexavier) **D**
|
|
125
128
|
- X O <xo@MASKED>
|
|
126
129
|
- Yaron de Leeuw <me@jarondl.net> (gh: @jarondl)
|
|
@@ -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,56 @@
|
|
|
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
|
+
|
|
1
54
|
Version 3.0.0 (2026-10-21)
|
|
2
55
|
==========================
|
|
3
56
|
|
|
@@ -1,31 +1,19 @@
|
|
|
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
|
|
31
19
|
Classifier: Programming Language :: Python :: 3.13
|
|
@@ -35,13 +23,9 @@ Classifier: Programming Language :: Python :: Free Threading :: 2 - Beta
|
|
|
35
23
|
Classifier: Programming Language :: Python :: Implementation :: CPython
|
|
36
24
|
Classifier: Programming Language :: Python :: Implementation :: PyPy
|
|
37
25
|
Classifier: Topic :: Software Development :: Libraries
|
|
38
|
-
Requires-Python:
|
|
39
|
-
Description-Content-Type: text/x-rst
|
|
40
|
-
License-File: LICENSE
|
|
41
|
-
Requires-Dist: six>=1.6
|
|
26
|
+
Requires-Python: >=3.11
|
|
42
27
|
Requires-Dist: tzdata
|
|
43
|
-
|
|
44
|
-
Dynamic: license-file
|
|
28
|
+
Description-Content-Type: text/x-rst
|
|
45
29
|
|
|
46
30
|
dateutil - powerful extensions to datetime
|
|
47
31
|
==========================================
|
|
@@ -50,7 +34,7 @@ dateutil - powerful extensions to datetime
|
|
|
50
34
|
|
|
51
35
|
|gitter| |readthedocs|
|
|
52
36
|
|
|
53
|
-
|
|
|
37
|
+
|gha| |coverage|
|
|
54
38
|
|
|
55
39
|
.. |pypi| image:: https://img.shields.io/pypi/v/python-dateutil.svg?style=flat-square
|
|
56
40
|
:target: https://pypi.org/project/python-dateutil/
|
|
@@ -60,10 +44,6 @@ dateutil - powerful extensions to datetime
|
|
|
60
44
|
:target: https://pypi.org/project/python-dateutil/
|
|
61
45
|
:alt: supported Python version
|
|
62
46
|
|
|
63
|
-
.. |appveyor| image:: https://img.shields.io/appveyor/ci/dateutil/dateutil/master.svg?style=flat-square&logo=appveyor
|
|
64
|
-
:target: https://ci.appveyor.com/project/dateutil/dateutil
|
|
65
|
-
:alt: appveyor build status
|
|
66
|
-
|
|
67
47
|
.. |gha| image:: https://github.com/dateutil/dateutil/actions/workflows/validate.yml/badge.svg
|
|
68
48
|
:target: https://github.com/dateutil/dateutil/actions
|
|
69
49
|
:alt: github actions build status
|
|
@@ -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,10 +15,6 @@ dateutil - powerful extensions to datetime
|
|
|
15
15
|
:target: https://pypi.org/project/python-dateutil/
|
|
16
16
|
:alt: supported Python version
|
|
17
17
|
|
|
18
|
-
.. |appveyor| image:: https://img.shields.io/appveyor/ci/dateutil/dateutil/master.svg?style=flat-square&logo=appveyor
|
|
19
|
-
:target: https://ci.appveyor.com/project/dateutil/dateutil
|
|
20
|
-
:alt: appveyor build status
|
|
21
|
-
|
|
22
18
|
.. |gha| image:: https://github.com/dateutil/dateutil/actions/workflows/validate.yml/badge.svg
|
|
23
19
|
:target: https://github.com/dateutil/dateutil/actions
|
|
24
20
|
:alt: github actions build status
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
#!/usr/bin/env python3
|
|
2
|
-
# -*- coding: utf-8 -*-
|
|
3
2
|
#
|
|
4
3
|
# dateutil documentation build configuration file, created by
|
|
5
4
|
# sphinx-quickstart on Thu Nov 20 23:18:41 2014.
|
|
@@ -13,7 +12,6 @@
|
|
|
13
12
|
# All configuration values have a default; values that are commented out
|
|
14
13
|
# serve to show the default.
|
|
15
14
|
|
|
16
|
-
import os
|
|
17
15
|
import sys
|
|
18
16
|
|
|
19
17
|
# -- General configuration ------------------------------------------------
|
|
@@ -183,7 +181,7 @@ htmlhelp_basename = 'dateutildoc'
|
|
|
183
181
|
|
|
184
182
|
# -- Options for autodoc -------------------------------------------------
|
|
185
183
|
|
|
186
|
-
autodoc_mock_imports = [
|
|
184
|
+
autodoc_mock_imports = ["ctypes.wintypes", "winreg"]
|
|
187
185
|
|
|
188
186
|
# Need to mock this out specifically to avoid errors
|
|
189
187
|
import ctypes
|
|
@@ -19,7 +19,7 @@ Objects
|
|
|
19
19
|
can be set by the ``PYTHONTZPATH`` environment variable, or updated
|
|
20
20
|
via :func:`reset_tzpath`.
|
|
21
21
|
|
|
22
|
-
|
|
22
|
+
This is an alias for :py:data:`zoneinfo.TZPATH`.
|
|
23
23
|
|
|
24
24
|
.. versionadded:: 3.0.0
|
|
25
25
|
|
|
@@ -35,7 +35,7 @@ Functions
|
|
|
35
35
|
|
|
36
36
|
.. py:function:: reset_tzpath(to=None)
|
|
37
37
|
|
|
38
|
-
Sets the value of :data:`TZPATH`.
|
|
38
|
+
Sets the value of :data:`TZPATH`. This is an alias for
|
|
39
39
|
:py:func:`zoneinfo.reset_tzpath`, and calling it *will* reset the
|
|
40
40
|
search path for both ``dateutil`` and :py:mod:`zoneinfo`.
|
|
41
41
|
|
|
@@ -95,13 +95,12 @@ Warnings
|
|
|
95
95
|
IANA Time Zone Data
|
|
96
96
|
-------------------
|
|
97
97
|
``dateutil`` attempts to search for time zone data the same way that the
|
|
98
|
-
standard library does.
|
|
99
|
-
|
|
98
|
+
standard library does. :data:`TZPATH` is a proxy for
|
|
99
|
+
:py:data:`zoneinfo.TZPATH` and
|
|
100
100
|
:py:func:`reset_tzpath` is an alias for :py:func:`zoneinfo.reset_tzpath`.
|
|
101
101
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
equivalent to the Python compiler option).
|
|
102
|
+
The environment variable ``PYTHONTZPATH`` can be used to configure the search
|
|
103
|
+
path, as described in the :py:mod:`zoneinfo` documentation.
|
|
105
104
|
|
|
106
105
|
``dateutil`` also takes an unconditional dependency on the `tzdata
|
|
107
106
|
<https://pypi.org/project/tzdata/>`_ package, which provides a self-contained,
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["hatchling>=1.27", "hatch-vcs>=0.4", "hatch-fancy-pypi-readme>=24.1"]
|
|
3
|
+
build-backend = "hatchling.build"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "python-dateutil"
|
|
7
|
+
description = "Extensions to the standard Python datetime module"
|
|
8
|
+
dynamic = ["version", "readme"]
|
|
9
|
+
requires-python = ">=3.11"
|
|
10
|
+
dependencies = ["tzdata"]
|
|
11
|
+
license = "BSD-3-Clause"
|
|
12
|
+
license-files = ["LICENSE", "AUTHORS.md"]
|
|
13
|
+
classifiers = [
|
|
14
|
+
"Development Status :: 5 - Production/Stable",
|
|
15
|
+
"Intended Audience :: Developers",
|
|
16
|
+
"Programming Language :: Python",
|
|
17
|
+
"Programming Language :: Python :: 3",
|
|
18
|
+
"Programming Language :: Python :: 3.11",
|
|
19
|
+
"Programming Language :: Python :: 3.12",
|
|
20
|
+
"Programming Language :: Python :: 3.13",
|
|
21
|
+
"Programming Language :: Python :: 3.14",
|
|
22
|
+
"Programming Language :: Python :: 3.15",
|
|
23
|
+
"Programming Language :: Python :: Free Threading :: 2 - Beta",
|
|
24
|
+
"Programming Language :: Python :: Implementation :: CPython",
|
|
25
|
+
"Programming Language :: Python :: Implementation :: PyPy",
|
|
26
|
+
"Topic :: Software Development :: Libraries",
|
|
27
|
+
]
|
|
28
|
+
|
|
29
|
+
[[project.authors]]
|
|
30
|
+
name = "Gustavo Niemeyer"
|
|
31
|
+
email = "gustavo@niemeyer.net"
|
|
32
|
+
|
|
33
|
+
[[project.maintainers]]
|
|
34
|
+
name = "Paul Ganssle"
|
|
35
|
+
email = "dateutil@python.org"
|
|
36
|
+
|
|
37
|
+
[project.urls]
|
|
38
|
+
Homepage = "https://github.com/dateutil/dateutil"
|
|
39
|
+
Documentation = "https://dateutil.readthedocs.io/en/stable/"
|
|
40
|
+
Source = "https://github.com/dateutil/dateutil"
|
|
41
|
+
|
|
42
|
+
[tool.towncrier]
|
|
43
|
+
package = "dateutil"
|
|
44
|
+
package_dir = "dateutil"
|
|
45
|
+
filename = "NEWS"
|
|
46
|
+
directory = "changelog.d"
|
|
47
|
+
title_format = "Version {version} ({project_date})"
|
|
48
|
+
issue_format = "GH #{issue}"
|
|
49
|
+
template = "changelog.d/template.rst"
|
|
50
|
+
|
|
51
|
+
[[tool.towncrier.type]]
|
|
52
|
+
directory = "data"
|
|
53
|
+
name = "Data updates"
|
|
54
|
+
showcontent = true
|
|
55
|
+
|
|
56
|
+
[[tool.towncrier.type]]
|
|
57
|
+
directory = "deprecations"
|
|
58
|
+
name = "Deprecations"
|
|
59
|
+
showcontent = true
|
|
60
|
+
|
|
61
|
+
[[tool.towncrier.type]]
|
|
62
|
+
directory = "feature"
|
|
63
|
+
name = "Features"
|
|
64
|
+
showcontent = true
|
|
65
|
+
|
|
66
|
+
[[tool.towncrier.type]]
|
|
67
|
+
directory = "bugfix"
|
|
68
|
+
name = "Bugfixes"
|
|
69
|
+
showcontent = true
|
|
70
|
+
|
|
71
|
+
[[tool.towncrier.type]]
|
|
72
|
+
directory = "doc"
|
|
73
|
+
name = "Documentation changes"
|
|
74
|
+
showcontent = true
|
|
75
|
+
|
|
76
|
+
[[tool.towncrier.type]]
|
|
77
|
+
directory = "misc"
|
|
78
|
+
name = "Misc"
|
|
79
|
+
showcontent = true
|
|
80
|
+
|
|
81
|
+
[tool.black]
|
|
82
|
+
line-length = 80
|
|
83
|
+
|
|
84
|
+
[tool.isort]
|
|
85
|
+
atomic=true
|
|
86
|
+
force_grid_wrap=0
|
|
87
|
+
include_trailing_comma=true
|
|
88
|
+
known_first_party = ["dateutil"]
|
|
89
|
+
known_third_party=[
|
|
90
|
+
"pytest",
|
|
91
|
+
"hypothesis",
|
|
92
|
+
"freezegun",
|
|
93
|
+
]
|
|
94
|
+
multi_line_output=3
|
|
95
|
+
use_parentheses=true
|
|
96
|
+
|
|
97
|
+
[tool.pytest.ini_options]
|
|
98
|
+
python_files = [
|
|
99
|
+
"test_*.py",
|
|
100
|
+
"*_test.py",
|
|
101
|
+
"*_solution.py",
|
|
102
|
+
]
|
|
103
|
+
xfail_strict = true
|
|
104
|
+
filterwarnings = [
|
|
105
|
+
"error",
|
|
106
|
+
"error::DeprecationWarning",
|
|
107
|
+
"error::PendingDeprecationWarning",
|
|
108
|
+
]
|
|
109
|
+
markers = [
|
|
110
|
+
"gettz",
|
|
111
|
+
"import_star",
|
|
112
|
+
"isoparser",
|
|
113
|
+
"parserinfo",
|
|
114
|
+
"rrule",
|
|
115
|
+
"rruleset",
|
|
116
|
+
"rrulestr",
|
|
117
|
+
"smoke",
|
|
118
|
+
"tz_resolve_imaginary",
|
|
119
|
+
"tzdata_properties",
|
|
120
|
+
"tzfile",
|
|
121
|
+
"tzlocal",
|
|
122
|
+
"tzoffset",
|
|
123
|
+
"tzstr",
|
|
124
|
+
]
|
|
125
|
+
|
|
126
|
+
[tool.hatch.version]
|
|
127
|
+
source = "vcs"
|
|
128
|
+
|
|
129
|
+
[tool.hatch.build.hooks.vcs]
|
|
130
|
+
version-file = "src/dateutil/_version.py"
|
|
131
|
+
|
|
132
|
+
[tool.hatch.build.targets.wheel]
|
|
133
|
+
packages = ["src/dateutil"]
|
|
134
|
+
|
|
135
|
+
[tool.hatch.build.targets.sdist]
|
|
136
|
+
exclude = [
|
|
137
|
+
"/AGENTS.md",
|
|
138
|
+
"/RELEASING",
|
|
139
|
+
"/.github",
|
|
140
|
+
"/.gitattributes",
|
|
141
|
+
"**/.gitignore",
|
|
142
|
+
"/.readthedocs.yml",
|
|
143
|
+
"/.pre-commit-config.yaml",
|
|
144
|
+
"/codecov.yml",
|
|
145
|
+
]
|
|
146
|
+
|
|
147
|
+
[tool.hatch.metadata.hooks.fancy-pypi-readme]
|
|
148
|
+
content-type = "text/x-rst"
|
|
149
|
+
|
|
150
|
+
[[tool.hatch.metadata.hooks.fancy-pypi-readme.fragments]]
|
|
151
|
+
path = "README.rst"
|
|
152
|
+
|
|
153
|
+
[[tool.hatch.metadata.hooks.fancy-pypi-readme.substitutions]]
|
|
154
|
+
pattern = "(?m)^\\.\\. doctest[^\\n]*"
|
|
155
|
+
replacement = ".. code-block:: python3"
|
|
@@ -3,7 +3,7 @@ Common code used in multiple modules.
|
|
|
3
3
|
"""
|
|
4
4
|
|
|
5
5
|
|
|
6
|
-
class weekday
|
|
6
|
+
class weekday:
|
|
7
7
|
__slots__ = ["weekday", "n"]
|
|
8
8
|
|
|
9
9
|
def __init__(self, weekday, n=None):
|
|
@@ -30,9 +30,6 @@ class weekday(object):
|
|
|
30
30
|
self.n,
|
|
31
31
|
))
|
|
32
32
|
|
|
33
|
-
def __ne__(self, other):
|
|
34
|
-
return not (self == other)
|
|
35
|
-
|
|
36
33
|
def __repr__(self):
|
|
37
34
|
s = ("MO", "TU", "WE", "TH", "FR", "SA", "SU")[self.weekday]
|
|
38
35
|
if not self.n:
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
"""This is an implementation of functions that interact with the tzdata module.
|
|
2
|
+
|
|
3
|
+
It will only live as long as :mod:`dateutil.zoneinfo` lives; when the
|
|
4
|
+
``dateutil.zoneinfo`` module is removed, this can all move under :mod:`tz`.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
import importlib.resources
|
|
8
|
+
from typing import BinaryIO, TextIO
|
|
9
|
+
|
|
10
|
+
_TZDATA_LOAD_EXCEPTIONS = (
|
|
11
|
+
ImportError,
|
|
12
|
+
FileNotFoundError,
|
|
13
|
+
UnicodeEncodeError,
|
|
14
|
+
IsADirectoryError,
|
|
15
|
+
ValueError,
|
|
16
|
+
)
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def _open_text(package: str, resource: str) -> TextIO:
|
|
20
|
+
return (
|
|
21
|
+
importlib.resources.files(package)
|
|
22
|
+
.joinpath(resource)
|
|
23
|
+
.open("r", encoding="utf-8")
|
|
24
|
+
)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def _open_binary(package: str, resource: str) -> BinaryIO:
|
|
28
|
+
return importlib.resources.files(package).joinpath(resource).open("rb")
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def _is_package_directory(package: str, resource: str) -> bool:
|
|
32
|
+
"""Checks for directories before opening resources on Windows."""
|
|
33
|
+
try:
|
|
34
|
+
return importlib.resources.files(package).joinpath(resource).is_dir()
|
|
35
|
+
except ImportError:
|
|
36
|
+
return False
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def _load_tzdata(key):
|
|
40
|
+
components = key.split("/")
|
|
41
|
+
package_name = ".".join(["tzdata.zoneinfo"] + components[:-1])
|
|
42
|
+
resource_name = components[-1]
|
|
43
|
+
|
|
44
|
+
# Empty or relative path components cannot name a zone, and they produce
|
|
45
|
+
# module names that the import machinery handles inconsistently across
|
|
46
|
+
# versions, so treat them as not found up front. A key naming a directory
|
|
47
|
+
# (a subpackage) is not a zone either, and opening it raises a
|
|
48
|
+
# platform-dependent error, see CPython gh-85702.
|
|
49
|
+
if any(c in ("", ".", "..") for c in components) or _is_package_directory(
|
|
50
|
+
package_name, resource_name
|
|
51
|
+
):
|
|
52
|
+
raise TZFileNotFound("Time zone not found: %s", zone_key=key)
|
|
53
|
+
|
|
54
|
+
try:
|
|
55
|
+
return _open_binary(package_name, resource_name)
|
|
56
|
+
except _TZDATA_LOAD_EXCEPTIONS:
|
|
57
|
+
# ImportError: package does not exist (or tzdata is not installed)
|
|
58
|
+
# FileNotFoundError: the key is not a file in the package
|
|
59
|
+
# UnicodeEncodeError: the key is not encodable as a filename
|
|
60
|
+
# IsADirectoryError: the key names a package rather than a resource
|
|
61
|
+
# ValueError: the key is not a valid path (e.g. contains a NUL byte)
|
|
62
|
+
raise TZFileNotFound("Time zone not found: %s", zone_key=key) from None
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
def _load_tzdata_keys():
|
|
66
|
+
with _open_text("tzdata", "zones") as f:
|
|
67
|
+
return list(filter(None, (l.strip() for l in f)))
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
class TZFileNotFound(ValueError):
|
|
71
|
+
"""Indicates that a time zone file isn't present in tzdata."""
|
|
72
|
+
|
|
73
|
+
def __init__(self, msg: str, *args: object, zone_key: str) -> None:
|
|
74
|
+
super().__init__(msg % zone_key, *args)
|
|
75
|
+
self.zone_key = zone_key
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# file generated by vcs-versioning
|
|
2
|
+
# don't change, don't track in version control
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
__all__ = [
|
|
6
|
+
"__version__",
|
|
7
|
+
"__version_tuple__",
|
|
8
|
+
"version",
|
|
9
|
+
"version_tuple",
|
|
10
|
+
"__commit_id__",
|
|
11
|
+
"commit_id",
|
|
12
|
+
]
|
|
13
|
+
|
|
14
|
+
version: str
|
|
15
|
+
__version__: str
|
|
16
|
+
__version_tuple__: tuple[int | str, ...]
|
|
17
|
+
version_tuple: tuple[int | str, ...]
|
|
18
|
+
commit_id: str | None
|
|
19
|
+
__commit_id__: str | None
|
|
20
|
+
|
|
21
|
+
__version__ = version = '4.0.0'
|
|
22
|
+
__version_tuple__ = version_tuple = (4, 0, 0)
|
|
23
|
+
|
|
24
|
+
__commit_id__ = commit_id = None
|
|
@@ -1,11 +1,14 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
1
|
+
from ._parser import (
|
|
2
|
+
DEFAULTPARSER,
|
|
3
|
+
DEFAULTTZPARSER,
|
|
4
|
+
ParserError,
|
|
5
|
+
UnknownTimezoneWarning,
|
|
6
|
+
__doc__,
|
|
7
|
+
parse,
|
|
8
|
+
parser,
|
|
9
|
+
parserinfo,
|
|
10
|
+
)
|
|
11
|
+
from .isoparser import isoparse, isoparser
|
|
9
12
|
|
|
10
13
|
__all__ = ['parse', 'parser', 'parserinfo',
|
|
11
14
|
'isoparse', 'isoparser',
|
|
@@ -19,8 +22,8 @@ __all__ = ['parse', 'parser', 'parserinfo',
|
|
|
19
22
|
|
|
20
23
|
|
|
21
24
|
def __deprecated_private_func(f):
|
|
22
|
-
from functools import wraps
|
|
23
25
|
import warnings
|
|
26
|
+
from functools import wraps
|
|
24
27
|
|
|
25
28
|
msg = ('{name} is a private function and may break without warning, '
|
|
26
29
|
'it will be moved and or renamed in future versions.')
|
|
@@ -45,15 +48,14 @@ def __deprecate_private_class(c):
|
|
|
45
48
|
|
|
46
49
|
def __init__(self, *args, **kwargs):
|
|
47
50
|
warnings.warn(msg, DeprecationWarning)
|
|
48
|
-
super(
|
|
51
|
+
super().__init__(*args, **kwargs)
|
|
49
52
|
|
|
50
53
|
private_class.__name__ = c.__name__
|
|
51
54
|
|
|
52
55
|
return private_class
|
|
53
56
|
|
|
54
57
|
|
|
55
|
-
from ._parser import _timelex,
|
|
56
|
-
from ._parser import _tzparser, _parsetz
|
|
58
|
+
from ._parser import _parsetz, _resultbase, _timelex, _tzparser
|
|
57
59
|
|
|
58
60
|
_timelex = __deprecate_private_class(_timelex)
|
|
59
61
|
_tzparser = __deprecate_private_class(_tzparser)
|