aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/python/dateutil
diff options
context:
space:
mode:
authorshadchin <shadchin@yandex-team.ru>2022-02-10 16:44:30 +0300
committerDaniil Cherednik <dcherednik@yandex-team.ru>2022-02-10 16:44:30 +0300
commit2598ef1d0aee359b4b6d5fdd1758916d5907d04f (patch)
tree012bb94d777798f1f56ac1cec429509766d05181 /contrib/python/dateutil
parent6751af0b0c1b952fede40b19b71da8025b5d8bcf (diff)
downloadydb-2598ef1d0aee359b4b6d5fdd1758916d5907d04f.tar.gz
Restoring authorship annotation for <shadchin@yandex-team.ru>. Commit 1 of 2.
Diffstat (limited to 'contrib/python/dateutil')
-rw-r--r--contrib/python/dateutil/.dist-info/METADATA408
-rw-r--r--contrib/python/dateutil/.dist-info/top_level.txt2
-rw-r--r--contrib/python/dateutil/AUTHORS.md260
-rw-r--r--contrib/python/dateutil/LICENSE108
-rw-r--r--contrib/python/dateutil/README.rst48
-rw-r--r--contrib/python/dateutil/dateutil/_version.py4
-rw-r--r--contrib/python/dateutil/dateutil/easter.py16
-rw-r--r--contrib/python/dateutil/dateutil/parser/__init__.py8
-rw-r--r--contrib/python/dateutil/dateutil/parser/_parser.py206
-rw-r--r--contrib/python/dateutil/dateutil/parser/isoparser.py66
-rw-r--r--contrib/python/dateutil/dateutil/relativedelta.py42
-rw-r--r--contrib/python/dateutil/dateutil/rrule.py272
-rw-r--r--contrib/python/dateutil/dateutil/test/_common.py16
-rw-r--r--contrib/python/dateutil/dateutil/test/conftest.py82
-rw-r--r--contrib/python/dateutil/dateutil/test/property/test_isoparse_prop.py2
-rw-r--r--contrib/python/dateutil/dateutil/test/property/test_tz_prop.py70
-rw-r--r--contrib/python/dateutil/dateutil/test/test_easter.py32
-rw-r--r--contrib/python/dateutil/dateutil/test/test_import_star.py40
-rw-r--r--contrib/python/dateutil/dateutil/test/test_imports.py266
-rw-r--r--contrib/python/dateutil/dateutil/test/test_internals.py50
-rw-r--r--contrib/python/dateutil/dateutil/test/test_isoparser.py150
-rw-r--r--contrib/python/dateutil/dateutil/test/test_parser.py980
-rw-r--r--contrib/python/dateutil/dateutil/test/test_relativedelta.py78
-rw-r--r--contrib/python/dateutil/dateutil/test/test_rrule.py156
-rw-r--r--contrib/python/dateutil/dateutil/test/test_tz.py560
-rw-r--r--contrib/python/dateutil/dateutil/test/test_utils.py62
-rw-r--r--contrib/python/dateutil/dateutil/tz/_common.py26
-rw-r--r--contrib/python/dateutil/dateutil/tz/_factories.py98
-rw-r--r--contrib/python/dateutil/dateutil/tz/tz.py252
-rw-r--r--contrib/python/dateutil/dateutil/tz/win.py86
-rw-r--r--contrib/python/dateutil/dateutil/utils.py4
-rw-r--r--contrib/python/dateutil/dateutil/zoneinfo/__init__.py4
-rw-r--r--contrib/python/dateutil/dateutil/zoneinfo/rebuild.py56
-rw-r--r--contrib/python/dateutil/tests/ya.make74
-rw-r--r--contrib/python/dateutil/ya.make34
35 files changed, 2309 insertions, 2309 deletions
diff --git a/contrib/python/dateutil/.dist-info/METADATA b/contrib/python/dateutil/.dist-info/METADATA
index 1e46c96a44..2c5c2c523a 100644
--- a/contrib/python/dateutil/.dist-info/METADATA
+++ b/contrib/python/dateutil/.dist-info/METADATA
@@ -1,204 +1,204 @@
-Metadata-Version: 2.1
-Name: python-dateutil
-Version: 2.8.2
-Summary: Extensions to the standard Python datetime module
-Home-page: https://github.com/dateutil/dateutil
-Author: Gustavo Niemeyer
-Author-email: gustavo@niemeyer.net
-Maintainer: Paul Ganssle
-Maintainer-email: dateutil@python.org
-License: Dual License
-Project-URL: Documentation, https://dateutil.readthedocs.io/en/stable/
-Project-URL: Source, https://github.com/dateutil/dateutil
-Platform: UNKNOWN
-Classifier: Development Status :: 5 - Production/Stable
-Classifier: Intended Audience :: Developers
-Classifier: License :: OSI Approved :: BSD License
-Classifier: License :: OSI Approved :: Apache Software License
-Classifier: Programming Language :: Python
-Classifier: Programming Language :: Python :: 2
-Classifier: Programming Language :: Python :: 2.7
-Classifier: Programming Language :: Python :: 3
-Classifier: Programming Language :: Python :: 3.3
-Classifier: Programming Language :: Python :: 3.4
-Classifier: Programming Language :: Python :: 3.5
-Classifier: Programming Language :: Python :: 3.6
-Classifier: Programming Language :: Python :: 3.7
-Classifier: Programming Language :: Python :: 3.8
-Classifier: Programming Language :: Python :: 3.9
-Classifier: Topic :: Software Development :: Libraries
-Requires-Python: !=3.0.*,!=3.1.*,!=3.2.*,>=2.7
-Description-Content-Type: text/x-rst
-License-File: LICENSE
-Requires-Dist: six (>=1.5)
-
-dateutil - powerful extensions to datetime
-==========================================
-
-|pypi| |support| |licence|
-
-|gitter| |readthedocs|
-
-|travis| |appveyor| |pipelines| |coverage|
-
-.. |pypi| image:: https://img.shields.io/pypi/v/python-dateutil.svg?style=flat-square
- :target: https://pypi.org/project/python-dateutil/
- :alt: pypi version
-
-.. |support| image:: https://img.shields.io/pypi/pyversions/python-dateutil.svg?style=flat-square
- :target: https://pypi.org/project/python-dateutil/
- :alt: supported Python version
-
-.. |travis| image:: https://img.shields.io/travis/dateutil/dateutil/master.svg?style=flat-square&label=Travis%20Build
- :target: https://travis-ci.org/dateutil/dateutil
- :alt: travis build status
-
-.. |appveyor| image:: https://img.shields.io/appveyor/ci/dateutil/dateutil/master.svg?style=flat-square&logo=appveyor
- :target: https://ci.appveyor.com/project/dateutil/dateutil
- :alt: appveyor build status
-
-.. |pipelines| image:: https://dev.azure.com/pythondateutilazure/dateutil/_apis/build/status/dateutil.dateutil?branchName=master
- :target: https://dev.azure.com/pythondateutilazure/dateutil/_build/latest?definitionId=1&branchName=master
- :alt: azure pipelines build status
-
-.. |coverage| image:: https://codecov.io/gh/dateutil/dateutil/branch/master/graphs/badge.svg?branch=master
- :target: https://codecov.io/gh/dateutil/dateutil?branch=master
- :alt: Code coverage
-
-.. |gitter| image:: https://badges.gitter.im/dateutil/dateutil.svg
- :alt: Join the chat at https://gitter.im/dateutil/dateutil
- :target: https://gitter.im/dateutil/dateutil
-
-.. |licence| image:: https://img.shields.io/pypi/l/python-dateutil.svg?style=flat-square
- :target: https://pypi.org/project/python-dateutil/
- :alt: licence
-
-.. |readthedocs| image:: https://img.shields.io/readthedocs/dateutil/latest.svg?style=flat-square&label=Read%20the%20Docs
- :alt: Read the documentation at https://dateutil.readthedocs.io/en/latest/
- :target: https://dateutil.readthedocs.io/en/latest/
-
-The `dateutil` module provides powerful extensions to
-the standard `datetime` module, available in Python.
-
-Installation
-============
-`dateutil` can be installed from PyPI using `pip` (note that the package name is
-different from the importable name)::
-
- pip install python-dateutil
-
-Download
-========
-dateutil is available on PyPI
-https://pypi.org/project/python-dateutil/
-
-The documentation is hosted at:
-https://dateutil.readthedocs.io/en/stable/
-
-Code
-====
-The code and issue tracker are hosted on GitHub:
-https://github.com/dateutil/dateutil/
-
-Features
-========
-
-* Computing of relative deltas (next month, next year,
- next Monday, last week of month, etc);
-* Computing of relative deltas between two given
- date and/or datetime objects;
-* Computing of dates based on very flexible recurrence rules,
- using a superset of the `iCalendar <https://www.ietf.org/rfc/rfc2445.txt>`_
- specification. Parsing of RFC strings is supported as well.
-* Generic parsing of dates in almost any string format;
-* Timezone (tzinfo) implementations for tzfile(5) format
- files (/etc/localtime, /usr/share/zoneinfo, etc), TZ
- environment string (in all known formats), iCalendar
- format files, given ranges (with help from relative deltas),
- local machine timezone, fixed offset timezone, UTC timezone,
- and Windows registry-based time zones.
-* Internal up-to-date world timezone information based on
- Olson's database.
-* Computing of Easter Sunday dates for any given year,
- using Western, Orthodox or Julian algorithms;
-* A comprehensive test suite.
-
-Quick example
-=============
-Here's a snapshot, just to give an idea about the power of the
-package. For more examples, look at the documentation.
-
-Suppose you want to know how much time is left, in
-years/months/days/etc, before the next easter happening on a
-year with a Friday 13th in August, and you want to get today's
-date out of the "date" unix system command. Here is the code:
-
-.. code-block:: python3
-
- >>> from dateutil.relativedelta import *
- >>> from dateutil.easter import *
- >>> from dateutil.rrule import *
- >>> from dateutil.parser import *
- >>> from datetime import *
- >>> now = parse("Sat Oct 11 17:13:46 UTC 2003")
- >>> today = now.date()
- >>> year = rrule(YEARLY,dtstart=now,bymonth=8,bymonthday=13,byweekday=FR)[0].year
- >>> rdelta = relativedelta(easter(year), today)
- >>> print("Today is: %s" % today)
- Today is: 2003-10-11
- >>> print("Year with next Aug 13th on a Friday is: %s" % year)
- Year with next Aug 13th on a Friday is: 2004
- >>> print("How far is the Easter of that year: %s" % rdelta)
- How far is the Easter of that year: relativedelta(months=+6)
- >>> print("And the Easter of that year is: %s" % (today+rdelta))
- And the Easter of that year is: 2004-04-11
-
-Being exactly 6 months ahead was **really** a coincidence :)
-
-Contributing
-============
-
-We welcome many types of contributions - bug reports, pull requests (code, infrastructure or documentation fixes). For more information about how to contribute to the project, see the ``CONTRIBUTING.md`` file in the repository.
-
-
-Author
-======
-The dateutil module was written by Gustavo Niemeyer <gustavo@niemeyer.net>
-in 2003.
-
-It is maintained by:
-
-* Gustavo Niemeyer <gustavo@niemeyer.net> 2003-2011
-* Tomi Pieviläinen <tomi.pievilainen@iki.fi> 2012-2014
-* Yaron de Leeuw <me@jarondl.net> 2014-2016
-* Paul Ganssle <paul@ganssle.io> 2015-
-
-Starting with version 2.4.1 and running until 2.8.2, all source and binary
-distributions will be signed by a PGP key that has, at the very least, been
-signed by the key which made the previous release. A table of release signing
-keys can be found below:
-
-=========== ============================
-Releases Signing key fingerprint
-=========== ============================
-2.4.1-2.8.2 `6B49 ACBA DCF6 BD1C A206 67AB CD54 FCE3 D964 BEFB`_
-=========== ============================
-
-New releases *may* have signed tags, but binary and source distributions
-uploaded to PyPI will no longer have GPG signatures attached.
-
-Contact
-=======
-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
-conduct <https://www.python.org/psf/conduct/>`_.
-
-License
-=======
-
-All contributions after December 1, 2017 released under dual license - either `Apache 2.0 License <https://www.apache.org/licenses/LICENSE-2.0>`_ or the `BSD 3-Clause License <https://opensource.org/licenses/BSD-3-Clause>`_. Contributions before December 1, 2017 - except those those explicitly relicensed - are released only under the BSD 3-Clause License.
-
-
-.. _6B49 ACBA DCF6 BD1C A206 67AB CD54 FCE3 D964 BEFB:
- https://pgp.mit.edu/pks/lookup?op=vindex&search=0xCD54FCE3D964BEFB
-
-
+Metadata-Version: 2.1
+Name: python-dateutil
+Version: 2.8.2
+Summary: Extensions to the standard Python datetime module
+Home-page: https://github.com/dateutil/dateutil
+Author: Gustavo Niemeyer
+Author-email: gustavo@niemeyer.net
+Maintainer: Paul Ganssle
+Maintainer-email: dateutil@python.org
+License: Dual License
+Project-URL: Documentation, https://dateutil.readthedocs.io/en/stable/
+Project-URL: Source, https://github.com/dateutil/dateutil
+Platform: UNKNOWN
+Classifier: Development Status :: 5 - Production/Stable
+Classifier: Intended Audience :: Developers
+Classifier: License :: OSI Approved :: BSD License
+Classifier: License :: OSI Approved :: Apache Software License
+Classifier: Programming Language :: Python
+Classifier: Programming Language :: Python :: 2
+Classifier: Programming Language :: Python :: 2.7
+Classifier: Programming Language :: Python :: 3
+Classifier: Programming Language :: Python :: 3.3
+Classifier: Programming Language :: Python :: 3.4
+Classifier: Programming Language :: Python :: 3.5
+Classifier: Programming Language :: Python :: 3.6
+Classifier: Programming Language :: Python :: 3.7
+Classifier: Programming Language :: Python :: 3.8
+Classifier: Programming Language :: Python :: 3.9
+Classifier: Topic :: Software Development :: Libraries
+Requires-Python: !=3.0.*,!=3.1.*,!=3.2.*,>=2.7
+Description-Content-Type: text/x-rst
+License-File: LICENSE
+Requires-Dist: six (>=1.5)
+
+dateutil - powerful extensions to datetime
+==========================================
+
+|pypi| |support| |licence|
+
+|gitter| |readthedocs|
+
+|travis| |appveyor| |pipelines| |coverage|
+
+.. |pypi| image:: https://img.shields.io/pypi/v/python-dateutil.svg?style=flat-square
+ :target: https://pypi.org/project/python-dateutil/
+ :alt: pypi version
+
+.. |support| image:: https://img.shields.io/pypi/pyversions/python-dateutil.svg?style=flat-square
+ :target: https://pypi.org/project/python-dateutil/
+ :alt: supported Python version
+
+.. |travis| image:: https://img.shields.io/travis/dateutil/dateutil/master.svg?style=flat-square&label=Travis%20Build
+ :target: https://travis-ci.org/dateutil/dateutil
+ :alt: travis build status
+
+.. |appveyor| image:: https://img.shields.io/appveyor/ci/dateutil/dateutil/master.svg?style=flat-square&logo=appveyor
+ :target: https://ci.appveyor.com/project/dateutil/dateutil
+ :alt: appveyor build status
+
+.. |pipelines| image:: https://dev.azure.com/pythondateutilazure/dateutil/_apis/build/status/dateutil.dateutil?branchName=master
+ :target: https://dev.azure.com/pythondateutilazure/dateutil/_build/latest?definitionId=1&branchName=master
+ :alt: azure pipelines build status
+
+.. |coverage| image:: https://codecov.io/gh/dateutil/dateutil/branch/master/graphs/badge.svg?branch=master
+ :target: https://codecov.io/gh/dateutil/dateutil?branch=master
+ :alt: Code coverage
+
+.. |gitter| image:: https://badges.gitter.im/dateutil/dateutil.svg
+ :alt: Join the chat at https://gitter.im/dateutil/dateutil
+ :target: https://gitter.im/dateutil/dateutil
+
+.. |licence| image:: https://img.shields.io/pypi/l/python-dateutil.svg?style=flat-square
+ :target: https://pypi.org/project/python-dateutil/
+ :alt: licence
+
+.. |readthedocs| image:: https://img.shields.io/readthedocs/dateutil/latest.svg?style=flat-square&label=Read%20the%20Docs
+ :alt: Read the documentation at https://dateutil.readthedocs.io/en/latest/
+ :target: https://dateutil.readthedocs.io/en/latest/
+
+The `dateutil` module provides powerful extensions to
+the standard `datetime` module, available in Python.
+
+Installation
+============
+`dateutil` can be installed from PyPI using `pip` (note that the package name is
+different from the importable name)::
+
+ pip install python-dateutil
+
+Download
+========
+dateutil is available on PyPI
+https://pypi.org/project/python-dateutil/
+
+The documentation is hosted at:
+https://dateutil.readthedocs.io/en/stable/
+
+Code
+====
+The code and issue tracker are hosted on GitHub:
+https://github.com/dateutil/dateutil/
+
+Features
+========
+
+* Computing of relative deltas (next month, next year,
+ next Monday, last week of month, etc);
+* Computing of relative deltas between two given
+ date and/or datetime objects;
+* Computing of dates based on very flexible recurrence rules,
+ using a superset of the `iCalendar <https://www.ietf.org/rfc/rfc2445.txt>`_
+ specification. Parsing of RFC strings is supported as well.
+* Generic parsing of dates in almost any string format;
+* Timezone (tzinfo) implementations for tzfile(5) format
+ files (/etc/localtime, /usr/share/zoneinfo, etc), TZ
+ environment string (in all known formats), iCalendar
+ format files, given ranges (with help from relative deltas),
+ local machine timezone, fixed offset timezone, UTC timezone,
+ and Windows registry-based time zones.
+* Internal up-to-date world timezone information based on
+ Olson's database.
+* Computing of Easter Sunday dates for any given year,
+ using Western, Orthodox or Julian algorithms;
+* A comprehensive test suite.
+
+Quick example
+=============
+Here's a snapshot, just to give an idea about the power of the
+package. For more examples, look at the documentation.
+
+Suppose you want to know how much time is left, in
+years/months/days/etc, before the next easter happening on a
+year with a Friday 13th in August, and you want to get today's
+date out of the "date" unix system command. Here is the code:
+
+.. code-block:: python3
+
+ >>> from dateutil.relativedelta import *
+ >>> from dateutil.easter import *
+ >>> from dateutil.rrule import *
+ >>> from dateutil.parser import *
+ >>> from datetime import *
+ >>> now = parse("Sat Oct 11 17:13:46 UTC 2003")
+ >>> today = now.date()
+ >>> year = rrule(YEARLY,dtstart=now,bymonth=8,bymonthday=13,byweekday=FR)[0].year
+ >>> rdelta = relativedelta(easter(year), today)
+ >>> print("Today is: %s" % today)
+ Today is: 2003-10-11
+ >>> print("Year with next Aug 13th on a Friday is: %s" % year)
+ Year with next Aug 13th on a Friday is: 2004
+ >>> print("How far is the Easter of that year: %s" % rdelta)
+ How far is the Easter of that year: relativedelta(months=+6)
+ >>> print("And the Easter of that year is: %s" % (today+rdelta))
+ And the Easter of that year is: 2004-04-11
+
+Being exactly 6 months ahead was **really** a coincidence :)
+
+Contributing
+============
+
+We welcome many types of contributions - bug reports, pull requests (code, infrastructure or documentation fixes). For more information about how to contribute to the project, see the ``CONTRIBUTING.md`` file in the repository.
+
+
+Author
+======
+The dateutil module was written by Gustavo Niemeyer <gustavo@niemeyer.net>
+in 2003.
+
+It is maintained by:
+
+* Gustavo Niemeyer <gustavo@niemeyer.net> 2003-2011
+* Tomi Pieviläinen <tomi.pievilainen@iki.fi> 2012-2014
+* Yaron de Leeuw <me@jarondl.net> 2014-2016
+* Paul Ganssle <paul@ganssle.io> 2015-
+
+Starting with version 2.4.1 and running until 2.8.2, all source and binary
+distributions will be signed by a PGP key that has, at the very least, been
+signed by the key which made the previous release. A table of release signing
+keys can be found below:
+
+=========== ============================
+Releases Signing key fingerprint
+=========== ============================
+2.4.1-2.8.2 `6B49 ACBA DCF6 BD1C A206 67AB CD54 FCE3 D964 BEFB`_
+=========== ============================
+
+New releases *may* have signed tags, but binary and source distributions
+uploaded to PyPI will no longer have GPG signatures attached.
+
+Contact
+=======
+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
+conduct <https://www.python.org/psf/conduct/>`_.
+
+License
+=======
+
+All contributions after December 1, 2017 released under dual license - either `Apache 2.0 License <https://www.apache.org/licenses/LICENSE-2.0>`_ or the `BSD 3-Clause License <https://opensource.org/licenses/BSD-3-Clause>`_. Contributions before December 1, 2017 - except those those explicitly relicensed - are released only under the BSD 3-Clause License.
+
+
+.. _6B49 ACBA DCF6 BD1C A206 67AB CD54 FCE3 D964 BEFB:
+ https://pgp.mit.edu/pks/lookup?op=vindex&search=0xCD54FCE3D964BEFB
+
+
diff --git a/contrib/python/dateutil/.dist-info/top_level.txt b/contrib/python/dateutil/.dist-info/top_level.txt
index 66501480ba..629459ea16 100644
--- a/contrib/python/dateutil/.dist-info/top_level.txt
+++ b/contrib/python/dateutil/.dist-info/top_level.txt
@@ -1 +1 @@
-dateutil
+dateutil
diff --git a/contrib/python/dateutil/AUTHORS.md b/contrib/python/dateutil/AUTHORS.md
index fa9184207f..19668e2268 100644
--- a/contrib/python/dateutil/AUTHORS.md
+++ b/contrib/python/dateutil/AUTHORS.md
@@ -1,130 +1,130 @@
-This is a (possibly incomplete) list of all the contributors to python-dateutil,
-initially generated from the git author metadata. The details of their specific
-contributions can be found in the git history.
-
-Prior to 2017-12-01, the library was licensed solely under the BSD 3-clause
-license, all contributions on or after 2017-12-01 are dual-licensed between
-Apache 2.0 and BSD 3-clause. In the list below, anyone whose name is marked with
-**R** has agreed to re-license their previously submitted code under Apache 2.0.
-Anyone whose name is marked with a **D** has only made contributions since the
-switch, and thus all their contributions are dual-licensed.
-
-## Contributors (alphabetical order)
-
-- Adam Chainz <adam@MASKED>
-- Adrien Cossa <cossa@MASKED>
-- Alec Nikolas Reiter <alecreiter@MASKED>
-- Alec Reiter <areiter@MASKED>
-- Alex Chamberlain (gh: @alexchamberlain) **D**
-- Alex Verdyan <verdyan@MASKED>
-- Alex Willmer <alex@moreati.org.uk> (gh: @moreati) **R**
-- Alexander Brugh <alexander.brugh@MASKED> (gh: @abrugh)
-- Alexander Shadchin <alexandr.shadchin@gmail.com> (gh: @shadchin) **D**
-- Alistair McMaster <alistair@MASKED> (gh: @alimcmaster1 ) **D**
-- Allison Quinlan <aquinlan82@gmail.com> (gh: @aquinlan) **D**
-- Andrew Bennett (gh: @andrewcbennett) **D**
-- Andrew Murray <radarhere@MASKED>
-- Arclight <arclight@MASKED> (gh: @arclightslavik)
-- Aritro Nandi <gurgenz221@gmail.com> (gh: @gurgenz221) **D**
-- Bernat Gabor <bgabor8@bloomberg.net> (gh: @gaborbernat) **D**
-- Bradlee Speice <bradlee@speice.io> (gh: @bspeice) **D**
-- Brandon W Maister <quodlibetor@MASKED>
-- Brock Mendel <jbrockmendel@MASKED> (gh: @jbrockmendel) **R**
-- Brook Li (gh: @absreim) **D**
-- Carlos <carlosxl@MASKED>
-- Cheuk Ting Ho <cheukting.ho@gmail.com> (gh: @cheukting) **D**
-- Chris van den Berg (gh: bergvca) **D**
-- Christopher Cordero <ccordero@pm.me> (gh: cs-cordero) **D**
-- Christopher Corley <cscorley@MASKED>
-- Claudio Canepa <ccanepacc@MASKED>
-- Corey Girard <corey.r.girard@gmail.com> (gh: @coreygirard) **D**
-- Cosimo Lupo <cosimo@anthrotype.com> (gh: @anthrotype) **D**
-- Daniel Lemm (gh: @ffe4) **D**
-- Daniel Lepage <dplepage@MASKED>
-- David Lehrian <david@MASKED>
-- Dean Allsopp (gh: @daplantagenet) **D**
-- Dominik Kozaczko <dominik@MASKED>
-- Elliot Hughes <elliot.hughes@gmail.com> (gh: @ElliotJH) **D**
-- Elvis Pranskevichus <el@MASKED>
-- Fan Huang <fanhuang.scb@gmail.com>(gh: @fhuang5) **D**
-- Florian Rathgeber (gh: @kynan) **D**
-- Gabriel Bianconi <gabriel@MASKED> (gh: @GabrielBianconi) **D**
-- Gabriel Poesia <gabriel.poesia@MASKED>
-- Gökçen Nurlu <gnurlu1@bloomberg.net> (gh: @gokcennurlu) **D**
-- Grant Garrett-Grossman <grantlycee@gmail.com> (gh: @FakeNameSE) **D**
-- Gustavo Niemeyer <gustavo@niemeyer.net> (gh: @niemeyer)
-- Holger Joukl <holger.joukl@MASKED> (gh: @hjoukl)
-- Hugo van Kemenade (gh: @hugovk) **D**
-- Igor <mrigor83@MASKED>
-- Ionuț Ciocîrlan <jdxlark@MASKED>
-- Jacqueline Chen <jacqueline415@outlook.com> (gh: @jachen20) **D**
-- Jake Chorley (gh: @jakec-github) **D**
-- Jan Studený <jendas1@MASKED>
-- Jay Weisskopf <jay@jayschwa.net> (gh: @jayschwa) **D**
-- Jitesh <jitesh@MASKED>
-- John Purviance <jpurviance@MASKED> (gh @jpurviance) **D**
-- Jon Dufresne <jon.dufresne@MASKED> (gh: @jdufresne) **R**
-- Jonas Neubert <jonas@MASKED> (gh: @jonemo) **R**
-- Kevin Nguyen <kvn219@MASKED> **D**
-- Kirit Thadaka <kirit.thadaka@gmail.com> (gh: @kirit93) **D**
-- Kubilay Kocak <koobs@MASKED>
-- Laszlo Kiss Kollar <kiss.kollar.laszlo@MASKED> (gh: @lkollar) **D**
-- Lauren Oldja <oldja@MASKED> (gh: @loldja) **D**
-- Luca Ferocino <luca.ferox@MASKED> (gh: @lucaferocino) **D**
-- Mario Corchero <mcorcherojim@MASKED> (gh: @mariocj89) **R**
-- Mark Bailey <msb@MASKED> **D**
-- Mateusz Dziedzic (gh: @m-dz) **D**
-- Matt Cooper <vtbassmatt@MASKED> (gh: @vtbassmatt) **D**
-- Matthew Schinckel <matt@MASKED>
-- Max Shenfield <shenfieldmax@MASKED>
-- Maxime Lorant <maxime.lorant@MASKED>
-- Michael Aquilina <michaelaquilina@MASKED> (gh: @MichaelAquilina)
-- Michael J. Schultz <mjschultz@MASKED>
-- Michael Käufl (gh: @michael-k)
-- Mike Gilbert <floppym@MASKED>
-- Nicholas Herrriot <Nicholas.Herriot@gmail.com> **D**
-- Nicolas Évrard (gh: @nicoe) **D**
-- Nick Smith <nick.smith@MASKED>
-- Orson Adams <orson.network@MASKED> (gh: @parsethis) **D**
-- Paul Brown (gh: @pawl) **D**
-- Paul Dickson (gh @prdickson) **D**
-- Paul Ganssle <paul@ganssle.io> (gh: @pganssle) **R**
-- Pascal van Kooten <kootenpv@MASKED> (gh: @kootenpv) **R**
-- Pavel Ponomarev <comrad.awsum@MASKED>
-- Peter Bieringer <pb@MASKED>
-- Pierre Gergondet <pierre.gergondet@MASKED> (gh: @gergondet) **D**
-- Quentin Pradet <quentin@MASKED>
-- Raymond Cha (gh: @weatherpattern) **D**
-- Ridhi Mahajan <ridhikmahajan@MASKED> **D**
-- Robin Henriksson Törnström <gh: @MrRawbin> **D**
-- Roy Williams <rwilliams@MASKED>
-- Rustem Saiargaliev (gh: @amureki) **D**
-- Satyabrat Bhol <satyabrat35@MASKED> (gh: @Satyabrat35) **D**
-- Savraj <savraj@MASKED>
-- Sergey Vishnikin <armicron@MASKED>
-- Sherry Zhou (gh: @cssherry) **D**
-- Siping Meng (gh: @smeng10) **D**
-- Stefan Bonchev **D**
-- Thierry Bastian <thierryb@MASKED>
-- Thomas A Caswell <tcaswell@MASKED> (gh: @tacaswell) **R**
-- Thomas Achtemichuk <tom@MASKED>
-- Thomas Kluyver <takowl@MASKED> (gh: @takluyver)
-- Tim Gates <tim.gates@iress.com> (gh: timgates42)
-- Tomasz Kluczkowski (gh: @Tomasz-Kluczkowski) **D**
-- Tomi Pieviläinen <tomi.pievilainen@iki.fi>
-- Unrud <Unrud@MASKED> (gh: @unrud)
-- Xavier Lapointe <lapointe.xavier@MASKED> (gh: @lapointexavier) **D**
-- X O <xo@MASKED>
-- Yaron de Leeuw <me@jarondl.net> (gh: @jarondl)
-- Yoney <alper_yoney@hotmail.com> **D**
-- Yuan Huang <huangy22@gmail.com> (gh: @huangy22) **D**
-- Zbigniew Jędrzejewski-Szmek <zbyszek@MASKED>
-- bachmann <bachmann.matt@MASKED>
-- bjv <brandon.vanvaerenbergh@MASKED> (@bjamesvERT)
-- gl <gl@MASKED>
-- gfyoung <gfyoung17@gmail.com> **D**
-- Labrys <labrys.git@gmail.com> (gh: @labrys) **R**
-- ms-boom <ms-boom@MASKED>
-- ryanss <ryanssdev@MASKED> (gh: @ryanss) **R**
-
-Unless someone has deliberately given permission to publish their e-mail, I have masked the domain names. If you are not on this list and believe you should be, or you *are* on this list and your information is inaccurate, please e-mail the current maintainer or the mailing list (dateutil@python.org) with your name, e-mail (if desired) and GitHub (if desired / applicable), as you would like them displayed. Additionally, please indicate if you are willing to dual license your old contributions under Apache 2.0.
+This is a (possibly incomplete) list of all the contributors to python-dateutil,
+initially generated from the git author metadata. The details of their specific
+contributions can be found in the git history.
+
+Prior to 2017-12-01, the library was licensed solely under the BSD 3-clause
+license, all contributions on or after 2017-12-01 are dual-licensed between
+Apache 2.0 and BSD 3-clause. In the list below, anyone whose name is marked with
+**R** has agreed to re-license their previously submitted code under Apache 2.0.
+Anyone whose name is marked with a **D** has only made contributions since the
+switch, and thus all their contributions are dual-licensed.
+
+## Contributors (alphabetical order)
+
+- Adam Chainz <adam@MASKED>
+- Adrien Cossa <cossa@MASKED>
+- Alec Nikolas Reiter <alecreiter@MASKED>
+- Alec Reiter <areiter@MASKED>
+- Alex Chamberlain (gh: @alexchamberlain) **D**
+- Alex Verdyan <verdyan@MASKED>
+- Alex Willmer <alex@moreati.org.uk> (gh: @moreati) **R**
+- Alexander Brugh <alexander.brugh@MASKED> (gh: @abrugh)
+- Alexander Shadchin <alexandr.shadchin@gmail.com> (gh: @shadchin) **D**
+- Alistair McMaster <alistair@MASKED> (gh: @alimcmaster1 ) **D**
+- Allison Quinlan <aquinlan82@gmail.com> (gh: @aquinlan) **D**
+- Andrew Bennett (gh: @andrewcbennett) **D**
+- Andrew Murray <radarhere@MASKED>
+- Arclight <arclight@MASKED> (gh: @arclightslavik)
+- Aritro Nandi <gurgenz221@gmail.com> (gh: @gurgenz221) **D**
+- Bernat Gabor <bgabor8@bloomberg.net> (gh: @gaborbernat) **D**
+- Bradlee Speice <bradlee@speice.io> (gh: @bspeice) **D**
+- Brandon W Maister <quodlibetor@MASKED>
+- Brock Mendel <jbrockmendel@MASKED> (gh: @jbrockmendel) **R**
+- Brook Li (gh: @absreim) **D**
+- Carlos <carlosxl@MASKED>
+- Cheuk Ting Ho <cheukting.ho@gmail.com> (gh: @cheukting) **D**
+- Chris van den Berg (gh: bergvca) **D**
+- Christopher Cordero <ccordero@pm.me> (gh: cs-cordero) **D**
+- Christopher Corley <cscorley@MASKED>
+- Claudio Canepa <ccanepacc@MASKED>
+- Corey Girard <corey.r.girard@gmail.com> (gh: @coreygirard) **D**
+- Cosimo Lupo <cosimo@anthrotype.com> (gh: @anthrotype) **D**
+- Daniel Lemm (gh: @ffe4) **D**
+- Daniel Lepage <dplepage@MASKED>
+- David Lehrian <david@MASKED>
+- Dean Allsopp (gh: @daplantagenet) **D**
+- Dominik Kozaczko <dominik@MASKED>
+- Elliot Hughes <elliot.hughes@gmail.com> (gh: @ElliotJH) **D**
+- Elvis Pranskevichus <el@MASKED>
+- Fan Huang <fanhuang.scb@gmail.com>(gh: @fhuang5) **D**
+- Florian Rathgeber (gh: @kynan) **D**
+- Gabriel Bianconi <gabriel@MASKED> (gh: @GabrielBianconi) **D**
+- Gabriel Poesia <gabriel.poesia@MASKED>
+- Gökçen Nurlu <gnurlu1@bloomberg.net> (gh: @gokcennurlu) **D**
+- Grant Garrett-Grossman <grantlycee@gmail.com> (gh: @FakeNameSE) **D**
+- Gustavo Niemeyer <gustavo@niemeyer.net> (gh: @niemeyer)
+- Holger Joukl <holger.joukl@MASKED> (gh: @hjoukl)
+- Hugo van Kemenade (gh: @hugovk) **D**
+- Igor <mrigor83@MASKED>
+- Ionuț Ciocîrlan <jdxlark@MASKED>
+- Jacqueline Chen <jacqueline415@outlook.com> (gh: @jachen20) **D**
+- Jake Chorley (gh: @jakec-github) **D**
+- Jan Studený <jendas1@MASKED>
+- Jay Weisskopf <jay@jayschwa.net> (gh: @jayschwa) **D**
+- Jitesh <jitesh@MASKED>
+- John Purviance <jpurviance@MASKED> (gh @jpurviance) **D**
+- Jon Dufresne <jon.dufresne@MASKED> (gh: @jdufresne) **R**
+- Jonas Neubert <jonas@MASKED> (gh: @jonemo) **R**
+- Kevin Nguyen <kvn219@MASKED> **D**
+- Kirit Thadaka <kirit.thadaka@gmail.com> (gh: @kirit93) **D**
+- Kubilay Kocak <koobs@MASKED>
+- Laszlo Kiss Kollar <kiss.kollar.laszlo@MASKED> (gh: @lkollar) **D**
+- Lauren Oldja <oldja@MASKED> (gh: @loldja) **D**
+- Luca Ferocino <luca.ferox@MASKED> (gh: @lucaferocino) **D**
+- Mario Corchero <mcorcherojim@MASKED> (gh: @mariocj89) **R**
+- Mark Bailey <msb@MASKED> **D**
+- Mateusz Dziedzic (gh: @m-dz) **D**
+- Matt Cooper <vtbassmatt@MASKED> (gh: @vtbassmatt) **D**
+- Matthew Schinckel <matt@MASKED>
+- Max Shenfield <shenfieldmax@MASKED>
+- Maxime Lorant <maxime.lorant@MASKED>
+- Michael Aquilina <michaelaquilina@MASKED> (gh: @MichaelAquilina)
+- Michael J. Schultz <mjschultz@MASKED>
+- Michael Käufl (gh: @michael-k)
+- Mike Gilbert <floppym@MASKED>
+- Nicholas Herrriot <Nicholas.Herriot@gmail.com> **D**
+- Nicolas Évrard (gh: @nicoe) **D**
+- Nick Smith <nick.smith@MASKED>
+- Orson Adams <orson.network@MASKED> (gh: @parsethis) **D**
+- Paul Brown (gh: @pawl) **D**
+- Paul Dickson (gh @prdickson) **D**
+- Paul Ganssle <paul@ganssle.io> (gh: @pganssle) **R**
+- Pascal van Kooten <kootenpv@MASKED> (gh: @kootenpv) **R**
+- Pavel Ponomarev <comrad.awsum@MASKED>
+- Peter Bieringer <pb@MASKED>
+- Pierre Gergondet <pierre.gergondet@MASKED> (gh: @gergondet) **D**
+- Quentin Pradet <quentin@MASKED>
+- Raymond Cha (gh: @weatherpattern) **D**
+- Ridhi Mahajan <ridhikmahajan@MASKED> **D**
+- Robin Henriksson Törnström <gh: @MrRawbin> **D**
+- Roy Williams <rwilliams@MASKED>
+- Rustem Saiargaliev (gh: @amureki) **D**
+- Satyabrat Bhol <satyabrat35@MASKED> (gh: @Satyabrat35) **D**
+- Savraj <savraj@MASKED>
+- Sergey Vishnikin <armicron@MASKED>
+- Sherry Zhou (gh: @cssherry) **D**
+- Siping Meng (gh: @smeng10) **D**
+- Stefan Bonchev **D**
+- Thierry Bastian <thierryb@MASKED>
+- Thomas A Caswell <tcaswell@MASKED> (gh: @tacaswell) **R**
+- Thomas Achtemichuk <tom@MASKED>
+- Thomas Kluyver <takowl@MASKED> (gh: @takluyver)
+- Tim Gates <tim.gates@iress.com> (gh: timgates42)
+- Tomasz Kluczkowski (gh: @Tomasz-Kluczkowski) **D**
+- Tomi Pieviläinen <tomi.pievilainen@iki.fi>
+- Unrud <Unrud@MASKED> (gh: @unrud)
+- Xavier Lapointe <lapointe.xavier@MASKED> (gh: @lapointexavier) **D**
+- X O <xo@MASKED>
+- Yaron de Leeuw <me@jarondl.net> (gh: @jarondl)
+- Yoney <alper_yoney@hotmail.com> **D**
+- Yuan Huang <huangy22@gmail.com> (gh: @huangy22) **D**
+- Zbigniew Jędrzejewski-Szmek <zbyszek@MASKED>
+- bachmann <bachmann.matt@MASKED>
+- bjv <brandon.vanvaerenbergh@MASKED> (@bjamesvERT)
+- gl <gl@MASKED>
+- gfyoung <gfyoung17@gmail.com> **D**
+- Labrys <labrys.git@gmail.com> (gh: @labrys) **R**
+- ms-boom <ms-boom@MASKED>
+- ryanss <ryanssdev@MASKED> (gh: @ryanss) **R**
+
+Unless someone has deliberately given permission to publish their e-mail, I have masked the domain names. If you are not on this list and believe you should be, or you *are* on this list and your information is inaccurate, please e-mail the current maintainer or the mailing list (dateutil@python.org) with your name, e-mail (if desired) and GitHub (if desired / applicable), as you would like them displayed. Additionally, please indicate if you are willing to dual license your old contributions under Apache 2.0.
diff --git a/contrib/python/dateutil/LICENSE b/contrib/python/dateutil/LICENSE
index 1e65815cf0..50e6fe0257 100644
--- a/contrib/python/dateutil/LICENSE
+++ b/contrib/python/dateutil/LICENSE
@@ -1,54 +1,54 @@
-Copyright 2017- Paul Ganssle <paul@ganssle.io>
-Copyright 2017- dateutil contributors (see AUTHORS file)
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
-The above license applies to all contributions after 2017-12-01, as well as
-all contributions that have been re-licensed (see AUTHORS file for the list of
-contributors who have re-licensed their code).
---------------------------------------------------------------------------------
-dateutil - Extensions to the standard Python datetime module.
-
-Copyright (c) 2003-2011 - Gustavo Niemeyer <gustavo@niemeyer.net>
-Copyright (c) 2012-2014 - Tomi Pieviläinen <tomi.pievilainen@iki.fi>
-Copyright (c) 2014-2016 - Yaron de Leeuw <me@jarondl.net>
-Copyright (c) 2015- - Paul Ganssle <paul@ganssle.io>
-Copyright (c) 2015- - dateutil contributors (see AUTHORS file)
-
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above copyright notice,
- this list of conditions and the following disclaimer in the documentation
- and/or other materials provided with the distribution.
- * Neither the name of the copyright holder nor the names of its
- contributors may be used to endorse or promote products derived from
- this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
-CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
-PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
-LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-The above BSD License Applies to all code, even that also covered by Apache 2.0. \ No newline at end of file
+Copyright 2017- Paul Ganssle <paul@ganssle.io>
+Copyright 2017- dateutil contributors (see AUTHORS file)
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+The above license applies to all contributions after 2017-12-01, as well as
+all contributions that have been re-licensed (see AUTHORS file for the list of
+contributors who have re-licensed their code).
+--------------------------------------------------------------------------------
+dateutil - Extensions to the standard Python datetime module.
+
+Copyright (c) 2003-2011 - Gustavo Niemeyer <gustavo@niemeyer.net>
+Copyright (c) 2012-2014 - Tomi Pieviläinen <tomi.pievilainen@iki.fi>
+Copyright (c) 2014-2016 - Yaron de Leeuw <me@jarondl.net>
+Copyright (c) 2015- - Paul Ganssle <paul@ganssle.io>
+Copyright (c) 2015- - dateutil contributors (see AUTHORS file)
+
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+ * Neither the name of the copyright holder nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+The above BSD License Applies to all code, even that also covered by Apache 2.0. \ No newline at end of file
diff --git a/contrib/python/dateutil/README.rst b/contrib/python/dateutil/README.rst
index 106023b324..b7461b951f 100644
--- a/contrib/python/dateutil/README.rst
+++ b/contrib/python/dateutil/README.rst
@@ -1,11 +1,11 @@
dateutil - powerful extensions to datetime
==========================================
-|pypi| |support| |licence|
+|pypi| |support| |licence|
|gitter| |readthedocs|
-|travis| |appveyor| |pipelines| |coverage|
+|travis| |appveyor| |pipelines| |coverage|
.. |pypi| image:: https://img.shields.io/pypi/v/python-dateutil.svg?style=flat-square
:target: https://pypi.org/project/python-dateutil/
@@ -23,12 +23,12 @@ dateutil - powerful extensions to datetime
:target: https://ci.appveyor.com/project/dateutil/dateutil
:alt: appveyor build status
-.. |pipelines| image:: https://dev.azure.com/pythondateutilazure/dateutil/_apis/build/status/dateutil.dateutil?branchName=master
- :target: https://dev.azure.com/pythondateutilazure/dateutil/_build/latest?definitionId=1&branchName=master
- :alt: azure pipelines build status
-
-.. |coverage| image:: https://codecov.io/gh/dateutil/dateutil/branch/master/graphs/badge.svg?branch=master
- :target: https://codecov.io/gh/dateutil/dateutil?branch=master
+.. |pipelines| image:: https://dev.azure.com/pythondateutilazure/dateutil/_apis/build/status/dateutil.dateutil?branchName=master
+ :target: https://dev.azure.com/pythondateutilazure/dateutil/_build/latest?definitionId=1&branchName=master
+ :alt: azure pipelines build status
+
+.. |coverage| image:: https://codecov.io/gh/dateutil/dateutil/branch/master/graphs/badge.svg?branch=master
+ :target: https://codecov.io/gh/dateutil/dateutil?branch=master
:alt: Code coverage
.. |gitter| image:: https://badges.gitter.im/dateutil/dateutil.svg
@@ -46,13 +46,13 @@ dateutil - powerful extensions to datetime
The `dateutil` module provides powerful extensions to
the standard `datetime` module, available in Python.
-Installation
-============
-`dateutil` can be installed from PyPI using `pip` (note that the package name is
-different from the importable name)::
-
- pip install python-dateutil
+Installation
+============
+`dateutil` can be installed from PyPI using `pip` (note that the package name is
+different from the importable name)::
+ pip install python-dateutil
+
Download
========
dateutil is available on PyPI
@@ -63,14 +63,14 @@ https://dateutil.readthedocs.io/en/stable/
Code
====
-The code and issue tracker are hosted on GitHub:
+The code and issue tracker are hosted on GitHub:
https://github.com/dateutil/dateutil/
Features
========
* Computing of relative deltas (next month, next year,
- next Monday, last week of month, etc);
+ next Monday, last week of month, etc);
* Computing of relative deltas between two given
date and/or datetime objects;
* Computing of dates based on very flexible recurrence rules,
@@ -139,24 +139,24 @@ It is maintained by:
* Yaron de Leeuw <me@jarondl.net> 2014-2016
* Paul Ganssle <paul@ganssle.io> 2015-
-Starting with version 2.4.1 and running until 2.8.2, all source and binary
-distributions will be signed by a PGP key that has, at the very least, been
-signed by the key which made the previous release. A table of release signing
-keys can be found below:
+Starting with version 2.4.1 and running until 2.8.2, all source and binary
+distributions will be signed by a PGP key that has, at the very least, been
+signed by the key which made the previous release. A table of release signing
+keys can be found below:
=========== ============================
Releases Signing key fingerprint
=========== ============================
-2.4.1-2.8.2 `6B49 ACBA DCF6 BD1C A206 67AB CD54 FCE3 D964 BEFB`_
+2.4.1-2.8.2 `6B49 ACBA DCF6 BD1C A206 67AB CD54 FCE3 D964 BEFB`_
=========== ============================
-New releases *may* have signed tags, but binary and source distributions
-uploaded to PyPI will no longer have GPG signatures attached.
+New releases *may* have signed tags, but binary and source distributions
+uploaded to PyPI will no longer have GPG signatures attached.
Contact
=======
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
-conduct <https://www.python.org/psf/conduct/>`_.
+conduct <https://www.python.org/psf/conduct/>`_.
License
=======
diff --git a/contrib/python/dateutil/dateutil/_version.py b/contrib/python/dateutil/dateutil/_version.py
index b723056a75..1f875d99b3 100644
--- a/contrib/python/dateutil/dateutil/_version.py
+++ b/contrib/python/dateutil/dateutil/_version.py
@@ -1,5 +1,5 @@
# coding: utf-8
# file generated by setuptools_scm
# don't change, don't track in version control
-version = '2.8.2'
-version_tuple = (2, 8, 2)
+version = '2.8.2'
+version_tuple = (2, 8, 2)
diff --git a/contrib/python/dateutil/dateutil/easter.py b/contrib/python/dateutil/dateutil/easter.py
index f74d1f7442..9a200a7021 100644
--- a/contrib/python/dateutil/dateutil/easter.py
+++ b/contrib/python/dateutil/dateutil/easter.py
@@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
"""
-This module offers a generic Easter computing method for any given year, using
+This module offers a generic Easter computing method for any given year, using
Western, Orthodox or Julian algorithms.
"""
@@ -21,15 +21,15 @@ def easter(year, method=EASTER_WESTERN):
quoted in "Explanatory Supplement to the Astronomical
Almanac", P. Kenneth Seidelmann, editor.
- This algorithm implements three different Easter
+ This algorithm implements three different Easter
calculation methods:
- 1. Original calculation in Julian calendar, valid in
- dates after 326 AD
- 2. Original method, with date converted to Gregorian
- calendar, valid in years 1583 to 4099
- 3. Revised method, in Gregorian calendar, valid in
- years 1583 to 4099 as well
+ 1. Original calculation in Julian calendar, valid in
+ dates after 326 AD
+ 2. Original method, with date converted to Gregorian
+ calendar, valid in years 1583 to 4099
+ 3. Revised method, in Gregorian calendar, valid in
+ years 1583 to 4099 as well
These methods are represented by the constants:
diff --git a/contrib/python/dateutil/dateutil/parser/__init__.py b/contrib/python/dateutil/dateutil/parser/__init__.py
index d174b0e4dc..676f701184 100644
--- a/contrib/python/dateutil/dateutil/parser/__init__.py
+++ b/contrib/python/dateutil/dateutil/parser/__init__.py
@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
-from ._parser import parse, parser, parserinfo, ParserError
+from ._parser import parse, parser, parserinfo, ParserError
from ._parser import DEFAULTPARSER, DEFAULTTZPARSER
from ._parser import UnknownTimezoneWarning
@@ -9,7 +9,7 @@ from .isoparser import isoparser, isoparse
__all__ = ['parse', 'parser', 'parserinfo',
'isoparse', 'isoparser',
- 'ParserError',
+ 'ParserError',
'UnknownTimezoneWarning']
@@ -52,8 +52,8 @@ def __deprecate_private_class(c):
return private_class
-from ._parser import _timelex, _resultbase
-from ._parser import _tzparser, _parsetz
+from ._parser import _timelex, _resultbase
+from ._parser import _tzparser, _parsetz
_timelex = __deprecate_private_class(_timelex)
_tzparser = __deprecate_private_class(_tzparser)
diff --git a/contrib/python/dateutil/dateutil/parser/_parser.py b/contrib/python/dateutil/dateutil/parser/_parser.py
index 37d1663b2f..4436fd363e 100644
--- a/contrib/python/dateutil/dateutil/parser/_parser.py
+++ b/contrib/python/dateutil/dateutil/parser/_parser.py
@@ -20,11 +20,11 @@ value falls back to the end of the month.
Additional resources about date/time string formats can be found below:
- `A summary of the international standard date and time notation
- <https://www.cl.cam.ac.uk/~mgk25/iso-time.html>`_
-- `W3C Date and Time Formats <https://www.w3.org/TR/NOTE-datetime>`_
+ <https://www.cl.cam.ac.uk/~mgk25/iso-time.html>`_
+- `W3C Date and Time Formats <https://www.w3.org/TR/NOTE-datetime>`_
- `Time Formats (Planetary Rings Node) <https://pds-rings.seti.org:443/tools/time_formats.html>`_
- `CPAN ParseDate module
- <https://metacpan.org/pod/release/MUIR/Time-modules-2013.0912/lib/Time/ParseDate.pm>`_
+ <https://metacpan.org/pod/release/MUIR/Time-modules-2013.0912/lib/Time/ParseDate.pm>`_
- `Java SimpleDateFormat Class
<https://docs.oracle.com/javase/6/docs/api/java/text/SimpleDateFormat.html>`_
"""
@@ -40,7 +40,7 @@ from calendar import monthrange
from io import StringIO
import six
-from six import integer_types, text_type
+from six import integer_types, text_type
from decimal import Decimal
@@ -49,7 +49,7 @@ from warnings import warn
from .. import relativedelta
from .. import tz
-__all__ = ["parse", "parserinfo", "ParserError"]
+__all__ = ["parse", "parserinfo", "ParserError"]
# TODO: pandas.core.tools.datetimes imports this explicitly. Might be worth
@@ -60,8 +60,8 @@ class _timelex(object):
_split_decimal = re.compile("([.,])")
def __init__(self, instream):
- if isinstance(instream, (bytes, bytearray)):
- instream = instream.decode()
+ if isinstance(instream, (bytes, bytearray)):
+ instream = instream.decode()
if isinstance(instream, text_type):
instream = StringIO(instream)
@@ -285,7 +285,7 @@ class parserinfo(object):
("s", "second", "seconds")]
AMPM = [("am", "a"),
("pm", "p")]
- UTCZONE = ["UTC", "GMT", "Z", "z"]
+ UTCZONE = ["UTC", "GMT", "Z", "z"]
PERTAIN = ["of"]
TZOFFSET = {}
# TODO: ERA = ["AD", "BC", "CE", "BCE", "Stardate",
@@ -382,8 +382,8 @@ class parserinfo(object):
if res.year is not None:
res.year = self.convertyear(res.year, res.century_specified)
- if ((res.tzoffset == 0 and not res.tzname) or
- (res.tzname == 'Z' or res.tzname == 'z')):
+ if ((res.tzoffset == 0 and not res.tzname) or
+ (res.tzname == 'Z' or res.tzname == 'z')):
res.tzname = "UTC"
res.tzoffset = 0
elif res.tzoffset != 0 and res.tzname and self.utczone(res.tzname):
@@ -417,7 +417,7 @@ class _ymd(list):
elif not self.has_month:
return 1 <= value <= 31
elif not self.has_year:
- # Be permissive, assume leap year
+ # Be permissive, assume leap year
month = self[self.mstridx]
return 1 <= value <= monthrange(2000, month)[1]
else:
@@ -533,7 +533,7 @@ class _ymd(list):
year, month, day = self
else:
# 01-Jan-01
- # Give precedence to day-first, since
+ # Give precedence to day-first, since
# two-digit years is usually hand-written.
day, month, year = self
@@ -620,7 +620,7 @@ class parser(object):
first element being a :class:`datetime.datetime` object, the second
a tuple containing the fuzzy tokens.
- :raises ParserError:
+ :raises ParserError:
Raised for invalid or unknown string format, if the provided
:class:`tzinfo` is not in a valid format, or if an invalid date
would be created.
@@ -640,15 +640,15 @@ class parser(object):
res, skipped_tokens = self._parse(timestr, **kwargs)
if res is None:
- raise ParserError("Unknown string format: %s", timestr)
+ raise ParserError("Unknown string format: %s", timestr)
if len(res) == 0:
- raise ParserError("String does not contain a date: %s", timestr)
+ raise ParserError("String does not contain a date: %s", timestr)
- try:
- ret = self._build_naive(res, default)
- except ValueError as e:
- six.raise_from(ParserError(str(e) + ": %s", timestr), e)
+ try:
+ ret = self._build_naive(res, default)
+ except ValueError as e:
+ six.raise_from(ParserError(str(e) + ": %s", timestr), e)
if not ignoretz:
ret = self._build_tzaware(ret, res, tzinfos)
@@ -1019,7 +1019,7 @@ class parser(object):
hms_idx = idx + 2
elif idx > 0 and info.hms(tokens[idx-1]) is not None:
- # There is a "h", "m", or "s" preceding this token. Since neither
+ # There is a "h", "m", or "s" preceding this token. Since neither
# of the previous cases was hit, there is no label following this
# token, so we use the previous label.
# e.g. the "04" in "12h04"
@@ -1058,8 +1058,8 @@ class parser(object):
tzname is None and
tzoffset is None and
len(token) <= 5 and
- (all(x in string.ascii_uppercase for x in token)
- or token in self.info.UTCZONE))
+ (all(x in string.ascii_uppercase for x in token)
+ or token in self.info.UTCZONE))
def _ampm_valid(self, hour, ampm, fuzzy):
"""
@@ -1099,7 +1099,7 @@ class parser(object):
def _parse_min_sec(self, value):
# TODO: Every usage of this function sets res.second to the return
# value. Are there any cases where second will be returned as None and
- # we *don't* want to set res.second = None?
+ # we *don't* want to set res.second = None?
minute = int(value)
second = None
@@ -1126,36 +1126,36 @@ class parser(object):
return (new_idx, hms)
- # ------------------------------------------------------------------
- # Handling for individual tokens. These are kept as methods instead
- # of functions for the sake of customizability via subclassing.
-
- def _parsems(self, value):
- """Parse a I[.F] seconds value into (seconds, microseconds)."""
- if "." not in value:
- return int(value), 0
- else:
- i, f = value.split(".")
- return int(i), int(f.ljust(6, "0")[:6])
-
- def _to_decimal(self, val):
- try:
- decimal_value = Decimal(val)
- # See GH 662, edge case, infinite value should not be converted
- # via `_to_decimal`
- if not decimal_value.is_finite():
- raise ValueError("Converted decimal value is infinite or NaN")
- except Exception as e:
- msg = "Could not convert %s to decimal" % val
- six.raise_from(ValueError(msg), e)
- else:
- return decimal_value
-
- # ------------------------------------------------------------------
- # Post-Parsing construction of datetime output. These are kept as
- # methods instead of functions for the sake of customizability via
- # subclassing.
-
+ # ------------------------------------------------------------------
+ # Handling for individual tokens. These are kept as methods instead
+ # of functions for the sake of customizability via subclassing.
+
+ def _parsems(self, value):
+ """Parse a I[.F] seconds value into (seconds, microseconds)."""
+ if "." not in value:
+ return int(value), 0
+ else:
+ i, f = value.split(".")
+ return int(i), int(f.ljust(6, "0")[:6])
+
+ def _to_decimal(self, val):
+ try:
+ decimal_value = Decimal(val)
+ # See GH 662, edge case, infinite value should not be converted
+ # via `_to_decimal`
+ if not decimal_value.is_finite():
+ raise ValueError("Converted decimal value is infinite or NaN")
+ except Exception as e:
+ msg = "Could not convert %s to decimal" % val
+ six.raise_from(ValueError(msg), e)
+ else:
+ return decimal_value
+
+ # ------------------------------------------------------------------
+ # Post-Parsing construction of datetime output. These are kept as
+ # methods instead of functions for the sake of customizability via
+ # subclassing.
+
def _build_tzinfo(self, tzinfos, tzname, tzoffset):
if callable(tzinfos):
tzdata = tzinfos(tzname, tzoffset)
@@ -1169,9 +1169,9 @@ class parser(object):
tzinfo = tz.tzstr(tzdata)
elif isinstance(tzdata, integer_types):
tzinfo = tz.tzoffset(tzname, tzdata)
- else:
- raise TypeError("Offset must be tzinfo subclass, tz string, "
- "or int offset.")
+ else:
+ raise TypeError("Offset must be tzinfo subclass, tz string, "
+ "or int offset.")
return tzinfo
def _build_tzaware(self, naive, res, tzinfos):
@@ -1189,10 +1189,10 @@ class parser(object):
# This is mostly relevant for winter GMT zones parsed in the UK
if (aware.tzname() != res.tzname and
res.tzname in self.info.UTCZONE):
- aware = aware.replace(tzinfo=tz.UTC)
+ aware = aware.replace(tzinfo=tz.UTC)
elif res.tzoffset == 0:
- aware = naive.replace(tzinfo=tz.UTC)
+ aware = naive.replace(tzinfo=tz.UTC)
elif res.tzoffset:
aware = naive.replace(tzinfo=tz.tzoffset(res.tzname, res.tzoffset))
@@ -1247,23 +1247,23 @@ class parser(object):
return dt
- def _recombine_skipped(self, tokens, skipped_idxs):
- """
- >>> tokens = ["foo", " ", "bar", " ", "19June2000", "baz"]
- >>> skipped_idxs = [0, 1, 2, 5]
- >>> _recombine_skipped(tokens, skipped_idxs)
- ["foo bar", "baz"]
- """
- skipped_tokens = []
- for i, idx in enumerate(sorted(skipped_idxs)):
- if i > 0 and idx - 1 == skipped_idxs[i - 1]:
- skipped_tokens[-1] = skipped_tokens[-1] + tokens[idx]
- else:
- skipped_tokens.append(tokens[idx])
-
- return skipped_tokens
-
-
+ def _recombine_skipped(self, tokens, skipped_idxs):
+ """
+ >>> tokens = ["foo", " ", "bar", " ", "19June2000", "baz"]
+ >>> skipped_idxs = [0, 1, 2, 5]
+ >>> _recombine_skipped(tokens, skipped_idxs)
+ ["foo bar", "baz"]
+ """
+ skipped_tokens = []
+ for i, idx in enumerate(sorted(skipped_idxs)):
+ if i > 0 and idx - 1 == skipped_idxs[i - 1]:
+ skipped_tokens[-1] = skipped_tokens[-1] + tokens[idx]
+ else:
+ skipped_tokens.append(tokens[idx])
+
+ return skipped_tokens
+
+
DEFAULTPARSER = parser()
@@ -1353,10 +1353,10 @@ def parse(timestr, parserinfo=None, **kwargs):
first element being a :class:`datetime.datetime` object, the second
a tuple containing the fuzzy tokens.
- :raises ParserError:
- Raised for invalid or unknown string formats, if the provided
- :class:`tzinfo` is not in a valid format, or if an invalid date would
- be created.
+ :raises ParserError:
+ Raised for invalid or unknown string formats, if the provided
+ :class:`tzinfo` is not in a valid format, or if an invalid date would
+ be created.
:raises OverflowError:
Raised if the parsed date exceeds the largest valid C integer on
@@ -1585,29 +1585,29 @@ DEFAULTTZPARSER = _tzparser()
def _parsetz(tzstr):
return DEFAULTTZPARSER.parse(tzstr)
-
-class ParserError(ValueError):
- """Exception subclass used for any failure to parse a datetime string.
-
- This is a subclass of :py:exc:`ValueError`, and should be raised any time
- earlier versions of ``dateutil`` would have raised ``ValueError``.
-
- .. versionadded:: 2.8.1
- """
- def __str__(self):
- try:
- return self.args[0] % self.args[1:]
- except (TypeError, IndexError):
- return super(ParserError, self).__str__()
-
- def __repr__(self):
- args = ", ".join("'%s'" % arg for arg in self.args)
- return "%s(%s)" % (self.__class__.__name__, args)
-
-
+
+class ParserError(ValueError):
+ """Exception subclass used for any failure to parse a datetime string.
+
+ This is a subclass of :py:exc:`ValueError`, and should be raised any time
+ earlier versions of ``dateutil`` would have raised ``ValueError``.
+
+ .. versionadded:: 2.8.1
+ """
+ def __str__(self):
+ try:
+ return self.args[0] % self.args[1:]
+ except (TypeError, IndexError):
+ return super(ParserError, self).__str__()
+
+ def __repr__(self):
+ args = ", ".join("'%s'" % arg for arg in self.args)
+ return "%s(%s)" % (self.__class__.__name__, args)
+
+
class UnknownTimezoneWarning(RuntimeWarning):
- """Raised when the parser finds a timezone it cannot parse into a tzinfo.
-
- .. versionadded:: 2.7.0
- """
+ """Raised when the parser finds a timezone it cannot parse into a tzinfo.
+
+ .. versionadded:: 2.7.0
+ """
# vim:ts=4:sw=4:et
diff --git a/contrib/python/dateutil/dateutil/parser/isoparser.py b/contrib/python/dateutil/dateutil/parser/isoparser.py
index 5d7bee3800..3c5fd07b22 100644
--- a/contrib/python/dateutil/dateutil/parser/isoparser.py
+++ b/contrib/python/dateutil/dateutil/parser/isoparser.py
@@ -88,13 +88,13 @@ class isoparser(object):
- ``hh``
- ``hh:mm`` or ``hhmm``
- ``hh:mm:ss`` or ``hhmmss``
- - ``hh:mm:ss.ssssss`` (Up to 6 sub-second digits)
+ - ``hh:mm:ss.ssssss`` (Up to 6 sub-second digits)
Midnight is a special case for `hh`, as the standard supports both
- 00:00 and 24:00 as a representation. The decimal separator can be
- either a dot or a comma.
-
+ 00:00 and 24:00 as a representation. The decimal separator can be
+ either a dot or a comma.
+
.. caution::
Support for fractional components other than seconds is part of the
@@ -139,10 +139,10 @@ class isoparser(object):
else:
raise ValueError('String contains unknown ISO components')
- if len(components) > 3 and components[3] == 24:
- components[3] = 0
- return datetime(*components) + timedelta(days=1)
-
+ if len(components) > 3 and components[3] == 24:
+ components[3] = 0
+ return datetime(*components) + timedelta(days=1)
+
return datetime(*components)
@_takes_ascii
@@ -159,7 +159,7 @@ class isoparser(object):
components, pos = self._parse_isodate(datestr)
if pos < len(datestr):
raise ValueError('String contains unknown ISO ' +
- 'components: {!r}'.format(datestr.decode('ascii')))
+ 'components: {!r}'.format(datestr.decode('ascii')))
return date(*components)
@_takes_ascii
@@ -173,10 +173,10 @@ class isoparser(object):
:return:
Returns a :class:`datetime.time` object
"""
- components = self._parse_isotime(timestr)
- if components[0] == 24:
- components[0] = 0
- return time(*components)
+ components = self._parse_isotime(timestr)
+ if components[0] == 24:
+ components[0] = 0
+ return time(*components)
@_takes_ascii
def parse_tzstr(self, tzstr, zero_as_utc=True):
@@ -201,7 +201,7 @@ class isoparser(object):
# Constants
_DATE_SEP = b'-'
_TIME_SEP = b':'
- _FRACTION_REGEX = re.compile(b'[\\.,]([0-9]+)')
+ _FRACTION_REGEX = re.compile(b'[\\.,]([0-9]+)')
def _parse_isodate(self, dt_str):
try:
@@ -333,42 +333,42 @@ class isoparser(object):
pos = 0
comp = -1
- if len_str < 2:
+ if len_str < 2:
raise ValueError('ISO time too short')
- has_sep = False
+ has_sep = False
while pos < len_str and comp < 5:
comp += 1
- if timestr[pos:pos + 1] in b'-+Zz':
+ if timestr[pos:pos + 1] in b'-+Zz':
# Detect time zone boundary
components[-1] = self._parse_tzstr(timestr[pos:])
pos = len_str
break
- if comp == 1 and timestr[pos:pos+1] == self._TIME_SEP:
- has_sep = True
- pos += 1
- elif comp == 2 and has_sep:
- if timestr[pos:pos+1] != self._TIME_SEP:
- raise ValueError('Inconsistent use of colon separator')
- pos += 1
-
+ if comp == 1 and timestr[pos:pos+1] == self._TIME_SEP:
+ has_sep = True
+ pos += 1
+ elif comp == 2 and has_sep:
+ if timestr[pos:pos+1] != self._TIME_SEP:
+ raise ValueError('Inconsistent use of colon separator')
+ pos += 1
+
if comp < 3:
# Hour, minute, second
components[comp] = int(timestr[pos:pos + 2])
pos += 2
if comp == 3:
- # Fraction of a second
- frac = self._FRACTION_REGEX.match(timestr[pos:])
- if not frac:
+ # Fraction of a second
+ frac = self._FRACTION_REGEX.match(timestr[pos:])
+ if not frac:
continue
- us_str = frac.group(1)[:6] # Truncate to microseconds
+ us_str = frac.group(1)[:6] # Truncate to microseconds
components[comp] = int(us_str) * 10**(6 - len(us_str))
- pos += len(frac.group())
+ pos += len(frac.group())
if pos < len_str:
raise ValueError('Unused components in ISO string')
@@ -381,8 +381,8 @@ class isoparser(object):
return components
def _parse_tzstr(self, tzstr, zero_as_utc=True):
- if tzstr == b'Z' or tzstr == b'z':
- return tz.UTC
+ if tzstr == b'Z' or tzstr == b'z':
+ return tz.UTC
if len(tzstr) not in {3, 5, 6}:
raise ValueError('Time zone offset must be 1, 3, 5 or 6 characters')
@@ -401,7 +401,7 @@ class isoparser(object):
minutes = int(tzstr[(4 if tzstr[3:4] == self._TIME_SEP else 3):])
if zero_as_utc and hours == 0 and minutes == 0:
- return tz.UTC
+ return tz.UTC
else:
if minutes > 59:
raise ValueError('Invalid minutes in time zone offset')
diff --git a/contrib/python/dateutil/dateutil/relativedelta.py b/contrib/python/dateutil/dateutil/relativedelta.py
index a9e85f7e6c..2791a42477 100644
--- a/contrib/python/dateutil/dateutil/relativedelta.py
+++ b/contrib/python/dateutil/dateutil/relativedelta.py
@@ -17,12 +17,12 @@ __all__ = ["relativedelta", "MO", "TU", "WE", "TH", "FR", "SA", "SU"]
class relativedelta(object):
"""
- The relativedelta type is designed to be applied to an existing datetime and
- can replace specific components of that datetime, or represents an interval
- of time.
-
- It is based on the specification of the excellent work done by M.-A. Lemburg
- in his
+ The relativedelta type is designed to be applied to an existing datetime and
+ can replace specific components of that datetime, or represents an interval
+ of time.
+
+ It is based on the specification of the excellent work done by M.-A. Lemburg
+ in his
`mx.DateTime <https://www.egenix.com/products/python/mxBase/mxDateTime/>`_ extension.
However, notice that this type does *NOT* implement the same algorithm as
his work. Do *NOT* expect it to behave like mx.DateTime's counterpart.
@@ -45,19 +45,19 @@ class relativedelta(object):
years, months, weeks, days, hours, minutes, seconds, microseconds:
Relative information, may be negative (argument is plural); adding
or subtracting a relativedelta with relative information performs
- the corresponding arithmetic operation on the original datetime value
+ the corresponding arithmetic operation on the original datetime value
with the information in the relativedelta.
weekday:
- One of the weekday instances (MO, TU, etc) available in the
- relativedelta module. These instances may receive a parameter N,
- specifying the Nth weekday, which could be positive or negative
- (like MO(+1) or MO(-2)). Not specifying it is the same as specifying
- +1. You can also use an integer, where 0=MO. This argument is always
- relative e.g. if the calculated date is already Monday, using MO(1)
- or MO(-1) won't change the day. To effectively make it absolute, use
- it in combination with the day argument (e.g. day=1, MO(1) for first
- Monday of the month).
+ One of the weekday instances (MO, TU, etc) available in the
+ relativedelta module. These instances may receive a parameter N,
+ specifying the Nth weekday, which could be positive or negative
+ (like MO(+1) or MO(-2)). Not specifying it is the same as specifying
+ +1. You can also use an integer, where 0=MO. This argument is always
+ relative e.g. if the calculated date is already Monday, using MO(1)
+ or MO(-1) won't change the day. To effectively make it absolute, use
+ it in combination with the day argument (e.g. day=1, MO(1) for first
+ Monday of the month).
leapdays:
Will add given days to the date found, if year is a leap
@@ -88,12 +88,12 @@ class relativedelta(object):
For example
- >>> from datetime import datetime
- >>> from dateutil.relativedelta import relativedelta, MO
+ >>> from datetime import datetime
+ >>> from dateutil.relativedelta import relativedelta, MO
>>> dt = datetime(2018, 4, 9, 13, 37, 0)
>>> delta = relativedelta(hours=25, day=1, weekday=MO(1))
- >>> dt + delta
- datetime.datetime(2018, 4, 2, 14, 37)
+ >>> dt + delta
+ datetime.datetime(2018, 4, 2, 14, 37)
First, the day is set to 1 (the first of the month), then 25 hours
are added, to get to the 2nd day and 14th hour, finally the
@@ -285,7 +285,7 @@ class relativedelta(object):
values for the relative attributes.
>>> relativedelta(days=1.5, hours=2).normalized()
- relativedelta(days=+1, hours=+14)
+ relativedelta(days=+1, hours=+14)
:return:
Returns a :class:`dateutil.relativedelta.relativedelta` object.
diff --git a/contrib/python/dateutil/dateutil/rrule.py b/contrib/python/dateutil/dateutil/rrule.py
index b3203393c6..ca3b7d7e28 100644
--- a/contrib/python/dateutil/dateutil/rrule.py
+++ b/contrib/python/dateutil/dateutil/rrule.py
@@ -5,26 +5,26 @@ the recurrence rules documented in the
`iCalendar RFC <https://tools.ietf.org/html/rfc5545>`_,
including support for caching of results.
"""
-import calendar
-import datetime
-import heapq
+import calendar
+import datetime
+import heapq
import itertools
import re
import sys
-from functools import wraps
-# For warning about deprecation of until and count
-from warnings import warn
+from functools import wraps
+# For warning about deprecation of until and count
+from warnings import warn
-from six import advance_iterator, integer_types
+from six import advance_iterator, integer_types
from six.moves import _thread, range
from ._common import weekday as weekdaybase
-try:
- from math import gcd
-except ImportError:
- from fractions import gcd
+try:
+ from math import gcd
+except ImportError:
+ from fractions import gcd
__all__ = ["rrule", "rruleset", "rrulestr",
"YEARLY", "MONTHLY", "WEEKLY", "DAILY",
@@ -82,7 +82,7 @@ def _invalidates_cache(f):
Decorator for rruleset methods which may invalidate the
cached length.
"""
- @wraps(f)
+ @wraps(f)
def inner_func(self, *args, **kwargs):
rv = f(self, *args, **kwargs)
self._invalidate_cache()
@@ -179,7 +179,7 @@ class rrulebase(object):
return False
return False
- # __len__() introduces a large performance penalty.
+ # __len__() introduces a large performance penalty.
def count(self):
""" Returns the number of recurrences in this set. It will have go
trough the whole recurrence, if this hasn't been done before. """
@@ -354,26 +354,26 @@ class rrule(rrulebase):
from calendar.firstweekday(), and may be modified by
calendar.setfirstweekday().
:param count:
- If given, this determines how many occurrences will be generated.
+ If given, this determines how many occurrences will be generated.
.. note::
- As of version 2.5.0, the use of the keyword ``until`` in conjunction
- with ``count`` is deprecated, to make sure ``dateutil`` is fully
- compliant with `RFC-5545 Sec. 3.3.10 <https://tools.ietf.org/
- html/rfc5545#section-3.3.10>`_. Therefore, ``until`` and ``count``
- **must not** occur in the same call to ``rrule``.
+ As of version 2.5.0, the use of the keyword ``until`` in conjunction
+ with ``count`` is deprecated, to make sure ``dateutil`` is fully
+ compliant with `RFC-5545 Sec. 3.3.10 <https://tools.ietf.org/
+ html/rfc5545#section-3.3.10>`_. Therefore, ``until`` and ``count``
+ **must not** occur in the same call to ``rrule``.
:param until:
- If given, this must be a datetime instance specifying the upper-bound
+ If given, this must be a datetime instance specifying the upper-bound
limit of the recurrence. The last recurrence in the rule is the greatest
datetime that is less than or equal to the value specified in the
``until`` parameter.
.. note::
- As of version 2.5.0, the use of the keyword ``until`` in conjunction
- with ``count`` is deprecated, to make sure ``dateutil`` is fully
- compliant with `RFC-5545 Sec. 3.3.10 <https://tools.ietf.org/
- html/rfc5545#section-3.3.10>`_. Therefore, ``until`` and ``count``
- **must not** occur in the same call to ``rrule``.
+ As of version 2.5.0, the use of the keyword ``until`` in conjunction
+ with ``count`` is deprecated, to make sure ``dateutil`` is fully
+ compliant with `RFC-5545 Sec. 3.3.10 <https://tools.ietf.org/
+ html/rfc5545#section-3.3.10>`_. Therefore, ``until`` and ``count``
+ **must not** occur in the same call to ``rrule``.
:param bysetpos:
If given, it must be either an integer, or a sequence of integers,
positive or negative. Each given integer will specify an occurrence
@@ -436,7 +436,7 @@ class rrule(rrulebase):
if not dtstart:
if until and until.tzinfo:
dtstart = datetime.datetime.now(tz=until.tzinfo).replace(microsecond=0)
- else:
+ else:
dtstart = datetime.datetime.now().replace(microsecond=0)
elif not isinstance(dtstart, datetime.datetime):
dtstart = datetime.datetime.fromordinal(dtstart.toordinal())
@@ -1413,53 +1413,53 @@ class rruleset(rrulebase):
self._len = total
-
-
+
+
class _rrulestr(object):
- """ Parses a string representation of a recurrence rule or set of
- recurrence rules.
-
- :param s:
- Required, a string defining one or more recurrence rules.
-
- :param dtstart:
- If given, used as the default recurrence start if not specified in the
- rule string.
-
- :param cache:
- If set ``True`` caching of results will be enabled, improving
- performance of multiple queries considerably.
-
- :param unfold:
- If set ``True`` indicates that a rule string is split over more
- than one line and should be joined before processing.
-
- :param forceset:
- If set ``True`` forces a :class:`dateutil.rrule.rruleset` to
- be returned.
-
- :param compatible:
- If set ``True`` forces ``unfold`` and ``forceset`` to be ``True``.
-
- :param ignoretz:
- If set ``True``, time zones in parsed strings are ignored and a naive
- :class:`datetime.datetime` object is returned.
-
- :param tzids:
- If given, a callable or mapping used to retrieve a
- :class:`datetime.tzinfo` from a string representation.
- Defaults to :func:`dateutil.tz.gettz`.
-
- :param tzinfos:
- Additional time zone names / aliases which may be present in a string
- representation. See :func:`dateutil.parser.parse` for more
- information.
-
- :return:
- Returns a :class:`dateutil.rrule.rruleset` or
- :class:`dateutil.rrule.rrule`
- """
-
+ """ Parses a string representation of a recurrence rule or set of
+ recurrence rules.
+
+ :param s:
+ Required, a string defining one or more recurrence rules.
+
+ :param dtstart:
+ If given, used as the default recurrence start if not specified in the
+ rule string.
+
+ :param cache:
+ If set ``True`` caching of results will be enabled, improving
+ performance of multiple queries considerably.
+
+ :param unfold:
+ If set ``True`` indicates that a rule string is split over more
+ than one line and should be joined before processing.
+
+ :param forceset:
+ If set ``True`` forces a :class:`dateutil.rrule.rruleset` to
+ be returned.
+
+ :param compatible:
+ If set ``True`` forces ``unfold`` and ``forceset`` to be ``True``.
+
+ :param ignoretz:
+ If set ``True``, time zones in parsed strings are ignored and a naive
+ :class:`datetime.datetime` object is returned.
+
+ :param tzids:
+ If given, a callable or mapping used to retrieve a
+ :class:`datetime.tzinfo` from a string representation.
+ Defaults to :func:`dateutil.tz.gettz`.
+
+ :param tzinfos:
+ Additional time zone names / aliases which may be present in a string
+ representation. See :func:`dateutil.parser.parse` for more
+ information.
+
+ :return:
+ Returns a :class:`dateutil.rrule.rruleset` or
+ :class:`dateutil.rrule.rrule`
+ """
+
_freq_map = {"YEARLY": YEARLY,
"MONTHLY": MONTHLY,
"WEEKLY": WEEKLY,
@@ -1560,58 +1560,58 @@ class _rrulestr(object):
raise ValueError("invalid '%s': %s" % (name, value))
return rrule(dtstart=dtstart, cache=cache, **rrkwargs)
- def _parse_date_value(self, date_value, parms, rule_tzids,
- ignoretz, tzids, tzinfos):
- global parser
- if not parser:
- from dateutil import parser
-
- datevals = []
- value_found = False
- TZID = None
-
- for parm in parms:
- if parm.startswith("TZID="):
- try:
- tzkey = rule_tzids[parm.split('TZID=')[-1]]
- except KeyError:
- continue
- if tzids is None:
- from . import tz
- tzlookup = tz.gettz
- elif callable(tzids):
- tzlookup = tzids
- else:
- tzlookup = getattr(tzids, 'get', None)
- if tzlookup is None:
- msg = ('tzids must be a callable, mapping, or None, '
- 'not %s' % tzids)
- raise ValueError(msg)
-
- TZID = tzlookup(tzkey)
- continue
-
- # RFC 5445 3.8.2.4: The VALUE parameter is optional, but may be found
- # only once.
- if parm not in {"VALUE=DATE-TIME", "VALUE=DATE"}:
- raise ValueError("unsupported parm: " + parm)
- else:
- if value_found:
- msg = ("Duplicate value parameter found in: " + parm)
- raise ValueError(msg)
- value_found = True
-
- for datestr in date_value.split(','):
- date = parser.parse(datestr, ignoretz=ignoretz, tzinfos=tzinfos)
- if TZID is not None:
- if date.tzinfo is None:
- date = date.replace(tzinfo=TZID)
- else:
- raise ValueError('DTSTART/EXDATE specifies multiple timezone')
- datevals.append(date)
-
- return datevals
-
+ def _parse_date_value(self, date_value, parms, rule_tzids,
+ ignoretz, tzids, tzinfos):
+ global parser
+ if not parser:
+ from dateutil import parser
+
+ datevals = []
+ value_found = False
+ TZID = None
+
+ for parm in parms:
+ if parm.startswith("TZID="):
+ try:
+ tzkey = rule_tzids[parm.split('TZID=')[-1]]
+ except KeyError:
+ continue
+ if tzids is None:
+ from . import tz
+ tzlookup = tz.gettz
+ elif callable(tzids):
+ tzlookup = tzids
+ else:
+ tzlookup = getattr(tzids, 'get', None)
+ if tzlookup is None:
+ msg = ('tzids must be a callable, mapping, or None, '
+ 'not %s' % tzids)
+ raise ValueError(msg)
+
+ TZID = tzlookup(tzkey)
+ continue
+
+ # RFC 5445 3.8.2.4: The VALUE parameter is optional, but may be found
+ # only once.
+ if parm not in {"VALUE=DATE-TIME", "VALUE=DATE"}:
+ raise ValueError("unsupported parm: " + parm)
+ else:
+ if value_found:
+ msg = ("Duplicate value parameter found in: " + parm)
+ raise ValueError(msg)
+ value_found = True
+
+ for datestr in date_value.split(','):
+ date = parser.parse(datestr, ignoretz=ignoretz, tzinfos=tzinfos)
+ if TZID is not None:
+ if date.tzinfo is None:
+ date = date.replace(tzinfo=TZID)
+ else:
+ raise ValueError('DTSTART/EXDATE specifies multiple timezone')
+ datevals.append(date)
+
+ return datevals
+
def _parse_rfc(self, s,
dtstart=None,
cache=False,
@@ -1684,18 +1684,18 @@ class _rrulestr(object):
raise ValueError("unsupported EXRULE parm: "+parm)
exrulevals.append(value)
elif name == "EXDATE":
- exdatevals.extend(
- self._parse_date_value(value, parms,
- TZID_NAMES, ignoretz,
- tzids, tzinfos)
- )
+ exdatevals.extend(
+ self._parse_date_value(value, parms,
+ TZID_NAMES, ignoretz,
+ tzids, tzinfos)
+ )
elif name == "DTSTART":
- dtvals = self._parse_date_value(value, parms, TZID_NAMES,
- ignoretz, tzids, tzinfos)
- if len(dtvals) != 1:
- raise ValueError("Multiple DTSTART values specified:" +
- value)
- dtstart = dtvals[0]
+ dtvals = self._parse_date_value(value, parms, TZID_NAMES,
+ ignoretz, tzids, tzinfos)
+ if len(dtvals) != 1:
+ raise ValueError("Multiple DTSTART values specified:" +
+ value)
+ dtstart = dtvals[0]
else:
raise ValueError("unsupported property: "+name)
if (forceset or len(rrulevals) > 1 or rdatevals
@@ -1717,7 +1717,7 @@ class _rrulestr(object):
ignoretz=ignoretz,
tzinfos=tzinfos))
for value in exdatevals:
- rset.exdate(value)
+ rset.exdate(value)
if compatible and dtstart:
rset.rdate(dtstart)
return rset
diff --git a/contrib/python/dateutil/dateutil/test/_common.py b/contrib/python/dateutil/dateutil/test/_common.py
index b8d2047374..dddd8dc9e7 100644
--- a/contrib/python/dateutil/dateutil/test/_common.py
+++ b/contrib/python/dateutil/dateutil/test/_common.py
@@ -6,7 +6,7 @@ import warnings
import tempfile
import pickle
-import pytest
+import pytest
class PicklableMixin(object):
@@ -69,12 +69,12 @@ class TZContextBase(object):
Class method used to query whether or not this class allows time zone
changes.
"""
- guard = bool(os.environ.get(cls._guard_var_name, False))
+ guard = bool(os.environ.get(cls._guard_var_name, False))
# _guard_allows_change gives the "default" behavior - if True, the
# guard is overcoming a block. If false, the guard is causing a block.
# Whether tz_change is allowed is therefore the XNOR of the two.
- return guard == cls._guard_allows_change
+ return guard == cls._guard_allows_change
@classmethod
def tz_change_disallowed_message(cls):
@@ -87,12 +87,12 @@ class TZContextBase(object):
def __enter__(self):
if not self.tz_change_allowed():
- msg = self.tz_change_disallowed_message()
- pytest.skip(msg)
-
- # If this is used outside of a test suite, we still want an error.
- raise ValueError(msg) # pragma: no cover
+ msg = self.tz_change_disallowed_message()
+ pytest.skip(msg)
+ # If this is used outside of a test suite, we still want an error.
+ raise ValueError(msg) # pragma: no cover
+
self._old_tz = self.get_current_tz()
self.set_current_tz(self.tzval)
diff --git a/contrib/python/dateutil/dateutil/test/conftest.py b/contrib/python/dateutil/dateutil/test/conftest.py
index 78ed70acb3..a7e4a27bf1 100644
--- a/contrib/python/dateutil/dateutil/test/conftest.py
+++ b/contrib/python/dateutil/dateutil/test/conftest.py
@@ -1,41 +1,41 @@
-import os
-import pytest
-
-
-# Configure pytest to ignore xfailing tests
-# See: https://stackoverflow.com/a/53198349/467366
-def pytest_collection_modifyitems(items):
- for item in items:
- marker_getter = getattr(item, 'get_closest_marker', None)
-
- # Python 3.3 support
- if marker_getter is None:
- marker_getter = item.get_marker
-
- marker = marker_getter('xfail')
-
- # Need to query the args because conditional xfail tests still have
- # the xfail mark even if they are not expected to fail
- if marker and (not marker.args or marker.args[0]):
- item.add_marker(pytest.mark.no_cover)
-
-
-def set_tzpath():
- """
- Sets the TZPATH variable if it's specified in an environment variable.
- """
- tzpath = os.environ.get('DATEUTIL_TZPATH', None)
-
- if tzpath is None:
- return
-
- path_components = tzpath.split(':')
-
- print("Setting TZPATH to {}".format(path_components))
-
- from dateutil import tz
- tz.TZPATHS.clear()
- tz.TZPATHS.extend(path_components)
-
-
-set_tzpath()
+import os
+import pytest
+
+
+# Configure pytest to ignore xfailing tests
+# See: https://stackoverflow.com/a/53198349/467366
+def pytest_collection_modifyitems(items):
+ for item in items:
+ marker_getter = getattr(item, 'get_closest_marker', None)
+
+ # Python 3.3 support
+ if marker_getter is None:
+ marker_getter = item.get_marker
+
+ marker = marker_getter('xfail')
+
+ # Need to query the args because conditional xfail tests still have
+ # the xfail mark even if they are not expected to fail
+ if marker and (not marker.args or marker.args[0]):
+ item.add_marker(pytest.mark.no_cover)
+
+
+def set_tzpath():
+ """
+ Sets the TZPATH variable if it's specified in an environment variable.
+ """
+ tzpath = os.environ.get('DATEUTIL_TZPATH', None)
+
+ if tzpath is None:
+ return
+
+ path_components = tzpath.split(':')
+
+ print("Setting TZPATH to {}".format(path_components))
+
+ from dateutil import tz
+ tz.TZPATHS.clear()
+ tz.TZPATHS.extend(path_components)
+
+
+set_tzpath()
diff --git a/contrib/python/dateutil/dateutil/test/property/test_isoparse_prop.py b/contrib/python/dateutil/dateutil/test/property/test_isoparse_prop.py
index f8e288f3d6..ec81ba5d22 100644
--- a/contrib/python/dateutil/dateutil/test/property/test_isoparse_prop.py
+++ b/contrib/python/dateutil/dateutil/test/property/test_isoparse_prop.py
@@ -7,7 +7,7 @@ from dateutil.parser import isoparse
import pytest
# Strategies
-TIME_ZONE_STRATEGY = st.sampled_from([None, tz.UTC] +
+TIME_ZONE_STRATEGY = st.sampled_from([None, tz.UTC] +
[tz.gettz(zname) for zname in ('US/Eastern', 'US/Pacific',
'Australia/Sydney', 'Europe/London')])
ASCII_STRATEGY = st.characters(max_codepoint=127)
diff --git a/contrib/python/dateutil/dateutil/test/property/test_tz_prop.py b/contrib/python/dateutil/dateutil/test/property/test_tz_prop.py
index ec6d271dcf..2966c99fa0 100644
--- a/contrib/python/dateutil/dateutil/test/property/test_tz_prop.py
+++ b/contrib/python/dateutil/dateutil/test/property/test_tz_prop.py
@@ -1,35 +1,35 @@
-from datetime import datetime, timedelta
-
-import pytest
-import six
-from hypothesis import assume, given
-from hypothesis import strategies as st
-
-from dateutil import tz as tz
-
-EPOCHALYPSE = datetime.fromtimestamp(2147483647)
-NEGATIVE_EPOCHALYPSE = datetime.fromtimestamp(0) - timedelta(seconds=2147483648)
-
-
-@pytest.mark.gettz
-@pytest.mark.parametrize("gettz_arg", [None, ""])
-# TODO: Remove bounds when GH #590 is resolved
-@given(
- dt=st.datetimes(
- min_value=NEGATIVE_EPOCHALYPSE, max_value=EPOCHALYPSE, timezones=st.just(tz.UTC),
- )
-)
-def test_gettz_returns_local(gettz_arg, dt):
- act_tz = tz.gettz(gettz_arg)
- if isinstance(act_tz, tz.tzlocal):
- return
-
- dt_act = dt.astimezone(tz.gettz(gettz_arg))
- if six.PY2:
- dt_exp = dt.astimezone(tz.tzlocal())
- else:
- dt_exp = dt.astimezone()
-
- assert dt_act == dt_exp
- assert dt_act.tzname() == dt_exp.tzname()
- assert dt_act.utcoffset() == dt_exp.utcoffset()
+from datetime import datetime, timedelta
+
+import pytest
+import six
+from hypothesis import assume, given
+from hypothesis import strategies as st
+
+from dateutil import tz as tz
+
+EPOCHALYPSE = datetime.fromtimestamp(2147483647)
+NEGATIVE_EPOCHALYPSE = datetime.fromtimestamp(0) - timedelta(seconds=2147483648)
+
+
+@pytest.mark.gettz
+@pytest.mark.parametrize("gettz_arg", [None, ""])
+# TODO: Remove bounds when GH #590 is resolved
+@given(
+ dt=st.datetimes(
+ min_value=NEGATIVE_EPOCHALYPSE, max_value=EPOCHALYPSE, timezones=st.just(tz.UTC),
+ )
+)
+def test_gettz_returns_local(gettz_arg, dt):
+ act_tz = tz.gettz(gettz_arg)
+ if isinstance(act_tz, tz.tzlocal):
+ return
+
+ dt_act = dt.astimezone(tz.gettz(gettz_arg))
+ if six.PY2:
+ dt_exp = dt.astimezone(tz.tzlocal())
+ else:
+ dt_exp = dt.astimezone()
+
+ assert dt_act == dt_exp
+ assert dt_act.tzname() == dt_exp.tzname()
+ assert dt_act.utcoffset() == dt_exp.utcoffset()
diff --git a/contrib/python/dateutil/dateutil/test/test_easter.py b/contrib/python/dateutil/dateutil/test/test_easter.py
index cf2ec7f287..688d802c0f 100644
--- a/contrib/python/dateutil/dateutil/test/test_easter.py
+++ b/contrib/python/dateutil/dateutil/test/test_easter.py
@@ -2,7 +2,7 @@ from dateutil.easter import easter
from dateutil.easter import EASTER_WESTERN, EASTER_ORTHODOX, EASTER_JULIAN
from datetime import date
-import pytest
+import pytest
# List of easters between 1990 and 2050
western_easter_dates = [
@@ -73,21 +73,21 @@ julian_easter_dates = [
]
-@pytest.mark.parametrize("easter_date", western_easter_dates)
-def test_easter_western(easter_date):
- assert easter_date == easter(easter_date.year, EASTER_WESTERN)
+@pytest.mark.parametrize("easter_date", western_easter_dates)
+def test_easter_western(easter_date):
+ assert easter_date == easter(easter_date.year, EASTER_WESTERN)
-@pytest.mark.parametrize("easter_date", orthodox_easter_dates)
-def test_easter_orthodox(easter_date):
- assert easter_date == easter(easter_date.year, EASTER_ORTHODOX)
+@pytest.mark.parametrize("easter_date", orthodox_easter_dates)
+def test_easter_orthodox(easter_date):
+ assert easter_date == easter(easter_date.year, EASTER_ORTHODOX)
-
-@pytest.mark.parametrize("easter_date", julian_easter_dates)
-def test_easter_julian(easter_date):
- assert easter_date == easter(easter_date.year, EASTER_JULIAN)
-
-
-def test_easter_bad_method():
- with pytest.raises(ValueError):
- easter(1975, 4)
+
+@pytest.mark.parametrize("easter_date", julian_easter_dates)
+def test_easter_julian(easter_date):
+ assert easter_date == easter(easter_date.year, EASTER_JULIAN)
+
+
+def test_easter_bad_method():
+ with pytest.raises(ValueError):
+ easter(1975, 4)
diff --git a/contrib/python/dateutil/dateutil/test/test_import_star.py b/contrib/python/dateutil/dateutil/test/test_import_star.py
index 2fb7098128..247fe911ce 100644
--- a/contrib/python/dateutil/dateutil/test/test_import_star.py
+++ b/contrib/python/dateutil/dateutil/test/test_import_star.py
@@ -1,8 +1,8 @@
"""Test for the "import *" functionality.
-As import * can be only done at module level, it has been added in a separate file
+As import * can be only done at module level, it has been added in a separate file
"""
-import pytest
+import pytest
prev_locals = list(locals())
from dateutil import *
@@ -11,23 +11,23 @@ new_locals = {name:value for name,value in locals().items()
new_locals.pop('prev_locals')
-@pytest.mark.import_star
-def test_imported_modules():
- """ Test that `from dateutil import *` adds modules in __all__ locally """
- import dateutil.easter
- import dateutil.parser
- import dateutil.relativedelta
- import dateutil.rrule
- import dateutil.tz
- import dateutil.utils
- import dateutil.zoneinfo
+@pytest.mark.import_star
+def test_imported_modules():
+ """ Test that `from dateutil import *` adds modules in __all__ locally """
+ import dateutil.easter
+ import dateutil.parser
+ import dateutil.relativedelta
+ import dateutil.rrule
+ import dateutil.tz
+ import dateutil.utils
+ import dateutil.zoneinfo
- assert dateutil.easter == new_locals.pop("easter")
- assert dateutil.parser == new_locals.pop("parser")
- assert dateutil.relativedelta == new_locals.pop("relativedelta")
- assert dateutil.rrule == new_locals.pop("rrule")
- assert dateutil.tz == new_locals.pop("tz")
- assert dateutil.utils == new_locals.pop("utils")
- assert dateutil.zoneinfo == new_locals.pop("zoneinfo")
+ assert dateutil.easter == new_locals.pop("easter")
+ assert dateutil.parser == new_locals.pop("parser")
+ assert dateutil.relativedelta == new_locals.pop("relativedelta")
+ assert dateutil.rrule == new_locals.pop("rrule")
+ assert dateutil.tz == new_locals.pop("tz")
+ assert dateutil.utils == new_locals.pop("utils")
+ assert dateutil.zoneinfo == new_locals.pop("zoneinfo")
- assert not new_locals
+ assert not new_locals
diff --git a/contrib/python/dateutil/dateutil/test/test_imports.py b/contrib/python/dateutil/dateutil/test/test_imports.py
index 60b86005ca..351ee41e86 100644
--- a/contrib/python/dateutil/dateutil/test/test_imports.py
+++ b/contrib/python/dateutil/dateutil/test/test_imports.py
@@ -1,176 +1,176 @@
import sys
-import pytest
+import pytest
-
-HOST_IS_WINDOWS = sys.platform.startswith('win')
-
-
-def test_import_version_str():
+
+HOST_IS_WINDOWS = sys.platform.startswith('win')
+
+
+def test_import_version_str():
""" Test that dateutil.__version__ can be imported"""
- from dateutil import __version__
-
-
-def test_import_version_root():
- import dateutil
- assert hasattr(dateutil, '__version__')
-
-
-# Test that dateutil.easter-related imports work properly
-def test_import_easter_direct():
- import dateutil.easter
-
-
-def test_import_easter_from():
- from dateutil import easter
-
-
-def test_import_easter_start():
- from dateutil.easter import easter
-
-
-# Test that dateutil.parser-related imports work properly
-def test_import_parser_direct():
- import dateutil.parser
-
-
-def test_import_parser_from():
- from dateutil import parser
-
-
-def test_import_parser_all():
- # All interface
- from dateutil.parser import parse
- from dateutil.parser import parserinfo
-
- # Other public classes
- from dateutil.parser import parser
-
- for var in (parse, parserinfo, parser):
- assert var is not None
+ from dateutil import __version__
-# Test that dateutil.relativedelta-related imports work properly
-def test_import_relative_delta_direct():
- import dateutil.relativedelta
+def test_import_version_root():
+ import dateutil
+ assert hasattr(dateutil, '__version__')
-def test_import_relative_delta_from():
- from dateutil import relativedelta
+# Test that dateutil.easter-related imports work properly
+def test_import_easter_direct():
+ import dateutil.easter
-def test_import_relative_delta_all():
- from dateutil.relativedelta import relativedelta
- from dateutil.relativedelta import MO, TU, WE, TH, FR, SA, SU
- for var in (relativedelta, MO, TU, WE, TH, FR, SA, SU):
- assert var is not None
+def test_import_easter_from():
+ from dateutil import easter
- # In the public interface but not in all
- from dateutil.relativedelta import weekday
- assert weekday is not None
+def test_import_easter_start():
+ from dateutil.easter import easter
-# Test that dateutil.rrule related imports work properly
-def test_import_rrule_direct():
- import dateutil.rrule
+# Test that dateutil.parser-related imports work properly
+def test_import_parser_direct():
+ import dateutil.parser
-def test_import_rrule_from():
- from dateutil import rrule
+def test_import_parser_from():
+ from dateutil import parser
-def test_import_rrule_all():
- from dateutil.rrule import rrule
- from dateutil.rrule import rruleset
- from dateutil.rrule import rrulestr
- from dateutil.rrule import YEARLY, MONTHLY, WEEKLY, DAILY
- from dateutil.rrule import HOURLY, MINUTELY, SECONDLY
- from dateutil.rrule import MO, TU, WE, TH, FR, SA, SU
- rr_all = (rrule, rruleset, rrulestr,
- YEARLY, MONTHLY, WEEKLY, DAILY,
- HOURLY, MINUTELY, SECONDLY,
- MO, TU, WE, TH, FR, SA, SU)
+def test_import_parser_all():
+ # All interface
+ from dateutil.parser import parse
+ from dateutil.parser import parserinfo
- for var in rr_all:
- assert var is not None
+ # Other public classes
+ from dateutil.parser import parser
- # In the public interface but not in all
- from dateutil.rrule import weekday
- assert weekday is not None
+ for var in (parse, parserinfo, parser):
+ assert var is not None
-# Test that dateutil.tz related imports work properly
-def test_import_tztest_direct():
- import dateutil.tz
+# Test that dateutil.relativedelta-related imports work properly
+def test_import_relative_delta_direct():
+ import dateutil.relativedelta
-def test_import_tz_from():
- from dateutil import tz
+def test_import_relative_delta_from():
+ from dateutil import relativedelta
+def test_import_relative_delta_all():
+ from dateutil.relativedelta import relativedelta
+ from dateutil.relativedelta import MO, TU, WE, TH, FR, SA, SU
-def test_import_tz_all():
- from dateutil.tz import tzutc
- from dateutil.tz import tzoffset
- from dateutil.tz import tzlocal
- from dateutil.tz import tzfile
- from dateutil.tz import tzrange
- from dateutil.tz import tzstr
- from dateutil.tz import tzical
- from dateutil.tz import gettz
- from dateutil.tz import tzwin
- from dateutil.tz import tzwinlocal
- from dateutil.tz import UTC
- from dateutil.tz import datetime_ambiguous
- from dateutil.tz import datetime_exists
- from dateutil.tz import resolve_imaginary
+ for var in (relativedelta, MO, TU, WE, TH, FR, SA, SU):
+ assert var is not None
- tz_all = ["tzutc", "tzoffset", "tzlocal", "tzfile", "tzrange",
- "tzstr", "tzical", "gettz", "datetime_ambiguous",
- "datetime_exists", "resolve_imaginary", "UTC"]
+ # In the public interface but not in all
+ from dateutil.relativedelta import weekday
+ assert weekday is not None
- tz_all += ["tzwin", "tzwinlocal"] if sys.platform.startswith("win") else []
- lvars = locals()
- for var in tz_all:
- assert lvars[var] is not None
+# Test that dateutil.rrule related imports work properly
+def test_import_rrule_direct():
+ import dateutil.rrule
-# Test that dateutil.tzwin related imports work properly
-@pytest.mark.skipif(not HOST_IS_WINDOWS, reason="Requires Windows")
-def test_import_tz_windows_direct():
- import dateutil.tzwin
+def test_import_rrule_from():
+ from dateutil import rrule
-@pytest.mark.skipif(not HOST_IS_WINDOWS, reason="Requires Windows")
-def test_import_tz_windows_from():
- from dateutil import tzwin
+def test_import_rrule_all():
+ from dateutil.rrule import rrule
+ from dateutil.rrule import rruleset
+ from dateutil.rrule import rrulestr
+ from dateutil.rrule import YEARLY, MONTHLY, WEEKLY, DAILY
+ from dateutil.rrule import HOURLY, MINUTELY, SECONDLY
+ from dateutil.rrule import MO, TU, WE, TH, FR, SA, SU
-@pytest.mark.skipif(not HOST_IS_WINDOWS, reason="Requires Windows")
-def test_import_tz_windows_star():
- from dateutil.tzwin import tzwin
- from dateutil.tzwin import tzwinlocal
+ rr_all = (rrule, rruleset, rrulestr,
+ YEARLY, MONTHLY, WEEKLY, DAILY,
+ HOURLY, MINUTELY, SECONDLY,
+ MO, TU, WE, TH, FR, SA, SU)
- tzwin_all = [tzwin, tzwinlocal]
+ for var in rr_all:
+ assert var is not None
- for var in tzwin_all:
- assert var is not None
+ # In the public interface but not in all
+ from dateutil.rrule import weekday
+ assert weekday is not None
-# Test imports of Zone Info
-def test_import_zone_info_direct():
- import dateutil.zoneinfo
+# Test that dateutil.tz related imports work properly
+def test_import_tztest_direct():
+ import dateutil.tz
-def test_import_zone_info_from():
- from dateutil import zoneinfo
+def test_import_tz_from():
+ from dateutil import tz
-def test_import_zone_info_star():
- from dateutil.zoneinfo import gettz
- from dateutil.zoneinfo import gettz_db_metadata
- from dateutil.zoneinfo import rebuild
+def test_import_tz_all():
+ from dateutil.tz import tzutc
+ from dateutil.tz import tzoffset
+ from dateutil.tz import tzlocal
+ from dateutil.tz import tzfile
+ from dateutil.tz import tzrange
+ from dateutil.tz import tzstr
+ from dateutil.tz import tzical
+ from dateutil.tz import gettz
+ from dateutil.tz import tzwin
+ from dateutil.tz import tzwinlocal
+ from dateutil.tz import UTC
+ from dateutil.tz import datetime_ambiguous
+ from dateutil.tz import datetime_exists
+ from dateutil.tz import resolve_imaginary
- zi_all = (gettz, gettz_db_metadata, rebuild)
+ tz_all = ["tzutc", "tzoffset", "tzlocal", "tzfile", "tzrange",
+ "tzstr", "tzical", "gettz", "datetime_ambiguous",
+ "datetime_exists", "resolve_imaginary", "UTC"]
- for var in zi_all:
- assert var is not None
+ tz_all += ["tzwin", "tzwinlocal"] if sys.platform.startswith("win") else []
+ lvars = locals()
+
+ for var in tz_all:
+ assert lvars[var] is not None
+
+# Test that dateutil.tzwin related imports work properly
+@pytest.mark.skipif(not HOST_IS_WINDOWS, reason="Requires Windows")
+def test_import_tz_windows_direct():
+ import dateutil.tzwin
+
+
+@pytest.mark.skipif(not HOST_IS_WINDOWS, reason="Requires Windows")
+def test_import_tz_windows_from():
+ from dateutil import tzwin
+
+
+@pytest.mark.skipif(not HOST_IS_WINDOWS, reason="Requires Windows")
+def test_import_tz_windows_star():
+ from dateutil.tzwin import tzwin
+ from dateutil.tzwin import tzwinlocal
+
+ tzwin_all = [tzwin, tzwinlocal]
+
+ for var in tzwin_all:
+ assert var is not None
+
+
+# Test imports of Zone Info
+def test_import_zone_info_direct():
+ import dateutil.zoneinfo
+
+
+def test_import_zone_info_from():
+ from dateutil import zoneinfo
+
+
+def test_import_zone_info_star():
+ from dateutil.zoneinfo import gettz
+ from dateutil.zoneinfo import gettz_db_metadata
+ from dateutil.zoneinfo import rebuild
+
+ zi_all = (gettz, gettz_db_metadata, rebuild)
+
+ for var in zi_all:
+ assert var is not None
diff --git a/contrib/python/dateutil/dateutil/test/test_internals.py b/contrib/python/dateutil/dateutil/test/test_internals.py
index 530813147d..f1d0bdee89 100644
--- a/contrib/python/dateutil/dateutil/test/test_internals.py
+++ b/contrib/python/dateutil/dateutil/test/test_internals.py
@@ -16,31 +16,31 @@ from dateutil import tz
IS_PY32 = sys.version_info[0:2] == (3, 2)
-@pytest.mark.smoke
-def test_YMD_could_be_day():
- ymd = _ymd('foo bar 124 baz')
-
- ymd.append(2, 'M')
- assert ymd.has_month
- assert not ymd.has_year
- assert ymd.could_be_day(4)
- assert not ymd.could_be_day(-6)
- assert not ymd.could_be_day(32)
-
- # Assumes leap year
- assert ymd.could_be_day(29)
-
- ymd.append(1999)
- assert ymd.has_year
- assert not ymd.could_be_day(29)
-
- ymd.append(16, 'D')
- assert ymd.has_day
- assert not ymd.could_be_day(1)
-
- ymd = _ymd('foo bar 124 baz')
- ymd.append(1999)
- assert ymd.could_be_day(31)
+@pytest.mark.smoke
+def test_YMD_could_be_day():
+ ymd = _ymd('foo bar 124 baz')
+
+ ymd.append(2, 'M')
+ assert ymd.has_month
+ assert not ymd.has_year
+ assert ymd.could_be_day(4)
+ assert not ymd.could_be_day(-6)
+ assert not ymd.could_be_day(32)
+
+ # Assumes leap year
+ assert ymd.could_be_day(29)
+
+ ymd.append(1999)
+ assert ymd.has_year
+ assert not ymd.could_be_day(29)
+
+ ymd.append(16, 'D')
+ assert ymd.has_day
+ assert not ymd.could_be_day(1)
+
+ ymd = _ymd('foo bar 124 baz')
+ ymd.append(1999)
+ assert ymd.could_be_day(31)
###
diff --git a/contrib/python/dateutil/dateutil/test/test_isoparser.py b/contrib/python/dateutil/dateutil/test/test_isoparser.py
index 35899ab9b1..3705d124b1 100644
--- a/contrib/python/dateutil/dateutil/test/test_isoparser.py
+++ b/contrib/python/dateutil/dateutil/test/test_isoparser.py
@@ -4,8 +4,8 @@ from __future__ import unicode_literals
from datetime import datetime, timedelta, date, time
import itertools as it
-from dateutil import tz
-from dateutil.tz import UTC
+from dateutil import tz
+from dateutil.tz import UTC
from dateutil.parser import isoparser, isoparse
import pytest
@@ -36,7 +36,7 @@ def _generate_tzoffsets(limited):
out += [_mkoffset(hm, fmt) for hm in hm_out for fmt in fmts]
# Also add in UTC and naive
- out.append((UTC, 'Z'))
+ out.append((UTC, 'Z'))
out.append((None, ''))
return out
@@ -77,13 +77,13 @@ def _isoparse_date_and_time(dt, date_fmt, time_fmt, tzoffset,
dtstr = dt.strftime(fmt)
if microsecond_precision is not None:
- if not fmt.endswith('%f'): # pragma: nocover
+ if not fmt.endswith('%f'): # pragma: nocover
raise ValueError('Time format has no microseconds!')
- if microsecond_precision != 6:
+ if microsecond_precision != 6:
dtstr = dtstr[:-(6 - microsecond_precision)]
- elif microsecond_precision > 6: # pragma: nocover
- raise ValueError('Precision must be 1-6')
+ elif microsecond_precision > 6: # pragma: nocover
+ raise ValueError('Precision must be 1-6')
dtstr += offset_str
@@ -120,8 +120,8 @@ def test_ymd_hms(dt, date_fmt, time_fmt, tzoffset):
DATETIMES = [datetime(2017, 11, 27, 6, 14, 30, 123456)]
@pytest.mark.parametrize('dt', tuple(DATETIMES))
@pytest.mark.parametrize('date_fmt', YMD_FMTS)
-@pytest.mark.parametrize('time_fmt', (x + sep + '%f' for x in HMS_FMTS
- for sep in '.,'))
+@pytest.mark.parametrize('time_fmt', (x + sep + '%f' for x in HMS_FMTS
+ for sep in '.,'))
@pytest.mark.parametrize('tzoffset', TZOFFSETS)
@pytest.mark.parametrize('precision', list(range(3, 7)))
def test_ymd_hms_micro(dt, date_fmt, time_fmt, tzoffset, precision):
@@ -130,15 +130,15 @@ def test_ymd_hms_micro(dt, date_fmt, time_fmt, tzoffset, precision):
_isoparse_date_and_time(dt, date_fmt, time_fmt, tzoffset, precision)
-###
-# Truncation of extra digits beyond microsecond precision
-@pytest.mark.parametrize('dt_str', [
- '2018-07-03T14:07:00.123456000001',
- '2018-07-03T14:07:00.123456999999',
-])
-def test_extra_subsecond_digits(dt_str):
- assert isoparse(dt_str) == datetime(2018, 7, 3, 14, 7, 0, 123456)
-
+###
+# Truncation of extra digits beyond microsecond precision
+@pytest.mark.parametrize('dt_str', [
+ '2018-07-03T14:07:00.123456000001',
+ '2018-07-03T14:07:00.123456999999',
+])
+def test_extra_subsecond_digits(dt_str):
+ assert isoparse(dt_str) == datetime(2018, 7, 3, 14, 7, 0, 123456)
+
@pytest.mark.parametrize('tzoffset', FULL_TZOFFSETS)
def test_full_tzoffsets(tzoffset):
dt = datetime(2017, 11, 27, 6, 14, 30, 123456)
@@ -149,15 +149,15 @@ def test_full_tzoffsets(tzoffset):
@pytest.mark.parametrize('dt_str', [
'2014-04-11T00',
- '2014-04-10T24',
+ '2014-04-10T24',
'2014-04-11T00:00',
- '2014-04-10T24:00',
+ '2014-04-10T24:00',
'2014-04-11T00:00:00',
- '2014-04-10T24:00:00',
+ '2014-04-10T24:00:00',
'2014-04-11T00:00:00.000',
- '2014-04-10T24:00:00.000',
+ '2014-04-10T24:00:00.000',
'2014-04-11T00:00:00.000000',
- '2014-04-10T24:00:00.000000']
+ '2014-04-10T24:00:00.000000']
)
def test_datetime_midnight(dt_str):
assert isoparse(dt_str) == datetime(2014, 4, 11, 0, 0, 0, 0)
@@ -227,9 +227,9 @@ def test_iso_ordinal(isoord, dt_expected):
(b'2014-02-04T12:30:15.224', datetime(2014, 2, 4, 12, 30, 15, 224000)),
(b'20140204T123015.224', datetime(2014, 2, 4, 12, 30, 15, 224000)),
(b'2014-02-04T12:30:15.224Z', datetime(2014, 2, 4, 12, 30, 15, 224000,
- UTC)),
- (b'2014-02-04T12:30:15.224z', datetime(2014, 2, 4, 12, 30, 15, 224000,
- UTC)),
+ UTC)),
+ (b'2014-02-04T12:30:15.224z', datetime(2014, 2, 4, 12, 30, 15, 224000,
+ UTC)),
(b'2014-02-04T12:30:15.224+05:00',
datetime(2014, 2, 4, 12, 30, 15, 224000,
tzinfo=tz.tzoffset(None, timedelta(hours=5))))])
@@ -244,8 +244,8 @@ def test_bytes(isostr, dt):
('2012-0425', ValueError), # Inconsistent date separators
('201204-25', ValueError), # Inconsistent date separators
('20120425T0120:00', ValueError), # Inconsistent time separators
- ('20120425T01:2000', ValueError), # Inconsistent time separators
- ('14:3015', ValueError), # Inconsistent time separator
+ ('20120425T01:2000', ValueError), # Inconsistent time separators
+ ('14:3015', ValueError), # Inconsistent time separator
('20120425T012500-334', ValueError), # Wrong microsecond separator
('2001-1', ValueError), # YYYY-M not valid
('2012-04-9', ValueError), # YYYY-MM-D not valid
@@ -277,15 +277,15 @@ def test_iso_raises(isostr, exception):
isoparse(isostr)
-@pytest.mark.parametrize('sep_act, valid_sep, exception', [
- ('T', 'C', ValueError),
- ('C', 'T', ValueError),
+@pytest.mark.parametrize('sep_act, valid_sep, exception', [
+ ('T', 'C', ValueError),
+ ('C', 'T', ValueError),
])
-def test_iso_with_sep_raises(sep_act, valid_sep, exception):
- parser = isoparser(sep=valid_sep)
+def test_iso_with_sep_raises(sep_act, valid_sep, exception):
+ parser = isoparser(sep=valid_sep)
isostr = '2012-04-25' + sep_act + '01:25:00'
- with pytest.raises(exception):
- parser.isoparse(isostr)
+ with pytest.raises(exception):
+ parser.isoparse(isostr)
###
@@ -297,7 +297,7 @@ def test_isoparser_invalid_sep(sep):
# This only fails on Python 3
-@pytest.mark.xfail(not six.PY2, reason="Fails on Python 3 only")
+@pytest.mark.xfail(not six.PY2, reason="Fails on Python 3 only")
def test_isoparser_byte_sep():
dt = datetime(2017, 12, 6, 12, 30, 45)
dt_str = dt.isoformat(sep=str('T'))
@@ -324,7 +324,7 @@ def test_parse_tzstr(tzoffset):
@pytest.mark.parametrize('zero_as_utc', [True, False])
def test_parse_tzstr_zero_as_utc(tzstr, zero_as_utc):
tzi = isoparser().parse_tzstr(tzstr, zero_as_utc=zero_as_utc)
- assert tzi == UTC
+ assert tzi == UTC
assert (type(tzi) == tz.tzutc) == zero_as_utc
@@ -347,7 +347,7 @@ def __make_date_examples():
date(2016, 2, 1)
]
- if not six.PY2:
+ if not six.PY2:
# strftime does not support dates before 1900 in Python 2
dates_no_day.append(date(1000, 11, 1))
@@ -373,7 +373,7 @@ def test_parse_isodate(d, dt_fmt, as_bytes):
d_str = d.strftime(dt_fmt)
if isinstance(d_str, six.text_type) and as_bytes:
d_str = d_str.encode('ascii')
- elif isinstance(d_str, bytes) and not as_bytes:
+ elif isinstance(d_str, bytes) and not as_bytes:
d_str = d_str.decode('ascii')
iparser = isoparser()
@@ -388,25 +388,25 @@ def test_parse_isodate(d, dt_fmt, as_bytes):
('2013-02-29', ValueError), # Not a leap year
('2014/12/03', ValueError), # Wrong separators
('2014-04-19T', ValueError), # Unknown components
- ('201202', ValueError), # Invalid format
+ ('201202', ValueError), # Invalid format
])
def test_isodate_raises(isostr, exception):
with pytest.raises(exception):
isoparser().parse_isodate(isostr)
-def test_parse_isodate_error_text():
- with pytest.raises(ValueError) as excinfo:
- isoparser().parse_isodate('2014-0423')
-
- # ensure the error message does not contain b' prefixes
- if six.PY2:
- expected_error = "String contains unknown ISO components: u'2014-0423'"
- else:
- expected_error = "String contains unknown ISO components: '2014-0423'"
- assert expected_error == str(excinfo.value)
-
-
+def test_parse_isodate_error_text():
+ with pytest.raises(ValueError) as excinfo:
+ isoparser().parse_isodate('2014-0423')
+
+ # ensure the error message does not contain b' prefixes
+ if six.PY2:
+ expected_error = "String contains unknown ISO components: u'2014-0423'"
+ else:
+ expected_error = "String contains unknown ISO components: '2014-0423'"
+ assert expected_error == str(excinfo.value)
+
+
###
# Test parse_isotime
def __make_time_examples():
@@ -458,31 +458,31 @@ def __make_time_examples():
@pytest.mark.parametrize('as_bytes', [True, False])
def test_isotime(time_val, time_fmt, as_bytes):
tstr = time_val.strftime(time_fmt)
- if isinstance(tstr, six.text_type) and as_bytes:
+ if isinstance(tstr, six.text_type) and as_bytes:
tstr = tstr.encode('ascii')
- elif isinstance(tstr, bytes) and not as_bytes:
+ elif isinstance(tstr, bytes) and not as_bytes:
tstr = tstr.decode('ascii')
iparser = isoparser()
assert iparser.parse_isotime(tstr) == time_val
-
-@pytest.mark.parametrize('isostr', [
- '24:00',
- '2400',
- '24:00:00',
- '240000',
- '24:00:00.000',
- '24:00:00,000',
- '24:00:00.000000',
- '24:00:00,000000',
-])
-def test_isotime_midnight(isostr):
- iparser = isoparser()
- assert iparser.parse_isotime(isostr) == time(0, 0, 0, 0)
-
-
+
+@pytest.mark.parametrize('isostr', [
+ '24:00',
+ '2400',
+ '24:00:00',
+ '240000',
+ '24:00:00.000',
+ '24:00:00,000',
+ '24:00:00.000000',
+ '24:00:00,000000',
+])
+def test_isotime_midnight(isostr):
+ iparser = isoparser()
+ assert iparser.parse_isotime(isostr) == time(0, 0, 0, 0)
+
+
@pytest.mark.parametrize('isostr,exception', [
('3', ValueError), # ISO string too short
('14時30分15秒', ValueError), # Not ASCII
@@ -492,16 +492,16 @@ def test_isotime_midnight(isostr):
('25:15', ValueError), # Invalid hours
('14:60', ValueError), # Invalid minutes
('14:59:61', ValueError), # Invalid seconds
- ('14:30:15.34468305:00', ValueError), # No sign in time zone
+ ('14:30:15.34468305:00', ValueError), # No sign in time zone
('14:30:15+', ValueError), # Time zone too short
('14:30:15+1234567', ValueError), # Time zone invalid
('14:59:59+25:00', ValueError), # Invalid tz hours
('14:59:59+12:62', ValueError), # Invalid tz minutes
('14:59:30_344583', ValueError), # Invalid microsecond separator
- ('24:01', ValueError), # 24 used for non-midnight time
- ('24:00:01', ValueError), # 24 used for non-midnight time
- ('24:00:00.001', ValueError), # 24 used for non-midnight time
- ('24:00:00.000001', ValueError), # 24 used for non-midnight time
+ ('24:01', ValueError), # 24 used for non-midnight time
+ ('24:00:01', ValueError), # 24 used for non-midnight time
+ ('24:00:00.001', ValueError), # 24 used for non-midnight time
+ ('24:00:00.000001', ValueError), # 24 used for non-midnight time
])
def test_isotime_raises(isostr, exception):
iparser = isoparser()
diff --git a/contrib/python/dateutil/dateutil/test/test_parser.py b/contrib/python/dateutil/dateutil/test/test_parser.py
index 08a34dafbc..3241a39553 100644
--- a/contrib/python/dateutil/dateutil/test/test_parser.py
+++ b/contrib/python/dateutil/dateutil/test/test_parser.py
@@ -9,222 +9,222 @@ import sys
from dateutil import tz
from dateutil.tz import tzoffset
from dateutil.parser import parse, parserinfo
-from dateutil.parser import ParserError
+from dateutil.parser import ParserError
from dateutil.parser import UnknownTimezoneWarning
from ._common import TZEnvContext
-from six import assertRaisesRegex, PY2
-from io import StringIO
+from six import assertRaisesRegex, PY2
+from io import StringIO
import pytest
# Platform info
IS_WIN = sys.platform.startswith('win')
-PLATFORM_HAS_DASH_D = False
+PLATFORM_HAS_DASH_D = False
try:
- if datetime.now().strftime('%-d'):
- PLATFORM_HAS_DASH_D = True
+ if datetime.now().strftime('%-d'):
+ PLATFORM_HAS_DASH_D = True
except ValueError:
- pass
-
-
-@pytest.fixture(params=[True, False])
-def fuzzy(request):
- """Fixture to pass fuzzy=True or fuzzy=False to parse"""
- return request.param
-
-
-# Parser test cases using no keyword arguments. Format: (parsable_text, expected_datetime, assertion_message)
-PARSER_TEST_CASES = [
- ("Thu Sep 25 10:36:28 2003", datetime(2003, 9, 25, 10, 36, 28), "date command format strip"),
- ("Thu Sep 25 2003", datetime(2003, 9, 25), "date command format strip"),
- ("2003-09-25T10:49:41", datetime(2003, 9, 25, 10, 49, 41), "iso format strip"),
- ("2003-09-25T10:49", datetime(2003, 9, 25, 10, 49), "iso format strip"),
- ("2003-09-25T10", datetime(2003, 9, 25, 10), "iso format strip"),
- ("2003-09-25", datetime(2003, 9, 25), "iso format strip"),
- ("20030925T104941", datetime(2003, 9, 25, 10, 49, 41), "iso stripped format strip"),
- ("20030925T1049", datetime(2003, 9, 25, 10, 49, 0), "iso stripped format strip"),
- ("20030925T10", datetime(2003, 9, 25, 10), "iso stripped format strip"),
- ("20030925", datetime(2003, 9, 25), "iso stripped format strip"),
- ("2003-09-25 10:49:41,502", datetime(2003, 9, 25, 10, 49, 41, 502000), "python logger format"),
- ("199709020908", datetime(1997, 9, 2, 9, 8), "no separator"),
- ("19970902090807", datetime(1997, 9, 2, 9, 8, 7), "no separator"),
- ("09-25-2003", datetime(2003, 9, 25), "date with dash"),
- ("25-09-2003", datetime(2003, 9, 25), "date with dash"),
- ("10-09-2003", datetime(2003, 10, 9), "date with dash"),
- ("10-09-03", datetime(2003, 10, 9), "date with dash"),
- ("2003.09.25", datetime(2003, 9, 25), "date with dot"),
- ("09.25.2003", datetime(2003, 9, 25), "date with dot"),
- ("25.09.2003", datetime(2003, 9, 25), "date with dot"),
- ("10.09.2003", datetime(2003, 10, 9), "date with dot"),
- ("10.09.03", datetime(2003, 10, 9), "date with dot"),
- ("2003/09/25", datetime(2003, 9, 25), "date with slash"),
- ("09/25/2003", datetime(2003, 9, 25), "date with slash"),
- ("25/09/2003", datetime(2003, 9, 25), "date with slash"),
- ("10/09/2003", datetime(2003, 10, 9), "date with slash"),
- ("10/09/03", datetime(2003, 10, 9), "date with slash"),
- ("2003 09 25", datetime(2003, 9, 25), "date with space"),
- ("09 25 2003", datetime(2003, 9, 25), "date with space"),
- ("25 09 2003", datetime(2003, 9, 25), "date with space"),
- ("10 09 2003", datetime(2003, 10, 9), "date with space"),
- ("10 09 03", datetime(2003, 10, 9), "date with space"),
- ("25 09 03", datetime(2003, 9, 25), "date with space"),
- ("03 25 Sep", datetime(2003, 9, 25), "strangely ordered date"),
- ("25 03 Sep", datetime(2025, 9, 3), "strangely ordered date"),
- (" July 4 , 1976 12:01:02 am ", datetime(1976, 7, 4, 0, 1, 2), "extra space"),
- ("Wed, July 10, '96", datetime(1996, 7, 10, 0, 0), "random format"),
- ("1996.July.10 AD 12:08 PM", datetime(1996, 7, 10, 12, 8), "random format"),
- ("July 4, 1976", datetime(1976, 7, 4), "random format"),
- ("7 4 1976", datetime(1976, 7, 4), "random format"),
- ("4 jul 1976", datetime(1976, 7, 4), "random format"),
- ("4 Jul 1976", datetime(1976, 7, 4), "'%-d %b %Y' format"),
- ("7-4-76", datetime(1976, 7, 4), "random format"),
- ("19760704", datetime(1976, 7, 4), "random format"),
- ("0:01:02 on July 4, 1976", datetime(1976, 7, 4, 0, 1, 2), "random format"),
- ("July 4, 1976 12:01:02 am", datetime(1976, 7, 4, 0, 1, 2), "random format"),
- ("Mon Jan 2 04:24:27 1995", datetime(1995, 1, 2, 4, 24, 27), "random format"),
- ("04.04.95 00:22", datetime(1995, 4, 4, 0, 22), "random format"),
- ("Jan 1 1999 11:23:34.578", datetime(1999, 1, 1, 11, 23, 34, 578000), "random format"),
- ("950404 122212", datetime(1995, 4, 4, 12, 22, 12), "random format"),
- ("3rd of May 2001", datetime(2001, 5, 3), "random format"),
- ("5th of March 2001", datetime(2001, 3, 5), "random format"),
- ("1st of May 2003", datetime(2003, 5, 1), "random format"),
- ('0099-01-01T00:00:00', datetime(99, 1, 1, 0, 0), "99 ad"),
- ('0031-01-01T00:00:00', datetime(31, 1, 1, 0, 0), "31 ad"),
- ("20080227T21:26:01.123456789", datetime(2008, 2, 27, 21, 26, 1, 123456), "high precision seconds"),
- ('13NOV2017', datetime(2017, 11, 13), "dBY (See GH360)"),
- ('0003-03-04', datetime(3, 3, 4), "pre 12 year same month (See GH PR #293)"),
- ('December.0031.30', datetime(31, 12, 30), "BYd corner case (GH#687)"),
-
- # Cases with legacy h/m/s format, candidates for deprecation (GH#886)
- ("2016-12-21 04.2h", datetime(2016, 12, 21, 4, 12), "Fractional Hours"),
-]
-# Check that we don't have any duplicates
-assert len(set([x[0] for x in PARSER_TEST_CASES])) == len(PARSER_TEST_CASES)
-
-
-@pytest.mark.parametrize("parsable_text,expected_datetime,assertion_message", PARSER_TEST_CASES)
-def test_parser(parsable_text, expected_datetime, assertion_message):
- assert parse(parsable_text) == expected_datetime, assertion_message
-
-
-# Parser test cases using datetime(2003, 9, 25) as a default.
-# Format: (parsable_text, expected_datetime, assertion_message)
-PARSER_DEFAULT_TEST_CASES = [
- ("Thu Sep 25 10:36:28", datetime(2003, 9, 25, 10, 36, 28), "date command format strip"),
- ("Thu Sep 10:36:28", datetime(2003, 9, 25, 10, 36, 28), "date command format strip"),
- ("Thu 10:36:28", datetime(2003, 9, 25, 10, 36, 28), "date command format strip"),
- ("Sep 10:36:28", datetime(2003, 9, 25, 10, 36, 28), "date command format strip"),
- ("10:36:28", datetime(2003, 9, 25, 10, 36, 28), "date command format strip"),
- ("10:36", datetime(2003, 9, 25, 10, 36), "date command format strip"),
- ("Sep 2003", datetime(2003, 9, 25), "date command format strip"),
- ("Sep", datetime(2003, 9, 25), "date command format strip"),
- ("2003", datetime(2003, 9, 25), "date command format strip"),
- ("10h36m28.5s", datetime(2003, 9, 25, 10, 36, 28, 500000), "hour with letters"),
- ("10h36m28s", datetime(2003, 9, 25, 10, 36, 28), "hour with letters strip"),
- ("10h36m", datetime(2003, 9, 25, 10, 36), "hour with letters strip"),
- ("10h", datetime(2003, 9, 25, 10), "hour with letters strip"),
- ("10 h 36", datetime(2003, 9, 25, 10, 36), "hour with letters strip"),
- ("10 h 36.5", datetime(2003, 9, 25, 10, 36, 30), "hour with letter strip"),
- ("36 m 5", datetime(2003, 9, 25, 0, 36, 5), "hour with letters spaces"),
- ("36 m 5 s", datetime(2003, 9, 25, 0, 36, 5), "minute with letters spaces"),
- ("36 m 05", datetime(2003, 9, 25, 0, 36, 5), "minute with letters spaces"),
- ("36 m 05 s", datetime(2003, 9, 25, 0, 36, 5), "minutes with letters spaces"),
- ("10h am", datetime(2003, 9, 25, 10), "hour am pm"),
- ("10h pm", datetime(2003, 9, 25, 22), "hour am pm"),
- ("10am", datetime(2003, 9, 25, 10), "hour am pm"),
- ("10pm", datetime(2003, 9, 25, 22), "hour am pm"),
- ("10:00 am", datetime(2003, 9, 25, 10), "hour am pm"),
- ("10:00 pm", datetime(2003, 9, 25, 22), "hour am pm"),
- ("10:00am", datetime(2003, 9, 25, 10), "hour am pm"),
- ("10:00pm", datetime(2003, 9, 25, 22), "hour am pm"),
- ("10:00a.m", datetime(2003, 9, 25, 10), "hour am pm"),
- ("10:00p.m", datetime(2003, 9, 25, 22), "hour am pm"),
- ("10:00a.m.", datetime(2003, 9, 25, 10), "hour am pm"),
- ("10:00p.m.", datetime(2003, 9, 25, 22), "hour am pm"),
- ("Wed", datetime(2003, 10, 1), "weekday alone"),
- ("Wednesday", datetime(2003, 10, 1), "long weekday"),
- ("October", datetime(2003, 10, 25), "long month"),
- ("31-Dec-00", datetime(2000, 12, 31), "zero year"),
- ("0:01:02", datetime(2003, 9, 25, 0, 1, 2), "random format"),
- ("12h 01m02s am", datetime(2003, 9, 25, 0, 1, 2), "random format"),
- ("12:08 PM", datetime(2003, 9, 25, 12, 8), "random format"),
- ("01h02m03", datetime(2003, 9, 25, 1, 2, 3), "random format"),
- ("01h02", datetime(2003, 9, 25, 1, 2), "random format"),
- ("01h02s", datetime(2003, 9, 25, 1, 0, 2), "random format"),
- ("01m02", datetime(2003, 9, 25, 0, 1, 2), "random format"),
- ("01m02h", datetime(2003, 9, 25, 2, 1), "random format"),
- ("2004 10 Apr 11h30m", datetime(2004, 4, 10, 11, 30), "random format")
-]
-# Check that we don't have any duplicates
-assert len(set([x[0] for x in PARSER_DEFAULT_TEST_CASES])) == len(PARSER_DEFAULT_TEST_CASES)
-
-
-@pytest.mark.parametrize("parsable_text,expected_datetime,assertion_message", PARSER_DEFAULT_TEST_CASES)
-def test_parser_default(parsable_text, expected_datetime, assertion_message):
- assert parse(parsable_text, default=datetime(2003, 9, 25)) == expected_datetime, assertion_message
-
-
-@pytest.mark.parametrize('sep', ['-', '.', '/', ' '])
-def test_parse_dayfirst(sep):
- expected = datetime(2003, 9, 10)
- fmt = sep.join(['%d', '%m', '%Y'])
- dstr = expected.strftime(fmt)
- result = parse(dstr, dayfirst=True)
- assert result == expected
-
-
-@pytest.mark.parametrize('sep', ['-', '.', '/', ' '])
-def test_parse_yearfirst(sep):
- expected = datetime(2010, 9, 3)
- fmt = sep.join(['%Y', '%m', '%d'])
- dstr = expected.strftime(fmt)
- result = parse(dstr, yearfirst=True)
- assert result == expected
-
-
-@pytest.mark.parametrize('dstr,expected', [
- ("Thu Sep 25 10:36:28 BRST 2003", datetime(2003, 9, 25, 10, 36, 28)),
- ("1996.07.10 AD at 15:08:56 PDT", datetime(1996, 7, 10, 15, 8, 56)),
- ("Tuesday, April 12, 1952 AD 3:30:42pm PST",
- datetime(1952, 4, 12, 15, 30, 42)),
- ("November 5, 1994, 8:15:30 am EST", datetime(1994, 11, 5, 8, 15, 30)),
- ("1994-11-05T08:15:30-05:00", datetime(1994, 11, 5, 8, 15, 30)),
- ("1994-11-05T08:15:30Z", datetime(1994, 11, 5, 8, 15, 30)),
- ("1976-07-04T00:01:02Z", datetime(1976, 7, 4, 0, 1, 2)),
- ("1986-07-05T08:15:30z", datetime(1986, 7, 5, 8, 15, 30)),
- ("Tue Apr 4 00:22:12 PDT 1995", datetime(1995, 4, 4, 0, 22, 12)),
-])
-def test_parse_ignoretz(dstr, expected):
- result = parse(dstr, ignoretz=True)
- assert result == expected
-
-
-_brsttz = tzoffset("BRST", -10800)
-
-
-@pytest.mark.parametrize('dstr,expected', [
- ("20030925T104941-0300",
- datetime(2003, 9, 25, 10, 49, 41, tzinfo=_brsttz)),
- ("Thu, 25 Sep 2003 10:49:41 -0300",
- datetime(2003, 9, 25, 10, 49, 41, tzinfo=_brsttz)),
- ("2003-09-25T10:49:41.5-03:00",
- datetime(2003, 9, 25, 10, 49, 41, 500000, tzinfo=_brsttz)),
- ("2003-09-25T10:49:41-03:00",
- datetime(2003, 9, 25, 10, 49, 41, tzinfo=_brsttz)),
- ("20030925T104941.5-0300",
- datetime(2003, 9, 25, 10, 49, 41, 500000, tzinfo=_brsttz)),
-])
-def test_parse_with_tzoffset(dstr, expected):
- # In these cases, we are _not_ passing a tzinfos arg
- result = parse(dstr)
- assert result == expected
-
-
-class TestFormat(object):
-
+ pass
+
+
+@pytest.fixture(params=[True, False])
+def fuzzy(request):
+ """Fixture to pass fuzzy=True or fuzzy=False to parse"""
+ return request.param
+
+
+# Parser test cases using no keyword arguments. Format: (parsable_text, expected_datetime, assertion_message)
+PARSER_TEST_CASES = [
+ ("Thu Sep 25 10:36:28 2003", datetime(2003, 9, 25, 10, 36, 28), "date command format strip"),
+ ("Thu Sep 25 2003", datetime(2003, 9, 25), "date command format strip"),
+ ("2003-09-25T10:49:41", datetime(2003, 9, 25, 10, 49, 41), "iso format strip"),
+ ("2003-09-25T10:49", datetime(2003, 9, 25, 10, 49), "iso format strip"),
+ ("2003-09-25T10", datetime(2003, 9, 25, 10), "iso format strip"),
+ ("2003-09-25", datetime(2003, 9, 25), "iso format strip"),
+ ("20030925T104941", datetime(2003, 9, 25, 10, 49, 41), "iso stripped format strip"),
+ ("20030925T1049", datetime(2003, 9, 25, 10, 49, 0), "iso stripped format strip"),
+ ("20030925T10", datetime(2003, 9, 25, 10), "iso stripped format strip"),
+ ("20030925", datetime(2003, 9, 25), "iso stripped format strip"),
+ ("2003-09-25 10:49:41,502", datetime(2003, 9, 25, 10, 49, 41, 502000), "python logger format"),
+ ("199709020908", datetime(1997, 9, 2, 9, 8), "no separator"),
+ ("19970902090807", datetime(1997, 9, 2, 9, 8, 7), "no separator"),
+ ("09-25-2003", datetime(2003, 9, 25), "date with dash"),
+ ("25-09-2003", datetime(2003, 9, 25), "date with dash"),
+ ("10-09-2003", datetime(2003, 10, 9), "date with dash"),
+ ("10-09-03", datetime(2003, 10, 9), "date with dash"),
+ ("2003.09.25", datetime(2003, 9, 25), "date with dot"),
+ ("09.25.2003", datetime(2003, 9, 25), "date with dot"),
+ ("25.09.2003", datetime(2003, 9, 25), "date with dot"),
+ ("10.09.2003", datetime(2003, 10, 9), "date with dot"),
+ ("10.09.03", datetime(2003, 10, 9), "date with dot"),
+ ("2003/09/25", datetime(2003, 9, 25), "date with slash"),
+ ("09/25/2003", datetime(2003, 9, 25), "date with slash"),
+ ("25/09/2003", datetime(2003, 9, 25), "date with slash"),
+ ("10/09/2003", datetime(2003, 10, 9), "date with slash"),
+ ("10/09/03", datetime(2003, 10, 9), "date with slash"),
+ ("2003 09 25", datetime(2003, 9, 25), "date with space"),
+ ("09 25 2003", datetime(2003, 9, 25), "date with space"),
+ ("25 09 2003", datetime(2003, 9, 25), "date with space"),
+ ("10 09 2003", datetime(2003, 10, 9), "date with space"),
+ ("10 09 03", datetime(2003, 10, 9), "date with space"),
+ ("25 09 03", datetime(2003, 9, 25), "date with space"),
+ ("03 25 Sep", datetime(2003, 9, 25), "strangely ordered date"),
+ ("25 03 Sep", datetime(2025, 9, 3), "strangely ordered date"),
+ (" July 4 , 1976 12:01:02 am ", datetime(1976, 7, 4, 0, 1, 2), "extra space"),
+ ("Wed, July 10, '96", datetime(1996, 7, 10, 0, 0), "random format"),
+ ("1996.July.10 AD 12:08 PM", datetime(1996, 7, 10, 12, 8), "random format"),
+ ("July 4, 1976", datetime(1976, 7, 4), "random format"),
+ ("7 4 1976", datetime(1976, 7, 4), "random format"),
+ ("4 jul 1976", datetime(1976, 7, 4), "random format"),
+ ("4 Jul 1976", datetime(1976, 7, 4), "'%-d %b %Y' format"),
+ ("7-4-76", datetime(1976, 7, 4), "random format"),
+ ("19760704", datetime(1976, 7, 4), "random format"),
+ ("0:01:02 on July 4, 1976", datetime(1976, 7, 4, 0, 1, 2), "random format"),
+ ("July 4, 1976 12:01:02 am", datetime(1976, 7, 4, 0, 1, 2), "random format"),
+ ("Mon Jan 2 04:24:27 1995", datetime(1995, 1, 2, 4, 24, 27), "random format"),
+ ("04.04.95 00:22", datetime(1995, 4, 4, 0, 22), "random format"),
+ ("Jan 1 1999 11:23:34.578", datetime(1999, 1, 1, 11, 23, 34, 578000), "random format"),
+ ("950404 122212", datetime(1995, 4, 4, 12, 22, 12), "random format"),
+ ("3rd of May 2001", datetime(2001, 5, 3), "random format"),
+ ("5th of March 2001", datetime(2001, 3, 5), "random format"),
+ ("1st of May 2003", datetime(2003, 5, 1), "random format"),
+ ('0099-01-01T00:00:00', datetime(99, 1, 1, 0, 0), "99 ad"),
+ ('0031-01-01T00:00:00', datetime(31, 1, 1, 0, 0), "31 ad"),
+ ("20080227T21:26:01.123456789", datetime(2008, 2, 27, 21, 26, 1, 123456), "high precision seconds"),
+ ('13NOV2017', datetime(2017, 11, 13), "dBY (See GH360)"),
+ ('0003-03-04', datetime(3, 3, 4), "pre 12 year same month (See GH PR #293)"),
+ ('December.0031.30', datetime(31, 12, 30), "BYd corner case (GH#687)"),
+
+ # Cases with legacy h/m/s format, candidates for deprecation (GH#886)
+ ("2016-12-21 04.2h", datetime(2016, 12, 21, 4, 12), "Fractional Hours"),
+]
+# Check that we don't have any duplicates
+assert len(set([x[0] for x in PARSER_TEST_CASES])) == len(PARSER_TEST_CASES)
+
+
+@pytest.mark.parametrize("parsable_text,expected_datetime,assertion_message", PARSER_TEST_CASES)
+def test_parser(parsable_text, expected_datetime, assertion_message):
+ assert parse(parsable_text) == expected_datetime, assertion_message
+
+
+# Parser test cases using datetime(2003, 9, 25) as a default.
+# Format: (parsable_text, expected_datetime, assertion_message)
+PARSER_DEFAULT_TEST_CASES = [
+ ("Thu Sep 25 10:36:28", datetime(2003, 9, 25, 10, 36, 28), "date command format strip"),
+ ("Thu Sep 10:36:28", datetime(2003, 9, 25, 10, 36, 28), "date command format strip"),
+ ("Thu 10:36:28", datetime(2003, 9, 25, 10, 36, 28), "date command format strip"),
+ ("Sep 10:36:28", datetime(2003, 9, 25, 10, 36, 28), "date command format strip"),
+ ("10:36:28", datetime(2003, 9, 25, 10, 36, 28), "date command format strip"),
+ ("10:36", datetime(2003, 9, 25, 10, 36), "date command format strip"),
+ ("Sep 2003", datetime(2003, 9, 25), "date command format strip"),
+ ("Sep", datetime(2003, 9, 25), "date command format strip"),
+ ("2003", datetime(2003, 9, 25), "date command format strip"),
+ ("10h36m28.5s", datetime(2003, 9, 25, 10, 36, 28, 500000), "hour with letters"),
+ ("10h36m28s", datetime(2003, 9, 25, 10, 36, 28), "hour with letters strip"),
+ ("10h36m", datetime(2003, 9, 25, 10, 36), "hour with letters strip"),
+ ("10h", datetime(2003, 9, 25, 10), "hour with letters strip"),
+ ("10 h 36", datetime(2003, 9, 25, 10, 36), "hour with letters strip"),
+ ("10 h 36.5", datetime(2003, 9, 25, 10, 36, 30), "hour with letter strip"),
+ ("36 m 5", datetime(2003, 9, 25, 0, 36, 5), "hour with letters spaces"),
+ ("36 m 5 s", datetime(2003, 9, 25, 0, 36, 5), "minute with letters spaces"),
+ ("36 m 05", datetime(2003, 9, 25, 0, 36, 5), "minute with letters spaces"),
+ ("36 m 05 s", datetime(2003, 9, 25, 0, 36, 5), "minutes with letters spaces"),
+ ("10h am", datetime(2003, 9, 25, 10), "hour am pm"),
+ ("10h pm", datetime(2003, 9, 25, 22), "hour am pm"),
+ ("10am", datetime(2003, 9, 25, 10), "hour am pm"),
+ ("10pm", datetime(2003, 9, 25, 22), "hour am pm"),
+ ("10:00 am", datetime(2003, 9, 25, 10), "hour am pm"),
+ ("10:00 pm", datetime(2003, 9, 25, 22), "hour am pm"),
+ ("10:00am", datetime(2003, 9, 25, 10), "hour am pm"),
+ ("10:00pm", datetime(2003, 9, 25, 22), "hour am pm"),
+ ("10:00a.m", datetime(2003, 9, 25, 10), "hour am pm"),
+ ("10:00p.m", datetime(2003, 9, 25, 22), "hour am pm"),
+ ("10:00a.m.", datetime(2003, 9, 25, 10), "hour am pm"),
+ ("10:00p.m.", datetime(2003, 9, 25, 22), "hour am pm"),
+ ("Wed", datetime(2003, 10, 1), "weekday alone"),
+ ("Wednesday", datetime(2003, 10, 1), "long weekday"),
+ ("October", datetime(2003, 10, 25), "long month"),
+ ("31-Dec-00", datetime(2000, 12, 31), "zero year"),
+ ("0:01:02", datetime(2003, 9, 25, 0, 1, 2), "random format"),
+ ("12h 01m02s am", datetime(2003, 9, 25, 0, 1, 2), "random format"),
+ ("12:08 PM", datetime(2003, 9, 25, 12, 8), "random format"),
+ ("01h02m03", datetime(2003, 9, 25, 1, 2, 3), "random format"),
+ ("01h02", datetime(2003, 9, 25, 1, 2), "random format"),
+ ("01h02s", datetime(2003, 9, 25, 1, 0, 2), "random format"),
+ ("01m02", datetime(2003, 9, 25, 0, 1, 2), "random format"),
+ ("01m02h", datetime(2003, 9, 25, 2, 1), "random format"),
+ ("2004 10 Apr 11h30m", datetime(2004, 4, 10, 11, 30), "random format")
+]
+# Check that we don't have any duplicates
+assert len(set([x[0] for x in PARSER_DEFAULT_TEST_CASES])) == len(PARSER_DEFAULT_TEST_CASES)
+
+
+@pytest.mark.parametrize("parsable_text,expected_datetime,assertion_message", PARSER_DEFAULT_TEST_CASES)
+def test_parser_default(parsable_text, expected_datetime, assertion_message):
+ assert parse(parsable_text, default=datetime(2003, 9, 25)) == expected_datetime, assertion_message
+
+
+@pytest.mark.parametrize('sep', ['-', '.', '/', ' '])
+def test_parse_dayfirst(sep):
+ expected = datetime(2003, 9, 10)
+ fmt = sep.join(['%d', '%m', '%Y'])
+ dstr = expected.strftime(fmt)
+ result = parse(dstr, dayfirst=True)
+ assert result == expected
+
+
+@pytest.mark.parametrize('sep', ['-', '.', '/', ' '])
+def test_parse_yearfirst(sep):
+ expected = datetime(2010, 9, 3)
+ fmt = sep.join(['%Y', '%m', '%d'])
+ dstr = expected.strftime(fmt)
+ result = parse(dstr, yearfirst=True)
+ assert result == expected
+
+
+@pytest.mark.parametrize('dstr,expected', [
+ ("Thu Sep 25 10:36:28 BRST 2003", datetime(2003, 9, 25, 10, 36, 28)),
+ ("1996.07.10 AD at 15:08:56 PDT", datetime(1996, 7, 10, 15, 8, 56)),
+ ("Tuesday, April 12, 1952 AD 3:30:42pm PST",
+ datetime(1952, 4, 12, 15, 30, 42)),
+ ("November 5, 1994, 8:15:30 am EST", datetime(1994, 11, 5, 8, 15, 30)),
+ ("1994-11-05T08:15:30-05:00", datetime(1994, 11, 5, 8, 15, 30)),
+ ("1994-11-05T08:15:30Z", datetime(1994, 11, 5, 8, 15, 30)),
+ ("1976-07-04T00:01:02Z", datetime(1976, 7, 4, 0, 1, 2)),
+ ("1986-07-05T08:15:30z", datetime(1986, 7, 5, 8, 15, 30)),
+ ("Tue Apr 4 00:22:12 PDT 1995", datetime(1995, 4, 4, 0, 22, 12)),
+])
+def test_parse_ignoretz(dstr, expected):
+ result = parse(dstr, ignoretz=True)
+ assert result == expected
+
+
+_brsttz = tzoffset("BRST", -10800)
+
+
+@pytest.mark.parametrize('dstr,expected', [
+ ("20030925T104941-0300",
+ datetime(2003, 9, 25, 10, 49, 41, tzinfo=_brsttz)),
+ ("Thu, 25 Sep 2003 10:49:41 -0300",
+ datetime(2003, 9, 25, 10, 49, 41, tzinfo=_brsttz)),
+ ("2003-09-25T10:49:41.5-03:00",
+ datetime(2003, 9, 25, 10, 49, 41, 500000, tzinfo=_brsttz)),
+ ("2003-09-25T10:49:41-03:00",
+ datetime(2003, 9, 25, 10, 49, 41, tzinfo=_brsttz)),
+ ("20030925T104941.5-0300",
+ datetime(2003, 9, 25, 10, 49, 41, 500000, tzinfo=_brsttz)),
+])
+def test_parse_with_tzoffset(dstr, expected):
+ # In these cases, we are _not_ passing a tzinfos arg
+ result = parse(dstr)
+ assert result == expected
+
+
+class TestFormat(object):
+
def test_ybd(self):
# If we have a 4-digit year, a non-numeric month (abbreviated or not),
# and a day (1 or 2 digits), then there is no ambiguity as to which
@@ -248,63 +248,63 @@ class TestFormat(object):
for fmt in unambig_fmts:
dstr = actual.strftime(fmt)
res = parse(dstr)
- assert res == actual
-
- # TODO: some redundancy with PARSER_TEST_CASES cases
- @pytest.mark.parametrize("fmt,dstr", [
- ("%a %b %d %Y", "Thu Sep 25 2003"),
- ("%b %d %Y", "Sep 25 2003"),
- ("%Y-%m-%d", "2003-09-25"),
- ("%Y%m%d", "20030925"),
- ("%Y-%b-%d", "2003-Sep-25"),
- ("%d-%b-%Y", "25-Sep-2003"),
- ("%b-%d-%Y", "Sep-25-2003"),
- ("%m-%d-%Y", "09-25-2003"),
- ("%d-%m-%Y", "25-09-2003"),
- ("%Y.%m.%d", "2003.09.25"),
- ("%Y.%b.%d", "2003.Sep.25"),
- ("%d.%b.%Y", "25.Sep.2003"),
- ("%b.%d.%Y", "Sep.25.2003"),
- ("%m.%d.%Y", "09.25.2003"),
- ("%d.%m.%Y", "25.09.2003"),
- ("%Y/%m/%d", "2003/09/25"),
- ("%Y/%b/%d", "2003/Sep/25"),
- ("%d/%b/%Y", "25/Sep/2003"),
- ("%b/%d/%Y", "Sep/25/2003"),
- ("%m/%d/%Y", "09/25/2003"),
- ("%d/%m/%Y", "25/09/2003"),
- ("%Y %m %d", "2003 09 25"),
- ("%Y %b %d", "2003 Sep 25"),
- ("%d %b %Y", "25 Sep 2003"),
- ("%m %d %Y", "09 25 2003"),
- ("%d %m %Y", "25 09 2003"),
- ("%y %d %b", "03 25 Sep",),
- ])
- def test_strftime_formats_2003Sep25(self, fmt, dstr):
- expected = datetime(2003, 9, 25)
-
- # First check that the format strings behave as expected
- # (not strictly necessary, but nice to have)
- assert expected.strftime(fmt) == dstr
-
- res = parse(dstr)
- assert res == expected
-
-
-class TestInputTypes(object):
- def test_empty_string_invalid(self):
- with pytest.raises(ParserError):
+ assert res == actual
+
+ # TODO: some redundancy with PARSER_TEST_CASES cases
+ @pytest.mark.parametrize("fmt,dstr", [
+ ("%a %b %d %Y", "Thu Sep 25 2003"),
+ ("%b %d %Y", "Sep 25 2003"),
+ ("%Y-%m-%d", "2003-09-25"),
+ ("%Y%m%d", "20030925"),
+ ("%Y-%b-%d", "2003-Sep-25"),
+ ("%d-%b-%Y", "25-Sep-2003"),
+ ("%b-%d-%Y", "Sep-25-2003"),
+ ("%m-%d-%Y", "09-25-2003"),
+ ("%d-%m-%Y", "25-09-2003"),
+ ("%Y.%m.%d", "2003.09.25"),
+ ("%Y.%b.%d", "2003.Sep.25"),
+ ("%d.%b.%Y", "25.Sep.2003"),
+ ("%b.%d.%Y", "Sep.25.2003"),
+ ("%m.%d.%Y", "09.25.2003"),
+ ("%d.%m.%Y", "25.09.2003"),
+ ("%Y/%m/%d", "2003/09/25"),
+ ("%Y/%b/%d", "2003/Sep/25"),
+ ("%d/%b/%Y", "25/Sep/2003"),
+ ("%b/%d/%Y", "Sep/25/2003"),
+ ("%m/%d/%Y", "09/25/2003"),
+ ("%d/%m/%Y", "25/09/2003"),
+ ("%Y %m %d", "2003 09 25"),
+ ("%Y %b %d", "2003 Sep 25"),
+ ("%d %b %Y", "25 Sep 2003"),
+ ("%m %d %Y", "09 25 2003"),
+ ("%d %m %Y", "25 09 2003"),
+ ("%y %d %b", "03 25 Sep",),
+ ])
+ def test_strftime_formats_2003Sep25(self, fmt, dstr):
+ expected = datetime(2003, 9, 25)
+
+ # First check that the format strings behave as expected
+ # (not strictly necessary, but nice to have)
+ assert expected.strftime(fmt) == dstr
+
+ res = parse(dstr)
+ assert res == expected
+
+
+class TestInputTypes(object):
+ def test_empty_string_invalid(self):
+ with pytest.raises(ParserError):
parse('')
- def test_none_invalid(self):
- with pytest.raises(TypeError):
+ def test_none_invalid(self):
+ with pytest.raises(TypeError):
parse(None)
- def test_int_invalid(self):
- with pytest.raises(TypeError):
+ def test_int_invalid(self):
+ with pytest.raises(TypeError):
parse(13)
- def test_duck_typing(self):
+ def test_duck_typing(self):
# We want to support arbitrary classes that implement the stream
# interface.
@@ -317,110 +317,110 @@ class TestInputTypes(object):
dstr = StringPassThrough(StringIO('2014 January 19'))
- res = parse(dstr)
- expected = datetime(2014, 1, 19)
- assert res == expected
+ res = parse(dstr)
+ expected = datetime(2014, 1, 19)
+ assert res == expected
- def test_parse_stream(self):
+ def test_parse_stream(self):
dstr = StringIO('2014 January 19')
- res = parse(dstr)
- expected = datetime(2014, 1, 19)
- assert res == expected
-
- def test_parse_str(self):
- # Parser should be able to handle bytestring and unicode
- uni_str = '2014-05-01 08:00:00'
- bytes_str = uni_str.encode()
-
- res = parse(bytes_str)
- expected = parse(uni_str)
- assert res == expected
-
- def test_parse_bytes(self):
- res = parse(b'2014 January 19')
- expected = datetime(2014, 1, 19)
- assert res == expected
-
- def test_parse_bytearray(self):
- # GH#417
- res = parse(bytearray(b'2014 January 19'))
- expected = datetime(2014, 1, 19)
- assert res == expected
-
-
-class TestTzinfoInputTypes(object):
- def assert_equal_same_tz(self, dt1, dt2):
- assert dt1 == dt2
- assert dt1.tzinfo is dt2.tzinfo
-
- def test_tzinfo_dict_could_return_none(self):
- dstr = "2017-02-03 12:40 BRST"
- result = parse(dstr, tzinfos={"BRST": None})
- expected = datetime(2017, 2, 3, 12, 40)
- self.assert_equal_same_tz(result, expected)
-
- def test_tzinfos_callable_could_return_none(self):
- dstr = "2017-02-03 12:40 BRST"
- result = parse(dstr, tzinfos=lambda *args: None)
- expected = datetime(2017, 2, 3, 12, 40)
- self.assert_equal_same_tz(result, expected)
-
- def test_invalid_tzinfo_input(self):
- dstr = "2014 January 19 09:00 UTC"
- # Pass an absurd tzinfos object
- tzinfos = {"UTC": ValueError}
- with pytest.raises(TypeError):
- parse(dstr, tzinfos=tzinfos)
-
- def test_valid_tzinfo_tzinfo_input(self):
- dstr = "2014 January 19 09:00 UTC"
- tzinfos = {"UTC": tz.UTC}
- expected = datetime(2014, 1, 19, 9, tzinfo=tz.UTC)
- res = parse(dstr, tzinfos=tzinfos)
- self.assert_equal_same_tz(res, expected)
-
- def test_valid_tzinfo_unicode_input(self):
- dstr = "2014 January 19 09:00 UTC"
- tzinfos = {u"UTC": u"UTC+0"}
- expected = datetime(2014, 1, 19, 9, tzinfo=tz.tzstr("UTC+0"))
- res = parse(dstr, tzinfos=tzinfos)
- self.assert_equal_same_tz(res, expected)
-
- def test_valid_tzinfo_callable_input(self):
- dstr = "2014 January 19 09:00 UTC"
-
- def tzinfos(*args, **kwargs):
- return u"UTC+0"
-
- expected = datetime(2014, 1, 19, 9, tzinfo=tz.tzstr("UTC+0"))
- res = parse(dstr, tzinfos=tzinfos)
- self.assert_equal_same_tz(res, expected)
-
- def test_valid_tzinfo_int_input(self):
- dstr = "2014 January 19 09:00 UTC"
- tzinfos = {u"UTC": -28800}
- expected = datetime(2014, 1, 19, 9, tzinfo=tz.tzoffset(u"UTC", -28800))
- res = parse(dstr, tzinfos=tzinfos)
- self.assert_equal_same_tz(res, expected)
-
-
-class ParserTest(unittest.TestCase):
-
- @classmethod
- def setup_class(cls):
- cls.tzinfos = {"BRST": -10800}
- cls.brsttz = tzoffset("BRST", -10800)
- cls.default = datetime(2003, 9, 25)
-
- # Parser should be able to handle bytestring and unicode
- cls.uni_str = '2014-05-01 08:00:00'
- cls.str_str = cls.uni_str.encode()
-
+ res = parse(dstr)
+ expected = datetime(2014, 1, 19)
+ assert res == expected
+
+ def test_parse_str(self):
+ # Parser should be able to handle bytestring and unicode
+ uni_str = '2014-05-01 08:00:00'
+ bytes_str = uni_str.encode()
+
+ res = parse(bytes_str)
+ expected = parse(uni_str)
+ assert res == expected
+
+ def test_parse_bytes(self):
+ res = parse(b'2014 January 19')
+ expected = datetime(2014, 1, 19)
+ assert res == expected
+
+ def test_parse_bytearray(self):
+ # GH#417
+ res = parse(bytearray(b'2014 January 19'))
+ expected = datetime(2014, 1, 19)
+ assert res == expected
+
+
+class TestTzinfoInputTypes(object):
+ def assert_equal_same_tz(self, dt1, dt2):
+ assert dt1 == dt2
+ assert dt1.tzinfo is dt2.tzinfo
+
+ def test_tzinfo_dict_could_return_none(self):
+ dstr = "2017-02-03 12:40 BRST"
+ result = parse(dstr, tzinfos={"BRST": None})
+ expected = datetime(2017, 2, 3, 12, 40)
+ self.assert_equal_same_tz(result, expected)
+
+ def test_tzinfos_callable_could_return_none(self):
+ dstr = "2017-02-03 12:40 BRST"
+ result = parse(dstr, tzinfos=lambda *args: None)
+ expected = datetime(2017, 2, 3, 12, 40)
+ self.assert_equal_same_tz(result, expected)
+
+ def test_invalid_tzinfo_input(self):
+ dstr = "2014 January 19 09:00 UTC"
+ # Pass an absurd tzinfos object
+ tzinfos = {"UTC": ValueError}
+ with pytest.raises(TypeError):
+ parse(dstr, tzinfos=tzinfos)
+
+ def test_valid_tzinfo_tzinfo_input(self):
+ dstr = "2014 January 19 09:00 UTC"
+ tzinfos = {"UTC": tz.UTC}
+ expected = datetime(2014, 1, 19, 9, tzinfo=tz.UTC)
+ res = parse(dstr, tzinfos=tzinfos)
+ self.assert_equal_same_tz(res, expected)
+
+ def test_valid_tzinfo_unicode_input(self):
+ dstr = "2014 January 19 09:00 UTC"
+ tzinfos = {u"UTC": u"UTC+0"}
+ expected = datetime(2014, 1, 19, 9, tzinfo=tz.tzstr("UTC+0"))
+ res = parse(dstr, tzinfos=tzinfos)
+ self.assert_equal_same_tz(res, expected)
+
+ def test_valid_tzinfo_callable_input(self):
+ dstr = "2014 January 19 09:00 UTC"
+
+ def tzinfos(*args, **kwargs):
+ return u"UTC+0"
+
+ expected = datetime(2014, 1, 19, 9, tzinfo=tz.tzstr("UTC+0"))
+ res = parse(dstr, tzinfos=tzinfos)
+ self.assert_equal_same_tz(res, expected)
+
+ def test_valid_tzinfo_int_input(self):
+ dstr = "2014 January 19 09:00 UTC"
+ tzinfos = {u"UTC": -28800}
+ expected = datetime(2014, 1, 19, 9, tzinfo=tz.tzoffset(u"UTC", -28800))
+ res = parse(dstr, tzinfos=tzinfos)
+ self.assert_equal_same_tz(res, expected)
+
+
+class ParserTest(unittest.TestCase):
+
+ @classmethod
+ def setup_class(cls):
+ cls.tzinfos = {"BRST": -10800}
+ cls.brsttz = tzoffset("BRST", -10800)
+ cls.default = datetime(2003, 9, 25)
+
+ # Parser should be able to handle bytestring and unicode
+ cls.uni_str = '2014-05-01 08:00:00'
+ cls.str_str = cls.uni_str.encode()
+
def testParserParseStr(self):
from dateutil.parser import parser
- assert parser().parse(self.str_str) == parser().parse(self.uni_str)
+ assert parser().parse(self.str_str) == parser().parse(self.uni_str)
def testParseUnicodeWords(self):
@@ -438,9 +438,9 @@ class ParserTest(unittest.TestCase):
("ноя", "Ноябрь"),
("дек", "Декабрь")]
- expected = datetime(2015, 9, 10, 10, 20)
- res = parse('10 Сентябрь 2015 10:20', parserinfo=rus_parserinfo())
- assert res == expected
+ expected = datetime(2015, 9, 10, 10, 20)
+ res = parse('10 Сентябрь 2015 10:20', parserinfo=rus_parserinfo())
+ assert res == expected
def testParseWithNulls(self):
# This relies on the from __future__ import unicode_literals, because
@@ -448,7 +448,7 @@ class ParserTest(unittest.TestCase):
# May want to switch to u'...' if we ever drop Python 3.2 support.
pstring = '\x00\x00August 29, 1924'
- assert parse(pstring) == datetime(1924, 8, 29)
+ assert parse(pstring) == datetime(1924, 8, 29)
def testDateCommandFormat(self):
self.assertEqual(parse("Thu Sep 25 10:36:28 BRST 2003",
@@ -463,34 +463,34 @@ class ParserTest(unittest.TestCase):
tzinfo=self.brsttz))
def testDateCommandFormatWithLong(self):
- if PY2:
+ if PY2:
self.assertEqual(parse("Thu Sep 25 10:36:28 BRST 2003",
tzinfos={"BRST": long(-10800)}),
datetime(2003, 9, 25, 10, 36, 28,
tzinfo=self.brsttz))
-
+
def testISOFormatStrip2(self):
- self.assertEqual(parse("2003-09-25T10:49:41+03:00"),
- datetime(2003, 9, 25, 10, 49, 41,
- tzinfo=tzoffset(None, 10800)))
+ self.assertEqual(parse("2003-09-25T10:49:41+03:00"),
+ datetime(2003, 9, 25, 10, 49, 41,
+ tzinfo=tzoffset(None, 10800)))
def testISOStrippedFormatStrip2(self):
- self.assertEqual(parse("20030925T104941+0300"),
- datetime(2003, 9, 25, 10, 49, 41,
- tzinfo=tzoffset(None, 10800)))
+ self.assertEqual(parse("20030925T104941+0300"),
+ datetime(2003, 9, 25, 10, 49, 41,
+ tzinfo=tzoffset(None, 10800)))
def testAMPMNoHour(self):
- with pytest.raises(ParserError):
+ with pytest.raises(ParserError):
parse("AM")
- with pytest.raises(ParserError):
+ with pytest.raises(ParserError):
parse("Jan 20, 2015 PM")
def testAMPMRange(self):
- with pytest.raises(ParserError):
+ with pytest.raises(ParserError):
parse("13:44 AM")
- with pytest.raises(ParserError):
+ with pytest.raises(ParserError):
parse("January 25, 1921 23:13 PM")
def testPertain(self):
@@ -566,15 +566,15 @@ class ParserTest(unittest.TestCase):
datetime(2008, 2, 29))
def testErrorType01(self):
- with pytest.raises(ParserError):
- parse('shouldfail')
+ with pytest.raises(ParserError):
+ parse('shouldfail')
def testCorrectErrorOnFuzzyWithTokens(self):
- assertRaisesRegex(self, ParserError, 'Unknown string format',
+ assertRaisesRegex(self, ParserError, 'Unknown string format',
parse, '04/04/32/423', fuzzy_with_tokens=True)
- assertRaisesRegex(self, ParserError, 'Unknown string format',
+ assertRaisesRegex(self, ParserError, 'Unknown string format',
parse, '04/04/04 +32423', fuzzy_with_tokens=True)
- assertRaisesRegex(self, ParserError, 'Unknown string format',
+ assertRaisesRegex(self, ParserError, 'Unknown string format',
parse, '04/04/0d4', fuzzy_with_tokens=True)
def testIncreasingCTime(self):
@@ -585,22 +585,22 @@ class ParserTest(unittest.TestCase):
delta = timedelta(days=365+31+1, seconds=1+60+60*60)
dt = datetime(1900, 1, 1, 0, 0, 0, 0)
for i in range(200):
- assert parse(dt.ctime()) == dt
+ assert parse(dt.ctime()) == dt
dt += delta
def testIncreasingISOFormat(self):
delta = timedelta(days=365+31+1, seconds=1+60+60*60)
dt = datetime(1900, 1, 1, 0, 0, 0, 0)
for i in range(200):
- assert parse(dt.isoformat()) == dt
+ assert parse(dt.isoformat()) == dt
dt += delta
def testMicrosecondsPrecisionError(self):
# Skip found out that sad precision problem. :-(
dt1 = parse("00:11:25.01")
dt2 = parse("00:12:10.01")
- assert dt1.microsecond == 10000
- assert dt2.microsecond == 10000
+ assert dt1.microsecond == 10000
+ assert dt2.microsecond == 10000
def testMicrosecondPrecisionErrorReturns(self):
# One more precision issue, discovered by Eric Brown. This should
@@ -610,7 +610,7 @@ class ParserTest(unittest.TestCase):
1001, 1000, 999, 998,
101, 100, 99, 98]:
dt = datetime(2008, 2, 27, 21, 26, 1, ms)
- assert parse(dt.isoformat()) == dt
+ assert parse(dt.isoformat()) == dt
def testCustomParserInfo(self):
# Custom parser info wasn't working, as Michael Elsdörfer discovered.
@@ -621,7 +621,7 @@ class ParserTest(unittest.TestCase):
MONTHS[0] = ("Foo", "Foo")
myparser = parser(myparserinfo())
dt = myparser.parse("01/Foo/2007")
- assert dt == datetime(2007, 1, 1)
+ assert dt == datetime(2007, 1, 1)
def testCustomParserShortDaynames(self):
# Horacio Hoyos discovered that day names shorter than 3 characters,
@@ -704,18 +704,18 @@ class ParserTest(unittest.TestCase):
# Pre-PR, the trailing colon will cause an IndexError at 824-825
# when checking `i < len_l` and then accessing `l[i+1]`
res = parse(dtstr, fuzzy=True)
- assert res == datetime(2017, 7, 17, 6, 15)
+ assert res == datetime(2017, 7, 17, 6, 15)
def test_hmBY(self):
# See GH#483
dtstr = '02:17NOV2017'
res = parse(dtstr, default=self.default)
- assert res == datetime(2017, 11, self.default.day, 2, 17)
+ assert res == datetime(2017, 11, self.default.day, 2, 17)
def test_validate_hour(self):
# See GH353
invalid = "201A-01-01T23:58:39.239769+03:00"
- with pytest.raises(ParserError):
+ with pytest.raises(ParserError):
parse(invalid)
def test_era_trailing_year(self):
@@ -723,52 +723,52 @@ class ParserTest(unittest.TestCase):
res = parse(dstr)
assert res.year == 2001, res
- def test_includes_timestr(self):
- timestr = "2020-13-97T44:61:83"
-
- try:
- parse(timestr)
- except ParserError as e:
- assert e.args[1] == timestr
- else:
- pytest.fail("Failed to raise ParserError")
-
-
-class TestOutOfBounds(object):
-
- def test_no_year_zero(self):
- with pytest.raises(ParserError):
- parse("0000 Jun 20")
-
- def test_out_of_bound_day(self):
- with pytest.raises(ParserError):
- parse("Feb 30, 2007")
-
- def test_illegal_month_error(self):
- with pytest.raises(ParserError):
- parse("0-100")
-
- def test_day_sanity(self, fuzzy):
- dstr = "2014-15-25"
- with pytest.raises(ParserError):
- parse(dstr, fuzzy=fuzzy)
-
- def test_minute_sanity(self, fuzzy):
- dstr = "2014-02-28 22:64"
- with pytest.raises(ParserError):
- parse(dstr, fuzzy=fuzzy)
-
- def test_hour_sanity(self, fuzzy):
- dstr = "2014-02-28 25:16 PM"
- with pytest.raises(ParserError):
- parse(dstr, fuzzy=fuzzy)
-
- def test_second_sanity(self, fuzzy):
- dstr = "2014-02-28 22:14:64"
- with pytest.raises(ParserError):
- parse(dstr, fuzzy=fuzzy)
-
-
+ def test_includes_timestr(self):
+ timestr = "2020-13-97T44:61:83"
+
+ try:
+ parse(timestr)
+ except ParserError as e:
+ assert e.args[1] == timestr
+ else:
+ pytest.fail("Failed to raise ParserError")
+
+
+class TestOutOfBounds(object):
+
+ def test_no_year_zero(self):
+ with pytest.raises(ParserError):
+ parse("0000 Jun 20")
+
+ def test_out_of_bound_day(self):
+ with pytest.raises(ParserError):
+ parse("Feb 30, 2007")
+
+ def test_illegal_month_error(self):
+ with pytest.raises(ParserError):
+ parse("0-100")
+
+ def test_day_sanity(self, fuzzy):
+ dstr = "2014-15-25"
+ with pytest.raises(ParserError):
+ parse(dstr, fuzzy=fuzzy)
+
+ def test_minute_sanity(self, fuzzy):
+ dstr = "2014-02-28 22:64"
+ with pytest.raises(ParserError):
+ parse(dstr, fuzzy=fuzzy)
+
+ def test_hour_sanity(self, fuzzy):
+ dstr = "2014-02-28 25:16 PM"
+ with pytest.raises(ParserError):
+ parse(dstr, fuzzy=fuzzy)
+
+ def test_second_sanity(self, fuzzy):
+ dstr = "2014-02-28 22:14:64"
+ with pytest.raises(ParserError):
+ parse(dstr, fuzzy=fuzzy)
+
+
class TestParseUnimplementedCases(object):
@pytest.mark.xfail
def test_somewhat_ambiguous_string(self):
@@ -818,7 +818,7 @@ class TestParseUnimplementedCases(object):
@pytest.mark.xfail
def test_non_date_number(self):
dstr = '1,700'
- with pytest.raises(ParserError):
+ with pytest.raises(ParserError):
parse(dstr)
@pytest.mark.xfail
@@ -842,7 +842,7 @@ class TestParseUnimplementedCases(object):
def test_extraneous_year_tokens(self):
# This was found in the wild at insidertrading.org
# Unlike in the case above, identifying the first "2012" as the year
- # would not be a problem, but inferring that the latter 2012 is hhmm
+ # would not be a problem, but inferring that the latter 2012 is hhmm
# is a problem.
dstr = "2012 MARTIN CHILDREN'S IRREVOCABLE TRUST u/a/d NOVEMBER 7, 2012"
expected = datetime(2012, 11, 7)
@@ -876,52 +876,52 @@ class TestParseUnimplementedCases(object):
expected = datetime(2017, 12, 1)
assert res == expected
- @pytest.mark.xfail
- def test_extraneous_numerical_content(self):
- # ref: https://github.com/dateutil/dateutil/issues/1029
- # parser interprets price and percentage as parts of the date
- dstr = "£14.99 (25% off, until April 20)"
- res = parse(dstr, fuzzy=True, default=datetime(2000, 1, 1))
- expected = datetime(2000, 4, 20)
- assert res == expected
-
-
-@pytest.mark.skipif(IS_WIN, reason="Windows does not use TZ var")
-class TestTZVar(object):
- def test_parse_unambiguous_nonexistent_local(self):
- # When dates are specified "EST" even when they should be "EDT" in the
- # local time zone, we should still assign the local time zone
- with TZEnvContext('EST+5EDT,M3.2.0/2,M11.1.0/2'):
- dt_exp = datetime(2011, 8, 1, 12, 30, tzinfo=tz.tzlocal())
- dt = parse('2011-08-01T12:30 EST')
-
- assert dt.tzname() == 'EDT'
- assert dt == dt_exp
-
- def test_tzlocal_in_gmt(self):
- # GH #318
- with TZEnvContext('GMT0BST,M3.5.0,M10.5.0'):
- # This is an imaginary datetime in tz.tzlocal() but should still
- # parse using the GMT-as-alias-for-UTC rule
- dt = parse('2004-05-01T12:00 GMT')
- dt_exp = datetime(2004, 5, 1, 12, tzinfo=tz.UTC)
-
- assert dt == dt_exp
-
- def test_tzlocal_parse_fold(self):
- # One manifestion of GH #318
- with TZEnvContext('EST+5EDT,M3.2.0/2,M11.1.0/2'):
- dt_exp = datetime(2011, 11, 6, 1, 30, tzinfo=tz.tzlocal())
- dt_exp = tz.enfold(dt_exp, fold=1)
- dt = parse('2011-11-06T01:30 EST')
-
- # Because this is ambiguous, until `tz.tzlocal() is tz.tzlocal()`
- # we'll just check the attributes we care about rather than
- # dt == dt_exp
- assert dt.tzname() == dt_exp.tzname()
- assert dt.replace(tzinfo=None) == dt_exp.replace(tzinfo=None)
- assert getattr(dt, 'fold') == getattr(dt_exp, 'fold')
- assert dt.astimezone(tz.UTC) == dt_exp.astimezone(tz.UTC)
+ @pytest.mark.xfail
+ def test_extraneous_numerical_content(self):
+ # ref: https://github.com/dateutil/dateutil/issues/1029
+ # parser interprets price and percentage as parts of the date
+ dstr = "£14.99 (25% off, until April 20)"
+ res = parse(dstr, fuzzy=True, default=datetime(2000, 1, 1))
+ expected = datetime(2000, 4, 20)
+ assert res == expected
+
+
+@pytest.mark.skipif(IS_WIN, reason="Windows does not use TZ var")
+class TestTZVar(object):
+ def test_parse_unambiguous_nonexistent_local(self):
+ # When dates are specified "EST" even when they should be "EDT" in the
+ # local time zone, we should still assign the local time zone
+ with TZEnvContext('EST+5EDT,M3.2.0/2,M11.1.0/2'):
+ dt_exp = datetime(2011, 8, 1, 12, 30, tzinfo=tz.tzlocal())
+ dt = parse('2011-08-01T12:30 EST')
+
+ assert dt.tzname() == 'EDT'
+ assert dt == dt_exp
+
+ def test_tzlocal_in_gmt(self):
+ # GH #318
+ with TZEnvContext('GMT0BST,M3.5.0,M10.5.0'):
+ # This is an imaginary datetime in tz.tzlocal() but should still
+ # parse using the GMT-as-alias-for-UTC rule
+ dt = parse('2004-05-01T12:00 GMT')
+ dt_exp = datetime(2004, 5, 1, 12, tzinfo=tz.UTC)
+
+ assert dt == dt_exp
+
+ def test_tzlocal_parse_fold(self):
+ # One manifestion of GH #318
+ with TZEnvContext('EST+5EDT,M3.2.0/2,M11.1.0/2'):
+ dt_exp = datetime(2011, 11, 6, 1, 30, tzinfo=tz.tzlocal())
+ dt_exp = tz.enfold(dt_exp, fold=1)
+ dt = parse('2011-11-06T01:30 EST')
+
+ # Because this is ambiguous, until `tz.tzlocal() is tz.tzlocal()`
+ # we'll just check the attributes we care about rather than
+ # dt == dt_exp
+ assert dt.tzname() == dt_exp.tzname()
+ assert dt.replace(tzinfo=None) == dt_exp.replace(tzinfo=None)
+ assert getattr(dt, 'fold') == getattr(dt_exp, 'fold')
+ assert dt.astimezone(tz.UTC) == dt_exp.astimezone(tz.UTC)
def test_parse_tzinfos_fold():
@@ -934,7 +934,7 @@ def test_parse_tzinfos_fold():
assert dt == dt_exp
assert dt.tzinfo is dt_exp.tzinfo
assert getattr(dt, 'fold') == getattr(dt_exp, 'fold')
- assert dt.astimezone(tz.UTC) == dt_exp.astimezone(tz.UTC)
+ assert dt.astimezone(tz.UTC) == dt_exp.astimezone(tz.UTC)
@pytest.mark.parametrize('dtstr,dt', [
@@ -949,16 +949,16 @@ def test_rounding_floatlike_strings(dtstr, dt):
@pytest.mark.parametrize('value', ['1: test', 'Nan'])
def test_decimal_error(value):
- # GH 632, GH 662 - decimal.Decimal raises some non-ParserError exception
- # when constructed with an invalid value
- with pytest.raises(ParserError):
+ # GH 632, GH 662 - decimal.Decimal raises some non-ParserError exception
+ # when constructed with an invalid value
+ with pytest.raises(ParserError):
parse(value)
-
-def test_parsererror_repr():
- # GH 991 — the __repr__ was not properly indented and so was never defined.
- # This tests the current behavior of the ParserError __repr__, but the
- # precise format is not guaranteed to be stable and may change even in
- # minor versions. This test exists to avoid regressions.
- s = repr(ParserError("Problem with string: %s", "2019-01-01"))
-
- assert s == "ParserError('Problem with string: %s', '2019-01-01')"
+
+def test_parsererror_repr():
+ # GH 991 — the __repr__ was not properly indented and so was never defined.
+ # This tests the current behavior of the ParserError __repr__, but the
+ # precise format is not guaranteed to be stable and may change even in
+ # minor versions. This test exists to avoid regressions.
+ s = repr(ParserError("Problem with string: %s", "2019-01-01"))
+
+ assert s == "ParserError('Problem with string: %s', '2019-01-01')"
diff --git a/contrib/python/dateutil/dateutil/test/test_relativedelta.py b/contrib/python/dateutil/dateutil/test/test_relativedelta.py
index 1e5d170449..9a72b2e3af 100644
--- a/contrib/python/dateutil/dateutil/test/test_relativedelta.py
+++ b/contrib/python/dateutil/dateutil/test/test_relativedelta.py
@@ -1,17 +1,17 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
-from ._common import NotAValue
+from ._common import NotAValue
import calendar
from datetime import datetime, date, timedelta
import unittest
-import pytest
-
+import pytest
+
from dateutil.relativedelta import relativedelta, MO, TU, WE, FR, SU
-class RelativeDeltaTest(unittest.TestCase):
+class RelativeDeltaTest(unittest.TestCase):
now = datetime(2003, 9, 17, 20, 54, 47, 282310)
today = date(2003, 9, 17)
@@ -119,30 +119,30 @@ class RelativeDeltaTest(unittest.TestCase):
self.assertEqual(self.today+relativedelta(day=31, weekday=FR(-1)),
date(2003, 9, 26))
- def testLastDayOfFebruary(self):
- self.assertEqual(date(2021, 2, 1) + relativedelta(day=31),
- date(2021, 2, 28))
-
- def testLastDayOfFebruaryLeapYear(self):
- self.assertEqual(date(2020, 2, 1) + relativedelta(day=31),
- date(2020, 2, 29))
-
+ def testLastDayOfFebruary(self):
+ self.assertEqual(date(2021, 2, 1) + relativedelta(day=31),
+ date(2021, 2, 28))
+
+ def testLastDayOfFebruaryLeapYear(self):
+ self.assertEqual(date(2020, 2, 1) + relativedelta(day=31),
+ date(2020, 2, 29))
+
def testNextWednesdayIsToday(self):
self.assertEqual(self.today+relativedelta(weekday=WE),
date(2003, 9, 17))
- def testNextWednesdayNotToday(self):
+ def testNextWednesdayNotToday(self):
self.assertEqual(self.today+relativedelta(days=+1, weekday=WE),
date(2003, 9, 24))
- def testAddMoreThan12Months(self):
- self.assertEqual(date(2003, 12, 1) + relativedelta(months=+13),
- date(2005, 1, 1))
-
- def testAddNegativeMonths(self):
- self.assertEqual(date(2003, 1, 1) + relativedelta(months=-2),
- date(2002, 11, 1))
-
+ def testAddMoreThan12Months(self):
+ self.assertEqual(date(2003, 12, 1) + relativedelta(months=+13),
+ date(2005, 1, 1))
+
+ def testAddNegativeMonths(self):
+ self.assertEqual(date(2003, 1, 1) + relativedelta(months=-2),
+ date(2002, 11, 1))
+
def test15thISOYearWeek(self):
self.assertEqual(date(2003, 1, 1) +
relativedelta(day=4, weeks=+14, weekday=MO(-1)),
@@ -368,38 +368,38 @@ class RelativeDeltaTest(unittest.TestCase):
with self.assertRaises(ValueError):
relativedelta(months=1.5)
- def testRelativeDeltaInvalidDatetimeObject(self):
- with self.assertRaises(TypeError):
- relativedelta(dt1='2018-01-01', dt2='2018-01-02')
-
- with self.assertRaises(TypeError):
- relativedelta(dt1=datetime(2018, 1, 1), dt2='2018-01-02')
-
- with self.assertRaises(TypeError):
- relativedelta(dt1='2018-01-01', dt2=datetime(2018, 1, 2))
-
+ def testRelativeDeltaInvalidDatetimeObject(self):
+ with self.assertRaises(TypeError):
+ relativedelta(dt1='2018-01-01', dt2='2018-01-02')
+
+ with self.assertRaises(TypeError):
+ relativedelta(dt1=datetime(2018, 1, 1), dt2='2018-01-02')
+
+ with self.assertRaises(TypeError):
+ relativedelta(dt1='2018-01-01', dt2=datetime(2018, 1, 2))
+
def testRelativeDeltaFractionalAbsolutes(self):
# Fractional absolute values will soon be unsupported,
# check for the deprecation warning.
- with pytest.warns(DeprecationWarning):
+ with pytest.warns(DeprecationWarning):
relativedelta(year=2.86)
- with pytest.warns(DeprecationWarning):
+ with pytest.warns(DeprecationWarning):
relativedelta(month=1.29)
- with pytest.warns(DeprecationWarning):
+ with pytest.warns(DeprecationWarning):
relativedelta(day=0.44)
- with pytest.warns(DeprecationWarning):
+ with pytest.warns(DeprecationWarning):
relativedelta(hour=23.98)
- with pytest.warns(DeprecationWarning):
+ with pytest.warns(DeprecationWarning):
relativedelta(minute=45.21)
- with pytest.warns(DeprecationWarning):
+ with pytest.warns(DeprecationWarning):
relativedelta(second=13.2)
- with pytest.warns(DeprecationWarning):
+ with pytest.warns(DeprecationWarning):
relativedelta(microsecond=157221.93)
def testRelativeDeltaFractionalRepr(self):
@@ -484,7 +484,7 @@ class RelativeDeltaTest(unittest.TestCase):
self.assertEqual(rd1.normalized(), relativedelta(days=2, hours=18))
- # Equivalent to (days=1, hours=11, minutes=31, seconds=12)
+ # Equivalent to (days=1, hours=11, minutes=31, seconds=12)
rd2 = relativedelta(days=1.48)
self.assertEqual(rd2.normalized(),
diff --git a/contrib/python/dateutil/dateutil/test/test_rrule.py b/contrib/python/dateutil/dateutil/test/test_rrule.py
index 52673ecc26..9a3dbca042 100644
--- a/contrib/python/dateutil/dateutil/test/test_rrule.py
+++ b/contrib/python/dateutil/dateutil/test/test_rrule.py
@@ -3,7 +3,7 @@ from __future__ import unicode_literals
from datetime import datetime, date
import unittest
-from six import PY2
+from six import PY2
from dateutil import tz
from dateutil.rrule import (
@@ -19,7 +19,7 @@ import pytest
@pytest.mark.rrule
-class RRuleTest(unittest.TestCase):
+class RRuleTest(unittest.TestCase):
def _rrulestr_reverse_test(self, rule):
"""
Call with an `rrule` and it will test that `str(rrule)` generates a
@@ -2283,7 +2283,7 @@ class RRuleTest(unittest.TestCase):
datetime(2010, 3, 22, 14, 1)])
def testLongIntegers(self):
- if PY2: # There are no longs in python3
+ if PY2: # There are no longs in python3
self.assertEqual(list(rrule(MINUTELY,
count=long(2),
interval=long(2),
@@ -2371,7 +2371,7 @@ class RRuleTest(unittest.TestCase):
See rfc-5545 3.3.10 - This checks for the deprecation warning, and will
eventually check for an error.
"""
- with pytest.warns(DeprecationWarning):
+ with pytest.warns(DeprecationWarning):
rrule(DAILY, dtstart=datetime(1997, 9, 2, 9, 0),
count=3, until=datetime(1997, 9, 4, 9, 0))
@@ -2852,74 +2852,74 @@ class RRuleTest(unittest.TestCase):
datetime(1997, 9, 9, 9, 0),
datetime(1997, 9, 16, 9, 0)])
- def testStrSetExDateMultiple(self):
- rrstr = ("DTSTART:19970902T090000\n"
- "RRULE:FREQ=YEARLY;COUNT=6;BYDAY=TU,TH\n"
- "EXDATE:19970904T090000,19970911T090000,19970918T090000\n")
-
- rr = rrulestr(rrstr)
- assert list(rr) == [datetime(1997, 9, 2, 9, 0),
- datetime(1997, 9, 9, 9, 0),
- datetime(1997, 9, 16, 9, 0)]
-
- def testStrSetExDateWithTZID(self):
- BXL = tz.gettz('Europe/Brussels')
- rr = rrulestr("DTSTART;TZID=Europe/Brussels:19970902T090000\n"
- "RRULE:FREQ=YEARLY;COUNT=6;BYDAY=TU,TH\n"
- "EXDATE;TZID=Europe/Brussels:19970904T090000\n"
- "EXDATE;TZID=Europe/Brussels:19970911T090000\n"
- "EXDATE;TZID=Europe/Brussels:19970918T090000\n")
-
- assert list(rr) == [datetime(1997, 9, 2, 9, 0, tzinfo=BXL),
- datetime(1997, 9, 9, 9, 0, tzinfo=BXL),
- datetime(1997, 9, 16, 9, 0, tzinfo=BXL)]
-
- def testStrSetExDateValueDateTimeNoTZID(self):
- rrstr = '\n'.join([
- "DTSTART:19970902T090000",
- "RRULE:FREQ=YEARLY;COUNT=4;BYDAY=TU,TH",
- "EXDATE;VALUE=DATE-TIME:19970902T090000",
- "EXDATE;VALUE=DATE-TIME:19970909T090000",
- ])
-
- rr = rrulestr(rrstr)
- assert list(rr) == [datetime(1997, 9, 4, 9), datetime(1997, 9, 11, 9)]
-
- def testStrSetExDateValueMixDateTimeNoTZID(self):
- rrstr = '\n'.join([
- "DTSTART:19970902T090000",
- "RRULE:FREQ=YEARLY;COUNT=4;BYDAY=TU,TH",
- "EXDATE;VALUE=DATE-TIME:19970902T090000",
- "EXDATE:19970909T090000",
- ])
-
- rr = rrulestr(rrstr)
- assert list(rr) == [datetime(1997, 9, 4, 9), datetime(1997, 9, 11, 9)]
-
- def testStrSetExDateValueDateTimeWithTZID(self):
- BXL = tz.gettz('Europe/Brussels')
- rrstr = '\n'.join([
- "DTSTART;VALUE=DATE-TIME;TZID=Europe/Brussels:19970902T090000",
- "RRULE:FREQ=YEARLY;COUNT=4;BYDAY=TU,TH",
- "EXDATE;VALUE=DATE-TIME;TZID=Europe/Brussels:19970902T090000",
- "EXDATE;VALUE=DATE-TIME;TZID=Europe/Brussels:19970909T090000",
- ])
-
- rr = rrulestr(rrstr)
- assert list(rr) == [datetime(1997, 9, 4, 9, tzinfo=BXL),
- datetime(1997, 9, 11, 9, tzinfo=BXL)]
-
- def testStrSetExDateValueDate(self):
- rrstr = '\n'.join([
- "DTSTART;VALUE=DATE:19970902",
- "RRULE:FREQ=YEARLY;COUNT=4;BYDAY=TU,TH",
- "EXDATE;VALUE=DATE:19970902",
- "EXDATE;VALUE=DATE:19970909",
- ])
-
- rr = rrulestr(rrstr)
- assert list(rr) == [datetime(1997, 9, 4), datetime(1997, 9, 11)]
-
+ def testStrSetExDateMultiple(self):
+ rrstr = ("DTSTART:19970902T090000\n"
+ "RRULE:FREQ=YEARLY;COUNT=6;BYDAY=TU,TH\n"
+ "EXDATE:19970904T090000,19970911T090000,19970918T090000\n")
+
+ rr = rrulestr(rrstr)
+ assert list(rr) == [datetime(1997, 9, 2, 9, 0),
+ datetime(1997, 9, 9, 9, 0),
+ datetime(1997, 9, 16, 9, 0)]
+
+ def testStrSetExDateWithTZID(self):
+ BXL = tz.gettz('Europe/Brussels')
+ rr = rrulestr("DTSTART;TZID=Europe/Brussels:19970902T090000\n"
+ "RRULE:FREQ=YEARLY;COUNT=6;BYDAY=TU,TH\n"
+ "EXDATE;TZID=Europe/Brussels:19970904T090000\n"
+ "EXDATE;TZID=Europe/Brussels:19970911T090000\n"
+ "EXDATE;TZID=Europe/Brussels:19970918T090000\n")
+
+ assert list(rr) == [datetime(1997, 9, 2, 9, 0, tzinfo=BXL),
+ datetime(1997, 9, 9, 9, 0, tzinfo=BXL),
+ datetime(1997, 9, 16, 9, 0, tzinfo=BXL)]
+
+ def testStrSetExDateValueDateTimeNoTZID(self):
+ rrstr = '\n'.join([
+ "DTSTART:19970902T090000",
+ "RRULE:FREQ=YEARLY;COUNT=4;BYDAY=TU,TH",
+ "EXDATE;VALUE=DATE-TIME:19970902T090000",
+ "EXDATE;VALUE=DATE-TIME:19970909T090000",
+ ])
+
+ rr = rrulestr(rrstr)
+ assert list(rr) == [datetime(1997, 9, 4, 9), datetime(1997, 9, 11, 9)]
+
+ def testStrSetExDateValueMixDateTimeNoTZID(self):
+ rrstr = '\n'.join([
+ "DTSTART:19970902T090000",
+ "RRULE:FREQ=YEARLY;COUNT=4;BYDAY=TU,TH",
+ "EXDATE;VALUE=DATE-TIME:19970902T090000",
+ "EXDATE:19970909T090000",
+ ])
+
+ rr = rrulestr(rrstr)
+ assert list(rr) == [datetime(1997, 9, 4, 9), datetime(1997, 9, 11, 9)]
+
+ def testStrSetExDateValueDateTimeWithTZID(self):
+ BXL = tz.gettz('Europe/Brussels')
+ rrstr = '\n'.join([
+ "DTSTART;VALUE=DATE-TIME;TZID=Europe/Brussels:19970902T090000",
+ "RRULE:FREQ=YEARLY;COUNT=4;BYDAY=TU,TH",
+ "EXDATE;VALUE=DATE-TIME;TZID=Europe/Brussels:19970902T090000",
+ "EXDATE;VALUE=DATE-TIME;TZID=Europe/Brussels:19970909T090000",
+ ])
+
+ rr = rrulestr(rrstr)
+ assert list(rr) == [datetime(1997, 9, 4, 9, tzinfo=BXL),
+ datetime(1997, 9, 11, 9, tzinfo=BXL)]
+
+ def testStrSetExDateValueDate(self):
+ rrstr = '\n'.join([
+ "DTSTART;VALUE=DATE:19970902",
+ "RRULE:FREQ=YEARLY;COUNT=4;BYDAY=TU,TH",
+ "EXDATE;VALUE=DATE:19970902",
+ "EXDATE;VALUE=DATE:19970909",
+ ])
+
+ rr = rrulestr(rrstr)
+ assert list(rr) == [datetime(1997, 9, 4), datetime(1997, 9, 11)]
+
def testStrSetDateAndExDate(self):
self.assertEqual(list(rrulestr(
"DTSTART:19970902T090000\n"
@@ -2996,11 +2996,11 @@ class RRuleTest(unittest.TestCase):
self.assertEqual(list(rr), [datetime(1997, 9, 2, 0, 0, 0),
datetime(1998, 9, 2, 0, 0, 0)])
- def testStrMultipleDTStartComma(self):
- with pytest.raises(ValueError):
- rr = rrulestr("DTSTART:19970101T000000,19970202T000000\n"
- "RRULE:FREQ=YEARLY;COUNT=1")
-
+ def testStrMultipleDTStartComma(self):
+ with pytest.raises(ValueError):
+ rr = rrulestr("DTSTART:19970101T000000,19970202T000000\n"
+ "RRULE:FREQ=YEARLY;COUNT=1")
+
def testStrInvalidUntil(self):
with self.assertRaises(ValueError):
list(rrulestr("DTSTART:19970902T090000\n"
@@ -4578,7 +4578,7 @@ class RRuleTest(unittest.TestCase):
dtstart=datetime(1997, 9, 2, 9, 0)))
def testToStrLongIntegers(self):
- if PY2: # There are no longs in python3
+ if PY2: # There are no longs in python3
self._rrulestr_reverse_test(rrule(MINUTELY,
count=long(2),
interval=long(2),
diff --git a/contrib/python/dateutil/dateutil/test/test_tz.py b/contrib/python/dateutil/dateutil/test/test_tz.py
index e5e4772d9a..0fba337a3e 100644
--- a/contrib/python/dateutil/dateutil/test/test_tz.py
+++ b/contrib/python/dateutil/dateutil/test/test_tz.py
@@ -7,15 +7,15 @@ from ._common import ComparesEqual
from datetime import datetime, timedelta
from datetime import time as dt_time
from datetime import tzinfo
-from six import PY2
-from io import BytesIO, StringIO
+from six import PY2
+from io import BytesIO, StringIO
import unittest
import sys
import base64
import copy
-import gc
-import weakref
+import gc
+import weakref
from functools import partial
@@ -156,9 +156,9 @@ END:VTIMEZONE
EST_TUPLE = ('EST', timedelta(hours=-5), timedelta(hours=0))
EDT_TUPLE = ('EDT', timedelta(hours=-4), timedelta(hours=1))
-SUPPORTS_SUB_MINUTE_OFFSETS = sys.version_info >= (3, 6)
-
+SUPPORTS_SUB_MINUTE_OFFSETS = sys.version_info >= (3, 6)
+
###
# Helper functions
def get_timezone_tuple(dt):
@@ -197,8 +197,8 @@ class TzFoldMixin(object):
with self._gettz_context(tzname):
SYD = self.gettz(tzname)
- t0_u = datetime(2012, 3, 31, 15, 30, tzinfo=tz.UTC) # AEST
- t1_u = datetime(2012, 3, 31, 16, 30, tzinfo=tz.UTC) # AEDT
+ t0_u = datetime(2012, 3, 31, 15, 30, tzinfo=tz.UTC) # AEST
+ t1_u = datetime(2012, 3, 31, 16, 30, tzinfo=tz.UTC) # AEDT
t0_syd0 = t0_u.astimezone(SYD)
t1_syd1 = t1_u.astimezone(SYD)
@@ -219,8 +219,8 @@ class TzFoldMixin(object):
with self._gettz_context(tzname):
SYD = self.gettz(tzname)
- t0_u = datetime(2012, 10, 6, 15, 30, tzinfo=tz.UTC) # AEST
- t1_u = datetime(2012, 10, 6, 16, 30, tzinfo=tz.UTC) # AEDT
+ t0_u = datetime(2012, 10, 6, 15, 30, tzinfo=tz.UTC) # AEST
+ t1_u = datetime(2012, 10, 6, 16, 30, tzinfo=tz.UTC) # AEDT
t0 = t0_u.astimezone(SYD)
t1 = t1_u.astimezone(SYD)
@@ -241,8 +241,8 @@ class TzFoldMixin(object):
with self._gettz_context(tzname):
TOR = self.gettz(tzname)
- t0_u = datetime(2011, 11, 6, 5, 30, tzinfo=tz.UTC)
- t1_u = datetime(2011, 11, 6, 6, 30, tzinfo=tz.UTC)
+ t0_u = datetime(2011, 11, 6, 5, 30, tzinfo=tz.UTC)
+ t1_u = datetime(2011, 11, 6, 6, 30, tzinfo=tz.UTC)
t0_tor = t0_u.astimezone(TOR)
t1_tor = t1_u.astimezone(TOR)
@@ -264,8 +264,8 @@ class TzFoldMixin(object):
with self._gettz_context(tzname):
TOR = self.gettz(tzname)
- t0_u = datetime(2011, 3, 13, 6, 30, tzinfo=tz.UTC)
- t1_u = datetime(2011, 3, 13, 7, 30, tzinfo=tz.UTC)
+ t0_u = datetime(2011, 3, 13, 6, 30, tzinfo=tz.UTC)
+ t1_u = datetime(2011, 3, 13, 7, 30, tzinfo=tz.UTC)
t0 = t0_u.astimezone(TOR)
t1 = t1_u.astimezone(TOR)
@@ -285,7 +285,7 @@ class TzFoldMixin(object):
with self._gettz_context(tzname):
LON = self.gettz(tzname)
- UTC = tz.UTC
+ UTC = tz.UTC
t0_u = datetime(2013, 10, 27, 0, 30, tzinfo=UTC) # BST
t1_u = datetime(2013, 10, 27, 1, 30, tzinfo=UTC) # GMT
@@ -307,7 +307,7 @@ class TzFoldMixin(object):
with self._gettz_context(tzname):
NYC = self.gettz(tzname)
- UTC = tz.UTC
+ UTC = tz.UTC
hour = timedelta(hours=1)
# Firmly 2015-11-01 0:30 EDT-4
@@ -338,7 +338,7 @@ class TzFoldMixin(object):
with self._gettz_context(tzname):
NYC = self.gettz(tzname)
- UTC = tz.UTC
+ UTC = tz.UTC
dt0 = datetime(2011, 11, 6, 1, 30, tzinfo=NYC)
dt1 = tz.enfold(dt0, fold=1)
@@ -424,7 +424,7 @@ class TzFoldMixin(object):
SYD0 = self.gettz(tzname)
SYD1 = self.gettz(tzname)
- t0_u = datetime(2012, 3, 31, 14, 30, tzinfo=tz.UTC) # AEST
+ t0_u = datetime(2012, 3, 31, 14, 30, tzinfo=tz.UTC) # AEST
t0_syd0 = t0_u.astimezone(SYD0)
t0_syd1 = t0_u.astimezone(SYD1)
@@ -453,13 +453,13 @@ class TzWinFoldMixin(object):
if gap:
t_n = dston - timedelta(minutes=30)
- t0_u = t_n.replace(tzinfo=tzi).astimezone(tz.UTC)
+ t0_u = t_n.replace(tzinfo=tzi).astimezone(tz.UTC)
t1_u = t0_u + timedelta(hours=1)
else:
# Get 1 hour before the first ambiguous date
t_n = dstoff - timedelta(minutes=30)
- t0_u = t_n.replace(tzinfo=tzi).astimezone(tz.UTC)
+ t0_u = t_n.replace(tzinfo=tzi).astimezone(tz.UTC)
t_n += timedelta(hours=1) # Naive ambiguous date
t0_u = t0_u + timedelta(hours=1) # First ambiguous date
t1_u = t0_u + timedelta(hours=1) # Second ambiguous date
@@ -560,7 +560,7 @@ class TzWinFoldMixin(object):
with self.context(tzname):
NYC = self.tzclass(*args)
- UTC = tz.UTC
+ UTC = tz.UTC
hour = timedelta(hours=1)
# Firmly 2015-11-01 0:30 EDT-4
@@ -595,7 +595,7 @@ class TzWinFoldMixin(object):
with self.context(tzname):
NYC = self.tzclass(*args)
- UTC = tz.UTC
+ UTC = tz.UTC
t_n, t0_u, t1_u = self.get_utc_transitions(NYC, 2011, False)
@@ -699,7 +699,7 @@ class TzOffsetTest(unittest.TestCase):
self.assertEqual(utc, gmt)
def testUTCEquality(self):
- utc = tz.UTC
+ utc = tz.UTC
o_utc = tz.tzoffset('UTC', 0)
self.assertEqual(utc, o_utc)
@@ -735,29 +735,29 @@ class TzOffsetTest(unittest.TestCase):
assert tz1 is tz2
-
-@pytest.mark.smoke
-@pytest.mark.tzoffset
-def test_tzoffset_weakref():
- UTC1 = tz.tzoffset('UTC', 0)
- UTC_ref = weakref.ref(tz.tzoffset('UTC', 0))
- UTC1 is UTC_ref()
- del UTC1
- gc.collect()
-
- assert UTC_ref() is not None # Should be in the strong cache
- assert UTC_ref() is tz.tzoffset('UTC', 0)
-
- # Fill the strong cache with other items
- for offset in range(5,15):
- tz.tzoffset('RandomZone', offset)
-
- gc.collect()
- assert UTC_ref() is None
- assert UTC_ref() is not tz.tzoffset('UTC', 0)
-
-
+
+@pytest.mark.smoke
@pytest.mark.tzoffset
+def test_tzoffset_weakref():
+ UTC1 = tz.tzoffset('UTC', 0)
+ UTC_ref = weakref.ref(tz.tzoffset('UTC', 0))
+ UTC1 is UTC_ref()
+ del UTC1
+ gc.collect()
+
+ assert UTC_ref() is not None # Should be in the strong cache
+ assert UTC_ref() is tz.tzoffset('UTC', 0)
+
+ # Fill the strong cache with other items
+ for offset in range(5,15):
+ tz.tzoffset('RandomZone', offset)
+
+ gc.collect()
+ assert UTC_ref() is None
+ assert UTC_ref() is not tz.tzoffset('UTC', 0)
+
+
+@pytest.mark.tzoffset
@pytest.mark.parametrize('args', [
('UTC', 0),
('EST', -18000),
@@ -770,25 +770,25 @@ def test_tzoffset_singleton(args):
assert tz1 is tz2
-
-@pytest.mark.tzoffset
-@pytest.mark.skipif(not SUPPORTS_SUB_MINUTE_OFFSETS,
- reason='Sub-minute offsets not supported')
-def test_tzoffset_sub_minute():
- delta = timedelta(hours=12, seconds=30)
- test_datetime = datetime(2000, 1, 1, tzinfo=tz.tzoffset(None, delta))
- assert test_datetime.utcoffset() == delta
-
-
-@pytest.mark.tzoffset
-@pytest.mark.skipif(SUPPORTS_SUB_MINUTE_OFFSETS,
- reason='Sub-minute offsets supported')
-def test_tzoffset_sub_minute_rounding():
- delta = timedelta(hours=12, seconds=30)
- test_date = datetime(2000, 1, 1, tzinfo=tz.tzoffset(None, delta))
- assert test_date.utcoffset() == timedelta(hours=12, minutes=1)
-
-
+
+@pytest.mark.tzoffset
+@pytest.mark.skipif(not SUPPORTS_SUB_MINUTE_OFFSETS,
+ reason='Sub-minute offsets not supported')
+def test_tzoffset_sub_minute():
+ delta = timedelta(hours=12, seconds=30)
+ test_datetime = datetime(2000, 1, 1, tzinfo=tz.tzoffset(None, delta))
+ assert test_datetime.utcoffset() == delta
+
+
+@pytest.mark.tzoffset
+@pytest.mark.skipif(SUPPORTS_SUB_MINUTE_OFFSETS,
+ reason='Sub-minute offsets supported')
+def test_tzoffset_sub_minute_rounding():
+ delta = timedelta(hours=12, seconds=30)
+ test_date = datetime(2000, 1, 1, tzinfo=tz.tzoffset(None, delta))
+ assert test_date.utcoffset() == timedelta(hours=12, minutes=1)
+
+
@pytest.mark.tzlocal
class TzLocalTest(unittest.TestCase):
def testEquality(self):
@@ -952,7 +952,7 @@ class TzLocalNixTest(unittest.TestCase, TzFoldMixin):
def testUTCEquality(self):
with TZEnvContext(self.UTC):
- assert tz.tzlocal() == tz.UTC
+ assert tz.tzlocal() == tz.UTC
# TODO: Maybe a better hack than this?
@@ -993,7 +993,7 @@ def test_tzlocal_local_time_trim_colon():
@mark_tzlocal_nix
@pytest.mark.parametrize('tzvar, tzoff', [
('EST5', tz.tzoffset('EST', -18000)),
- ('GMT0', tz.tzoffset('GMT', 0)),
+ ('GMT0', tz.tzoffset('GMT', 0)),
('YAKT-9', tz.tzoffset('YAKT', timedelta(hours=9))),
('JST-9', tz.tzoffset('JST', timedelta(hours=9))),
])
@@ -1078,65 +1078,65 @@ class GettzTest(unittest.TestCase, TzFoldMixin):
assert local1 is not local2
-
-@pytest.mark.gettz
-def test_gettz_same_result_for_none_and_empty_string():
- local_from_none = tz.gettz()
- local_from_empty_string = tz.gettz("")
- assert local_from_none is not None
- assert local_from_empty_string is not None
- assert local_from_none == local_from_empty_string
-
-
-@pytest.mark.gettz
-@pytest.mark.parametrize('badzone', [
- 'Fake.Region/Abcdefghijklmnop', # Violates several tz project name rules
-])
-def test_gettz_badzone(badzone):
- # Make sure passing a bad TZ string to gettz returns None (GH #800)
- tzi = tz.gettz(badzone)
- assert tzi is None
-
-
-@pytest.mark.gettz
-def test_gettz_badzone_unicode():
- # Make sure a unicode string can be passed to TZ (GH #802)
- # When fixed, combine this with test_gettz_badzone
- tzi = tz.gettz('🐼')
- assert tzi is None
-
-
-@pytest.mark.gettz
-@pytest.mark.parametrize(
- "badzone,exc_reason",
- [
- pytest.param(
- b"America/New_York",
- ".*should be str, not bytes.*",
- id="bytes on Python 3",
- marks=[
- pytest.mark.skipif(
- PY2, reason="bytes arguments accepted in Python 2"
- )
- ],
- ),
- pytest.param(
- object(),
- None,
- id="no startswith()",
- marks=[
- pytest.mark.xfail(reason="AttributeError instead of TypeError",
- raises=AttributeError),
- ],
- ),
- ],
-)
-def test_gettz_zone_wrong_type(badzone, exc_reason):
- with pytest.raises(TypeError, match=exc_reason):
- tz.gettz(badzone)
-
-
+
@pytest.mark.gettz
+def test_gettz_same_result_for_none_and_empty_string():
+ local_from_none = tz.gettz()
+ local_from_empty_string = tz.gettz("")
+ assert local_from_none is not None
+ assert local_from_empty_string is not None
+ assert local_from_none == local_from_empty_string
+
+
+@pytest.mark.gettz
+@pytest.mark.parametrize('badzone', [
+ 'Fake.Region/Abcdefghijklmnop', # Violates several tz project name rules
+])
+def test_gettz_badzone(badzone):
+ # Make sure passing a bad TZ string to gettz returns None (GH #800)
+ tzi = tz.gettz(badzone)
+ assert tzi is None
+
+
+@pytest.mark.gettz
+def test_gettz_badzone_unicode():
+ # Make sure a unicode string can be passed to TZ (GH #802)
+ # When fixed, combine this with test_gettz_badzone
+ tzi = tz.gettz('🐼')
+ assert tzi is None
+
+
+@pytest.mark.gettz
+@pytest.mark.parametrize(
+ "badzone,exc_reason",
+ [
+ pytest.param(
+ b"America/New_York",
+ ".*should be str, not bytes.*",
+ id="bytes on Python 3",
+ marks=[
+ pytest.mark.skipif(
+ PY2, reason="bytes arguments accepted in Python 2"
+ )
+ ],
+ ),
+ pytest.param(
+ object(),
+ None,
+ id="no startswith()",
+ marks=[
+ pytest.mark.xfail(reason="AttributeError instead of TypeError",
+ raises=AttributeError),
+ ],
+ ),
+ ],
+)
+def test_gettz_zone_wrong_type(badzone, exc_reason):
+ with pytest.raises(TypeError, match=exc_reason):
+ tz.gettz(badzone)
+
+
+@pytest.mark.gettz
@pytest.mark.xfail(IS_WIN, reason='zoneinfo separately cached')
def test_gettz_cache_clear():
NYC1 = tz.gettz('America/New_York')
@@ -1146,54 +1146,54 @@ def test_gettz_cache_clear():
assert NYC1 is not NYC2
-@pytest.mark.gettz
-@pytest.mark.xfail(IS_WIN, reason='zoneinfo separately cached')
-def test_gettz_set_cache_size():
- tz.gettz.cache_clear()
- tz.gettz.set_cache_size(3)
-
- MONACO_ref = weakref.ref(tz.gettz('Europe/Monaco'))
- EASTER_ref = weakref.ref(tz.gettz('Pacific/Easter'))
- CURRIE_ref = weakref.ref(tz.gettz('Australia/Currie'))
-
- gc.collect()
-
- assert MONACO_ref() is not None
- assert EASTER_ref() is not None
- assert CURRIE_ref() is not None
-
- tz.gettz.set_cache_size(2)
- gc.collect()
-
- assert MONACO_ref() is None
-
-@pytest.mark.xfail(IS_WIN, reason="Windows does not use system zoneinfo")
-@pytest.mark.smoke
-@pytest.mark.gettz
-def test_gettz_weakref():
- tz.gettz.cache_clear()
- tz.gettz.set_cache_size(2)
- NYC1 = tz.gettz('America/New_York')
- NYC_ref = weakref.ref(tz.gettz('America/New_York'))
-
- assert NYC1 is NYC_ref()
-
- del NYC1
- gc.collect()
-
- assert NYC_ref() is not None # Should still be in the strong cache
- assert tz.gettz('America/New_York') is NYC_ref()
-
- # Populate strong cache with other timezones
- tz.gettz('Europe/Monaco')
- tz.gettz('Pacific/Easter')
- tz.gettz('Australia/Currie')
-
- gc.collect()
- assert NYC_ref() is None # Should have been pushed out
- assert tz.gettz('America/New_York') is not NYC_ref()
-
-class ZoneInfoGettzTest(GettzTest):
+@pytest.mark.gettz
+@pytest.mark.xfail(IS_WIN, reason='zoneinfo separately cached')
+def test_gettz_set_cache_size():
+ tz.gettz.cache_clear()
+ tz.gettz.set_cache_size(3)
+
+ MONACO_ref = weakref.ref(tz.gettz('Europe/Monaco'))
+ EASTER_ref = weakref.ref(tz.gettz('Pacific/Easter'))
+ CURRIE_ref = weakref.ref(tz.gettz('Australia/Currie'))
+
+ gc.collect()
+
+ assert MONACO_ref() is not None
+ assert EASTER_ref() is not None
+ assert CURRIE_ref() is not None
+
+ tz.gettz.set_cache_size(2)
+ gc.collect()
+
+ assert MONACO_ref() is None
+
+@pytest.mark.xfail(IS_WIN, reason="Windows does not use system zoneinfo")
+@pytest.mark.smoke
+@pytest.mark.gettz
+def test_gettz_weakref():
+ tz.gettz.cache_clear()
+ tz.gettz.set_cache_size(2)
+ NYC1 = tz.gettz('America/New_York')
+ NYC_ref = weakref.ref(tz.gettz('America/New_York'))
+
+ assert NYC1 is NYC_ref()
+
+ del NYC1
+ gc.collect()
+
+ assert NYC_ref() is not None # Should still be in the strong cache
+ assert tz.gettz('America/New_York') is NYC_ref()
+
+ # Populate strong cache with other timezones
+ tz.gettz('Europe/Monaco')
+ tz.gettz('Pacific/Easter')
+ tz.gettz('Australia/Currie')
+
+ gc.collect()
+ assert NYC_ref() is None # Should have been pushed out
+ assert tz.gettz('America/New_York') is not NYC_ref()
+
+class ZoneInfoGettzTest(GettzTest):
def gettz(self, name):
zoneinfo_file = zoneinfo.get_zonefile_instance()
return zoneinfo_file.get(name)
@@ -1253,11 +1253,11 @@ class ZoneInfoGettzTest(GettzTest):
self.assertIs(zif_1, zif_2)
def testZoneInfoDeprecated(self):
- with pytest.warns(DeprecationWarning):
+ with pytest.warns(DeprecationWarning):
zoneinfo.gettz('US/Eastern')
def testZoneInfoMetadataDeprecated(self):
- with pytest.warns(DeprecationWarning):
+ with pytest.warns(DeprecationWarning):
zoneinfo.gettz_db_metadata()
@@ -1350,7 +1350,7 @@ class TZRangeTest(unittest.TestCase, TzFoldMixin):
def testBrokenIsDstHandling(self):
# tzrange._isdst() was using a date() rather than a datetime().
# Issue reported by Lennart Regebro.
- dt = datetime(2007, 8, 6, 4, 10, tzinfo=tz.UTC)
+ dt = datetime(2007, 8, 6, 4, 10, tzinfo=tz.UTC)
self.assertEqual(dt.astimezone(tz=tz.gettz("GMT+2")),
datetime(2007, 8, 6, 6, 10, tzinfo=tz.tzstr("GMT+2")))
@@ -1520,29 +1520,29 @@ class TZStrTest(unittest.TestCase, TzFoldMixin):
# Ensure that these still are all the same zone
assert tz1 == tz2 == tz3
-
-@pytest.mark.smoke
-@pytest.mark.tzstr
-def test_tzstr_weakref():
- tz_t1 = tz.tzstr('EST5EDT')
- tz_t2_ref = weakref.ref(tz.tzstr('EST5EDT'))
- assert tz_t1 is tz_t2_ref()
-
- del tz_t1
- gc.collect()
-
- assert tz_t2_ref() is not None
- assert tz.tzstr('EST5EDT') is tz_t2_ref()
-
- for offset in range(5,15):
- tz.tzstr('GMT+{}'.format(offset))
- gc.collect()
-
- assert tz_t2_ref() is None
- assert tz.tzstr('EST5EDT') is not tz_t2_ref()
-
-
+
+@pytest.mark.smoke
@pytest.mark.tzstr
+def test_tzstr_weakref():
+ tz_t1 = tz.tzstr('EST5EDT')
+ tz_t2_ref = weakref.ref(tz.tzstr('EST5EDT'))
+ assert tz_t1 is tz_t2_ref()
+
+ del tz_t1
+ gc.collect()
+
+ assert tz_t2_ref() is not None
+ assert tz.tzstr('EST5EDT') is tz_t2_ref()
+
+ for offset in range(5,15):
+ tz.tzstr('GMT+{}'.format(offset))
+ gc.collect()
+
+ assert tz_t2_ref() is None
+ assert tz.tzstr('EST5EDT') is not tz_t2_ref()
+
+
+@pytest.mark.tzstr
@pytest.mark.parametrize('tz_str,expected', [
# From https://www.gnu.org/software/libc/manual/html_node/TZ-Variable.html
('', tz.tzrange(None)), # TODO: Should change this so tz.tzrange('') works
@@ -2068,13 +2068,13 @@ class TZTest(unittest.TestCase):
def testGMTOffset(self):
# GMT and UTC offsets have inverted signal when compared to the
# usual TZ variable handling.
- dt = datetime(2007, 8, 6, 4, 10, tzinfo=tz.UTC)
+ dt = datetime(2007, 8, 6, 4, 10, tzinfo=tz.UTC)
self.assertEqual(dt.astimezone(tz=tz.tzstr("GMT+2")),
datetime(2007, 8, 6, 6, 10, tzinfo=tz.tzstr("GMT+2")))
self.assertEqual(dt.astimezone(tz=tz.gettz("UTC-2")),
datetime(2007, 8, 6, 2, 10, tzinfo=tz.tzstr("UTC-2")))
- @unittest.skipIf(IS_WIN, "requires Unix")
+ @unittest.skipIf(IS_WIN, "requires Unix")
def testTZSetDoesntCorrupt(self):
# if we start in non-UTC then tzset UTC make sure parse doesn't get
# confused
@@ -2084,41 +2084,41 @@ class TZTest(unittest.TestCase):
self.assertEqual(str(dt), '2014-07-20 12:34:56+00:00')
-@pytest.mark.tzfile
-@pytest.mark.skipif(not SUPPORTS_SUB_MINUTE_OFFSETS,
- reason='Sub-minute offsets not supported')
-def test_tzfile_sub_minute_offset():
- # If user running python 3.6 or newer, exact offset is used
- tzc = tz.tzfile(BytesIO(base64.b64decode(EUROPE_HELSINKI)))
- offset = timedelta(hours=1, minutes=39, seconds=52)
- assert datetime(1900, 1, 1, 0, 0, tzinfo=tzc).utcoffset() == offset
-
-
-@pytest.mark.tzfile
-@pytest.mark.skipif(SUPPORTS_SUB_MINUTE_OFFSETS,
- reason='Sub-minute offsets supported.')
-def test_sub_minute_rounding_tzfile():
- # This timezone has an offset of 5992 seconds in 1900-01-01.
- # For python version pre-3.6, this will be rounded
- tzc = tz.tzfile(BytesIO(base64.b64decode(EUROPE_HELSINKI)))
- offset = timedelta(hours=1, minutes=40)
- assert datetime(1900, 1, 1, 0, 0, tzinfo=tzc).utcoffset() == offset
-
-
-@pytest.mark.tzfile
-def test_samoa_transition():
- # utcoffset() was erroneously returning +14:00 an hour early (GH #812)
- APIA = tz.gettz('Pacific/Apia')
- dt = datetime(2011, 12, 29, 23, 59, tzinfo=APIA)
- assert dt.utcoffset() == timedelta(hours=-10)
-
- # Make sure the transition actually works, too
- dt_after = (dt.astimezone(tz.UTC) + timedelta(minutes=1)).astimezone(APIA)
- assert dt_after == datetime(2011, 12, 31, tzinfo=APIA)
- assert dt_after.utcoffset() == timedelta(hours=14)
-
-
-@unittest.skipUnless(IS_WIN, "Requires Windows")
+@pytest.mark.tzfile
+@pytest.mark.skipif(not SUPPORTS_SUB_MINUTE_OFFSETS,
+ reason='Sub-minute offsets not supported')
+def test_tzfile_sub_minute_offset():
+ # If user running python 3.6 or newer, exact offset is used
+ tzc = tz.tzfile(BytesIO(base64.b64decode(EUROPE_HELSINKI)))
+ offset = timedelta(hours=1, minutes=39, seconds=52)
+ assert datetime(1900, 1, 1, 0, 0, tzinfo=tzc).utcoffset() == offset
+
+
+@pytest.mark.tzfile
+@pytest.mark.skipif(SUPPORTS_SUB_MINUTE_OFFSETS,
+ reason='Sub-minute offsets supported.')
+def test_sub_minute_rounding_tzfile():
+ # This timezone has an offset of 5992 seconds in 1900-01-01.
+ # For python version pre-3.6, this will be rounded
+ tzc = tz.tzfile(BytesIO(base64.b64decode(EUROPE_HELSINKI)))
+ offset = timedelta(hours=1, minutes=40)
+ assert datetime(1900, 1, 1, 0, 0, tzinfo=tzc).utcoffset() == offset
+
+
+@pytest.mark.tzfile
+def test_samoa_transition():
+ # utcoffset() was erroneously returning +14:00 an hour early (GH #812)
+ APIA = tz.gettz('Pacific/Apia')
+ dt = datetime(2011, 12, 29, 23, 59, tzinfo=APIA)
+ assert dt.utcoffset() == timedelta(hours=-10)
+
+ # Make sure the transition actually works, too
+ dt_after = (dt.astimezone(tz.UTC) + timedelta(minutes=1)).astimezone(APIA)
+ assert dt_after == datetime(2011, 12, 31, tzinfo=APIA)
+ assert dt_after.utcoffset() == timedelta(hours=14)
+
+
+@unittest.skipUnless(IS_WIN, "Requires Windows")
class TzWinTest(unittest.TestCase, TzWinFoldMixin):
def setUp(self):
self.tzclass = tzwin.tzwin
@@ -2207,7 +2207,7 @@ class TzWinTest(unittest.TestCase, TzWinFoldMixin):
def testTzWinEqualityInvalid(self):
# Compare to objects that do not implement comparison with this
# (should default to False)
- UTC = tz.UTC
+ UTC = tz.UTC
EST = tz.tzwin('Eastern Standard Time')
self.assertFalse(EST == UTC)
@@ -2256,7 +2256,7 @@ class TzWinTest(unittest.TestCase, TzWinFoldMixin):
'South Africa Standard Time')
-@unittest.skipUnless(IS_WIN, "Requires Windows")
+@unittest.skipUnless(IS_WIN, "Requires Windows")
class TzWinLocalTest(unittest.TestCase, TzWinFoldMixin):
def setUp(self):
@@ -2269,7 +2269,7 @@ class TzWinLocalTest(unittest.TestCase, TzWinFoldMixin):
def testLocal(self):
# Not sure how to pin a local time zone, so for now we're just going
# to run this and make sure it doesn't raise an error
- # See GitHub Issue #135: https://github.com/dateutil/dateutil/issues/135
+ # See GitHub Issue #135: https://github.com/dateutil/dateutil/issues/135
datetime.now(tzwin.tzwinlocal())
def testTzwinLocalUTCOffset(self):
@@ -2663,46 +2663,46 @@ class DatetimeExistsTest(unittest.TestCase):
self.assertFalse(tz.datetime_exists(dt, tz=AEST))
-class TestEnfold:
- def test_enter_fold_default(self):
+class TestEnfold:
+ def test_enter_fold_default(self):
dt = tz.enfold(datetime(2020, 1, 19, 3, 32))
- assert dt.fold == 1
+ assert dt.fold == 1
- def test_enter_fold(self):
+ def test_enter_fold(self):
dt = tz.enfold(datetime(2020, 1, 19, 3, 32), fold=1)
- assert dt.fold == 1
+ assert dt.fold == 1
- def test_exit_fold(self):
+ def test_exit_fold(self):
dt = tz.enfold(datetime(2020, 1, 19, 3, 32), fold=0)
# Before Python 3.6, dt.fold won't exist if fold is 0.
- assert getattr(dt, 'fold', 0) == 0
-
- def test_defold(self):
- dt = tz.enfold(datetime(2020, 1, 19, 3, 32), fold=1)
-
- dt2 = tz.enfold(dt, fold=0)
-
- assert getattr(dt2, 'fold', 0) == 0
-
- def test_fold_replace_args(self):
- # This test can be dropped when Python < 3.6 is dropped, since it
- # is mainly to cover the `replace` method on _DatetimeWithFold
- dt = tz.enfold(datetime(1950, 1, 2, 12, 30, 15, 8), fold=1)
-
- dt2 = dt.replace(1952, 2, 3, 13, 31, 16, 9)
- assert dt2 == tz.enfold(datetime(1952, 2, 3, 13, 31, 16, 9), fold=1)
- assert dt2.fold == 1
-
- def test_fold_replace_exception_duplicate_args(self):
- dt = tz.enfold(datetime(1999, 1, 3), fold=1)
-
- with pytest.raises(TypeError):
- dt.replace(1950, year=2000)
-
-
+ assert getattr(dt, 'fold', 0) == 0
+
+ def test_defold(self):
+ dt = tz.enfold(datetime(2020, 1, 19, 3, 32), fold=1)
+
+ dt2 = tz.enfold(dt, fold=0)
+
+ assert getattr(dt2, 'fold', 0) == 0
+
+ def test_fold_replace_args(self):
+ # This test can be dropped when Python < 3.6 is dropped, since it
+ # is mainly to cover the `replace` method on _DatetimeWithFold
+ dt = tz.enfold(datetime(1950, 1, 2, 12, 30, 15, 8), fold=1)
+
+ dt2 = dt.replace(1952, 2, 3, 13, 31, 16, 9)
+ assert dt2 == tz.enfold(datetime(1952, 2, 3, 13, 31, 16, 9), fold=1)
+ assert dt2.fold == 1
+
+ def test_fold_replace_exception_duplicate_args(self):
+ dt = tz.enfold(datetime(1999, 1, 3), fold=1)
+
+ with pytest.raises(TypeError):
+ dt.replace(1950, year=2000)
+
+
@pytest.mark.tz_resolve_imaginary
class ImaginaryDateTest(unittest.TestCase):
def testCanberraForward(self):
@@ -2749,7 +2749,7 @@ def test_resolve_imaginary_ambiguous(dt):
datetime(2017, 12, 2, 12, 30, tzinfo=tz.gettz('America/New_York')),
datetime(2018, 12, 2, 9, 30, tzinfo=tz.gettz('Europe/London')),
datetime(2017, 6, 2, 16, 30, tzinfo=tz.gettz('Australia/Sydney')),
- datetime(2025, 9, 25, 1, 17, tzinfo=tz.UTC),
+ datetime(2025, 9, 25, 1, 17, tzinfo=tz.UTC),
datetime(2025, 9, 25, 1, 17, tzinfo=tz.tzoffset('EST', -18000)),
datetime(2019, 3, 4, tzinfo=None)
])
@@ -2782,7 +2782,7 @@ def __get_kiritimati_resolve_imaginary_test():
return (tzi, ) + dates
-resolve_imaginary_tests = [
+resolve_imaginary_tests = [
(tz.gettz('Europe/London'),
datetime(2018, 3, 25, 1, 30), datetime(2018, 3, 25, 2, 30)),
(tz.gettz('America/New_York'),
@@ -2790,20 +2790,20 @@ resolve_imaginary_tests = [
(tz.gettz('Australia/Sydney'),
datetime(2014, 10, 5, 2, 0), datetime(2014, 10, 5, 3, 0)),
__get_kiritimati_resolve_imaginary_test(),
-]
-
+]
-if SUPPORTS_SUB_MINUTE_OFFSETS:
- resolve_imaginary_tests.append(
- (tz.gettz('Africa/Monrovia'),
- datetime(1972, 1, 7, 0, 30), datetime(1972, 1, 7, 1, 14, 30)))
+if SUPPORTS_SUB_MINUTE_OFFSETS:
+ resolve_imaginary_tests.append(
+ (tz.gettz('Africa/Monrovia'),
+ datetime(1972, 1, 7, 0, 30), datetime(1972, 1, 7, 1, 14, 30)))
+
@pytest.mark.tz_resolve_imaginary
-@pytest.mark.parametrize('tzi, dt, dt_exp', resolve_imaginary_tests)
-def test_resolve_imaginary(tzi, dt, dt_exp):
- dt = dt.replace(tzinfo=tzi)
- dt_exp = dt_exp.replace(tzinfo=tzi)
+@pytest.mark.parametrize('tzi, dt, dt_exp', resolve_imaginary_tests)
+def test_resolve_imaginary(tzi, dt, dt_exp):
+ dt = dt.replace(tzinfo=tzi)
+ dt_exp = dt_exp.replace(tzinfo=tzi)
dt_r = tz.resolve_imaginary(dt)
assert dt_r == dt_exp
diff --git a/contrib/python/dateutil/dateutil/test/test_utils.py b/contrib/python/dateutil/dateutil/test/test_utils.py
index fe1bfdcb84..e955cfd05d 100644
--- a/contrib/python/dateutil/dateutil/test/test_utils.py
+++ b/contrib/python/dateutil/dateutil/test/test_utils.py
@@ -4,7 +4,7 @@ from datetime import timedelta, datetime
from dateutil import tz
from dateutil import utils
-from dateutil.tz import UTC
+from dateutil.tz import UTC
from dateutil.utils import within_delta
from freezegun import freeze_time
@@ -12,41 +12,41 @@ from freezegun import freeze_time
NYC = tz.gettz("America/New_York")
-@freeze_time(datetime(2014, 12, 15, 1, 21, 33, 4003))
-def test_utils_today():
- assert utils.today() == datetime(2014, 12, 15, 0, 0, 0)
+@freeze_time(datetime(2014, 12, 15, 1, 21, 33, 4003))
+def test_utils_today():
+ assert utils.today() == datetime(2014, 12, 15, 0, 0, 0)
-@freeze_time(datetime(2014, 12, 15, 12), tz_offset=5)
-def test_utils_today_tz_info():
- assert utils.today(NYC) == datetime(2014, 12, 15, 0, 0, 0, tzinfo=NYC)
+@freeze_time(datetime(2014, 12, 15, 12), tz_offset=5)
+def test_utils_today_tz_info():
+ assert utils.today(NYC) == datetime(2014, 12, 15, 0, 0, 0, tzinfo=NYC)
-@freeze_time(datetime(2014, 12, 15, 23), tz_offset=5)
-def test_utils_today_tz_info_different_day():
- assert utils.today(UTC) == datetime(2014, 12, 16, 0, 0, 0, tzinfo=UTC)
+@freeze_time(datetime(2014, 12, 15, 23), tz_offset=5)
+def test_utils_today_tz_info_different_day():
+ assert utils.today(UTC) == datetime(2014, 12, 16, 0, 0, 0, tzinfo=UTC)
-def test_utils_default_tz_info_naive():
- dt = datetime(2014, 9, 14, 9, 30)
- assert utils.default_tzinfo(dt, NYC).tzinfo is NYC
+def test_utils_default_tz_info_naive():
+ dt = datetime(2014, 9, 14, 9, 30)
+ assert utils.default_tzinfo(dt, NYC).tzinfo is NYC
-def test_utils_default_tz_info_aware():
- dt = datetime(2014, 9, 14, 9, 30, tzinfo=UTC)
- assert utils.default_tzinfo(dt, NYC).tzinfo is UTC
-
-
-def test_utils_within_delta():
- d1 = datetime(2016, 1, 1, 12, 14, 1, 9)
- d2 = d1.replace(microsecond=15)
-
- assert within_delta(d1, d2, timedelta(seconds=1))
- assert not within_delta(d1, d2, timedelta(microseconds=1))
-
-
-def test_utils_within_delta_with_negative_delta():
- d1 = datetime(2016, 1, 1)
- d2 = datetime(2015, 12, 31)
-
- assert within_delta(d2, d1, timedelta(days=-1))
+def test_utils_default_tz_info_aware():
+ dt = datetime(2014, 9, 14, 9, 30, tzinfo=UTC)
+ assert utils.default_tzinfo(dt, NYC).tzinfo is UTC
+
+
+def test_utils_within_delta():
+ d1 = datetime(2016, 1, 1, 12, 14, 1, 9)
+ d2 = d1.replace(microsecond=15)
+
+ assert within_delta(d1, d2, timedelta(seconds=1))
+ assert not within_delta(d1, d2, timedelta(microseconds=1))
+
+
+def test_utils_within_delta_with_negative_delta():
+ d1 = datetime(2016, 1, 1)
+ d2 = datetime(2015, 12, 31)
+
+ assert within_delta(d2, d1, timedelta(days=-1))
diff --git a/contrib/python/dateutil/dateutil/tz/_common.py b/contrib/python/dateutil/dateutil/tz/_common.py
index e6ac118315..c309591ec7 100644
--- a/contrib/python/dateutil/dateutil/tz/_common.py
+++ b/contrib/python/dateutil/dateutil/tz/_common.py
@@ -1,4 +1,4 @@
-from six import PY2
+from six import PY2
from functools import wraps
@@ -16,18 +16,18 @@ def tzname_in_python2(namefunc):
tzname() API changed in Python 3. It used to return bytes, but was changed
to unicode strings
"""
- if PY2:
- @wraps(namefunc)
- def adjust_encoding(*args, **kwargs):
- name = namefunc(*args, **kwargs)
- if name is not None:
- name = name.encode()
+ if PY2:
+ @wraps(namefunc)
+ def adjust_encoding(*args, **kwargs):
+ name = namefunc(*args, **kwargs)
+ if name is not None:
+ name = name.encode()
- return name
+ return name
- return adjust_encoding
- else:
- return namefunc
+ return adjust_encoding
+ else:
+ return namefunc
# The following is adapted from Alexander Belopolsky's tz library
@@ -212,7 +212,7 @@ class _tzinfo(tzinfo):
Since this is the one time that we *know* we have an unambiguous
datetime object, we take this opportunity to determine whether the
datetime is ambiguous and in a "fold" state (e.g. if it's the first
- occurrence, chronologically, of the ambiguous datetime).
+ occurrence, chronologically, of the ambiguous datetime).
:param dt:
A timezone-aware :class:`datetime.datetime` object.
@@ -250,7 +250,7 @@ class _tzinfo(tzinfo):
Since this is the one time that we *know* we have an unambiguous
datetime object, we take this opportunity to determine whether the
datetime is ambiguous and in a "fold" state (e.g. if it's the first
- occurrence, chronologically, of the ambiguous datetime).
+ occurrence, chronologically, of the ambiguous datetime).
:param dt:
A timezone-aware :class:`datetime.datetime` object.
diff --git a/contrib/python/dateutil/dateutil/tz/_factories.py b/contrib/python/dateutil/dateutil/tz/_factories.py
index f8a65891a0..737aa95e0f 100644
--- a/contrib/python/dateutil/dateutil/tz/_factories.py
+++ b/contrib/python/dateutil/dateutil/tz/_factories.py
@@ -1,10 +1,10 @@
from datetime import timedelta
-import weakref
-from collections import OrderedDict
-
-from six.moves import _thread
+import weakref
+from collections import OrderedDict
+from six.moves import _thread
+
class _TzSingleton(type):
def __init__(cls, *args, **kwargs):
cls.__instance = None
@@ -15,7 +15,7 @@ class _TzSingleton(type):
cls.__instance = super(_TzSingleton, cls).__call__()
return cls.__instance
-
+
class _TzFactory(type):
def instance(cls, *args, **kwargs):
"""Alternate constructor that returns a fresh instance"""
@@ -24,57 +24,57 @@ class _TzFactory(type):
class _TzOffsetFactory(_TzFactory):
def __init__(cls, *args, **kwargs):
- cls.__instances = weakref.WeakValueDictionary()
- cls.__strong_cache = OrderedDict()
- cls.__strong_cache_size = 8
-
- cls._cache_lock = _thread.allocate_lock()
+ cls.__instances = weakref.WeakValueDictionary()
+ cls.__strong_cache = OrderedDict()
+ cls.__strong_cache_size = 8
+
+ cls._cache_lock = _thread.allocate_lock()
def __call__(cls, name, offset):
- if isinstance(offset, timedelta):
- key = (name, offset.total_seconds())
- else:
- key = (name, offset)
-
- instance = cls.__instances.get(key, None)
- if instance is None:
- instance = cls.__instances.setdefault(key,
- cls.instance(name, offset))
-
- # This lock may not be necessary in Python 3. See GH issue #901
- with cls._cache_lock:
- cls.__strong_cache[key] = cls.__strong_cache.pop(key, instance)
-
- # Remove an item if the strong cache is overpopulated
- if len(cls.__strong_cache) > cls.__strong_cache_size:
- cls.__strong_cache.popitem(last=False)
-
+ if isinstance(offset, timedelta):
+ key = (name, offset.total_seconds())
+ else:
+ key = (name, offset)
+
+ instance = cls.__instances.get(key, None)
+ if instance is None:
+ instance = cls.__instances.setdefault(key,
+ cls.instance(name, offset))
+
+ # This lock may not be necessary in Python 3. See GH issue #901
+ with cls._cache_lock:
+ cls.__strong_cache[key] = cls.__strong_cache.pop(key, instance)
+
+ # Remove an item if the strong cache is overpopulated
+ if len(cls.__strong_cache) > cls.__strong_cache_size:
+ cls.__strong_cache.popitem(last=False)
+
return instance
class _TzStrFactory(_TzFactory):
def __init__(cls, *args, **kwargs):
- cls.__instances = weakref.WeakValueDictionary()
- cls.__strong_cache = OrderedDict()
- cls.__strong_cache_size = 8
-
- cls.__cache_lock = _thread.allocate_lock()
+ cls.__instances = weakref.WeakValueDictionary()
+ cls.__strong_cache = OrderedDict()
+ cls.__strong_cache_size = 8
+ cls.__cache_lock = _thread.allocate_lock()
+
def __call__(cls, s, posix_offset=False):
- key = (s, posix_offset)
- instance = cls.__instances.get(key, None)
-
- if instance is None:
- instance = cls.__instances.setdefault(key,
- cls.instance(s, posix_offset))
-
- # This lock may not be necessary in Python 3. See GH issue #901
- with cls.__cache_lock:
- cls.__strong_cache[key] = cls.__strong_cache.pop(key, instance)
-
- # Remove an item if the strong cache is overpopulated
- if len(cls.__strong_cache) > cls.__strong_cache_size:
- cls.__strong_cache.popitem(last=False)
-
+ key = (s, posix_offset)
+ instance = cls.__instances.get(key, None)
+
+ if instance is None:
+ instance = cls.__instances.setdefault(key,
+ cls.instance(s, posix_offset))
+
+ # This lock may not be necessary in Python 3. See GH issue #901
+ with cls.__cache_lock:
+ cls.__strong_cache[key] = cls.__strong_cache.pop(key, instance)
+
+ # Remove an item if the strong cache is overpopulated
+ if len(cls.__strong_cache) > cls.__strong_cache_size:
+ cls.__strong_cache.popitem(last=False)
+
return instance
-
+
diff --git a/contrib/python/dateutil/dateutil/tz/tz.py b/contrib/python/dateutil/dateutil/tz/tz.py
index c67f56d465..00b0984f87 100644
--- a/contrib/python/dateutil/dateutil/tz/tz.py
+++ b/contrib/python/dateutil/dateutil/tz/tz.py
@@ -13,8 +13,8 @@ import time
import sys
import os
import bisect
-import weakref
-from collections import OrderedDict
+import weakref
+from collections import OrderedDict
import six
from six import string_types
@@ -30,9 +30,9 @@ try:
except ImportError:
tzwin = tzwinlocal = None
-# For warning about rounding tzinfo
-from warnings import warn
-
+# For warning about rounding tzinfo
+from warnings import warn
+
ZERO = datetime.timedelta(0)
EPOCH = datetime.datetime.utcfromtimestamp(0)
EPOCHORDINAL = EPOCH.toordinal()
@@ -123,12 +123,12 @@ class tzutc(datetime.tzinfo):
__reduce__ = object.__reduce__
-#: Convenience constant providing a :class:`tzutc()` instance
-#:
-#: .. versionadded:: 2.7.0
-UTC = tzutc()
-
-
+#: Convenience constant providing a :class:`tzutc()` instance
+#:
+#: .. versionadded:: 2.7.0
+UTC = tzutc()
+
+
@six.add_metaclass(_TzOffsetFactory)
class tzoffset(datetime.tzinfo):
"""
@@ -149,8 +149,8 @@ class tzoffset(datetime.tzinfo):
except (TypeError, AttributeError):
pass
- self._offset = datetime.timedelta(seconds=_get_supported_offset(offset))
-
+ self._offset = datetime.timedelta(seconds=_get_supported_offset(offset))
+
def utcoffset(self, dt):
return self._offset
@@ -385,7 +385,7 @@ class _tzfile(object):
class tzfile(_tzinfo):
"""
- This is a ``tzinfo`` subclass that allows one to use the ``tzfile(5)``
+ This is a ``tzinfo`` subclass that allows one to use the ``tzfile(5)``
format timezone files to extract current and historical zone information.
:param fileobj:
@@ -472,7 +472,7 @@ class tzfile(_tzinfo):
if fileobj is not None:
if not file_opened_here:
- fileobj = _nullcontext(fileobj)
+ fileobj = _nullcontext(fileobj)
with fileobj as file_stream:
tzobj = self._read_tzfile(file_stream)
@@ -612,7 +612,7 @@ class tzfile(_tzinfo):
out.ttinfo_list = []
for i in range(typecnt):
gmtoff, isdst, abbrind = ttinfo[i]
- gmtoff = _get_supported_offset(gmtoff)
+ gmtoff = _get_supported_offset(gmtoff)
tti = _ttinfo()
tti.offset = gmtoff
tti.dstoffset = datetime.timedelta(0)
@@ -664,45 +664,45 @@ class tzfile(_tzinfo):
# isgmt are off, so it should be in wall time. OTOH, it's
# always in gmt time. Let me know if you have comments
# about this.
- lastdst = None
- lastoffset = None
- lastdstoffset = None
- lastbaseoffset = None
+ lastdst = None
+ lastoffset = None
+ lastdstoffset = None
+ lastbaseoffset = None
out.trans_list = []
-
+
for i, tti in enumerate(out.trans_idx):
- offset = tti.offset
- dstoffset = 0
-
- if lastdst is not None:
- if tti.isdst:
- if not lastdst:
- dstoffset = offset - lastoffset
-
- if not dstoffset and lastdstoffset:
- dstoffset = lastdstoffset
-
- tti.dstoffset = datetime.timedelta(seconds=dstoffset)
- lastdstoffset = dstoffset
-
- # If a time zone changes its base offset during a DST transition,
- # then you need to adjust by the previous base offset to get the
- # transition time in local time. Otherwise you use the current
- # base offset. Ideally, I would have some mathematical proof of
- # why this is true, but I haven't really thought about it enough.
- baseoffset = offset - dstoffset
- adjustment = baseoffset
- if (lastbaseoffset is not None and baseoffset != lastbaseoffset
- and tti.isdst != lastdst):
- # The base DST has changed
- adjustment = lastbaseoffset
-
- lastdst = tti.isdst
- lastoffset = offset
- lastbaseoffset = baseoffset
-
- out.trans_list.append(out.trans_list_utc[i] + adjustment)
-
+ offset = tti.offset
+ dstoffset = 0
+
+ if lastdst is not None:
+ if tti.isdst:
+ if not lastdst:
+ dstoffset = offset - lastoffset
+
+ if not dstoffset and lastdstoffset:
+ dstoffset = lastdstoffset
+
+ tti.dstoffset = datetime.timedelta(seconds=dstoffset)
+ lastdstoffset = dstoffset
+
+ # If a time zone changes its base offset during a DST transition,
+ # then you need to adjust by the previous base offset to get the
+ # transition time in local time. Otherwise you use the current
+ # base offset. Ideally, I would have some mathematical proof of
+ # why this is true, but I haven't really thought about it enough.
+ baseoffset = offset - dstoffset
+ adjustment = baseoffset
+ if (lastbaseoffset is not None and baseoffset != lastbaseoffset
+ and tti.isdst != lastdst):
+ # The base DST has changed
+ adjustment = lastbaseoffset
+
+ lastdst = tti.isdst
+ lastoffset = offset
+ lastbaseoffset = baseoffset
+
+ out.trans_list.append(out.trans_list_utc[i] + adjustment)
+
out.trans_idx = tuple(out.trans_idx)
out.trans_list = tuple(out.trans_list)
out.trans_list_utc = tuple(out.trans_list_utc)
@@ -1271,7 +1271,7 @@ class tzical(object):
fileobj = open(fileobj, 'r')
else:
self._s = getattr(fileobj, 'name', repr(fileobj))
- fileobj = _nullcontext(fileobj)
+ fileobj = _nullcontext(fileobj)
self._vtz = {}
@@ -1544,9 +1544,9 @@ def __get_gettz():
"""
def __init__(self):
- self.__instances = weakref.WeakValueDictionary()
- self.__strong_cache_size = 8
- self.__strong_cache = OrderedDict()
+ self.__instances = weakref.WeakValueDictionary()
+ self.__strong_cache_size = 8
+ self.__strong_cache = OrderedDict()
self._cache_lock = _thread.allocate_lock()
def __call__(self, name=None):
@@ -1555,37 +1555,37 @@ def __get_gettz():
if rv is None:
rv = self.nocache(name=name)
- if not (name is None
- or isinstance(rv, tzlocal_classes)
- or rv is None):
+ if not (name is None
+ or isinstance(rv, tzlocal_classes)
+ or rv is None):
# tzlocal is slightly more complicated than the other
# time zone providers because it depends on environment
# at construction time, so don't cache that.
- #
- # We also cannot store weak references to None, so we
- # will also not store that.
+ #
+ # We also cannot store weak references to None, so we
+ # will also not store that.
self.__instances[name] = rv
- else:
- # No need for strong caching, return immediately
- return rv
-
- self.__strong_cache[name] = self.__strong_cache.pop(name, rv)
-
- if len(self.__strong_cache) > self.__strong_cache_size:
- self.__strong_cache.popitem(last=False)
-
+ else:
+ # No need for strong caching, return immediately
+ return rv
+
+ self.__strong_cache[name] = self.__strong_cache.pop(name, rv)
+
+ if len(self.__strong_cache) > self.__strong_cache_size:
+ self.__strong_cache.popitem(last=False)
+
return rv
- def set_cache_size(self, size):
- with self._cache_lock:
- self.__strong_cache_size = size
- while len(self.__strong_cache) > size:
- self.__strong_cache.popitem(last=False)
-
+ def set_cache_size(self, size):
+ with self._cache_lock:
+ self.__strong_cache_size = size
+ while len(self.__strong_cache) > size:
+ self.__strong_cache.popitem(last=False)
+
def cache_clear(self):
with self._cache_lock:
- self.__instances = weakref.WeakValueDictionary()
- self.__strong_cache.clear()
+ self.__instances = weakref.WeakValueDictionary()
+ self.__strong_cache.clear()
@staticmethod
def nocache(name=None):
@@ -1596,7 +1596,7 @@ def __get_gettz():
name = os.environ["TZ"]
except KeyError:
pass
- if name is None or name in ("", ":"):
+ if name is None or name in ("", ":"):
for filepath in TZFILES:
if not os.path.isabs(filepath):
filename = filepath
@@ -1615,15 +1615,15 @@ def __get_gettz():
else:
tz = tzlocal()
else:
- try:
- if name.startswith(":"):
- name = name[1:]
- except TypeError as e:
- if isinstance(name, bytes):
- new_msg = "gettz argument should be str, not bytes"
- six.raise_from(TypeError(new_msg), e)
- else:
- raise
+ try:
+ if name.startswith(":"):
+ name = name[1:]
+ except TypeError as e:
+ if isinstance(name, bytes):
+ new_msg = "gettz argument should be str, not bytes"
+ six.raise_from(TypeError(new_msg), e)
+ else:
+ raise
if os.path.isabs(name):
if os.path.isfile(name):
tz = tzfile(name)
@@ -1646,8 +1646,8 @@ def __get_gettz():
if tzwin is not None:
try:
tz = tzwin(name)
- except (WindowsError, UnicodeEncodeError):
- # UnicodeEncodeError is for Python 2.7 compat
+ except (WindowsError, UnicodeEncodeError):
+ # UnicodeEncodeError is for Python 2.7 compat
tz = None
if not tz:
@@ -1668,7 +1668,7 @@ def __get_gettz():
break
else:
if name in ("GMT", "UTC"):
- tz = UTC
+ tz = UTC
elif name in time.tzname:
tz = tzlocal()
return tz
@@ -1708,7 +1708,7 @@ def datetime_exists(dt, tz=None):
# This is essentially a test of whether or not the datetime can survive
# a round trip to UTC.
- dt_rt = dt.replace(tzinfo=tz).astimezone(UTC).astimezone(tz)
+ dt_rt = dt.replace(tzinfo=tz).astimezone(UTC).astimezone(tz)
dt_rt = dt_rt.replace(tzinfo=None)
return dt == dt_rt
@@ -1814,36 +1814,36 @@ def _datetime_to_timestamp(dt):
return (dt.replace(tzinfo=None) - EPOCH).total_seconds()
-if sys.version_info >= (3, 6):
- def _get_supported_offset(second_offset):
- return second_offset
-else:
- def _get_supported_offset(second_offset):
- # For python pre-3.6, round to full-minutes if that's not the case.
- # Python's datetime doesn't accept sub-minute timezones. Check
- # http://python.org/sf/1447945 or https://bugs.python.org/issue5288
- # for some information.
- old_offset = second_offset
- calculated_offset = 60 * ((second_offset + 30) // 60)
- return calculated_offset
-
-
-try:
- # Python 3.7 feature
- from contextlib import nullcontext as _nullcontext
-except ImportError:
- class _nullcontext(object):
- """
- Class for wrapping contexts so that they are passed through in a
- with statement.
- """
- def __init__(self, context):
- self.context = context
-
- def __enter__(self):
- return self.context
-
- def __exit__(*args, **kwargs):
- pass
-
+if sys.version_info >= (3, 6):
+ def _get_supported_offset(second_offset):
+ return second_offset
+else:
+ def _get_supported_offset(second_offset):
+ # For python pre-3.6, round to full-minutes if that's not the case.
+ # Python's datetime doesn't accept sub-minute timezones. Check
+ # http://python.org/sf/1447945 or https://bugs.python.org/issue5288
+ # for some information.
+ old_offset = second_offset
+ calculated_offset = 60 * ((second_offset + 30) // 60)
+ return calculated_offset
+
+
+try:
+ # Python 3.7 feature
+ from contextlib import nullcontext as _nullcontext
+except ImportError:
+ class _nullcontext(object):
+ """
+ Class for wrapping contexts so that they are passed through in a
+ with statement.
+ """
+ def __init__(self, context):
+ self.context = context
+
+ def __enter__(self):
+ return self.context
+
+ def __exit__(*args, **kwargs):
+ pass
+
# vim:ts=4:sw=4:et
diff --git a/contrib/python/dateutil/dateutil/tz/win.py b/contrib/python/dateutil/dateutil/tz/win.py
index cde07ba792..80931b7c12 100644
--- a/contrib/python/dateutil/dateutil/tz/win.py
+++ b/contrib/python/dateutil/dateutil/tz/win.py
@@ -1,11 +1,11 @@
-# -*- coding: utf-8 -*-
-"""
-This module provides an interface to the native time zone data on Windows,
-including :py:class:`datetime.tzinfo` implementations.
-
-Attempting to import this module on a non-Windows platform will raise an
-:py:obj:`ImportError`.
-"""
+# -*- coding: utf-8 -*-
+"""
+This module provides an interface to the native time zone data on Windows,
+including :py:class:`datetime.tzinfo` implementations.
+
+Attempting to import this module on a non-Windows platform will raise an
+:py:obj:`ImportError`.
+"""
# This code was originally contributed by Jeffrey Harris.
import datetime
import struct
@@ -47,7 +47,7 @@ TZKEYNAME = _settzkeyname()
class tzres(object):
"""
- Class for accessing ``tzres.dll``, which contains timezone name related
+ Class for accessing ``tzres.dll``, which contains timezone name related
resources.
.. versionadded:: 2.5.0
@@ -80,10 +80,10 @@ class tzres(object):
:param offset:
A positive integer value referring to a string from the tzres dll.
- .. note::
-
+ .. note::
+
Offsets found in the registry are generally of the form
- ``@tzres.dll,-114``. The offset in this case is 114, not -114.
+ ``@tzres.dll,-114``. The offset in this case is 114, not -114.
"""
resource = self.p_wchar()
@@ -155,9 +155,9 @@ class tzwinbase(tzrangebase):
return result
def display(self):
- """
- Return the display name of the time zone.
- """
+ """
+ Return the display name of the time zone.
+ """
return self._display
def transitions(self, year):
@@ -200,18 +200,18 @@ class tzwinbase(tzrangebase):
class tzwin(tzwinbase):
- """
- Time zone object created from the zone info in the Windows registry
-
- These are similar to :py:class:`dateutil.tz.tzrange` objects in that
- the time zone data is provided in the format of a single offset rule
- for either 0 or 2 time zone transitions per year.
-
- :param: name
- The name of a Windows time zone key, e.g. "Eastern Standard Time".
- The full list of keys can be retrieved with :func:`tzwin.list`.
- """
-
+ """
+ Time zone object created from the zone info in the Windows registry
+
+ These are similar to :py:class:`dateutil.tz.tzrange` objects in that
+ the time zone data is provided in the format of a single offset rule
+ for either 0 or 2 time zone transitions per year.
+
+ :param: name
+ The name of a Windows time zone key, e.g. "Eastern Standard Time".
+ The full list of keys can be retrieved with :func:`tzwin.list`.
+ """
+
def __init__(self, name):
self._name = name
@@ -257,22 +257,22 @@ class tzwin(tzwinbase):
class tzwinlocal(tzwinbase):
- """
- Class representing the local time zone information in the Windows registry
-
- While :class:`dateutil.tz.tzlocal` makes system calls (via the :mod:`time`
- module) to retrieve time zone information, ``tzwinlocal`` retrieves the
- rules directly from the Windows registry and creates an object like
- :class:`dateutil.tz.tzwin`.
-
- Because Windows does not have an equivalent of :func:`time.tzset`, on
- Windows, :class:`dateutil.tz.tzlocal` instances will always reflect the
- time zone settings *at the time that the process was started*, meaning
- changes to the machine's time zone settings during the run of a program
- on Windows will **not** be reflected by :class:`dateutil.tz.tzlocal`.
- Because ``tzwinlocal`` reads the registry directly, it is unaffected by
- this issue.
- """
+ """
+ Class representing the local time zone information in the Windows registry
+
+ While :class:`dateutil.tz.tzlocal` makes system calls (via the :mod:`time`
+ module) to retrieve time zone information, ``tzwinlocal`` retrieves the
+ rules directly from the Windows registry and creates an object like
+ :class:`dateutil.tz.tzwin`.
+
+ Because Windows does not have an equivalent of :func:`time.tzset`, on
+ Windows, :class:`dateutil.tz.tzlocal` instances will always reflect the
+ time zone settings *at the time that the process was started*, meaning
+ changes to the machine's time zone settings during the run of a program
+ on Windows will **not** be reflected by :class:`dateutil.tz.tzlocal`.
+ Because ``tzwinlocal`` reads the registry directly, it is unaffected by
+ this issue.
+ """
def __init__(self):
with winreg.ConnectRegistry(None, winreg.HKEY_LOCAL_MACHINE) as handle:
with winreg.OpenKey(handle, TZLOCALKEYNAME) as tzlocalkey:
diff --git a/contrib/python/dateutil/dateutil/utils.py b/contrib/python/dateutil/dateutil/utils.py
index dd2d245a0b..af10d21688 100644
--- a/contrib/python/dateutil/dateutil/utils.py
+++ b/contrib/python/dateutil/dateutil/utils.py
@@ -28,7 +28,7 @@ def today(tzinfo=None):
def default_tzinfo(dt, tzinfo):
"""
- Sets the ``tzinfo`` parameter on naive datetimes only
+ Sets the ``tzinfo`` parameter on naive datetimes only
This is useful for example when you are provided a datetime that may have
either an implicit or explicit time zone, such as when parsing a time zone
@@ -63,7 +63,7 @@ def default_tzinfo(dt, tzinfo):
def within_delta(dt1, dt2, delta):
"""
- Useful for comparing two datetimes that may have a negligible difference
+ Useful for comparing two datetimes that may have a negligible difference
to be considered equal.
"""
delta = abs(delta)
diff --git a/contrib/python/dateutil/dateutil/zoneinfo/__init__.py b/contrib/python/dateutil/dateutil/zoneinfo/__init__.py
index 34f11ad66c..7759f2ce6b 100644
--- a/contrib/python/dateutil/dateutil/zoneinfo/__init__.py
+++ b/contrib/python/dateutil/dateutil/zoneinfo/__init__.py
@@ -3,7 +3,7 @@ import warnings
import json
from tarfile import TarFile
-from pkgutil import get_data
+from pkgutil import get_data
from io import BytesIO
from dateutil.tz import tzfile as _tzfile
@@ -21,7 +21,7 @@ class tzfile(_tzfile):
def getzoneinfofile_stream():
try:
- return BytesIO(get_data(__name__, ZONEFILENAME))
+ return BytesIO(get_data(__name__, ZONEFILENAME))
except IOError as e: # TODO switch to FileNotFoundError?
warnings.warn("I/O error({0}): {1}".format(e.errno, e.strerror))
return None
diff --git a/contrib/python/dateutil/dateutil/zoneinfo/rebuild.py b/contrib/python/dateutil/dateutil/zoneinfo/rebuild.py
index 684c6586f0..86e86e37d6 100644
--- a/contrib/python/dateutil/dateutil/zoneinfo/rebuild.py
+++ b/contrib/python/dateutil/dateutil/zoneinfo/rebuild.py
@@ -3,7 +3,7 @@ import os
import tempfile
import shutil
import json
-from subprocess import check_call, check_output
+from subprocess import check_call, check_output
from tarfile import TarFile
from dateutil.zoneinfo import METADATA_FN, ZONEFILENAME
@@ -23,9 +23,9 @@ def rebuild(filename, tag=None, format="gz", zonegroups=[], metadata=None):
for name in zonegroups:
tf.extract(name, tmpdir)
filepaths = [os.path.join(tmpdir, n) for n in zonegroups]
-
- _run_zic(zonedir, filepaths)
-
+
+ _run_zic(zonedir, filepaths)
+
# write metadata file
with open(os.path.join(zonedir, METADATA_FN), 'w') as f:
json.dump(metadata, f, indent=4, sort_keys=True)
@@ -38,30 +38,30 @@ def rebuild(filename, tag=None, format="gz", zonegroups=[], metadata=None):
shutil.rmtree(tmpdir)
-def _run_zic(zonedir, filepaths):
- """Calls the ``zic`` compiler in a compatible way to get a "fat" binary.
-
- Recent versions of ``zic`` default to ``-b slim``, while older versions
- don't even have the ``-b`` option (but default to "fat" binaries). The
- current version of dateutil does not support Version 2+ TZif files, which
- causes problems when used in conjunction with "slim" binaries, so this
- function is used to ensure that we always get a "fat" binary.
- """
-
- try:
- help_text = check_output(["zic", "--help"])
- except OSError as e:
- _print_on_nosuchfile(e)
- raise
-
- if b"-b " in help_text:
- bloat_args = ["-b", "fat"]
- else:
- bloat_args = []
-
- check_call(["zic"] + bloat_args + ["-d", zonedir] + filepaths)
-
-
+def _run_zic(zonedir, filepaths):
+ """Calls the ``zic`` compiler in a compatible way to get a "fat" binary.
+
+ Recent versions of ``zic`` default to ``-b slim``, while older versions
+ don't even have the ``-b`` option (but default to "fat" binaries). The
+ current version of dateutil does not support Version 2+ TZif files, which
+ causes problems when used in conjunction with "slim" binaries, so this
+ function is used to ensure that we always get a "fat" binary.
+ """
+
+ try:
+ help_text = check_output(["zic", "--help"])
+ except OSError as e:
+ _print_on_nosuchfile(e)
+ raise
+
+ if b"-b " in help_text:
+ bloat_args = ["-b", "fat"]
+ else:
+ bloat_args = []
+
+ check_call(["zic"] + bloat_args + ["-d", zonedir] + filepaths)
+
+
def _print_on_nosuchfile(e):
"""Print helpful troubleshooting message
diff --git a/contrib/python/dateutil/tests/ya.make b/contrib/python/dateutil/tests/ya.make
index 93c811e26e..bcf5b66692 100644
--- a/contrib/python/dateutil/tests/ya.make
+++ b/contrib/python/dateutil/tests/ya.make
@@ -1,39 +1,39 @@
-PY23_TEST()
-
+PY23_TEST()
+
OWNER(g:python-contrib)
-PEERDIR(
- contrib/python/dateutil
- contrib/python/freezegun
- contrib/python/hypothesis
-)
-
-ENV(LC_ALL=ru_RU.UTF-8)
-ENV(LANG=ru_RU.UTF-8)
-# because we cannot change TZ in arcadia CI
-ENV(DATEUTIL_MAY_NOT_CHANGE_TZ_VAR=1)
-
-SRCDIR(contrib/python/dateutil/dateutil/test)
-
-TEST_SRCS(
- property/test_isoparse_prop.py
- property/test_parser_prop.py
- # property/test_tz_prop.py
- __init__.py
- _common.py
- conftest.py
- test_easter.py
- test_import_star.py
- test_imports.py
- test_internals.py
- test_isoparser.py
- test_parser.py
- test_relativedelta.py
- test_rrule.py
- test_tz.py
- test_utils.py
-)
-
-NO_LINT()
-
-END()
+PEERDIR(
+ contrib/python/dateutil
+ contrib/python/freezegun
+ contrib/python/hypothesis
+)
+
+ENV(LC_ALL=ru_RU.UTF-8)
+ENV(LANG=ru_RU.UTF-8)
+# because we cannot change TZ in arcadia CI
+ENV(DATEUTIL_MAY_NOT_CHANGE_TZ_VAR=1)
+
+SRCDIR(contrib/python/dateutil/dateutil/test)
+
+TEST_SRCS(
+ property/test_isoparse_prop.py
+ property/test_parser_prop.py
+ # property/test_tz_prop.py
+ __init__.py
+ _common.py
+ conftest.py
+ test_easter.py
+ test_import_star.py
+ test_imports.py
+ test_internals.py
+ test_isoparser.py
+ test_parser.py
+ test_relativedelta.py
+ test_rrule.py
+ test_tz.py
+ test_utils.py
+)
+
+NO_LINT()
+
+END()
diff --git a/contrib/python/dateutil/ya.make b/contrib/python/dateutil/ya.make
index 0c4102c505..b131358690 100644
--- a/contrib/python/dateutil/ya.make
+++ b/contrib/python/dateutil/ya.make
@@ -1,19 +1,19 @@
-# Generated by devtools/yamaker (pypi).
-
-PY23_LIBRARY()
+# Generated by devtools/yamaker (pypi).
+
+PY23_LIBRARY()
OWNER(g:python-contrib)
-VERSION(2.8.2)
-
-LICENSE(BSD-3-Clause)
+VERSION(2.8.2)
+LICENSE(BSD-3-Clause)
+
PEERDIR(
contrib/python/six
)
-NO_LINT()
-
+NO_LINT()
+
NO_CHECK_IMPORTS(
dateutil.tz.win
dateutil.tzwin
@@ -41,15 +41,15 @@ PY_SRCS(
dateutil/zoneinfo/rebuild.py
)
-RESOURCE_FILES(
- PREFIX contrib/python/dateutil/
- .dist-info/METADATA
- .dist-info/top_level.txt
- dateutil/zoneinfo/dateutil-zoneinfo.tar.gz
+RESOURCE_FILES(
+ PREFIX contrib/python/dateutil/
+ .dist-info/METADATA
+ .dist-info/top_level.txt
+ dateutil/zoneinfo/dateutil-zoneinfo.tar.gz
)
END()
-
-RECURSE_FOR_TESTS(
- tests
-)
+
+RECURSE_FOR_TESTS(
+ tests
+)