Skip to content

gh-108973: Fix asyncio test_subprocess_consistent_callbacks() #109431

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

Merged
merged 1 commit into from
Sep 20, 2023

Conversation

vstinner
Copy link
Member

@vstinner vstinner commented Sep 14, 2023

SubprocessProtocol process_exited() method can be called before
pipe_data_received() and pipe_connection_lost() methods. Document it
and adapt the test for that.

Revert commit 282edd7.
_child_watcher_callback() calls immediately _process_exited(): don't
add an additional delay with call_soon(). The reverted change didn't
make _process_exited() more determistic: it can still be called
before pipe_connection_lost() for example.

Co-authored-by: Davide Rizzo [email protected]

@vstinner
Copy link
Member Author

cc @kumaraditya303 @gvanrossum

@gvanrossum
Copy link
Member

I’m on vacation until Sept. 25. Can this wait?

@vstinner
Copy link
Member Author

I’m on vacation until Sept. 25. Can this wait?

This bug is affecting many buildbots, it fails quite often :-( I will try to get a review from someone else :-) @sorcio seems to now have a good knowledge of what's going on.


def exit_maybe(self):
# Only exit when we got all expected events
if len(events) >= len(expected):
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Before, we stopped as soon as we seen process_exited. But sometimes, process_exited is get earlier than other events, and so events only contains some expected events and the test fails also in this case :-(

@vstinner
Copy link
Member Author

Procedure to reproduce the bug, by @sorcio.

Create subprocess-test-program.c:

#include <unistd.h>

int main(int argc, char** argv) {
    write(1, "stdout", 6);
    write(2, "stderr", 6);
    return 0;
}

Build it with:

cc subprocess-test-program.c -O3 -o subprocess-test-program

Apply this patch:

diff --git a/Lib/test/test_asyncio/test_subprocess.py b/Lib/test/test_asyncio/test_subprocess.py
index eeeca40c15..882c20a7ad 100644
--- a/Lib/test/test_asyncio/test_subprocess.py
+++ b/Lib/test/test_asyncio/test_subprocess.py
@@ -773,8 +773,9 @@ async def main() -> None:
             loop = asyncio.get_running_loop()
             exit_future = asyncio.Future()
             code = 'import sys; sys.stdout.write("stdout"); sys.stderr.write("stderr")'
+            program = os.path.join(os.path.dirname(sys.executable), 'subprocess-test-program')
             transport, _ = await loop.subprocess_exec(lambda: MyProtocol(exit_future),
-                                                      sys.executable, '-c', code, stdin=None)
+                                                      program, stdin=None)
             await exit_future
             transport.close()
             self.assertEqual(events, [

Run:

./python -m test test_asyncio.test_subprocess -m test_subprocess_consistent_callbacks -j4 --forever 

On Linux, it takes less than 5 seconds to reproduce the issue.

@vstinner
Copy link
Member Author

With this change, I can no longer reproduce the bug on Linux. I stressed the test with (my laptop has 6 threads / 12 CPU cores):

./python -m test test_asyncio.test_subprocess -m test_subprocess_consistent_callbacks -j50 --forever

I stopped the test after 7 minutes and 2656 success:

...
0:07:00 load avg: 51.24 [2654] test_asyncio.test_subprocess passed
0:07:01 load avg: 51.24 [2655] test_asyncio.test_subprocess passed
0:07:01 load avg: 51.24 [2656] test_asyncio.test_subprocess passed

@vstinner
Copy link
Member Author

@gvanrossum:

I’m on vacation until Sept. 25. Can this wait?

me:

This bug is affecting many buildbots, it fails quite often :-(

Oh, just a recent example (1 hour ago): I just fixed AMD64 RHEL8 FIPS Only Blake2 Builtin Hash 3.x buildbot which always failed. The buildbot turned green for its first time since it was set up! The build 6002 is a success.

And you know what? The following build 6003 is a failure because of:

FAIL: test_subprocess_consistent_callbacks (test.test_asyncio.test_subprocess.SubprocessThreadedWatcherTests.test_subprocess_consistent_callbacks)

This whack-a-mole game is less funny if I see the same bugs over and over :-(

@vstinner
Copy link
Member Author

@kumaraditya303 @sorcio: Would you mind to review this test_asyncio fix? See the issue for the rationale.

Copy link
Contributor

@sorcio sorcio left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As far as I understand, this test was introduced on the faulty assumption that process_exited should come last, but asyncio doesn't try to do that, and it doesn't always make sense. It has value in that it's the only subprocess test case that also covers pipe events, though. Unless we add better coverage, your version of the test is okay. The question is whether it's necessary. I suggest to remove it entirely, or at least to make it clear what it's testing (the name is not descriptive at all).

@vstinner
Copy link
Member Author

Oh. The asyncio doc has an example which makes the assumption that process_exit() will be first called last. As soon as it's called, the program stops: https://docs.python.org/dev/library/asyncio-protocol.html#loop-subprocess-exec-and-subprocessprotocol.

  • I completed the doc to clarify that subprocess protocol methods can be called in any order.
  • I fixed the example.
  • I changed the test name.

@sorcio: Would you mind to review the updated PR?

@vstinner
Copy link
Member Author

I also reverted commit 282edd7 as @sorcio suggested in his comment: #108973 (comment)

@@ -227,7 +227,7 @@ async def _make_subprocess_transport(self, protocol, args, shell,

def _child_watcher_callback(self, pid, returncode, transp):
# Skip one iteration for callbacks to be executed
self.call_soon_threadsafe(self.call_soon, transp._process_exited, returncode)
self.call_soon_threadsafe(transp._process_exited, returncode)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's safe to call the method immediately. It's up to the child watcher to take care to call this in the loop thread. ThreadedChildWatcher already does.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The child watcher runs in a different thread. call_soon_threadsafe() is needed to make sure that the callback is run in the same thread that the event loop. It's an important principle in asyncio, no?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What I meant is that the child watcher itself already uses call_soon_threadsafe() to schedule the callback. But I've just noticed a little complication. The documentation for AbstractChildWatcher.add_child_handler requires the callback itself to be thread-safe, which could mean that it can be called from any thread. One of the calls to call_soon_threadsafe() is redundant.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did a bit of digging and the comment requiring the callback to be thread-safe was there already before there was even support for running the loop on different threads. The watchers have been updated to use call_soon_threadsafe() for callbacks after that. Since watchers are public API (thankfully deprecated), the requirement can't be relaxed.

Possibly one of the redundant calls can still be removed, but considering 3.14 will remove watchers altogether it might not be worth it. Let's say that I'm skeptical of this approach of several layers of scheduling callbacks (there is one more when the transport calls the protocol's process_exited method) because it can hide race conditions such as the one in this bug.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would you be ok if this call is removed in a separated PR? I'm not comfortable to touch asyncio, but the bug is impacting many CIs and it's very annoying. I would prefer that someone who is more comfortable with asyncio does this change :-)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, clearly this would need more discussion/investigation/etc. Let's forget about it for this PR.

@vstinner vstinner force-pushed the test_subprocess_consistent_callbacks branch 3 times, most recently from 209b7e5 to 22489d4 Compare September 19, 2023 17:35
SubprocessProtocol process_exited() method can be called before
pipe_data_received() and pipe_connection_lost() methods. Document it
and adapt the test for that.

Revert commit 282edd7.
_child_watcher_callback() calls immediately _process_exited(): don't
add an additional delay with call_soon(). The reverted change didn't
make _process_exited() more determistic: it can still be called
before pipe_connection_lost() for example.

Co-authored-by: Davide Rizzo <[email protected]>
@vstinner vstinner force-pushed the test_subprocess_consistent_callbacks branch from 22489d4 to 59400e9 Compare September 19, 2023 17:37
@vstinner
Copy link
Member Author

  • I rebased my PR on main.
  • I rewrote my doc change only mention that process_exit() can be called before pipe events, nothing else.
  • I rewrote the test to check that we received all events in any order, and then check that pipe events were received in the expected order.

@sorcio: Would you mind to review my updated PR?

@vstinner
Copy link
Member Author

I stress tested my fix: it works as expected:

$ ./python -m test test_asyncio.test_subprocess -m test_subprocess_protocol_events -j50 --forever
(...)
0:04:32 load avg: 51.19 [1503/1] test_asyncio.test_subprocess passed
0:04:32 load avg: 51.09 [1504/1] test_asyncio.test_subprocess passed
0:04:33 load avg: 51.09 [1505/1] test_asyncio.test_subprocess passed
0:04:33 load avg: 51.09 [1506/1] test_asyncio.test_subprocess passed
^C

I interrupted it after 4 min 30 sec.

The only failure is unrelated to the initial issue:

0:02:26 load avg: 50.15 [806/1] test_asyncio.test_subprocess failed (env changed)
Warning -- threading_cleanup() failed to cleanup 1 threads (count: 1, dangling: 2)
Warning -- Dangling thread: <Thread(waitpid-0, started daemon 139780245042880)>
Warning -- Dangling thread: <_MainThread(MainThread, started 139780491732800)>

Copy link
Contributor

@sorcio sorcio left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me!

I came to appreciate that the example now shows the correct relationship between events for a simple case like this. It makes the documentation a lot clearer, so it doesn't matter if (if!) it's not perfectly idiomatic.

@vstinner vstinner merged commit ced6924 into python:main Sep 20, 2023
@vstinner vstinner deleted the test_subprocess_consistent_callbacks branch September 20, 2023 13:54
@miss-islington
Copy link
Contributor

Thanks @vstinner for the PR 🌮🎉.. I'm working now to backport this PR to: 3.11, 3.12.
🐍🍒⛏🤖

@miss-islington
Copy link
Contributor

Sorry, @vstinner, I could not cleanly backport this to 3.11 due to a conflict.
Please backport using cherry_picker on command line.
cherry_picker ced6924630037f1e5b3d1dbef2b600152fb07fbb 3.11

miss-islington pushed a commit to miss-islington/cpython that referenced this pull request Sep 20, 2023
…ythonGH-109431)

SubprocessProtocol process_exited() method can be called before
pipe_data_received() and pipe_connection_lost() methods. Document it
and adapt the test for that.

Revert commit 282edd7.
_child_watcher_callback() calls immediately _process_exited(): don't
add an additional delay with call_soon(). The reverted change didn't
make _process_exited() more determistic: it can still be called
before pipe_connection_lost() for example.

(cherry picked from commit ced6924)

Co-authored-by: Victor Stinner <[email protected]>
Co-authored-by: Davide Rizzo <[email protected]>
@bedevere-app
Copy link

bedevere-app bot commented Sep 20, 2023

GH-109609 is a backport of this pull request to the 3.12 branch.

@bedevere-app bedevere-app bot removed the needs backport to 3.12 only security fixes label Sep 20, 2023
@vstinner
Copy link
Member Author

@sorcio: In the main branch, I didn't want to remove call_soon_threadsafe() in _child_watcher_callback(), since this change is going to be backported to stable versions. Also, as I wrote, I'm not comfortable with touching asyncio in general. Do you want to propose a PR to change this code in the main branch?

@vstinner vstinner removed the needs backport to 3.11 only security fixes label Sep 20, 2023
@vstinner
Copy link
Member Author

Oh, the test was added to Python 3.11 and so test_asyncio is not affected in Python 3.11.

@bedevere-app
Copy link

bedevere-app bot commented Sep 20, 2023

GH-109610 is a backport of this pull request to the 3.11 branch.

@vstinner
Copy link
Member Author

Oh, the test was added to Python 3.11 and so test_asyncio is not affected in Python 3.11.

I just wrote PR #109610 to backport the documentation changes.

@vstinner
Copy link
Member Author

Thanks a lot for the very constructive review @sorcio, apparently, I misunderstood how subprocess events are delivered in asyncio and you helped me to fix the doc, the doc example and the test. I think that the situation is now well better documented and accurate than before.

@bedevere-bot
Copy link

⚠️⚠️⚠️ Buildbot failure ⚠️⚠️⚠️

Hi! The buildbot AMD64 RHEL8 3.x has failed when building commit ced6924.

What do you need to do:

  1. Don't panic.
  2. Check the buildbot page in the devguide if you don't know what the buildbots are or how they work.
  3. Go to the page of the buildbot that failed (https://buildbot.python.org/all/#builders/185/builds/5052) and take a look at the build logs.
  4. Check if the failure is related to this commit (ced6924) or if it is a false positive.
  5. If the failure is related to this commit, please, reflect that on the issue and make a new Pull Request with a fix.

You can take a look at the buildbot page here:

https://buildbot.python.org/all/#builders/185/builds/5052

Failed tests:

  • test.test_asyncio.test_unix_events

Failed subtests:

  • test_fork_signal_handling - test.test_asyncio.test_unix_events.TestFork.test_fork_signal_handling

Summary of the results of the build (if available):

==

Click to see traceback logs
Traceback (most recent call last):
  File "/home/buildbot/buildarea/3.x.cstratak-RHEL8-x86_64/build/Lib/unittest/async_case.py", line 90, in _callTestMethod
    if self._callMaybeAsync(method) is not None:
       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/buildbot/buildarea/3.x.cstratak-RHEL8-x86_64/build/Lib/unittest/async_case.py", line 117, in _callMaybeAsync
    return self._asyncioTestContext.run(func, *args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/buildbot/buildarea/3.x.cstratak-RHEL8-x86_64/build/Lib/test/support/hashlib_helper.py", line 49, in wrapper
    return func_or_class(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/buildbot/buildarea/3.x.cstratak-RHEL8-x86_64/build/Lib/test/test_asyncio/test_unix_events.py", line 1937, in test_fork_signal_handling
    self.assertTrue(child_handled.is_set())
AssertionError: False is not true

vstinner added a commit that referenced this pull request Sep 20, 2023
gh-108973: Fix asyncio SubprocessProtocol doc (#109431)

SubprocessProtocol process_exited() method can be called before
pipe_data_received() and pipe_connection_lost() methods. Document it
and adapt the example in the doc.

Co-authored-by: Davide Rizzo <[email protected]>
(cherry picked from commit ced6924)
@sorcio
Copy link
Contributor

sorcio commented Sep 20, 2023

@vstinner

In the main branch, I didn't want to remove call_soon_threadsafe() in _child_watcher_callback(), since this change is going to be backported to stable versions. Also, as I wrote, I'm not comfortable with touching asyncio in general. Do you want to propose a PR to change this code in the main branch?

Do we need an issue for this, or just a PR referencing the same issue?

@bedevere-bot
Copy link

⚠️⚠️⚠️ Buildbot failure ⚠️⚠️⚠️

Hi! The buildbot s390x Fedora LTO + PGO 3.x has failed when building commit ced6924.

What do you need to do:

  1. Don't panic.
  2. Check the buildbot page in the devguide if you don't know what the buildbots are or how they work.
  3. Go to the page of the buildbot that failed (https://buildbot.python.org/all/#builders/545/builds/4502) and take a look at the build logs.
  4. Check if the failure is related to this commit (ced6924) or if it is a false positive.
  5. If the failure is related to this commit, please, reflect that on the issue and make a new Pull Request with a fix.

You can take a look at the buildbot page here:

https://buildbot.python.org/all/#builders/545/builds/4502

Failed tests:

  • test.test_concurrent_futures.test_shutdown

Summary of the results of the build (if available):

==

Click to see traceback logs
remote: Enumerating objects: 12, done.        
remote: Counting objects:   8% (1/12)        
remote: Counting objects:  16% (2/12)        
remote: Counting objects:  25% (3/12)        
remote: Counting objects:  33% (4/12)        
remote: Counting objects:  41% (5/12)        
remote: Counting objects:  50% (6/12)        
remote: Counting objects:  58% (7/12)        
remote: Counting objects:  66% (8/12)        
remote: Counting objects:  75% (9/12)        
remote: Counting objects:  83% (10/12)        
remote: Counting objects:  91% (11/12)        
remote: Counting objects: 100% (12/12)        
remote: Counting objects: 100% (12/12), done.        
remote: Compressing objects:  10% (1/10)        
remote: Compressing objects:  20% (2/10)        
remote: Compressing objects:  30% (3/10)        
remote: Compressing objects:  40% (4/10)        
remote: Compressing objects:  50% (5/10)        
remote: Compressing objects:  60% (6/10)        
remote: Compressing objects:  70% (7/10)        
remote: Compressing objects:  80% (8/10)        
remote: Compressing objects:  90% (9/10)        
remote: Compressing objects: 100% (10/10)        
remote: Compressing objects: 100% (10/10), done.        
remote: Total 12 (delta 2), reused 7 (delta 2), pack-reused 0        
From https://github.com/python/cpython
 * branch                  main       -> FETCH_HEAD
Note: switching to 'ced6924630037f1e5b3d1dbef2b600152fb07fbb'.

You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by switching back to a branch.

If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -c with the switch command. Example:

  git switch -c <new-branch-name>

Or undo this operation with:

  git switch -

Turn off this advice by setting config variable advice.detachedHead to false

HEAD is now at ced6924630 gh-108973: Fix asyncio test_subprocess_consistent_callbacks() (#109431)
Switched to and reset branch 'main'

find: ‘build’: No such file or directory
find: ‘build’: No such file or directory
find: ‘build’: No such file or directory
find: ‘build’: No such file or directory
make[2]: [Makefile:2818: clean-retain-profile] Error 1 (ignored)
./Modules/_decimal/libmpdec/context.c:56: warning: mpd_setminalloc: ignoring request to set MPD_MINALLOC a second time

./Modules/_decimal/libmpdec/context.c:56: warning: mpd_setminalloc: ignoring request to set MPD_MINALLOC a second time

In file included from Python/bltinmodule.c:5:
In function ‘_PyObject_VectorcallTstate’,
    inlined from ‘_PyObject_VectorcallTstate’ at ./Include/internal/pycore_call.h:172:1,
    inlined from ‘map_next’ at Python/bltinmodule.c:1411:14:
./Include/internal/pycore_call.h:185:16: warning: ‘small_stack’ may be used uninitialized [-Wmaybe-uninitialized]
  185 |         return _PyObject_MakeTpCall(tstate, callable, args, nargs, kwnames);
      |                ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
./Include/internal/pycore_call.h: In function ‘map_next’:
./Include/internal/pycore_call.h:126:23: note: by argument 3 of type ‘struct PyObject * const *’ to ‘_PyObject_MakeTpCall’ declared here
  126 | PyAPI_FUNC(PyObject*) _PyObject_MakeTpCall(
      |                       ^~~~~~~~~~~~~~~~~~~~
Python/bltinmodule.c:1383:15: note: ‘small_stack’ declared here
 1383 |     PyObject *small_stack[_PY_FASTCALL_SMALL_STACK];
      |               ^~~~~~~~~~~
In function ‘_PyObject_VectorcallTstate’,
    inlined from ‘_PyObject_VectorcallTstate’ at ./Include/internal/pycore_call.h:172:1,
    inlined from ‘map_next’ at Python/bltinmodule.c:1411:14:
./Include/internal/pycore_call.h:185:16: warning: ‘small_stack’ may be used uninitialized [-Wmaybe-uninitialized]
  185 |         return _PyObject_MakeTpCall(tstate, callable, args, nargs, kwnames);
      |                ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
./Include/internal/pycore_call.h: In function ‘map_next’:
./Include/internal/pycore_call.h:126:23: note: by argument 3 of type ‘struct PyObject * const *’ to ‘_PyObject_MakeTpCall’ declared here
  126 | PyAPI_FUNC(PyObject*) _PyObject_MakeTpCall(
      |                       ^~~~~~~~~~~~~~~~~~~~
Python/bltinmodule.c:1383:15: note: ‘small_stack’ declared here
 1383 |     PyObject *small_stack[_PY_FASTCALL_SMALL_STACK];
      |               ^~~~~~~~~~~
In function ‘word_to_string’,
    inlined from ‘coeff_to_string’ at ./Modules/_decimal/libmpdec/io.c:410:13,
    inlined from ‘_mpd_to_string’ at ./Modules/_decimal/libmpdec/io.c:611:18:
./Modules/_decimal/libmpdec/io.c:348:40: warning: writing 1 byte into a region of size 0 [-Wstringop-overflow=]
  348 |         if (s == dot) *s++ = '.'; *s++ = '0' + (char)(x / d); x %= d
      |                                   ~~~~~^~~~~~~~~~~~~~~~~~~~~
./Modules/_decimal/libmpdec/io.c:348:40: warning: writing 1 byte into a region of size 0 [-Wstringop-overflow=]
  348 |         if (s == dot) *s++ = '.'; *s++ = '0' + (char)(x / d); x %= d
      |                                   ~~~~~^~~~~~~~~~~~~~~~~~~~~
./Modules/_decimal/libmpdec/io.c:348:40: warning: writing 1 byte into a region of size 0 [-Wstringop-overflow=]
  348 |         if (s == dot) *s++ = '.'; *s++ = '0' + (char)(x / d); x %= d
      |                                   ~~~~~^~~~~~~~~~~~~~~~~~~~~
./Modules/_decimal/libmpdec/io.c:348:40: warning: writing 1 byte into a region of size 0 [-Wstringop-overflow=]
  348 |         if (s == dot) *s++ = '.'; *s++ = '0' + (char)(x / d); x %= d
      |                                   ~~~~~^~~~~~~~~~~~~~~~~~~~~
./Modules/_decimal/libmpdec/io.c:348:40: warning: writing 1 byte into a region of size 0 [-Wstringop-overflow=]
  348 |         if (s == dot) *s++ = '.'; *s++ = '0' + (char)(x / d); x %= d
      |                                   ~~~~~^~~~~~~~~~~~~~~~~~~~~
./Modules/_decimal/libmpdec/io.c:348:40: warning: writing 1 byte into a region of size 0 [-Wstringop-overflow=]
  348 |         if (s == dot) *s++ = '.'; *s++ = '0' + (char)(x / d); x %= d
      |                                   ~~~~~^~~~~~~~~~~~~~~~~~~~~
./Modules/_decimal/libmpdec/io.c:348:40: warning: writing 1 byte into a region of size 0 [-Wstringop-overflow=]
  348 |         if (s == dot) *s++ = '.'; *s++ = '0' + (char)(x / d); x %= d
      |                                   ~~~~~^~~~~~~~~~~~~~~~~~~~~
./Modules/_decimal/libmpdec/io.c:348:40: warning: writing 1 byte into a region of size 0 [-Wstringop-overflow=]
  348 |         if (s == dot) *s++ = '.'; *s++ = '0' + (char)(x / d); x %= d
      |                                   ~~~~~^~~~~~~~~~~~~~~~~~~~~
./Modules/_decimal/libmpdec/io.c:348:40: warning: writing 1 byte into a region of size 0 [-Wstringop-overflow=]
  348 |         if (s == dot) *s++ = '.'; *s++ = '0' + (char)(x / d); x %= d
      |                                   ~~~~~^~~~~~~~~~~~~~~~~~~~~
./Modules/_decimal/libmpdec/io.c:348:40: warning: writing 1 byte into a region of size 0 [-Wstringop-overflow=]
  348 |         if (s == dot) *s++ = '.'; *s++ = '0' + (char)(x / d); x %= d
      |                                   ~~~~~^~~~~~~~~~~~~~~~~~~~~
./Modules/_decimal/libmpdec/io.c:348:40: warning: writing 1 byte into a region of size 0 [-Wstringop-overflow=]
  348 |         if (s == dot) *s++ = '.'; *s++ = '0' + (char)(x / d); x %= d
      |                                   ~~~~~^~~~~~~~~~~~~~~~~~~~~
./Modules/_decimal/libmpdec/io.c:348:40: warning: writing 1 byte into a region of size 0 [-Wstringop-overflow=]
  348 |         if (s == dot) *s++ = '.'; *s++ = '0' + (char)(x / d); x %= d
      |                                   ~~~~~^~~~~~~~~~~~~~~~~~~~~
./Modules/_decimal/libmpdec/io.c:348:40: warning: writing 1 byte into a region of size 0 [-Wstringop-overflow=]
  348 |         if (s == dot) *s++ = '.'; *s++ = '0' + (char)(x / d); x %= d
      |                                   ~~~~~^~~~~~~~~~~~~~~~~~~~~
./Modules/_decimal/libmpdec/io.c:348:40: warning: writing 1 byte into a region of size 0 [-Wstringop-overflow=]
  348 |         if (s == dot) *s++ = '.'; *s++ = '0' + (char)(x / d); x %= d
      |                                   ~~~~~^~~~~~~~~~~~~~~~~~~~~
./Modules/_decimal/libmpdec/io.c:348:40: warning: writing 1 byte into a region of size 0 [-Wstringop-overflow=]
  348 |         if (s == dot) *s++ = '.'; *s++ = '0' + (char)(x / d); x %= d
      |                                   ~~~~~^~~~~~~~~~~~~~~~~~~~~
./Modules/_decimal/libmpdec/io.c:348:40: warning: writing 1 byte into a region of size 0 [-Wstringop-overflow=]
  348 |         if (s == dot) *s++ = '.'; *s++ = '0' + (char)(x / d); x %= d
      |                                   ~~~~~^~~~~~~~~~~~~~~~~~~~~
./Modules/_decimal/libmpdec/io.c:348:40: warning: writing 1 byte into a region of size 0 [-Wstringop-overflow=]
  348 |         if (s == dot) *s++ = '.'; *s++ = '0' + (char)(x / d); x %= d
      |                                   ~~~~~^~~~~~~~~~~~~~~~~~~~~
./Modules/_decimal/libmpdec/io.c:348:40: warning: writing 1 byte into a region of size 0 [-Wstringop-overflow=]
  348 |         if (s == dot) *s++ = '.'; *s++ = '0' + (char)(x / d); x %= d
      |                                   ~~~~~^~~~~~~~~~~~~~~~~~~~~
./Modules/_decimal/libmpdec/io.c:348:40: warning: writing 1 byte into a region of size 0 [-Wstringop-overflow=]
  348 |         if (s == dot) *s++ = '.'; *s++ = '0' + (char)(x / d); x %= d
      |                                   ~~~~~^~~~~~~~~~~~~~~~~~~~~
./Modules/_decimal/libmpdec/io.c:348:40: warning: writing 1 byte into a region of size 0 [-Wstringop-overflow=]
  348 |         if (s == dot) *s++ = '.'; *s++ = '0' + (char)(x / d); x %= d
      |                                   ~~~~~^~~~~~~~~~~~~~~~~~~~~
./Modules/_decimal/libmpdec/io.c:348:40: warning: writing 1 byte into a region of size 0 [-Wstringop-overflow=]
  348 |         if (s == dot) *s++ = '.'; *s++ = '0' + (char)(x / d); x %= d
      |                                   ~~~~~^~~~~~~~~~~~~~~~~~~~~
./Modules/_decimal/libmpdec/io.c:348:40: warning: writing 1 byte into a region of size 0 [-Wstringop-overflow=]
  348 |         if (s == dot) *s++ = '.'; *s++ = '0' + (char)(x / d); x %= d
      |                                   ~~~~~^~~~~~~~~~~~~~~~~~~~~
./Modules/_decimal/libmpdec/io.c:348:40: warning: writing 1 byte into a region of size 0 [-Wstringop-overflow=]
  348 |         if (s == dot) *s++ = '.'; *s++ = '0' + (char)(x / d); x %= d
      |                                   ~~~~~^~~~~~~~~~~~~~~~~~~~~
./Modules/_decimal/libmpdec/io.c:348:40: warning: writing 1 byte into a region of size 0 [-Wstringop-overflow=]
  348 |         if (s == dot) *s++ = '.'; *s++ = '0' + (char)(x / d); x %= d
      |                                   ~~~~~^~~~~~~~~~~~~~~~~~~~~
./Modules/_decimal/libmpdec/io.c:348:40: warning: writing 1 byte into a region of size 0 [-Wstringop-overflow=]
  348 |         if (s == dot) *s++ = '.'; *s++ = '0' + (char)(x / d); x %= d
      |                                   ~~~~~^~~~~~~~~~~~~~~~~~~~~
./Modules/_decimal/libmpdec/io.c:348:40: warning: writing 1 byte into a region of size 0 [-Wstringop-overflow=]
  348 |         if (s == dot) *s++ = '.'; *s++ = '0' + (char)(x / d); x %= d
      |                                   ~~~~~^~~~~~~~~~~~~~~~~~~~~
./Modules/_decimal/libmpdec/io.c:348:40: warning: writing 1 byte into a region of size 0 [-Wstringop-overflow=]
  348 |         if (s == dot) *s++ = '.'; *s++ = '0' + (char)(x / d); x %= d
      |                                   ~~~~~^~~~~~~~~~~~~~~~~~~~~
./Modules/_decimal/libmpdec/io.c:348:40: warning: writing 1 byte into a region of size 0 [-Wstringop-overflow=]
  348 |         if (s == dot) *s++ = '.'; *s++ = '0' + (char)(x / d); x %= d
      |                                   ~~~~~^~~~~~~~~~~~~~~~~~~~~
./Modules/_decimal/libmpdec/io.c:348:40: warning: writing 1 byte into a region of size 0 [-Wstringop-overflow=]
  348 |         if (s == dot) *s++ = '.'; *s++ = '0' + (char)(x / d); x %= d
      |                                   ~~~~~^~~~~~~~~~~~~~~~~~~~~
./Modules/_decimal/libmpdec/io.c:348:40: warning: writing 1 byte into a region of size 0 [-Wstringop-overflow=]
  348 |         if (s == dot) *s++ = '.'; *s++ = '0' + (char)(x / d); x %= d
      |                                   ~~~~~^~~~~~~~~~~~~~~~~~~~~
./Modules/_decimal/libmpdec/io.c:348:40: warning: writing 1 byte into a region of size 0 [-Wstringop-overflow=]
./Modules/_decimal/libmpdec/io.c:348:40: warning: writing 1 byte into a region of size 0 [-Wstringop-overflow=]
  348 |         if (s == dot) *s++ = '.'; *s++ = '0' + (char)(x / d); x %= d
      |                                   ~~~~~^~~~~~~~~~~~~~~~~~~~~
./Modules/_decimal/libmpdec/io.c:348:40: warning: writing 1 byte into a region of size 0 [-Wstringop-overflow=]
In function ‘word_to_string’,
    inlined from ‘coeff_to_string’ at ./Modules/_decimal/libmpdec/io.c:410:13,
    inlined from ‘_mpd_to_string’ at ./Modules/_decimal/libmpdec/io.c:607:18:
./Modules/_decimal/libmpdec/io.c:348:40: warning: writing 1 byte into a region of size 0 [-Wstringop-overflow=]
  348 |         if (s == dot) *s++ = '.'; *s++ = '0' + (char)(x / d); x %= d
      |                                   ~~~~~^~~~~~~~~~~~~~~~~~~~~
./Modules/_decimal/libmpdec/io.c:348:40: warning: writing 1 byte into a region of size 0 [-Wstringop-overflow=]
  348 |         if (s == dot) *s++ = '.'; *s++ = '0' + (char)(x / d); x %= d
      |                                   ~~~~~^~~~~~~~~~~~~~~~~~~~~
./Modules/_decimal/libmpdec/io.c:348:40: warning: writing 1 byte into a region of size 0 [-Wstringop-overflow=]
  348 |         if (s == dot) *s++ = '.'; *s++ = '0' + (char)(x / d); x %= d
      |                                   ~~~~~^~~~~~~~~~~~~~~~~~~~~
./Modules/_decimal/libmpdec/io.c:348:40: warning: writing 1 byte into a region of size 0 [-Wstringop-overflow=]
  348 |         if (s == dot) *s++ = '.'; *s++ = '0' + (char)(x / d); x %= d
      |                                   ~~~~~^~~~~~~~~~~~~~~~~~~~~
./Modules/_decimal/libmpdec/io.c:348:40: warning: writing 1 byte into a region of size 0 [-Wstringop-overflow=]
  348 |         if (s == dot) *s++ = '.'; *s++ = '0' + (char)(x / d); x %= d
      |                                   ~~~~~^~~~~~~~~~~~~~~~~~~~~
./Modules/_decimal/libmpdec/io.c:348:40: warning: writing 1 byte into a region of size 0 [-Wstringop-overflow=]
  348 |         if (s == dot) *s++ = '.'; *s++ = '0' + (char)(x / d); x %= d
      |                                   ~~~~~^~~~~~~~~~~~~~~~~~~~~
./Modules/_decimal/libmpdec/io.c:348:40: warning: writing 1 byte into a region of size 0 [-Wstringop-overflow=]
  348 |         if (s == dot) *s++ = '.'; *s++ = '0' + (char)(x / d); x %= d
      |                                   ~~~~~^~~~~~~~~~~~~~~~~~~~~
./Modules/_decimal/libmpdec/io.c:348:40: warning: writing 1 byte into a region of size 0 [-Wstringop-overflow=]
  348 |         if (s == dot) *s++ = '.'; *s++ = '0' + (char)(x / d); x %= d
      |                                   ~~~~~^~~~~~~~~~~~~~~~~~~~~
./Modules/_decimal/libmpdec/io.c:348:40: warning: writing 1 byte into a region of size 0 [-Wstringop-overflow=]
  348 |         if (s == dot) *s++ = '.'; *s++ = '0' + (char)(x / d); x %= d
      |                                   ~~~~~^~~~~~~~~~~~~~~~~~~~~
./Modules/_decimal/libmpdec/io.c:348:40: warning: writing 1 byte into a region of size 0 [-Wstringop-overflow=]
  348 |         if (s == dot) *s++ = '.'; *s++ = '0' + (char)(x / d); x %= d
      |                                   ~~~~~^~~~~~~~~~~~~~~~~~~~~
./Modules/_decimal/libmpdec/io.c:348:40: warning: writing 1 byte into a region of size 0 [-Wstringop-overflow=]
  348 |         if (s == dot) *s++ = '.'; *s++ = '0' + (char)(x / d); x %= d
      |                                   ~~~~~^~~~~~~~~~~~~~~~~~~~~
./Modules/_decimal/libmpdec/io.c:348:40: warning: writing 1 byte into a region of size 0 [-Wstringop-overflow=]
  348 |         if (s == dot) *s++ = '.'; *s++ = '0' + (char)(x / d); x %= d
      |                                   ~~~~~^~~~~~~~~~~~~~~~~~~~~
./Modules/_decimal/libmpdec/io.c:348:40: warning: writing 1 byte into a region of size 0 [-Wstringop-overflow=]
  348 |         if (s == dot) *s++ = '.'; *s++ = '0' + (char)(x / d); x %= d
      |                                   ~~~~~^~~~~~~~~~~~~~~~~~~~~
./Modules/_decimal/libmpdec/io.c:348:40: warning: writing 1 byte into a region of size 0 [-Wstringop-overflow=]
  348 |         if (s == dot) *s++ = '.'; *s++ = '0' + (char)(x / d); x %= d
      |                                   ~~~~~^~~~~~~~~~~~~~~~~~~~~
./Modules/_decimal/libmpdec/io.c:348:40: warning: writing 1 byte into a region of size 0 [-Wstringop-overflow=]
  348 |         if (s == dot) *s++ = '.'; *s++ = '0' + (char)(x / d); x %= d
      |                                   ~~~~~^~~~~~~~~~~~~~~~~~~~~
./Modules/_decimal/libmpdec/io.c:348:40: warning: writing 1 byte into a region of size 0 [-Wstringop-overflow=]
  348 |         if (s == dot) *s++ = '.'; *s++ = '0' + (char)(x / d); x %= d
      |                                   ~~~~~^~~~~~~~~~~~~~~~~~~~~
./Modules/_decimal/libmpdec/io.c:348:40: warning: writing 1 byte into a region of size 0 [-Wstringop-overflow=]
  348 |         if (s == dot) *s++ = '.'; *s++ = '0' + (char)(x / d); x %= d
      |                                   ~~~~~^~~~~~~~~~~~~~~~~~~~~
./Modules/_decimal/libmpdec/io.c:348:40: warning: writing 1 byte into a region of size 0 [-Wstringop-overflow=]
  348 |         if (s == dot) *s++ = '.'; *s++ = '0' + (char)(x / d); x %= d
      |                                   ~~~~~^~~~~~~~~~~~~~~~~~~~~
./Modules/_decimal/libmpdec/io.c:348:40: warning: writing 1 byte into a region of size 0 [-Wstringop-overflow=]
  348 |         if (s == dot) *s++ = '.'; *s++ = '0' + (char)(x / d); x %= d
      |                                   ~~~~~^~~~~~~~~~~~~~~~~~~~~
./Modules/_decimal/libmpdec/io.c:348:40: warning: writing 1 byte into a region of size 0 [-Wstringop-overflow=]
  348 |         if (s == dot) *s++ = '.'; *s++ = '0' + (char)(x / d); x %= d
      |                                   ~~~~~^~~~~~~~~~~~~~~~~~~~~
./Modules/_decimal/libmpdec/io.c:348:40: warning: writing 1 byte into a region of size 0 [-Wstringop-overflow=]
  348 |         if (s == dot) *s++ = '.'; *s++ = '0' + (char)(x / d); x %= d
      |                                   ~~~~~^~~~~~~~~~~~~~~~~~~~~
./Modules/_decimal/libmpdec/io.c:348:40: warning: writing 1 byte into a region of size 0 [-Wstringop-overflow=]
  348 |         if (s == dot) *s++ = '.'; *s++ = '0' + (char)(x / d); x %= d
      |                                   ~~~~~^~~~~~~~~~~~~~~~~~~~~
./Modules/_decimal/libmpdec/io.c:348:40: warning: writing 1 byte into a region of size 0 [-Wstringop-overflow=]
  348 |         if (s == dot) *s++ = '.'; *s++ = '0' + (char)(x / d); x %= d
      |                                   ~~~~~^~~~~~~~~~~~~~~~~~~~~
./Modules/_decimal/libmpdec/io.c:348:40: warning: writing 1 byte into a region of size 0 [-Wstringop-overflow=]
  348 |         if (s == dot) *s++ = '.'; *s++ = '0' + (char)(x / d); x %= d
      |                                   ~~~~~^~~~~~~~~~~~~~~~~~~~~
./Modules/_decimal/libmpdec/io.c:348:40: warning: writing 1 byte into a region of size 0 [-Wstringop-overflow=]
  348 |         if (s == dot) *s++ = '.'; *s++ = '0' + (char)(x / d); x %= d
      |                                   ~~~~~^~~~~~~~~~~~~~~~~~~~~
./Modules/_decimal/libmpdec/io.c:348:40: warning: writing 1 byte into a region of size 0 [-Wstringop-overflow=]
  348 |         if (s == dot) *s++ = '.'; *s++ = '0' + (char)(x / d); x %= d
      |                                   ~~~~~^~~~~~~~~~~~~~~~~~~~~
./Modules/_decimal/libmpdec/io.c:348:40: warning: writing 1 byte into a region of size 0 [-Wstringop-overflow=]
  348 |         if (s == dot) *s++ = '.'; *s++ = '0' + (char)(x / d); x %= d
      |                                   ~~~~~^~~~~~~~~~~~~~~~~~~~~
./Modules/_decimal/libmpdec/io.c:348:40: warning: writing 1 byte into a region of size 0 [-Wstringop-overflow=]
  348 |         if (s == dot) *s++ = '.'; *s++ = '0' + (char)(x / d); x %= d
      |                                   ~~~~~^~~~~~~~~~~~~~~~~~~~~
./Modules/_decimal/libmpdec/io.c:348:40: warning: writing 1 byte into a region of size 0 [-Wstringop-overflow=]
  348 |         if (s == dot) *s++ = '.'; *s++ = '0' + (char)(x / d); x %= d
      |                                   ~~~~~^~~~~~~~~~~~~~~~~~~~~
./Modules/_decimal/libmpdec/io.c:348:40: warning: writing 1 byte into a region of size 0 [-Wstringop-overflow=]
  348 |         if (s == dot) *s++ = '.'; *s++ = '0' + (char)(x / d); x %= d
      |                                   ~~~~~^~~~~~~~~~~~~~~~~~~~~
./Modules/_decimal/libmpdec/io.c:348:40: warning: writing 1 byte into a region of size 0 [-Wstringop-overflow=]
  348 |         if (s == dot) *s++ = '.'; *s++ = '0' + (char)(x / d); x %= d
      |                                   ~~~~~^~~~~~~~~~~~~~~~~~~~~
./Modules/_decimal/libmpdec/io.c:348:40: warning: writing 1 byte into a region of size 0 [-Wstringop-overflow=]
  348 |         if (s == dot) *s++ = '.'; *s++ = '0' + (char)(x / d); x %= d
      |                                   ~~~~~^~~~~~~~~~~~~~~~~~~~~
./Modules/_decimal/libmpdec/io.c:348:40: warning: writing 1 byte into a region of size 0 [-Wstringop-overflow=]
  348 |         if (s == dot) *s++ = '.'; *s++ = '0' + (char)(x / d); x %= d
      |                                   ~~~~~^~~~~~~~~~~~~~~~~~~~~
In function ‘utf8_toUtf8’,
    inlined from ‘toAscii’ at ./Modules/expat/xmltok.c:1043:3,
    inlined from ‘doParseXmlDecl’ at ./Modules/expat/xmltok.c:1197:13:
./Modules/expat/xmltok.c:390:5: warning: ‘memcpy’ writing 2 or more bytes into a region of size 1 overflows the destination [-Wstringop-overflow=]
  390 |     memcpy(*toP, *fromP, bytesToCopy);
      |     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
./Modules/expat/xmltok.c: In function ‘doParseXmlDecl’:
./Modules/expat/xmltok.c:1041:8: note: destination object ‘buf’ of size 1
 1041 |   char buf[1];
      |        ^~~
In function ‘utf8_toUtf8’,
    inlined from ‘toAscii’ at ./Modules/expat/xmltok.c:1043:3,
    inlined from ‘parsePseudoAttribute’ at ./Modules/expat/xmltok.c:1075:9:
./Modules/expat/xmltok.c:390:5: warning: ‘memcpy’ writing 2 or more bytes into a region of size 1 overflows the destination [-Wstringop-overflow=]
  390 |     memcpy(*toP, *fromP, bytesToCopy);
      |     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
./Modules/expat/xmltok.c: In function ‘parsePseudoAttribute’:
./Modules/expat/xmltok.c:1041:8: note: destination object ‘buf’ of size 1
 1041 |   char buf[1];
      |        ^~~
In function ‘utf8_toUtf8’,
    inlined from ‘toAscii’ at ./Modules/expat/xmltok.c:1043:3,
    inlined from ‘parsePseudoAttribute’ at ./Modules/expat/xmltok.c:1081:12:
./Modules/expat/xmltok.c:390:5: warning: ‘memcpy’ writing 2 or more bytes into a region of size 1 overflows the destination [-Wstringop-overflow=]
  390 |     memcpy(*toP, *fromP, bytesToCopy);
      |     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
./Modules/expat/xmltok.c: In function ‘parsePseudoAttribute’:
./Modules/expat/xmltok.c:1041:8: note: destination object ‘buf’ of size 1
 1041 |   char buf[1];
      |        ^~~
In function ‘utf8_toUtf8’,
    inlined from ‘toAscii’ at ./Modules/expat/xmltok.c:1043:3,
    inlined from ‘parsePseudoAttribute’ at ./Modules/expat/xmltok.c:1081:12:
./Modules/expat/xmltok.c:390:5: warning: ‘memcpy’ writing 2 or more bytes into a region of size 1 overflows the destination [-Wstringop-overflow=]
  390 |     memcpy(*toP, *fromP, bytesToCopy);
      |     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
./Modules/expat/xmltok.c: In function ‘parsePseudoAttribute’:
./Modules/expat/xmltok.c:1041:8: note: destination object ‘buf’ of size 1
 1041 |   char buf[1];
      |        ^~~
In function ‘utf8_toUtf8’,
    inlined from ‘toAscii’ at ./Modules/expat/xmltok.c:1043:3,
    inlined from ‘parsePseudoAttribute’ at ./Modules/expat/xmltok.c:1088:9:
./Modules/expat/xmltok.c:390:5: warning: ‘memcpy’ writing 2 or more bytes into a region of size 1 overflows the destination [-Wstringop-overflow=]
  390 |     memcpy(*toP, *fromP, bytesToCopy);
      |     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
./Modules/expat/xmltok.c: In function ‘parsePseudoAttribute’:
./Modules/expat/xmltok.c:1041:8: note: destination object ‘buf’ of size 1
 1041 |   char buf[1];
      |        ^~~
In function ‘utf8_toUtf8’,
    inlined from ‘toAscii’ at ./Modules/expat/xmltok.c:1043:3,
    inlined from ‘parsePseudoAttribute’ at ./Modules/expat/xmltok.c:1088:9:
./Modules/expat/xmltok.c:390:5: warning: ‘memcpy’ writing 2 or more bytes into a region of size 1 overflows the destination [-Wstringop-overflow=]
  390 |     memcpy(*toP, *fromP, bytesToCopy);
      |     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
./Modules/expat/xmltok.c: In function ‘parsePseudoAttribute’:
./Modules/expat/xmltok.c:1041:8: note: destination object ‘buf’ of size 1
 1041 |   char buf[1];
      |        ^~~
In function ‘utf8_toUtf8’,
    inlined from ‘toAscii’ at ./Modules/expat/xmltok.c:1043:3,
    inlined from ‘parsePseudoAttribute’ at ./Modules/expat/xmltok.c:1115:7:
./Modules/expat/xmltok.c:390:5: warning: ‘memcpy’ writing 2 or more bytes into a region of size 1 overflows the destination [-Wstringop-overflow=]
  390 |     memcpy(*toP, *fromP, bytesToCopy);
      |     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
./Modules/expat/xmltok.c: In function ‘parsePseudoAttribute’:
./Modules/expat/xmltok.c:1041:8: note: destination object ‘buf’ of size 1
 1041 |   char buf[1];
      |        ^~~
In function ‘utf8_toUtf8’,
    inlined from ‘toAscii’ at ./Modules/expat/xmltok.c:1043:3,
    inlined from ‘parsePseudoAttribute’ at ./Modules/expat/xmltok.c:1128:9:
./Modules/expat/xmltok.c:390:5: warning: ‘memcpy’ writing 2 or more bytes into a region of size 1 overflows the destination [-Wstringop-overflow=]
  390 |     memcpy(*toP, *fromP, bytesToCopy);
      |     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
./Modules/expat/xmltok.c: In function ‘parsePseudoAttribute’:
./Modules/expat/xmltok.c:1041:8: note: destination object ‘buf’ of size 1
 1041 |   char buf[1];
      |        ^~~
In function ‘utf8_toUtf8’,
    inlined from ‘toAscii’ at ./Modules/expat/xmltok.c:1043:3,
    inlined from ‘parsePseudoAttribute’ at ./Modules/expat/xmltok.c:1128:9:
./Modules/expat/xmltok.c:390:5: warning: ‘memcpy’ writing 2 or more bytes into a region of size 1 overflows the destination [-Wstringop-overflow=]
  390 |     memcpy(*toP, *fromP, bytesToCopy);
      |     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
./Modules/expat/xmltok.c: In function ‘parsePseudoAttribute’:
./Modules/expat/xmltok.c:1041:8: note: destination object ‘buf’ of size 1
 1041 |   char buf[1];
      |        ^~~
In function ‘utf8_toUtf8’,
    inlined from ‘toAscii’ at ./Modules/expat/xmltok.c:1043:3,
    inlined from ‘doParseXmlDecl’ at ./Modules/expat/xmltok.c:1197:13:
./Modules/expat/xmltok.c:390:5: warning: ‘memcpy’ writing 2 or more bytes into a region of size 1 overflows the destination [-Wstringop-overflow=]
  390 |     memcpy(*toP, *fromP, bytesToCopy);
      |     ^
./Modules/expat/xmltok.c: In function ‘doParseXmlDecl’:
./Modules/expat/xmltok.c:1041:8: note: destination object ‘buf’ of size 1
 1041 |   char buf[1];
      |        ^
In function ‘utf8_toUtf8’,
    inlined from ‘toAscii’ at ./Modules/expat/xmltok.c:1043:3,
    inlined from ‘parsePseudoAttribute’ at ./Modules/expat/xmltok.c:1075:9:
./Modules/expat/xmltok.c:390:5: warning: ‘memcpy’ writing 2 or more bytes into a region of size 1 overflows the destination [-Wstringop-overflow=]
  390 |     memcpy(*toP, *fromP, bytesToCopy);
      |     ^
./Modules/expat/xmltok.c: In function ‘parsePseudoAttribute’:
./Modules/expat/xmltok.c:1041:8: note: destination object ‘buf’ of size 1
 1041 |   char buf[1];
      |        ^
In function ‘utf8_toUtf8’,
    inlined from ‘toAscii’ at ./Modules/expat/xmltok.c:1043:3,
    inlined from ‘parsePseudoAttribute’ at ./Modules/expat/xmltok.c:1081:12:
./Modules/expat/xmltok.c:390:5: warning: ‘memcpy’ writing 2 or more bytes into a region of size 1 overflows the destination [-Wstringop-overflow=]
  390 |     memcpy(*toP, *fromP, bytesToCopy);
      |     ^
./Modules/expat/xmltok.c: In function ‘parsePseudoAttribute’:
./Modules/expat/xmltok.c:1041:8: note: destination object ‘buf’ of size 1
 1041 |   char buf[1];
      |        ^
In function ‘utf8_toUtf8’,
    inlined from ‘toAscii’ at ./Modules/expat/xmltok.c:1043:3,
    inlined from ‘parsePseudoAttribute’ at ./Modules/expat/xmltok.c:1081:12:
./Modules/expat/xmltok.c:390:5: warning: ‘memcpy’ writing 2 or more bytes into a region of size 1 overflows the destination [-Wstringop-overflow=]
  390 |     memcpy(*toP, *fromP, bytesToCopy);
      |     ^
./Modules/expat/xmltok.c: In function ‘parsePseudoAttribute’:
./Modules/expat/xmltok.c:1041:8: note: destination object ‘buf’ of size 1
 1041 |   char buf[1];
      |        ^
In function ‘utf8_toUtf8’,
    inlined from ‘toAscii’ at ./Modules/expat/xmltok.c:1043:3,
    inlined from ‘parsePseudoAttribute’ at ./Modules/expat/xmltok.c:1088:9:
./Modules/expat/xmltok.c:390:5: warning: ‘memcpy’ writing 2 or more bytes into a region of size 1 overflows the destination [-Wstringop-overflow=]
  390 |     memcpy(*toP, *fromP, bytesToCopy);
      |     ^
./Modules/expat/xmltok.c: In function ‘parsePseudoAttribute’:
./Modules/expat/xmltok.c:1041:8: note: destination object ‘buf’ of size 1
 1041 |   char buf[1];
      |        ^
In function ‘utf8_toUtf8’,
    inlined from ‘toAscii’ at ./Modules/expat/xmltok.c:1043:3,
    inlined from ‘parsePseudoAttribute’ at ./Modules/expat/xmltok.c:1088:9:
./Modules/expat/xmltok.c:390:5: warning: ‘memcpy’ writing 2 or more bytes into a region of size 1 overflows the destination [-Wstringop-overflow=]
  390 |     memcpy(*toP, *fromP, bytesToCopy);
      |     ^
./Modules/expat/xmltok.c: In function ‘parsePseudoAttribute’:
./Modules/expat/xmltok.c:1041:8: note: destination object ‘buf’ of size 1
 1041 |   char buf[1];
      |        ^
In function ‘utf8_toUtf8’,
    inlined from ‘toAscii’ at ./Modules/expat/xmltok.c:1043:3,
    inlined from ‘parsePseudoAttribute’ at ./Modules/expat/xmltok.c:1115:7:
./Modules/expat/xmltok.c:390:5: warning: ‘memcpy’ writing 2 or more bytes into a region of size 1 overflows the destination [-Wstringop-overflow=]
  390 |     memcpy(*toP, *fromP, bytesToCopy);
      |     ^
./Modules/expat/xmltok.c: In function ‘parsePseudoAttribute’:
./Modules/expat/xmltok.c:1041:8: note: destination object ‘buf’ of size 1
 1041 |   char buf[1];
      |        ^
In function ‘utf8_toUtf8’,
    inlined from ‘toAscii’ at ./Modules/expat/xmltok.c:1043:3,
    inlined from ‘parsePseudoAttribute’ at ./Modules/expat/xmltok.c:1128:9:
./Modules/expat/xmltok.c:390:5: warning: ‘memcpy’ writing 2 or more bytes into a region of size 1 overflows the destination [-Wstringop-overflow=]
  390 |     memcpy(*toP, *fromP, bytesToCopy);
      |     ^
./Modules/expat/xmltok.c: In function ‘parsePseudoAttribute’:
./Modules/expat/xmltok.c:1041:8: note: destination object ‘buf’ of size 1
 1041 |   char buf[1];
      |        ^
In function ‘utf8_toUtf8’,
    inlined from ‘toAscii’ at ./Modules/expat/xmltok.c:1043:3,
    inlined from ‘parsePseudoAttribute’ at ./Modules/expat/xmltok.c:1128:9:
./Modules/expat/xmltok.c:390:5: warning: ‘memcpy’ writing 2 or more bytes into a region of size 1 overflows the destination [-Wstringop-overflow=]
  390 |     memcpy(*toP, *fromP, bytesToCopy);
      |     ^
./Modules/expat/xmltok.c: In function ‘parsePseudoAttribute’:
./Modules/expat/xmltok.c:1041:8: note: destination object ‘buf’ of size 1
 1041 |   char buf[1];
      |        ^
In function ‘word_to_string’,
    inlined from ‘coeff_to_string’ at ./Modules/_decimal/libmpdec/io.c:410:13:
./Modules/_decimal/libmpdec/io.c:359:14: warning: writing 1 byte into a region of size 0 [-Wstringop-overflow=]
  359 |     case 15: EXTRACT_DIGIT(s, x, 100000000000000ULL, dot);
      |              ^
./Modules/_decimal/libmpdec/io.c:358:14: warning: writing 1 byte into a region of size 0 [-Wstringop-overflow=]
  358 |     case 16: EXTRACT_DIGIT(s, x, 1000000000000000ULL, dot);
      |              ^
./Modules/_decimal/libmpdec/io.c:359:14: warning: writing 1 byte into a region of size 0 [-Wstringop-overflow=]
  359 |     case 15: EXTRACT_DIGIT(s, x, 100000000000000ULL, dot);
      |              ^
./Modules/_decimal/libmpdec/io.c:360:14: warning: writing 1 byte into a region of size 0 [-Wstringop-overflow=]
  360 |     case 14: EXTRACT_DIGIT(s, x, 10000000000000ULL, dot);
      |              ^
./Modules/_decimal/libmpdec/io.c:357:14: warning: writing 1 byte into a region of size 0 [-Wstringop-overflow=]
  357 |     case 17: EXTRACT_DIGIT(s, x, 10000000000000000ULL, dot);
      |              ^
./Modules/_decimal/libmpdec/io.c:356:14: warning: writing 1 byte into a region of size 0 [-Wstringop-overflow=]
  356 |     case 18: EXTRACT_DIGIT(s, x, 100000000000000000ULL, dot);
      |              ^
./Modules/_decimal/libmpdec/io.c:357:14: warning: writing 1 byte into a region of size 0 [-Wstringop-overflow=]
  357 |     case 17: EXTRACT_DIGIT(s, x, 10000000000000000ULL, dot);
      |              ^
./Modules/_decimal/libmpdec/io.c:358:14: warning: writing 1 byte into a region of size 0 [-Wstringop-overflow=]
  358 |     case 16: EXTRACT_DIGIT(s, x, 1000000000000000ULL, dot);
      |              ^
./Modules/_decimal/libmpdec/io.c:361:14: warning: writing 1 byte into a region of size 0 [-Wstringop-overflow=]
  361 |     case 13: EXTRACT_DIGIT(s, x, 1000000000000ULL, dot);
      |              ^
./Modules/_decimal/libmpdec/io.c:360:14: warning: writing 1 byte into a region of size 0 [-Wstringop-overflow=]
  360 |     case 14: EXTRACT_DIGIT(s, x, 10000000000000ULL, dot);
      |              ^
./Modules/_decimal/libmpdec/io.c:361:14: warning: writing 1 byte into a region of size 0 [-Wstringop-overflow=]
  361 |     case 13: EXTRACT_DIGIT(s, x, 1000000000000ULL, dot);
      |              ^
./Modules/_decimal/libmpdec/io.c:362:14: warning: writing 1 byte into a region of size 0 [-Wstringop-overflow=]
  362 |     case 12: EXTRACT_DIGIT(s, x, 100000000000ULL, dot);
      |              ^
./Modules/_decimal/libmpdec/io.c:363:14: warning: writing 1 byte into a region of size 0 [-Wstringop-overflow=]
  363 |     case 11: EXTRACT_DIGIT(s, x, 10000000000ULL, dot);
      |              ^
./Modules/_decimal/libmpdec/io.c:362:14: warning: writing 1 byte into a region of size 0 [-Wstringop-overflow=]
  362 |     case 12: EXTRACT_DIGIT(s, x, 100000000000ULL, dot);
      |              ^
./Modules/_decimal/libmpdec/io.c:363:14: warning: writing 1 byte into a region of size 0 [-Wstringop-overflow=]
  363 |     case 11: EXTRACT_DIGIT(s, x, 10000000000ULL, dot);
      |              ^
./Modules/_decimal/libmpdec/io.c:365:14: warning: writing 1 byte into a region of size 0 [-Wstringop-overflow=]
  365 |     case 10: EXTRACT_DIGIT(s, x, 1000000000UL, dot);
      |              ^
./Modules/_decimal/libmpdec/io.c:366:14: warning: writing 1 byte into a region of size 0 [-Wstringop-overflow=]
  366 |     case 9:  EXTRACT_DIGIT(s, x, 100000000UL, dot);
      |              ^
./Modules/_decimal/libmpdec/io.c:365:14: warning: writing 1 byte into a region of size 0 [-Wstringop-overflow=]
  365 |     case 10: EXTRACT_DIGIT(s, x, 1000000000UL, dot);
      |              ^
./Modules/_decimal/libmpdec/io.c:366:14: warning: writing 1 byte into a region of size 0 [-Wstringop-overflow=]
  366 |     case 9:  EXTRACT_DIGIT(s, x, 100000000UL, dot);
      |              ^
./Modules/_decimal/libmpdec/io.c:367:14: warning: writing 1 byte into a region of size 0 [-Wstringop-overflow=]
  367 |     case 8:  EXTRACT_DIGIT(s, x, 10000000UL, dot);
      |              ^
./Modules/_decimal/libmpdec/io.c:368:14: warning: writing 1 byte into a region of size 0 [-Wstringop-overflow=]
  368 |     case 7:  EXTRACT_DIGIT(s, x, 1000000UL, dot);
      |              ^
./Modules/_decimal/libmpdec/io.c:367:14: warning: writing 1 byte into a region of size 0 [-Wstringop-overflow=]
  367 |     case 8:  EXTRACT_DIGIT(s, x, 10000000UL, dot);
      |              ^
./Modules/_decimal/libmpdec/io.c:368:14: warning: writing 1 byte into a region of size 0 [-Wstringop-overflow=]
  368 |     case 7:  EXTRACT_DIGIT(s, x, 1000000UL, dot);
      |              ^
./Modules/_decimal/libmpdec/io.c:369:14: warning: writing 1 byte into a region of size 0 [-Wstringop-overflow=]
  369 |     case 6:  EXTRACT_DIGIT(s, x, 100000UL, dot);
      |              ^
./Modules/_decimal/libmpdec/io.c:370:14: warning: writing 1 byte into a region of size 0 [-Wstringop-overflow=]
  370 |     case 5:  EXTRACT_DIGIT(s, x, 10000UL, dot);
      |              ^
./Modules/_decimal/libmpdec/io.c:369:14: warning: writing 1 byte into a region of size 0 [-Wstringop-overflow=]
  369 |     case 6:  EXTRACT_DIGIT(s, x, 100000UL, dot);
      |              ^
./Modules/_decimal/libmpdec/io.c:370:14: warning: writing 1 byte into a region of size 0 [-Wstringop-overflow=]
  370 |     case 5:  EXTRACT_DIGIT(s, x, 10000UL, dot);
      |              ^
./Modules/_decimal/libmpdec/io.c:371:14: warning: writing 1 byte into a region of size 0 [-Wstringop-overflow=]
  371 |     case 4:  EXTRACT_DIGIT(s, x, 1000UL, dot);
      |              ^
./Modules/_decimal/libmpdec/io.c:372:14: warning: writing 1 byte into a region of size 0 [-Wstringop-overflow=]
  372 |     case 3:  EXTRACT_DIGIT(s, x, 100UL, dot);
      |              ^
./Modules/_decimal/libmpdec/io.c:371:14: warning: writing 1 byte into a region of size 0 [-Wstringop-overflow=]
  371 |     case 4:  EXTRACT_DIGIT(s, x, 1000UL, dot);
      |              ^
./Modules/_decimal/libmpdec/io.c:372:14: warning: writing 1 byte into a region of size 0 [-Wstringop-overflow=]
  372 |     case 3:  EXTRACT_DIGIT(s, x, 100UL, dot);
      |              ^
./Modules/_decimal/libmpdec/io.c:373:14: warning: writing 1 byte into a region of size 0 [-Wstringop-overflow=]
  373 |     case 2:  EXTRACT_DIGIT(s, x, 10UL, dot);
      |              ^
./Modules/_decimal/libmpdec/io.c:373:14: warning: writing 1 byte into a region of size 0 [-Wstringop-overflow=]

make: *** [Makefile:2038: buildbottest] Error 5

@bedevere-bot
Copy link

⚠️⚠️⚠️ Buildbot failure ⚠️⚠️⚠️

Hi! The buildbot AMD64 Debian root 3.x has failed when building commit ced6924.

What do you need to do:

  1. Don't panic.
  2. Check the buildbot page in the devguide if you don't know what the buildbots are or how they work.
  3. Go to the page of the buildbot that failed (https://buildbot.python.org/all/#builders/345/builds/5878) and take a look at the build logs.
  4. Check if the failure is related to this commit (ced6924) or if it is a false positive.
  5. If the failure is related to this commit, please, reflect that on the issue and make a new Pull Request with a fix.

You can take a look at the buildbot page here:

https://buildbot.python.org/all/#builders/345/builds/5878

Failed tests:

  • test_signal

Summary of the results of the build (if available):

==

Click to see traceback logs
Traceback (most recent call last):
  File "/root/buildarea/3.x.angelico-debian-amd64/build/Lib/test/test_signal.py", line 1287, in test_stress_delivery_dependent
    self.assertEqual(len(sigs), N, "Some signals were lost")
AssertionError: 4948 != 10000 : Some signals were lost

@bedevere-bot
Copy link

⚠️⚠️⚠️ Buildbot failure ⚠️⚠️⚠️

Hi! The buildbot PPC64LE Fedora Stable 3.x has failed when building commit ced6924.

What do you need to do:

  1. Don't panic.
  2. Check the buildbot page in the devguide if you don't know what the buildbots are or how they work.
  3. Go to the page of the buildbot that failed (https://buildbot.python.org/all/#builders/90/builds/3798) and take a look at the build logs.
  4. Check if the failure is related to this commit (ced6924) or if it is a false positive.
  5. If the failure is related to this commit, please, reflect that on the issue and make a new Pull Request with a fix.

You can take a look at the buildbot page here:

https://buildbot.python.org/all/#builders/90/builds/3798

Failed tests:

  • test_math
  • test.test_asyncio.test_unix_events

Failed subtests:

  • test_fork_signal_handling - test.test_asyncio.test_unix_events.TestFork.test_fork_signal_handling

Summary of the results of the build (if available):

==

Click to see traceback logs
Traceback (most recent call last):
  File "/home/buildbot/buildarea/3.x.cstratak-fedora-stable-ppc64le/build/Lib/unittest/async_case.py", line 90, in _callTestMethod
    if self._callMaybeAsync(method) is not None:
       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/buildbot/buildarea/3.x.cstratak-fedora-stable-ppc64le/build/Lib/unittest/async_case.py", line 117, in _callMaybeAsync
    return self._asyncioTestContext.run(func, *args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/buildbot/buildarea/3.x.cstratak-fedora-stable-ppc64le/build/Lib/test/support/hashlib_helper.py", line 49, in wrapper
    return func_or_class(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/buildbot/buildarea/3.x.cstratak-fedora-stable-ppc64le/build/Lib/test/test_asyncio/test_unix_events.py", line 1937, in test_fork_signal_handling
    self.assertTrue(child_handled.is_set())
AssertionError: False is not true

@bedevere-bot
Copy link

⚠️⚠️⚠️ Buildbot failure ⚠️⚠️⚠️

Hi! The buildbot s390x Fedora LTO 3.x has failed when building commit ced6924.

What do you need to do:

  1. Don't panic.
  2. Check the buildbot page in the devguide if you don't know what the buildbots are or how they work.
  3. Go to the page of the buildbot that failed (https://buildbot.python.org/all/#builders/55/builds/3856) and take a look at the build logs.
  4. Check if the failure is related to this commit (ced6924) or if it is a false positive.
  5. If the failure is related to this commit, please, reflect that on the issue and make a new Pull Request with a fix.

You can take a look at the buildbot page here:

https://buildbot.python.org/all/#builders/55/builds/3856

Failed tests:

  • test_tools

Failed subtests:

  • test_freeze_simple_script - test.test_tools.test_freeze.TestFreeze.test_freeze_simple_script

Summary of the results of the build (if available):

==

Click to see traceback logs
Traceback (most recent call last):
  File "/home/dje/cpython-buildarea/3.x.edelsohn-fedora-z.lto/build/Lib/test/test_tools/test_freeze.py", line 32, in test_freeze_simple_script
    outdir, scriptfile, python = helper.prepare(script, outdir)
                                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/dje/cpython-buildarea/3.x.edelsohn-fedora-z.lto/build/Tools/freeze/test/freeze.py", line 146, in prepare
    copy_source_tree(srcdir, SRCDIR)
  File "/home/dje/cpython-buildarea/3.x.edelsohn-fedora-z.lto/build/Tools/freeze/test/freeze.py", line 95, in copy_source_tree
    shutil.copytree(oldroot, newroot, ignore=ignore_non_src)
  File "/home/dje/cpython-buildarea/3.x.edelsohn-fedora-z.lto/build/Lib/shutil.py", line 588, in copytree
    return _copytree(entries=entries, src=src, dst=dst, symlinks=symlinks,
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/dje/cpython-buildarea/3.x.edelsohn-fedora-z.lto/build/Lib/shutil.py", line 542, in _copytree
    raise Error(errors)
shutil.Error: [('/home/dje/cpython-buildarea/3.x.edelsohn-fedora-z.lto/build/build/test_python_3434066æ/tmpt5kd153m', '/tmp/test_python__0a_zo2q/tmpnvztwv04/cpython/build/test_python_3434066æ/tmpt5kd153m', "[Errno 2] No such file or directory: '/home/dje/cpython-buildarea/3.x.edelsohn-fedora-z.lto/build/build/test_python_3434066æ/tmpt5kd153m'")]

@bedevere-bot
Copy link

⚠️⚠️⚠️ Buildbot failure ⚠️⚠️⚠️

Hi! The buildbot PPC64LE RHEL7 LTO 3.x has failed when building commit ced6924.

What do you need to do:

  1. Don't panic.
  2. Check the buildbot page in the devguide if you don't know what the buildbots are or how they work.
  3. Go to the page of the buildbot that failed (https://buildbot.python.org/all/#builders/503/builds/3935) and take a look at the build logs.
  4. Check if the failure is related to this commit (ced6924) or if it is a false positive.
  5. If the failure is related to this commit, please, reflect that on the issue and make a new Pull Request with a fix.

You can take a look at the buildbot page here:

https://buildbot.python.org/all/#builders/503/builds/3935

Failed tests:

  • test.test_multiprocessing_spawn.test_manager

Summary of the results of the build (if available):

==

Click to see traceback logs
remote: Enumerating objects: 12, done.        
remote: Counting objects:   8% (1/12)        
remote: Counting objects:  16% (2/12)        
remote: Counting objects:  25% (3/12)        
remote: Counting objects:  33% (4/12)        
remote: Counting objects:  41% (5/12)        
remote: Counting objects:  50% (6/12)        
remote: Counting objects:  58% (7/12)        
remote: Counting objects:  66% (8/12)        
remote: Counting objects:  75% (9/12)        
remote: Counting objects:  83% (10/12)        
remote: Counting objects:  91% (11/12)        
remote: Counting objects: 100% (12/12)        
remote: Counting objects: 100% (12/12), done.        
remote: Compressing objects:  10% (1/10)        
remote: Compressing objects:  20% (2/10)        
remote: Compressing objects:  30% (3/10)        
remote: Compressing objects:  40% (4/10)        
remote: Compressing objects:  50% (5/10)        
remote: Compressing objects:  60% (6/10)        
remote: Compressing objects:  70% (7/10)        
remote: Compressing objects:  80% (8/10)        
remote: Compressing objects:  90% (9/10)        
remote: Compressing objects: 100% (10/10)        
remote: Compressing objects: 100% (10/10), done.        
remote: Total 12 (delta 2), reused 7 (delta 2), pack-reused 0        
From https://github.com/python/cpython
 * branch            main       -> FETCH_HEAD
Note: checking out 'ced6924630037f1e5b3d1dbef2b600152fb07fbb'.

You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by performing another checkout.

If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -b with the checkout command again. Example:

  git checkout -b new_branch_name

HEAD is now at ced6924... gh-108973: Fix asyncio test_subprocess_consistent_callbacks() (#109431)
Switched to and reset branch 'main'

./Include/internal/pycore_semaphore.h:54:1: warning: type of ‘_PySemaphore_Wakeup’ does not match original declaration [-Wlto-type-mismatch]
 _PySemaphore_Wakeup(_PySemaphore *sema);
 ^
Python/parking_lot.c:197:1: note: ‘_PySemaphore_Wakeup’ was previously declared here
 _PySemaphore_Wakeup(_PySemaphore *sema)
 ^
Python/parking_lot.c:197:1: note: code may be misoptimized unless -fno-strict-aliasing is used
./Include/internal/pycore_semaphore.h:57:18: warning: type of ‘_PySemaphore_Init’ does not match original declaration [-Wlto-type-mismatch]
 PyAPI_FUNC(void) _PySemaphore_Init(_PySemaphore *sema);
                  ^
Python/parking_lot.c:53:1: note: ‘_PySemaphore_Init’ was previously declared here
 _PySemaphore_Init(_PySemaphore *sema)
 ^
Python/parking_lot.c:53:1: note: code may be misoptimized unless -fno-strict-aliasing is used
./Include/internal/pycore_semaphore.h:49:1: warning: type of ‘_PySemaphore_Wait’ does not match original declaration [-Wlto-type-mismatch]
 _PySemaphore_Wait(_PySemaphore *sema, _PyTime_t timeout_ns, int detach);
 ^
Python/parking_lot.c:178:1: note: ‘_PySemaphore_Wait’ was previously declared here
 _PySemaphore_Wait(_PySemaphore *sema, _PyTime_t timeout, int detach)
 ^
Python/parking_lot.c:178:1: note: code may be misoptimized unless -fno-strict-aliasing is used
./Include/internal/pycore_semaphore.h:58:18: warning: type of ‘_PySemaphore_Destroy’ does not match original declaration [-Wlto-type-mismatch]
 PyAPI_FUNC(void) _PySemaphore_Destroy(_PySemaphore *sema);
                  ^
Python/parking_lot.c:81:1: note: ‘_PySemaphore_Destroy’ was previously declared here
 _PySemaphore_Destroy(_PySemaphore *sema)
 ^
Python/parking_lot.c:81:1: note: code may be misoptimized unless -fno-strict-aliasing is used

make: *** [Makefile:2032: buildbottest] Error 5

csm10495 pushed a commit to csm10495/cpython that referenced this pull request Sep 28, 2023
…ython#109431)

SubprocessProtocol process_exited() method can be called before
pipe_data_received() and pipe_connection_lost() methods. Document it
and adapt the test for that.

Revert commit 282edd7.
_child_watcher_callback() calls immediately _process_exited(): don't
add an additional delay with call_soon(). The reverted change didn't
make _process_exited() more determistic: it can still be called
before pipe_connection_lost() for example.

Co-authored-by: Davide Rizzo <[email protected]>
Yhg1s pushed a commit that referenced this pull request Oct 2, 2023
…H-109431) (#109609)

gh-108973: Fix asyncio test_subprocess_consistent_callbacks() (GH-109431)

SubprocessProtocol process_exited() method can be called before
pipe_data_received() and pipe_connection_lost() methods. Document it
and adapt the test for that.

Revert commit 282edd7.
_child_watcher_callback() calls immediately _process_exited(): don't
add an additional delay with call_soon(). The reverted change didn't
make _process_exited() more determistic: it can still be called
before pipe_connection_lost() for example.

(cherry picked from commit ced6924)

Co-authored-by: Victor Stinner <[email protected]>
Co-authored-by: Davide Rizzo <[email protected]>
Glyphack pushed a commit to Glyphack/cpython that referenced this pull request Sep 2, 2024
…ython#109431)

SubprocessProtocol process_exited() method can be called before
pipe_data_received() and pipe_connection_lost() methods. Document it
and adapt the test for that.

Revert commit 282edd7.
_child_watcher_callback() calls immediately _process_exited(): don't
add an additional delay with call_soon(). The reverted change didn't
make _process_exited() more determistic: it can still be called
before pipe_connection_lost() for example.

Co-authored-by: Davide Rizzo <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
skip news tests Tests in the Lib/test dir
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants