- Add example idle response tuples, to make the minor difference from other
imaplib response tuples more obvious.
- Merge the idle context manager's burst() method docs with the IMAP
object's idle() method docs, for easier understanding.
- Upgrade the Windows note regarding lack of pipe timeouts to a warning.
- Rephrase various things for clarity.
This extends imaplib with support for the rfc2177 IMAP IDLE command,
as requested in #55454. It allows events to be pushed to a client as
they occur, rather than having to continually poll for mailbox changes.
The interface is a new idle() method, which returns an iterable context
manager. Entering the context starts IDLE mode, during which events
(untagged responses) can be retrieved using the iteration protocol.
Exiting the context sends DONE to the server, ending IDLE mode.
An optional time limit for the IDLE session is supported, for use with
servers that impose an inactivity timeout.
The context manager also offers a burst() method, designed for programs
wishing to process events in batch rather than one at a time.
Notable differences from other implementations:
- It's an extension to imaplib, rather than a replacement.
- It doesn't introduce additional threads.
- It doesn't impose new requirements on the use of imaplib's existing methods.
- It passes the unit tests in CPython's test/test_imaplib.py module
(and adds new ones).
- It works on Windows, Linux, and other unix-like systems.
- It makes IDLE available on all of imaplib's client variants
(including IMAP4_stream).
- The interface is pythonic and easy to use.
Caveats:
- Due to a Windows limitation, the special case of IMAP4_stream running
on Windows lacks a duration/timeout feature. (This is the stdin/stdout
pipe connection variant; timeouts work fine for socket-based
connections, even on Windows.) I have documented it where appropriate.
- The file-like imaplib instance attributes are changed from buffered to
unbuffered mode. This could potentially break any client code that
uses those objects directly without expecting partial reads/writes.
However, these attributes are undocumented. As such, I think (and
PEP 8 confirms) that they are fair game for changes.
https://peps.python.org/pep-0008/#public-and-internal-interfaces
Daniel Hollas [Sun, 1 Sep 2024 14:44:48 +0000 (15:44 +0100)]
gh-118761: Speedup pathlib import by deferring shutil (#123520)
Co-authored-by: blurb-it[bot] <43283697+blurb-it[bot]@users.noreply.github.com> Co-authored-by: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com>
Oded Arbel [Sat, 31 Aug 2024 06:11:57 +0000 (09:11 +0300)]
gh-108172: do not override OS preferred browser if it is a super-string of a known browser (GH-113011)
When checking if the registering browser is the "OS preferred browser", do not use a substring search - that makes no sense: one can have a preferred browser that looks like a super-string of a known browser, e.g. "firefox-nightly" vs "firefox".
https://github.com/python/cpython/issues/108172 explains in more detail, and lays out a potential better future enhancement for this case of just using xdg-open. We'll go with this for now.
---------
Co-authored-by: Alex Waygood <Alex.Waygood@Gmail.com>
Alexander P. [Sat, 31 Aug 2024 05:57:22 +0000 (07:57 +0200)]
gh-121313: Limit the reading size from pipes to their default buffer size on POSIX systems (GH-121315)
See https://github.com/python/cpython/issues/121313 for analysis, but this greatly reduces memory overallocation and overhead when multiprocessing is sending non-small data over its pipes between processes.
Serhiy Storchaka [Thu, 29 Aug 2024 05:26:16 +0000 (08:26 +0300)]
gh-123431: Harmonize extension code checks in pickle (GH-123434)
This checks are redundant in normal circumstances and can only work if
the extension registry was intentionally broken.
* The Python implementation now raises exception for the extension code
with false boolean value.
* Simplify the C code. RuntimeError is now raised in explicit checks.
* Add many tests.
Serhiy Storchaka [Wed, 28 Aug 2024 09:11:13 +0000 (12:11 +0300)]
gh-122561: Clean up and microoptimize str.translate and charmap codec (GH-122932)
* Replace PyLong_AS_LONG() with PyLong_AsLong().
* Call PyLong_AsLong() only once per the replacement code.
* Use PyMapping_GetOptionalItem() instead of PyObject_GetItem().
Pieter Eendebak [Tue, 27 Aug 2024 19:22:43 +0000 (21:22 +0200)]
gh-123271: Make builtin zip method safe under free-threading (#123272)
The `zip_next` function uses a common optimization technique for methods
that generate tuples. The iterator maintains an internal reference to
the returned tuple. When the method is called again, it checks if the
internal tuple's reference count is 1. If so, the tuple can be reused.
However, this approach is not safe under the free-threading build:
after checking the reference count, another thread may perform the same
check and also reuse the tuple. This can result in a double decref on
the items of the replaced tuple and a double incref (memory leak) on
the items of the tuple being set.
This adds a function, `_PyObject_IsUniquelyReferenced` that
encapsulates the stricter logic necessary for the free-threaded build:
the internal tuple must be owned by the current thread, have a local
refcount of one, and a shared refcount of zero.
Kumar Aditya [Tue, 27 Aug 2024 13:04:03 +0000 (18:34 +0530)]
gh-123089: Make weakref.WeakSet safe against concurrent mutations while it is being iterated (#123279)
* Make `weakref.WeakSet` safe against concurrent mutations while it is being iterated.
`_IterationGuard` is no longer used for `WeakSet`, it now relies on copying the underlying set which is an atomic operation while iterating so that it can be modified by other threads.
Barney Gale [Mon, 26 Aug 2024 16:05:34 +0000 (17:05 +0100)]
GH-73991: Prune `pathlib.Path.copy()` and `copy_into()` arguments (#123337)
Remove *ignore* and *on_error* arguments from `pathlib.Path.copy[_into]()`,
because these arguments are under-designed. Specifically:
- *ignore* is appropriated from `shutil.copytree()`, but it's not clear
how it should apply when the user copies a non-directory. We've changed
the callback signature from the `shutil` version, but I'm not confident
the new signature is as good as it can be.
- *on_error* is a generalisation of `shutil.copytree()`'s error handling,
which is to accumulate exceptions and raise a single `shutil.Error` at
the end. It's not obvious which solution is better.
Additionally, this arguments may be challenging to implement in future user
subclasses of `PathBase`, which might utilise a native recursive copying
method.
Barney Gale [Mon, 26 Aug 2024 15:26:34 +0000 (16:26 +0100)]
GH-73991: Make `pathlib.Path.delete()` private. (#123315)
Per feedback from Paul Moore on GH-123158, it's better to defer making
`Path.delete()` public than ship it with under-designed error handling
capabilities.
We leave a remnant `_delete()` method, which is used by `move()`. Any
functionality not needed by `move()` is deleted.
Barney Gale [Mon, 26 Aug 2024 13:14:23 +0000 (14:14 +0100)]
GH-73991: Add `pathlib.Path.copy_into()` and `move_into()` (#123314)
These two methods accept an *existing* directory path, onto which we join
the source path's base name to form the final target path.
A possible alternative implementation is to check for directories in
`copy()` and `move()` and adjust the target path, which is done in several
`shutil` functions. This behaviour is helpful in a shell context, but
less so in a stored program that explicitly specifies destinations. For
example, a user that calls `Path('foo.py').copy('bar.py')` might not
imagine that `bar.py/foo.py` would be created, but under the alternative
implementation this will happen if `bar.py` is an existing directory.
Matt Wozniski [Sun, 25 Aug 2024 22:54:06 +0000 (18:54 -0400)]
gh-123177: Fix prompt for wrapped lines in pyrepl (#123324)
When display lines above the cursor come from the cache, the first line
to not come from the cache may be a wrapped line, starting half way
through a logical line in the buffer. Detect and handle this case to
avoid accidentally drawing a stray prompt in the middle of a logical
line.
Barney Gale [Sun, 25 Aug 2024 15:51:51 +0000 (16:51 +0100)]
GH-73991: Add `pathlib.Path.move()` (#122073)
Add a `Path.move()` method that moves a file or directory tree, and returns a new `Path` instance pointing to the target.
This method is similar to `shutil.move()`, except that it doesn't accept a *copy_function* argument, and it doesn't check whether the destination is an existing directory.
Sam Gross [Fri, 23 Aug 2024 19:36:14 +0000 (15:36 -0400)]
gh-117376: Make `Py_DECREF` a macro in ceval.c in free-threaded build (#122975)
`Py_DECREF` and `PyStackRef_CLOSE` are now implemented as macros in the
free-threaded build in ceval.c. There are two motivations;
* MSVC has problems inlining functions in ceval.c in the PGO build.
* We will want to mark escaping calls in order to spill the stack
pointer in ceval.c and we will want to do this around `_Py_Dealloc`
(or `_Py_MergeZeroLocalRefcount` or `_Py_DecRefShared`), not around
the entire `Py_DECREF` or `PyStackRef_CLOSE` call.