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.
Files changed (108) hide show
  1. {python_dateutil-3.0.0 → python_dateutil-4.0.0}/AUTHORS.md +3 -0
  2. {python_dateutil-3.0.0 → python_dateutil-4.0.0}/CONTRIBUTING.md +31 -5
  3. {python_dateutil-3.0.0 → python_dateutil-4.0.0}/NEWS +53 -0
  4. {python_dateutil-3.0.0/src/python_dateutil.egg-info → python_dateutil-4.0.0}/PKG-INFO +11 -31
  5. {python_dateutil-3.0.0 → python_dateutil-4.0.0}/README.rst +1 -5
  6. {python_dateutil-3.0.0 → python_dateutil-4.0.0}/docs/conf.py +1 -3
  7. {python_dateutil-3.0.0 → python_dateutil-4.0.0}/docs/tz.rst +6 -7
  8. python_dateutil-4.0.0/pyproject.toml +155 -0
  9. python_dateutil-4.0.0/requirements-dev.txt +8 -0
  10. {python_dateutil-3.0.0 → python_dateutil-4.0.0}/src/dateutil/__init__.py +0 -1
  11. {python_dateutil-3.0.0 → python_dateutil-4.0.0}/src/dateutil/_common.py +1 -4
  12. python_dateutil-4.0.0/src/dateutil/_tzdata_impl.py +75 -0
  13. python_dateutil-4.0.0/src/dateutil/_version.py +24 -0
  14. {python_dateutil-3.0.0 → python_dateutil-4.0.0}/src/dateutil/easter.py +0 -1
  15. {python_dateutil-3.0.0 → python_dateutil-4.0.0}/src/dateutil/parser/__init__.py +14 -12
  16. {python_dateutil-3.0.0 → python_dateutil-4.0.0}/src/dateutil/parser/_parser.py +14 -20
  17. {python_dateutil-3.0.0 → python_dateutil-4.0.0}/src/dateutil/parser/isoparser.py +25 -15
  18. {python_dateutil-3.0.0 → python_dateutil-4.0.0}/src/dateutil/relativedelta.py +8 -9
  19. {python_dateutil-3.0.0 → python_dateutil-4.0.0}/src/dateutil/rrule.py +43 -55
  20. python_dateutil-4.0.0/src/dateutil/tz/__init__.py +44 -0
  21. {python_dateutil-3.0.0 → python_dateutil-4.0.0}/src/dateutil/tz/_common.py +12 -123
  22. {python_dateutil-3.0.0 → python_dateutil-4.0.0}/src/dateutil/tz/_factories.py +4 -6
  23. {python_dateutil-3.0.0 → python_dateutil-4.0.0}/src/dateutil/tz/_tzfile.py +27 -123
  24. python_dateutil-4.0.0/src/dateutil/tz/_tzpath.py +12 -0
  25. {python_dateutil-3.0.0 → python_dateutil-4.0.0}/src/dateutil/tz/tz.py +34 -114
  26. {python_dateutil-3.0.0 → python_dateutil-4.0.0}/src/dateutil/tz/win.py +17 -17
  27. {python_dateutil-3.0.0 → python_dateutil-4.0.0}/src/dateutil/utils.py +0 -2
  28. {python_dateutil-3.0.0 → python_dateutil-4.0.0}/src/dateutil/zoneinfo/__init__.py +5 -14
  29. {python_dateutil-3.0.0 → python_dateutil-4.0.0}/tests/_common.py +13 -46
  30. {python_dateutil-3.0.0 → python_dateutil-4.0.0}/tests/conftest.py +1 -7
  31. {python_dateutil-3.0.0 → python_dateutil-4.0.0}/tests/property/test_isoparse_prop.py +3 -7
  32. {python_dateutil-3.0.0 → python_dateutil-4.0.0}/tests/property/test_tz_prop.py +0 -4
  33. {python_dateutil-3.0.0 → python_dateutil-4.0.0}/tests/resources/update_tzif.py +0 -2
  34. {python_dateutil-3.0.0 → python_dateutil-4.0.0}/tests/test_imports.py +25 -20
  35. {python_dateutil-3.0.0 → python_dateutil-4.0.0}/tests/test_internals.py +0 -6
  36. {python_dateutil-3.0.0 → python_dateutil-4.0.0}/tests/test_isoparser.py +106 -90
  37. {python_dateutil-3.0.0 → python_dateutil-4.0.0}/tests/test_parser.py +45 -42
  38. {python_dateutil-3.0.0 → python_dateutil-4.0.0}/tests/test_relativedelta.py +31 -17
  39. {python_dateutil-3.0.0 → python_dateutil-4.0.0}/tests/test_rrule.py +45 -47
  40. {python_dateutil-3.0.0 → python_dateutil-4.0.0}/tests/test_tz.py +44 -81
  41. {python_dateutil-3.0.0 → python_dateutil-4.0.0}/tests/test_tzfile.py +70 -336
  42. {python_dateutil-3.0.0 → python_dateutil-4.0.0}/tests/test_tzpath_data.py +4 -19
  43. {python_dateutil-3.0.0 → python_dateutil-4.0.0}/tests/test_utils.py +0 -3
  44. {python_dateutil-3.0.0 → python_dateutil-4.0.0}/tox.ini +20 -38
  45. python_dateutil-3.0.0/.gitattributes +0 -21
  46. python_dateutil-3.0.0/.github/pull_request_template.md +0 -12
  47. python_dateutil-3.0.0/.github/workflows/publish.yml +0 -56
  48. python_dateutil-3.0.0/.github/workflows/validate.yml +0 -328
  49. python_dateutil-3.0.0/.pre-commit-config.yaml +0 -15
  50. python_dateutil-3.0.0/.readthedocs.yml +0 -15
  51. python_dateutil-3.0.0/MANIFEST.in +0 -4
  52. python_dateutil-3.0.0/PKG-INFO +0 -204
  53. python_dateutil-3.0.0/RELEASING +0 -87
  54. python_dateutil-3.0.0/appveyor.yml +0 -34
  55. python_dateutil-3.0.0/changelog.d/.gitignore +0 -0
  56. python_dateutil-3.0.0/codecov.yml +0 -9
  57. python_dateutil-3.0.0/pyproject.toml +0 -65
  58. python_dateutil-3.0.0/requirements/3.3/constraints.txt +0 -15
  59. python_dateutil-3.0.0/requirements/3.3/requirements-dev.txt +0 -8
  60. python_dateutil-3.0.0/requirements-dev.txt +0 -9
  61. python_dateutil-3.0.0/setup.cfg +0 -90
  62. python_dateutil-3.0.0/setup.py +0 -31
  63. python_dateutil-3.0.0/src/dateutil/_tzdata_impl.py +0 -147
  64. python_dateutil-3.0.0/src/dateutil/_version.py +0 -4
  65. python_dateutil-3.0.0/src/dateutil/tz/__init__.py +0 -60
  66. python_dateutil-3.0.0/src/dateutil/tz/_tzpath.py +0 -104
  67. python_dateutil-3.0.0/src/python_dateutil.egg-info/SOURCES.txt +0 -101
  68. python_dateutil-3.0.0/src/python_dateutil.egg-info/dependency_links.txt +0 -1
  69. python_dateutil-3.0.0/src/python_dateutil.egg-info/requires.txt +0 -2
  70. python_dateutil-3.0.0/src/python_dateutil.egg-info/top_level.txt +0 -1
  71. python_dateutil-3.0.0/src/python_dateutil.egg-info/zip-safe +0 -1
  72. {python_dateutil-3.0.0 → python_dateutil-4.0.0}/.gitignore +0 -0
  73. {python_dateutil-3.0.0 → python_dateutil-4.0.0}/LICENSE +0 -0
  74. {python_dateutil-3.0.0 → python_dateutil-4.0.0}/changelog.d/template.rst +0 -0
  75. {python_dateutil-3.0.0 → python_dateutil-4.0.0}/ci_tools/run_tz_master_env.sh +0 -0
  76. {python_dateutil-3.0.0 → python_dateutil-4.0.0}/docs/Makefile +0 -0
  77. {python_dateutil-3.0.0 → python_dateutil-4.0.0}/docs/changelog.rst +0 -0
  78. {python_dateutil-3.0.0 → python_dateutil-4.0.0}/docs/easter.rst +0 -0
  79. {python_dateutil-3.0.0 → python_dateutil-4.0.0}/docs/examples.rst +0 -0
  80. {python_dateutil-3.0.0 → python_dateutil-4.0.0}/docs/exercises/index.rst +0 -0
  81. {python_dateutil-3.0.0 → python_dateutil-4.0.0}/docs/exercises/solutions/mlk-day-rrule.rst +0 -0
  82. {python_dateutil-3.0.0 → python_dateutil-4.0.0}/docs/exercises/solutions/mlk_day_rrule_solution.py +0 -0
  83. {python_dateutil-3.0.0 → python_dateutil-4.0.0}/docs/index.rst +0 -0
  84. {python_dateutil-3.0.0 → python_dateutil-4.0.0}/docs/make.bat +0 -0
  85. {python_dateutil-3.0.0 → python_dateutil-4.0.0}/docs/parser.rst +0 -0
  86. {python_dateutil-3.0.0 → python_dateutil-4.0.0}/docs/relativedelta.rst +0 -0
  87. {python_dateutil-3.0.0 → python_dateutil-4.0.0}/docs/requirements-docs.txt +0 -0
  88. {python_dateutil-3.0.0 → python_dateutil-4.0.0}/docs/rrule.rst +0 -0
  89. {python_dateutil-3.0.0 → python_dateutil-4.0.0}/docs/samples/EST5EDT.ics +0 -0
  90. {python_dateutil-3.0.0 → python_dateutil-4.0.0}/docs/tzwin.rst +0 -0
  91. {python_dateutil-3.0.0 → python_dateutil-4.0.0}/docs/utils.rst +0 -0
  92. {python_dateutil-3.0.0 → python_dateutil-4.0.0}/docs/zoneinfo.rst +0 -0
  93. {python_dateutil-3.0.0 → python_dateutil-4.0.0}/src/dateutil/tzwin.py +0 -0
  94. {python_dateutil-3.0.0 → python_dateutil-4.0.0}/src/dateutil/zoneinfo/rebuild.py +0 -0
  95. {python_dateutil-3.0.0 → python_dateutil-4.0.0}/tests/__init__.py +0 -0
  96. {python_dateutil-3.0.0 → python_dateutil-4.0.0}/tests/property/test_parser_prop.py +0 -0
  97. {python_dateutil-3.0.0 → python_dateutil-4.0.0}/tests/property/test_rrule_prop.py +0 -0
  98. {python_dateutil-3.0.0 → python_dateutil-4.0.0}/tests/resources/__init__.py +0 -0
  99. {python_dateutil-3.0.0 → python_dateutil-4.0.0}/tests/resources/data/__init__.py +0 -0
  100. {python_dateutil-3.0.0 → python_dateutil-4.0.0}/tests/resources/data/keys.json +0 -0
  101. {python_dateutil-3.0.0 → python_dateutil-4.0.0}/tests/resources/data/metadata.json +0 -0
  102. {python_dateutil-3.0.0 → python_dateutil-4.0.0}/tests/resources/data/zoneinfo_fat.json +0 -0
  103. {python_dateutil-3.0.0 → python_dateutil-4.0.0}/tests/resources/data/zoneinfo_slim.json +0 -0
  104. {python_dateutil-3.0.0 → python_dateutil-4.0.0}/tests/resources/data/zoneinfo_v1.json +0 -0
  105. {python_dateutil-3.0.0 → python_dateutil-4.0.0}/tests/resources/liliput_tzif +0 -0
  106. {python_dateutil-3.0.0 → python_dateutil-4.0.0}/tests/test_easter.py +0 -0
  107. {python_dateutil-3.0.0 → python_dateutil-4.0.0}/tests/test_import_star.py +0 -0
  108. {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
- - `deprecation`: Used if deprecating a feature or dropping support for a Python version.
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 2.7 and Python 3.6:
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 py27,py36
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 py36 -- -m tzstr
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
- All GitHub pull requests are automatically tested using [GitHub Actions](https://github.com/dateutil/dateutil/actions/) and [Appveyor](https://ci.appveyor.com/project/dateutil/dateutil).
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.4
1
+ Metadata-Version: 2.5
2
2
  Name: python-dateutil
3
- Version: 3.0.0
3
+ Version: 4.0.0
4
4
  Summary: Extensions to the standard Python datetime module
5
- Home-page: https://github.com/dateutil/dateutil
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: !=3.0.*,!=3.1.*,!=3.2.*,>=2.7
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
- Dynamic: description
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
- |appveyor| |gha| |coverage|
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
- |appveyor| |gha| |coverage|
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 = ['ctypes.wintypes', 'six.moves.winreg']
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
- In Python >= 3.9, this is an alias for :py:data:`zoneinfo.TZPATH`.
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`. In Python >= 3.9, this is an alias for
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. In versions of Python that include the :py:mod:`zoneinfo`
99
- module, :data:`TZPATH` is a proxy for :py:data:`zoneinfo.TZPATH` and
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
- ``dateutil`` also backports the search path logic to Python versions < 3.9, and
103
- the environment variable ``PYTHONTZPATH`` can be used (though there is no
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"
@@ -0,0 +1,8 @@
1
+ pytest >= 3.0
2
+ pytest-cov >= 2.0.0
3
+ pytest-xdist >= 3.2.0
4
+ freezegun
5
+ hypothesis >= 3.30
6
+ coverage
7
+ build >= 0.3.0
8
+ attrs>=21.2.0
@@ -1,4 +1,3 @@
1
- # -*- coding: utf-8 -*-
2
1
  import sys
3
2
 
4
3
  try:
@@ -3,7 +3,7 @@ Common code used in multiple modules.
3
3
  """
4
4
 
5
5
 
6
- class weekday(object):
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,4 +1,3 @@
1
- # -*- coding: utf-8 -*-
2
1
  """
3
2
  This module offers a generic Easter computing method for any given year, using
4
3
  Western, Orthodox or Julian algorithms.
@@ -1,11 +1,14 @@
1
- # -*- coding: utf-8 -*-
2
- from ._parser import parse, parser, parserinfo, ParserError
3
- from ._parser import DEFAULTPARSER, DEFAULTTZPARSER
4
- from ._parser import UnknownTimezoneWarning
5
-
6
- from ._parser import __doc__
7
-
8
- from .isoparser import isoparser, isoparse
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(private_class, self).__init__(*args, **kwargs)
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, _resultbase
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)