Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Deprecate utcnow and utcfromtimestamp #103857

Closed
pganssle opened this issue Apr 25, 2023 · 4 comments
Closed

Deprecate utcnow and utcfromtimestamp #103857

pganssle opened this issue Apr 25, 2023 · 4 comments
Labels
type-feature A feature request or enhancement

Comments

@pganssle
Copy link
Member

pganssle commented Apr 25, 2023

Feature or enhancement

Previously, we have documented that utcnow and utcfromtimestamp should not be used, but we didn't go so far as to actually deprecate them, and I wrote a whole article about how you shouldn't use them.

The main reason I had for not deprecating them at the time was that .utcnow() is faster than .now(datetime.UTC), and if you are immediately converting the datetime to a string, like datetime.utcnow().isoformat(), there's no danger.

I have come around to the idea that this type of use case is not important enough to leave the attractive nuisances of utcnow() and utcfromtimestamp() in place, and we should go ahead and deprecate them.

Pitch

We should deprecate them in the documentation and also add DeprecationWarnings imploring people not to use them. I'm OK with us saying that we will remove them "at some point in the future" and not necessarily putting a deadline on it, considering how much use of utcnow() is out there.

Previous discussion

Linked PRs

@pganssle pganssle added the type-feature A feature request or enhancement label Apr 25, 2023
@pganssle
Copy link
Member Author

I've gone ahead and done some benchmarks for the most common legitimate use case I've seen for utcnow and utcfromtimestamp, which is getting a naïve datetime and immediately formatting it to a string with no time zone offset. The alternatives are considerably slower, though I don't know how important that is for real life use cases:

>>> %timeit datetime.now(UTC).replace(tzinfo=None).isoformat(' ')
2.15 µs ± 19.9 ns per loop (mean ± std. dev. of 7 runs, 100,000 loops each)
>>> %timeit datetime.now(UTC).isoformat(' ')[:-6]
1.61 µs ± 23.7 ns per loop (mean ± std. dev. of 7 runs, 1,000,000 loops each)
>>> %timeit datetime.utcnow().isoformat(' ')
919 ns ± 5.23 ns per loop (mean ± std. dev. of 7 runs, 1,000,000 loops each)

As an example of how this changes the speed in a real-life application, here are the before and after measurements for the change to http.cookiejar.time2isoz:

>>> t = datetime.now().timestamp()
>>> %timeit cookiejar(None)  # Uses datetime.now
1.52 µs ± 16.2 ns per loop (mean ± std. dev. of 7 runs, 1,000,000 loops each)
>>> %timeit cookiejar_utc(None)  # Uses datetime.utcnow
1.32 µs ± 6.72 ns per loop (mean ± std. dev. of 7 runs, 1,000,000 loops each)

>>> %timeit cookiejar(t)  # Uses datetime.fromtimestamp
1.77 µs ± 24.2 ns per loop (mean ± std. dev. of 7 runs, 1,000,000 loops each)
>>> %timeit cookiejar_utc(t)  # Uses datetime.utcfromtimestamp
1.4 µs ± 5.75 ns per loop (mean ± std. dev. of 7 runs, 1,000,000 loops each)

I'm still more or less convinced that this is useful to do, and I'd like to see if anyone complains that it's a major problem after the deprecation before worrying about these micro-optimizations.

pganssle added a commit that referenced this issue Apr 27, 2023
Using `datetime.datetime.utcnow()` and `datetime.datetime.utcfromtimestamp()` will now raise a `DeprecationWarning`.

We also have removed our internal uses of these functions and documented the change.
@pganssle
Copy link
Member Author

#103858 is now merged, but we still need a What's New entry before closing this, I believe.

@hugovk
Copy link
Member

hugovk commented May 16, 2023

#103858 is now merged, but we still need a What's New entry before closing this, I believe.

Please see PR #104542.

@hugovk
Copy link
Member

hugovk commented May 22, 2023

I think we're all set here! 🚀

netbsd-srcmastr pushed a commit to NetBSD/pkgsrc that referenced this issue Jul 29, 2023
Changes in Version 4.4.1
------------------------

Version 4.4.1 fixes the following bugs:

- Fixed a bug where pymongo would raise a ``ConfigurationError: Invalid SRV host``
  error when connecting to a "mongodb+srv://" URI that included capital letters
  in the SRV hosts returned from DNS. (`PYTHON-3800`_).
- Fixed a minor reference counting bug in the C extension (`PYTHON-3798`_).


Changes in Version 4.4
-----------------------

- Added support for MongoDB 7.0.
- Added support for Python 3.11.
- Added support for passing a list containing (key, direction) pairs
  or keys to :meth:`~pymongo.collection.Collection.create_index`.
- Improved bson encoding performance (`PYTHON-3717`_ and `PYTHON-3718`_).
- Improved support for Pyright to improve typing support for IDEs like Visual Studio Code
  or Visual Studio.
- Improved support for type-checking with MyPy "strict" mode (`--strict`).
- Added :meth:`~pymongo.encryption.ClientEncryption.create_encrypted_collection`,
  :class:`~pymongo.errors.EncryptedCollectionError`,
  :meth:`~pymongo.encryption.ClientEncryption.encrypt_expression`,
  :class:`~pymongo.encryption_options.RangeOpts`,
  and :attr:`~pymongo.encryption.Algorithm.RANGEPREVIEW` as part of the experimental
  Queryable Encryption beta.
- pymongocrypt 1.6.0 or later is now required for :ref:`In-Use Encryption` support. MongoDB
  Server 7.0 introduced a backwards breaking change to the QE protocol. Users taking
  advantage of the Queryable Encryption beta must now upgrade to MongoDB 7.0+ and
  PyMongo 4.4+.
- Previously, PyMongo's docs recommended using :meth:`datetime.datetime.utcnow` and
  :meth:`datetime.datetime.utcfromtimestamp`. utcnow and utcfromtimestamp are deprecated
  in Python 3.12, for reasons explained `in this Github issue`_. Instead, users should
  use :meth:`datetime.datetime.now(tz=timezone.utc)` and
  :meth:`datetime.datetime.fromtimestamp(tz=timezone.utc)` instead.

.. _in this Github issue: python/cpython#103857


Changes in Version 4.3.3
------------------------

Version 4.3.3 documents support for the following:

- :ref:`CSFLE on-demand credentials` for cloud KMS providers.
- Authentication support for :ref:`EKS Clusters`.
- Added the :ref:`timeout-example` example page to improve the documentation
  for :func:`pymongo.timeout`.

Bug Fixes
.........
- Fixed a performance regression in :meth:`~gridfs.GridFSBucket.download_to_stream`
  and :meth:`~gridfs.GridFSBucket.download_to_stream_by_name` by reading in chunks
  instead of line by line (`PYTHON-3502`_).
- Improved performance of :meth:`gridfs.grid_file.GridOut.read` and
  :meth:`gridfs.grid_file.GridOut.readline` (`PYTHON-3508`_).


Changes in Version 4.3 (4.3.2)
------------------------------

Note: We withheld uploading tags 4.3.0 and 4.3.1 to PyPI due to a
version handling error and a necessary documentation update.

`dnspython <https://pypi.python.org/pypi/dnspython>`_ is now a required
dependency. This change makes PyMongo easier to install for use with "mongodb+srv://"
connection strings and `MongoDB Atlas <https://www.mongodb.com/cloud>`_.

PyMongo 4.3 brings a number of improvements including:

- Added support for decoding BSON datetimes outside of the range supported
  by Python's :class:`~datetime.datetime` builtin. See
  :ref:`handling-out-of-range-datetimes` for examples, as well as
  :class:`bson.datetime_ms.DatetimeMS`,
  :class:`bson.codec_options.DatetimeConversion`, and
  :class:`bson.codec_options.CodecOptions`'s ``datetime_conversion``
  parameter for more details (`PYTHON-1824`_).
- PyMongo now resets its locks and other shared state in the child process
  after a :py:func:`os.fork` to reduce the frequency of deadlocks. Note that
  deadlocks are still possible because libraries that PyMongo depends like
  OpenSSL cannot be made fork() safe in multithreaded applications.
  (`PYTHON-2484`_). For more info see :ref:`pymongo-fork-safe`.
- When used with MongoDB 6.0+, :class:`~pymongo.change_stream.ChangeStream` s
  now allow for new types of events (such as DDL and C2C replication events)
  to be recorded with the new parameter ``show_expanded_events``
  that can be passed to methods such as :meth:`~pymongo.collection.Collection.watch`.
- PyMongo now internally caches AWS credentials that it fetches from AWS
  endpoints, to avoid rate limitations.  The cache is cleared when the
  credentials expire or an error is encountered.
- When using the ``MONGODB-AWS`` authentication mechanism with the
  ``aws`` extra, the behavior of credential fetching has changed with
  ``pymongo_auth_aws>=1.1.0``.  Please see :doc:`examples/authentication` for
  more information.

Bug fixes
.........

- Fixed a bug where  :class:`~pymongo.change_stream.ChangeStream`
  would allow an app to retry calling ``next()`` or ``try_next()`` even
  after non-resumable errors (`PYTHON-3389`_).
- Fixed a bug where the client could be unable to discover the new primary
  after a simultaneous replica set election and reconfig (`PYTHON-2970`_).
jakelishman added a commit to jakelishman/subunit that referenced this issue Sep 22, 2023
The methods `datetime.datetime.utc` and `.utcfromtimestamp` were marked
deprecated in Python 3.12 in favour of `now(tz=datetime.timezone.utc)`
and `fromtimestamp(tz=datetime.timezone.utc)` [1].

[1]: python/cpython#103857
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type-feature A feature request or enhancement
Projects
None yet
Development

No branches or pull requests

2 participants