Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Doc/deprecations/pending-removal-in-3.20.rst
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ Pending removal in Python 3.20
- :mod:`argparse`
- :mod:`csv`
- :mod:`!ctypes.macholib`
- :mod:`imaplib`
- :mod:`ipaddress`
- :mod:`json`
- :mod:`logging` (``__date__`` also deprecated)
Expand Down
16 changes: 10 additions & 6 deletions Doc/reference/datamodel.rst
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,8 @@ Objects, values and types
single: data

:dfn:`Objects` are Python's abstraction for data. All data in a Python program
is represented by objects or by relations between objects. (In a sense, and in
conformance to Von Neumann's model of a "stored program computer", code is also
represented by objects.)
is represented by objects or by relations between objects. Even code is
represented by objects.

.. index::
pair: built-in function; id
Expand All @@ -29,9 +28,6 @@ represented by objects.)
single: mutable object
single: immutable object

.. XXX it *is* now possible in some cases to change an object's
type, under certain controlled conditions

Every object has an identity, a type and a value. An object's *identity* never
changes once it has been created; you may think of it as the object's address in
memory. The :keyword:`is` operator compares the identity of two objects; the
Expand Down Expand Up @@ -1185,6 +1181,7 @@ Special attributes
single: __module__ (class attribute)
single: __dict__ (class attribute)
single: __bases__ (class attribute)
single: __base__ (class attribute)
single: __doc__ (class attribute)
single: __annotations__ (class attribute)
single: __annotate__ (class attribute)
Expand Down Expand Up @@ -1219,6 +1216,13 @@ Special attributes
In most cases, for a class defined as ``class X(A, B, C)``,
``X.__bases__`` will be exactly equal to ``(A, B, C)``.

* - .. attribute:: type.__base__
- .. impl-detail::

The single base class in the inheritance chain that is responsible
for the memory layout of instances. This attribute corresponds to
:c:member:`~PyTypeObject.tp_base` at the C level.

* - .. attribute:: type.__doc__
- The class's documentation string, or ``None`` if undefined.
Not inherited by subclasses.
Expand Down
3 changes: 3 additions & 0 deletions Doc/whatsnew/3.15.rst
Original file line number Diff line number Diff line change
Expand Up @@ -682,6 +682,8 @@ mimetypes
---------

* Add ``application/toml``. (Contributed by Gil Forcada in :gh:`139959`.)
* Rename ``application/x-texinfo`` to ``application/texinfo``.
(Contributed by Charlie Lin in :gh:`140165`)


pathlib
Expand Down Expand Up @@ -825,6 +827,7 @@ New deprecations
- :mod:`argparse`
- :mod:`csv`
- :mod:`!ctypes.macholib`
- :mod:`imaplib`
- :mod:`ipaddress`
- :mod:`json`
- :mod:`logging` (``__date__`` also deprecated)
Expand Down
12 changes: 9 additions & 3 deletions Lib/imaplib.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,6 @@
# GET/SETANNOTATION contributed by Tomas Lindroos <skitta@abo.fi> June 2005.
# IDLE contributed by Forest <forestix@nom.one> August 2024.

__version__ = "2.60"

import binascii, errno, random, re, socket, subprocess, sys, time, calendar
from datetime import datetime, timezone, timedelta
from io import DEFAULT_BUFFER_SIZE
Expand Down Expand Up @@ -247,7 +245,6 @@ def _connect(self):
self._cmd_log_idx = 0
self._cmd_log = {} # Last '_cmd_log_len' interactions
if self.debug >= 1:
self._mesg('imaplib version %s' % __version__)
self._mesg('new IMAP4 connection, tag=%s' % self.tagpre)

self.welcome = self._get_response()
Expand Down Expand Up @@ -1965,3 +1962,12 @@ def run(cmd, args):
''' % sys.argv[0])

raise


def __getattr__(name):
if name == "__version__":
from warnings import _deprecated

_deprecated("__version__", remove=(3, 20))
return "2.60" # Do not change
raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
4 changes: 2 additions & 2 deletions Lib/mimetypes.py
Original file line number Diff line number Diff line change
Expand Up @@ -500,6 +500,8 @@ def _default_mime_types():
'.ps' : 'application/postscript',
'.ai' : 'application/postscript',
'.eps' : 'application/postscript',
'.texi' : 'application/texinfo',
'.texinfo': 'application/texinfo',
'.toml' : 'application/toml',
'.trig' : 'application/trig',
'.m3u' : 'application/vnd.apple.mpegurl',
Expand Down Expand Up @@ -549,8 +551,6 @@ def _default_mime_types():
'.tar' : 'application/x-tar',
'.tcl' : 'application/x-tcl',
'.tex' : 'application/x-tex',
'.texi' : 'application/x-texinfo',
'.texinfo': 'application/x-texinfo',
'.roff' : 'application/x-troff',
'.t' : 'application/x-troff',
'.tr' : 'application/x-troff',
Expand Down
14 changes: 14 additions & 0 deletions Lib/test/test_gc.py
Original file line number Diff line number Diff line change
Expand Up @@ -1559,6 +1559,20 @@ def test_indirect_calls_with_gc_disabled(self):
finally:
gc.enable()

# Ensure that setting *threshold0* to zero disables collection.
@gc_threshold(0)
def test_threshold_zero(self):
junk = []
i = 0
detector = GC_Detector()
while not detector.gc_happened:
i += 1
if i > 50000:
break
junk.append([]) # this may eventually trigger gc (if it is enabled)

self.assertEqual(i, 50001)


class PythonFinalizationTests(unittest.TestCase):
def test_ast_fini(self):
Expand Down
10 changes: 10 additions & 0 deletions Lib/test/test_imaplib.py
Original file line number Diff line number Diff line change
Expand Up @@ -1117,5 +1117,15 @@ def test_ssl_verified(self):
client.shutdown()


class TestModule(unittest.TestCase):
def test_deprecated__version__(self):
with self.assertWarnsRegex(
DeprecationWarning,
"'__version__' is deprecated and slated for removal in Python 3.20",
) as cm:
getattr(imaplib, "__version__")
self.assertEqual(cm.filename, __file__)


if __name__ == "__main__":
unittest.main()
2 changes: 1 addition & 1 deletion Lib/test/test_mimetypes.py
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,7 @@ def check_extensions():
("application/gzip", ".gz"),
("application/ogg", ".ogx"),
("application/postscript", ".ps"),
("application/texinfo", ".texi"),
("application/toml", ".toml"),
("application/vnd.apple.mpegurl", ".m3u"),
("application/vnd.ms-excel", ".xls"),
Expand All @@ -247,7 +248,6 @@ def check_extensions():
("application/x-debian-package", ".deb"),
("application/x-httpd-php", ".php"),
("application/x-rpm", ".rpm"),
("application/x-texinfo", ".texi"),
("application/x-troff", ".roff"),
("application/xml", ".xsl"),
("application/yaml", ".yaml"),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
:mod:`mimetypes`: Per the `IANA assignment <https://www.iana.org/assignments/media-types/application/texinfo>`_, update the MIME type for the ``.texi`` and ``.texinfo`` file formats to ``application/texinfo``, instead of ``application/x-texinfo``.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Deprecate ``__version__`` from a :mod:`imaplib`. Patch by Hugo van Kemenade.
3 changes: 2 additions & 1 deletion Modules/_testinternalcapi/test_lock.c
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,8 @@ test_lock_two_threads(PyObject *self, PyObject *obj)
} while (v != 3 && iters < 200);

// both the "locked" and the "has parked" bits should be set
assert(test_data.m._bits == 3);
v = _Py_atomic_load_uint8_relaxed(&test_data.m._bits);
assert(v == 3);

PyMutex_Unlock(&test_data.m);
PyEvent_Wait(&test_data.done);
Expand Down
Loading