whenever


Namewhenever JSON
Version 0.5.2 PyPI version JSON
download
home_pagehttps://github.com/ariebovenberg/whenever
SummarySensible and typesafe datetimes
upload_time2024-04-30 17:57:03
maintainerNone
docs_urlNone
authorArie Bovenberg
requires_python>=3.8.1
licenseMIT
keywords datetime
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            ⏰ Whenever
===========

.. image:: https://img.shields.io/pypi/v/whenever.svg?style=flat-square&color=blue
   :target: https://pypi.python.org/pypi/whenever

.. image:: https://img.shields.io/pypi/pyversions/whenever.svg?style=flat-square
   :target: https://pypi.python.org/pypi/whenever

.. image:: https://img.shields.io/pypi/l/whenever.svg?style=flat-square&color=blue
   :target: https://pypi.python.org/pypi/whenever

.. image:: https://img.shields.io/badge/mypy-strict-forestgreen?style=flat-square
   :target: https://mypy.readthedocs.io/en/stable/command_line.html#cmdoption-mypy-strict

.. image:: https://img.shields.io/badge/coverage-100%25-forestgreen?style=flat-square
   :target: https://github.com/ariebovenberg/whenever

.. image::  https://img.shields.io/github/actions/workflow/status/ariebovenberg/whenever/tests.yml?branch=main&style=flat-square
   :target: https://github.com/ariebovenberg/whenever

.. image:: https://img.shields.io/readthedocs/whenever.svg?style=flat-square
   :target: http://whenever.readthedocs.io/

**Sensible and typesafe datetimes**

Do you cross your fingers every time you work with datetimes,
hoping that you didn't mix naive and aware?
or that you converted to UTC everywhere?
or that you avoided the many `pitfalls of the standard library <https://dev.arie.bovenberg.net/blog/python-datetime-pitfalls/>`_?
There's no way to be sure...

✨ Until now! ✨

**Whenever** is a datetime library designed from the ground up to enforce correctness.
Mistakes become red squiggles in your IDE, instead of bugs in production.

`📖 Docs <https://whenever.readthedocs.io>`_ |
`🐍 PyPI <https://pypi.org/project/whenever/>`_ |
`🐙 GitHub <https://github.com/ariebovenberg/whenever>`_ |
`🚀 Changelog <https://whenever.readthedocs.io/en/latest/changelog.html>`_ |
`❓ FAQ <https://whenever.readthedocs.io/en/latest/faq.html>`_ |
🗺️ `Roadmap`_ |
`💬 Issues & discussions <https://github.com/ariebovenberg/whenever/issues>`_

Benefits
--------

- Distinct classes with well-defined behavior
- Fixes pitfalls that `arrow and pendulum don't <https://dev.arie.bovenberg.net/blog/python-datetime-pitfalls/>`_
- Enforce correctness without runtime checks
- Based on `familiar concepts <https://www.youtube.com/watch?v=saeKBuPewcU>`_ and standards
- Simple and obvious; no frills or surprises
- `Thoroughly documented <https://whenever.rtfd.io/en/latest/overview.html>`_ and tested
- One file; no third-party dependencies

Quickstart
----------

.. code-block:: python

   >>> from whenever import (
   ...    # Explicit types for different use cases
   ...    UTCDateTime,     # -> Enforce UTC-normalization
   ...    OffsetDateTime,  # -> Simple localized times
   ...    ZonedDateTime,   # -> Full-featured timezones
   ...    NaiveDateTime,   # -> Without any timezone
   ... )

   >>> py311_release = UTCDateTime(2022, 10, 24, hour=17)
   UTCDateTime(2022-10-24 17:00:00Z)
   >>> pycon23_start = OffsetDateTime(2023, 4, 21, hour=9, offset=-6)
   OffsetDateTime(2023-04-21 09:00:00-06:00)

   # Simple, explicit conversions
   >>> py311_release.as_zoned("Europe/Paris")
   ZonedDateTime(2022-10-24 19:00:00+02:00[Europe/Paris])
   >>> pycon23_start.as_local()  # example: system timezone in NYC
   LocalSystemDateTime(2023-04-21 11:00:00-04:00)

   # Comparison and equality across aware types
   >>> py311_release > pycon23_start
   False
   >>> py311_release == py311_release.as_zoned("America/Los_Angeles")
   True

   # Naive type that can't accidentally mix with aware types
   >>> hackathon_invite = NaiveDateTime(2023, 10, 28, hour=12)
   >>> # Naïve/aware mixups are caught by typechecker
   >>> hackathon_invite - py311_release
   >>> # Only explicit assumptions will make it aware
   >>> hackathon_start = hackathon_invite.assume_zoned("Europe/Amsterdam")
   ZonedDateTime(2023-10-28 12:00:00+02:00[Europe/Amsterdam])

   # DST-aware operators
   >>> hackathon_end = hackathon_start.add(hours=24)
   ZonedDateTime(2022-10-29 11:00:00+01:00[Europe/Amsterdam])

   # Lossless round-trip to/from text (useful for JSON/serialization)
   >>> py311_release.canonical_format()
   '2022-10-24T17:00:00Z'
   >>> ZonedDateTime.from_canonical_format('2022-10-24T19:00:00+02:00[Europe/Paris]')
   ZonedDateTime(2022-10-24 19:00:00+02:00[Europe/Paris])

   # Conversion to/from common formats
   >>> py311_release.rfc2822()  # also: from_rfc2822()
   "Mon, 24 Oct 2022 17:00:00 GMT"
   >>> pycon23_start.rfc3339()  # also: from_rfc3339()
   "2023-04-21T09:00:00-06:00"

   # Basic parsing
   >>> OffsetDateTime.strptime("2022-10-24+02:00", "%Y-%m-%d%z")
   OffsetDateTime(2022-10-24 00:00:00+02:00)

   # If you must: you can access the underlying datetime object
   >>> pycon23_start.py_datetime().ctime()
   'Fri Apr 21 09:00:00 2023'

Read more in the `feature overview <https://whenever.readthedocs.io/en/latest/overview.html>`_
or `API reference <https://whenever.readthedocs.io/en/latest/api.html>`_.

Why not...?
-----------

The standard library
~~~~~~~~~~~~~~~~~~~~

The standard library is full of quirks and pitfalls.
To summarize the detailed `blog post <https://dev.arie.bovenberg.net/blog/python-datetime-pitfalls/>`_:

1.  Incompatible concepts of naive and aware are squeezed into one class
2.  Operators ignore Daylight Saving Time (DST)
3.  The meaning of "naive" is inconsistent (UTC, local, or unspecified?)
4.  Non-existent datetimes pass silently
5.  It guesses in the face of ambiguity
6.  False negatives on equality of ambiguous times between timezones
7.  False positives on equality of ambiguous times within the same timezone
8.  ``datetime`` inherits from ``date``, but behaves inconsistently
9.  ``datetime.timezone`` isn’t enough for full-featured timezones.
10. The local timezone is DST-unaware

Pendulum
~~~~~~~~

Pendulum is full-featured datetime library, but it's
hamstrung by the decision to inherit from the standard library ``datetime``.
This means it inherits most of the pitfalls mentioned above,
with the notable exception of DST-aware addition/subtraction.

Arrow
~~~~~

Arrow is probably the most historically popular datetime library.
Pendulum did a good write-up of `the issues with Arrow <https://pendulum.eustace.io/faq/>`_.
It addresses fewer of datetime's pitfalls than Pendulum.

DateType
~~~~~~~~

DateType mostly fixes the issue of mixing naive and aware datetimes,
and datetime/date inheritance during type-checking,
but doesn't address the other pitfalls.
The type-checker-only approach also means that it doesn't enforce correctness at runtime,
and it requires developers to be knowledgeable about
how the 'type checking reality' differs from the 'runtime reality'.

python-dateutil
~~~~~~~~~~~~~~~

Dateutil attempts to solve some of the issues with the standard library.
However, it only *adds* functionality to work around the issues,
instead of *removing* the pitfalls themselves.
This still puts the burden on the developer to know about the issues,
and to use the correct functions to avoid them.
Without removing the pitfalls, it's still very likely to make mistakes.

Maya
~~~~

It's unmaintained, but does have an interesting approach.
By enforcing UTC, it bypasses a lot of issues with the standard library.
To do so, it sacrifices the ability to represent offset, zoned, and local datetimes.
So in order to perform any timezone-aware operations, you need to convert
to the standard library ``datetime`` first, which reintroduces the issues.

Heliclockter
~~~~~~~~~~~~

This library is a lot more explicit about the different types of datetimes,
addressing issue of naive/aware mixing with UTC, local, and zoned datetime subclasses.
It doesn't address the other datetime pitfalls though.

.. _roadmap:

Roadmap
-------

- 🧪 **0.x**: get to feature-parity, process feedback, and tweak the API:

  - ✅ Datetime classes
  - ✅ Deltas
  - ✅ Date and time of day (separate from datetime)
  - 🚧 Interval
  - 🚧 Improved parsing and formatting
- 🔒 **1.0**:
  - API stability and backwards compatibility
  - Implement Rust extension for performance
- 🐍 **future**: Inspire a standard library improvement

Not planned:

- Different calendar systems

Versioning and compatibility policy
-----------------------------------

**Whenever** follows semantic versioning.
Until the 1.0 version, the API may change with minor releases.
Breaking changes will be avoided as much as possible,
and meticulously explained in the changelog.
Since the API is fully typed, your typechecker and/or IDE
will help you adjust to any API changes.

  ⚠️ **Note**: until 1.x, pickled objects may not be unpicklable across
  versions. After 1.0, backwards compatibility of pickles will be maintained
  as much as possible.

Acknowledgements
----------------

This project is inspired by the following projects. Check them out!

- `Noda Time <https://nodatime.org/>`_
- `Temporal <https://tc39.es/proposal-temporal/docs/>`_
- `Chrono <https://docs.rs/chrono/latest/chrono/>`_

Contributing
------------

Contributions are welcome! Please open an issue or a pull request.

  ⚠️ **Note**: big changes should be discussed in an issue first.
  This is to avoid wasted effort if the change isn't a good fit for the project.

..

  ⚠️ **Note**: Some tests are skipped on Windows.
  These tests use unix-specific features to set the timezone for the current process.
  As a result, Windows isn't able to run certain tests that rely on the system timezone.
  It appears that `this functionality is not available on Windows <https://stackoverflow.com/questions/62004265/python-3-time-tzset-alternative-for-windows>`_.

Setting up a development environment
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

You'll need `poetry <https://python-poetry.org/>`_ installed.
An example of setting up things up:

.. code-block:: bash

   poetry install

   # To run the tests with the current Python version
   pytest

   # if you want to build the docs
   pip install -r docs/requirements.txt

   # Various checks
   mypy src/ tests/
   flake8 src/ tests/

   # autoformatting
   black src/ tests/
   isort src/ tests/

   # To run the tests with all supported Python versions
   # Alternatively, let the github actions on the PR do it for you
   pip install tox
   tox -p auto


            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/ariebovenberg/whenever",
    "name": "whenever",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.8.1",
    "maintainer_email": null,
    "keywords": "datetime",
    "author": "Arie Bovenberg",
    "author_email": "a.c.bovenberg@gmail.com",
    "download_url": "https://files.pythonhosted.org/packages/43/3e/5ed21068d9dc51c40165604883e903102daf68b2ad7996575e0229663983/whenever-0.5.2.tar.gz",
    "platform": null,
    "description": "\u23f0 Whenever\n===========\n\n.. image:: https://img.shields.io/pypi/v/whenever.svg?style=flat-square&color=blue\n   :target: https://pypi.python.org/pypi/whenever\n\n.. image:: https://img.shields.io/pypi/pyversions/whenever.svg?style=flat-square\n   :target: https://pypi.python.org/pypi/whenever\n\n.. image:: https://img.shields.io/pypi/l/whenever.svg?style=flat-square&color=blue\n   :target: https://pypi.python.org/pypi/whenever\n\n.. image:: https://img.shields.io/badge/mypy-strict-forestgreen?style=flat-square\n   :target: https://mypy.readthedocs.io/en/stable/command_line.html#cmdoption-mypy-strict\n\n.. image:: https://img.shields.io/badge/coverage-100%25-forestgreen?style=flat-square\n   :target: https://github.com/ariebovenberg/whenever\n\n.. image::  https://img.shields.io/github/actions/workflow/status/ariebovenberg/whenever/tests.yml?branch=main&style=flat-square\n   :target: https://github.com/ariebovenberg/whenever\n\n.. image:: https://img.shields.io/readthedocs/whenever.svg?style=flat-square\n   :target: http://whenever.readthedocs.io/\n\n**Sensible and typesafe datetimes**\n\nDo you cross your fingers every time you work with datetimes,\nhoping that you didn't mix naive and aware?\nor that you converted to UTC everywhere?\nor that you avoided the many `pitfalls of the standard library <https://dev.arie.bovenberg.net/blog/python-datetime-pitfalls/>`_?\nThere's no way to be sure...\n\n\u2728 Until now! \u2728\n\n**Whenever** is a datetime library designed from the ground up to enforce correctness.\nMistakes become red squiggles in your IDE, instead of bugs in production.\n\n`\ud83d\udcd6\u00a0Docs <https://whenever.readthedocs.io>`_\u00a0|\n`\ud83d\udc0d\u00a0PyPI <https://pypi.org/project/whenever/>`_\u00a0|\n`\ud83d\udc19\u00a0GitHub <https://github.com/ariebovenberg/whenever>`_\u00a0|\n`\ud83d\ude80\u00a0Changelog <https://whenever.readthedocs.io/en/latest/changelog.html>`_\u00a0|\n`\u2753\u00a0FAQ <https://whenever.readthedocs.io/en/latest/faq.html>`_\u00a0|\n\ud83d\uddfa\ufe0f\u00a0`Roadmap`_\u00a0|\n`\ud83d\udcac\u00a0Issues\u00a0&\u00a0discussions <https://github.com/ariebovenberg/whenever/issues>`_\n\nBenefits\n--------\n\n- Distinct classes with well-defined behavior\n- Fixes pitfalls that `arrow and pendulum don't <https://dev.arie.bovenberg.net/blog/python-datetime-pitfalls/>`_\n- Enforce correctness without runtime checks\n- Based on `familiar concepts <https://www.youtube.com/watch?v=saeKBuPewcU>`_ and standards\n- Simple and obvious; no frills or surprises\n- `Thoroughly documented <https://whenever.rtfd.io/en/latest/overview.html>`_ and tested\n- One file; no third-party dependencies\n\nQuickstart\n----------\n\n.. code-block:: python\n\n   >>> from whenever import (\n   ...    # Explicit types for different use cases\n   ...    UTCDateTime,     # -> Enforce UTC-normalization\n   ...    OffsetDateTime,  # -> Simple localized times\n   ...    ZonedDateTime,   # -> Full-featured timezones\n   ...    NaiveDateTime,   # -> Without any timezone\n   ... )\n\n   >>> py311_release = UTCDateTime(2022, 10, 24, hour=17)\n   UTCDateTime(2022-10-24 17:00:00Z)\n   >>> pycon23_start = OffsetDateTime(2023, 4, 21, hour=9, offset=-6)\n   OffsetDateTime(2023-04-21 09:00:00-06:00)\n\n   # Simple, explicit conversions\n   >>> py311_release.as_zoned(\"Europe/Paris\")\n   ZonedDateTime(2022-10-24 19:00:00+02:00[Europe/Paris])\n   >>> pycon23_start.as_local()  # example: system timezone in NYC\n   LocalSystemDateTime(2023-04-21 11:00:00-04:00)\n\n   # Comparison and equality across aware types\n   >>> py311_release > pycon23_start\n   False\n   >>> py311_release == py311_release.as_zoned(\"America/Los_Angeles\")\n   True\n\n   # Naive type that can't accidentally mix with aware types\n   >>> hackathon_invite = NaiveDateTime(2023, 10, 28, hour=12)\n   >>> # Na\u00efve/aware mixups are caught by typechecker\n   >>> hackathon_invite - py311_release\n   >>> # Only explicit assumptions will make it aware\n   >>> hackathon_start = hackathon_invite.assume_zoned(\"Europe/Amsterdam\")\n   ZonedDateTime(2023-10-28 12:00:00+02:00[Europe/Amsterdam])\n\n   # DST-aware operators\n   >>> hackathon_end = hackathon_start.add(hours=24)\n   ZonedDateTime(2022-10-29 11:00:00+01:00[Europe/Amsterdam])\n\n   # Lossless round-trip to/from text (useful for JSON/serialization)\n   >>> py311_release.canonical_format()\n   '2022-10-24T17:00:00Z'\n   >>> ZonedDateTime.from_canonical_format('2022-10-24T19:00:00+02:00[Europe/Paris]')\n   ZonedDateTime(2022-10-24 19:00:00+02:00[Europe/Paris])\n\n   # Conversion to/from common formats\n   >>> py311_release.rfc2822()  # also: from_rfc2822()\n   \"Mon, 24 Oct 2022 17:00:00 GMT\"\n   >>> pycon23_start.rfc3339()  # also: from_rfc3339()\n   \"2023-04-21T09:00:00-06:00\"\n\n   # Basic parsing\n   >>> OffsetDateTime.strptime(\"2022-10-24+02:00\", \"%Y-%m-%d%z\")\n   OffsetDateTime(2022-10-24 00:00:00+02:00)\n\n   # If you must: you can access the underlying datetime object\n   >>> pycon23_start.py_datetime().ctime()\n   'Fri Apr 21 09:00:00 2023'\n\nRead more in the `feature overview <https://whenever.readthedocs.io/en/latest/overview.html>`_\nor `API reference <https://whenever.readthedocs.io/en/latest/api.html>`_.\n\nWhy not...?\n-----------\n\nThe standard library\n~~~~~~~~~~~~~~~~~~~~\n\nThe standard library is full of quirks and pitfalls.\nTo summarize the detailed `blog post <https://dev.arie.bovenberg.net/blog/python-datetime-pitfalls/>`_:\n\n1.  Incompatible concepts of naive and aware are squeezed into one class\n2.  Operators ignore Daylight Saving Time (DST)\n3.  The meaning of \"naive\" is inconsistent (UTC, local, or unspecified?)\n4.  Non-existent datetimes pass silently\n5.  It guesses in the face of ambiguity\n6.  False negatives on equality of ambiguous times between timezones\n7.  False positives on equality of ambiguous times within the same timezone\n8.  ``datetime`` inherits from ``date``, but behaves inconsistently\n9.  ``datetime.timezone`` isn\u2019t enough for full-featured timezones.\n10. The local timezone is DST-unaware\n\nPendulum\n~~~~~~~~\n\nPendulum is full-featured datetime library, but it's\nhamstrung by the decision to inherit from the standard library ``datetime``.\nThis means it inherits most of the pitfalls mentioned above,\nwith the notable exception of DST-aware addition/subtraction.\n\nArrow\n~~~~~\n\nArrow is probably the most historically popular datetime library.\nPendulum did a good write-up of `the issues with Arrow <https://pendulum.eustace.io/faq/>`_.\nIt addresses fewer of datetime's pitfalls than Pendulum.\n\nDateType\n~~~~~~~~\n\nDateType mostly fixes the issue of mixing naive and aware datetimes,\nand datetime/date inheritance during type-checking,\nbut doesn't address the other pitfalls.\nThe type-checker-only approach also means that it doesn't enforce correctness at runtime,\nand it requires developers to be knowledgeable about\nhow the 'type checking reality' differs from the 'runtime reality'.\n\npython-dateutil\n~~~~~~~~~~~~~~~\n\nDateutil attempts to solve some of the issues with the standard library.\nHowever, it only *adds* functionality to work around the issues,\ninstead of *removing* the pitfalls themselves.\nThis still puts the burden on the developer to know about the issues,\nand to use the correct functions to avoid them.\nWithout removing the pitfalls, it's still very likely to make mistakes.\n\nMaya\n~~~~\n\nIt's unmaintained, but does have an interesting approach.\nBy enforcing UTC, it bypasses a lot of issues with the standard library.\nTo do so, it sacrifices the ability to represent offset, zoned, and local datetimes.\nSo in order to perform any timezone-aware operations, you need to convert\nto the standard library ``datetime`` first, which reintroduces the issues.\n\nHeliclockter\n~~~~~~~~~~~~\n\nThis library is a lot more explicit about the different types of datetimes,\naddressing issue of naive/aware mixing with UTC, local, and zoned datetime subclasses.\nIt doesn't address the other datetime pitfalls though.\n\n.. _roadmap:\n\nRoadmap\n-------\n\n- \ud83e\uddea **0.x**: get to feature-parity, process feedback, and tweak the API:\n\n  - \u2705 Datetime classes\n  - \u2705 Deltas\n  - \u2705 Date and time of day (separate from datetime)\n  - \ud83d\udea7 Interval\n  - \ud83d\udea7 Improved parsing and formatting\n- \ud83d\udd12 **1.0**:\n  - API stability and backwards compatibility\n  - Implement Rust extension for performance\n- \ud83d\udc0d **future**: Inspire a standard library improvement\n\nNot planned:\n\n- Different calendar systems\n\nVersioning and compatibility policy\n-----------------------------------\n\n**Whenever** follows semantic versioning.\nUntil the 1.0 version, the API may change with minor releases.\nBreaking changes will be avoided as much as possible,\nand meticulously explained in the changelog.\nSince the API is fully typed, your typechecker and/or IDE\nwill help you adjust to any API changes.\n\n  \u26a0\ufe0f **Note**: until 1.x, pickled objects may not be unpicklable across\n  versions. After 1.0, backwards compatibility of pickles will be maintained\n  as much as possible.\n\nAcknowledgements\n----------------\n\nThis project is inspired by the following projects. Check them out!\n\n- `Noda Time <https://nodatime.org/>`_\n- `Temporal <https://tc39.es/proposal-temporal/docs/>`_\n- `Chrono <https://docs.rs/chrono/latest/chrono/>`_\n\nContributing\n------------\n\nContributions are welcome! Please open an issue or a pull request.\n\n  \u26a0\ufe0f **Note**: big changes should be discussed in an issue first.\n  This is to avoid wasted effort if the change isn't a good fit for the project.\n\n..\n\n  \u26a0\ufe0f **Note**: Some tests are skipped on Windows.\n  These tests use unix-specific features to set the timezone for the current process.\n  As a result, Windows isn't able to run certain tests that rely on the system timezone.\n  It appears that `this functionality is not available on Windows <https://stackoverflow.com/questions/62004265/python-3-time-tzset-alternative-for-windows>`_.\n\nSetting up a development environment\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nYou'll need `poetry <https://python-poetry.org/>`_ installed.\nAn example of setting up things up:\n\n.. code-block:: bash\n\n   poetry install\n\n   # To run the tests with the current Python version\n   pytest\n\n   # if you want to build the docs\n   pip install -r docs/requirements.txt\n\n   # Various checks\n   mypy src/ tests/\n   flake8 src/ tests/\n\n   # autoformatting\n   black src/ tests/\n   isort src/ tests/\n\n   # To run the tests with all supported Python versions\n   # Alternatively, let the github actions on the PR do it for you\n   pip install tox\n   tox -p auto\n\n",
    "bugtrack_url": null,
    "license": "MIT",
    "summary": "Sensible and typesafe datetimes",
    "version": "0.5.2",
    "project_urls": {
        "Documentation": "https://whenever.readthedocs.io",
        "Homepage": "https://github.com/ariebovenberg/whenever",
        "Repository": "https://github.com/ariebovenberg/whenever"
    },
    "split_keywords": [
        "datetime"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "00c3c1f4353e6e694b11d6cc725bf7eb9ddbd36a495b65e11709d7146ee58082",
                "md5": "e53e8fa27838ffc222a2a239ff560da3",
                "sha256": "3de4f4e9583f378242f7961c731907a8000333e1e6895a6f324d192caadd2cde"
            },
            "downloads": -1,
            "filename": "whenever-0.5.2-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "e53e8fa27838ffc222a2a239ff560da3",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.8.1",
            "size": 29692,
            "upload_time": "2024-04-30T17:57:01",
            "upload_time_iso_8601": "2024-04-30T17:57:01.780830Z",
            "url": "https://files.pythonhosted.org/packages/00/c3/c1f4353e6e694b11d6cc725bf7eb9ddbd36a495b65e11709d7146ee58082/whenever-0.5.2-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "433e5ed21068d9dc51c40165604883e903102daf68b2ad7996575e0229663983",
                "md5": "5b97c1ad2815525d8330ace85bd22151",
                "sha256": "684b99527b13aa57db0d1fe040ba8021b4d3149b10951ba2006495dfb7cd8f45"
            },
            "downloads": -1,
            "filename": "whenever-0.5.2.tar.gz",
            "has_sig": false,
            "md5_digest": "5b97c1ad2815525d8330ace85bd22151",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.8.1",
            "size": 32626,
            "upload_time": "2024-04-30T17:57:03",
            "upload_time_iso_8601": "2024-04-30T17:57:03.603520Z",
            "url": "https://files.pythonhosted.org/packages/43/3e/5ed21068d9dc51c40165604883e903102daf68b2ad7996575e0229663983/whenever-0.5.2.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2024-04-30 17:57:03",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "ariebovenberg",
    "github_project": "whenever",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "tox": true,
    "lcname": "whenever"
}
        
Elapsed time: 0.25881s