diff --git a/Doc/deprecations/pending-removal-in-3.20.rst b/Doc/deprecations/pending-removal-in-3.20.rst index c86979c8ff91e9..21a561e7952afd 100644 --- a/Doc/deprecations/pending-removal-in-3.20.rst +++ b/Doc/deprecations/pending-removal-in-3.20.rst @@ -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) diff --git a/Doc/reference/datamodel.rst b/Doc/reference/datamodel.rst index 29f82fc12da1cc..882b05e87319fa 100644 --- a/Doc/reference/datamodel.rst +++ b/Doc/reference/datamodel.rst @@ -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 @@ -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 @@ -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) @@ -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. diff --git a/Doc/whatsnew/3.15.rst b/Doc/whatsnew/3.15.rst index d3ae7c21a0358b..231ae565192efe 100644 --- a/Doc/whatsnew/3.15.rst +++ b/Doc/whatsnew/3.15.rst @@ -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 @@ -825,6 +827,7 @@ New deprecations - :mod:`argparse` - :mod:`csv` - :mod:`!ctypes.macholib` + - :mod:`imaplib` - :mod:`ipaddress` - :mod:`json` - :mod:`logging` (``__date__`` also deprecated) diff --git a/Lib/imaplib.py b/Lib/imaplib.py index cbe129b3e7c214..c176736548188c 100644 --- a/Lib/imaplib.py +++ b/Lib/imaplib.py @@ -21,8 +21,6 @@ # GET/SETANNOTATION contributed by Tomas Lindroos June 2005. # IDLE contributed by Forest 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 @@ -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() @@ -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}") diff --git a/Lib/mimetypes.py b/Lib/mimetypes.py index 6c0efb671975d4..48a9f430d45262 100644 --- a/Lib/mimetypes.py +++ b/Lib/mimetypes.py @@ -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', @@ -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', diff --git a/Lib/test/test_gc.py b/Lib/test/test_gc.py index 4328909053465e..70d9d009fa8bfd 100644 --- a/Lib/test/test_gc.py +++ b/Lib/test/test_gc.py @@ -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): diff --git a/Lib/test/test_imaplib.py b/Lib/test/test_imaplib.py index 999e6e69ab41ea..430fa71fa29f59 100644 --- a/Lib/test/test_imaplib.py +++ b/Lib/test/test_imaplib.py @@ -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() diff --git a/Lib/test/test_mimetypes.py b/Lib/test/test_mimetypes.py index a29815bf49b1e7..746984ec0ca9df 100644 --- a/Lib/test/test_mimetypes.py +++ b/Lib/test/test_mimetypes.py @@ -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"), @@ -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"), diff --git a/Misc/NEWS.d/next/Library/2025-10-15-15-10-34.gh-issue-140166.NtxRez.rst b/Misc/NEWS.d/next/Library/2025-10-15-15-10-34.gh-issue-140166.NtxRez.rst new file mode 100644 index 00000000000000..c140db9dcd5150 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2025-10-15-15-10-34.gh-issue-140166.NtxRez.rst @@ -0,0 +1 @@ +:mod:`mimetypes`: Per the `IANA assignment `_, update the MIME type for the ``.texi`` and ``.texinfo`` file formats to ``application/texinfo``, instead of ``application/x-texinfo``. diff --git a/Misc/NEWS.d/next/Library/2025-10-18-14-30-21.gh-issue-76007.peEgcr.rst b/Misc/NEWS.d/next/Library/2025-10-18-14-30-21.gh-issue-76007.peEgcr.rst new file mode 100644 index 00000000000000..be56b2ca6a1c97 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2025-10-18-14-30-21.gh-issue-76007.peEgcr.rst @@ -0,0 +1 @@ +Deprecate ``__version__`` from a :mod:`imaplib`. Patch by Hugo van Kemenade. diff --git a/Modules/_testinternalcapi/test_lock.c b/Modules/_testinternalcapi/test_lock.c index 8d8cb992b0e07f..ded76ca9fe6819 100644 --- a/Modules/_testinternalcapi/test_lock.c +++ b/Modules/_testinternalcapi/test_lock.c @@ -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);