[issue39735] Signal handler is invoked recursively

2020-02-23 Thread Masahiro Sakai


New submission from Masahiro Sakai :

If I run following program, the parent process fails with "RecursionError: 
maximum recursion depth exceeded", because the signal handler is invoked during 
the execution of the same handler.


import os
import signal
import time

def f(signum, frame):
time.sleep(1)

signal.signal(signal.SIGUSR1, f)

parent_pid = os.getpid()
child_pid = os.fork()
if child_pid == 0:
for i in range(10):
os.kill(parent_pid, signal.SIGUSR1)
time.sleep(0.01)
else:
os.waitpid(child_pid, 0)


This behavior is in contrast to other languages such as C or Ruby.

In C, when a handler function is invoked on a signal, that signal is 
automatically blocked during the time the handler is running, unless SA_NODEFER 
is specified.

In Ruby, signal handler is handled in a way similar to Python (i.e. flag is set 
by C-level signal handler and Ruby/Python-level signal handler is executed 
later point which is safe for VM), but it prevents recursive signal handler 
invocation. (Related issue and commit: https://bugs.ruby-lang.org/issues/6009 
https://github.com/ruby/ruby/commit/6190bb4d8ad7a07ddb1da8fc687b20612743a34a )

I believe that behavior of C and Ruby is desirable, because writing reentrant 
signal handler is sometimes error prone.

--
components: Extension Modules
messages: 362562
nosy: msakai
priority: normal
severity: normal
status: open
title: Signal handler is invoked recursively
type: behavior

___
Python tracker 
<https://bugs.python.org/issue39735>
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue39745] BlockingIOError.characters_written represents number of bytes not characters

2020-02-24 Thread Masahiro Sakai


New submission from Masahiro Sakai :

According to https://docs.python.org/3/library/exceptions.html#BlockingIOError 
, 'characters_written' is "An integer containing the number of characters 
written to the stream before it blocked". But I observed that it represents 
number of *bytes* not *characters* in the following program.

Program:

import os
import threading
import time

r, w = os.pipe()
os.set_blocking(w, False)
f_r = os.fdopen(r, mode="rb")
f_w = os.fdopen(w, mode="w", encoding="utf-8")

msg = "\u03b1\u03b2\u03b3\u3042\u3044\u3046\u3048\u304a" * (1024 * 16)
try:
print(msg, file=f_w, flush=True)
except BlockingIOError as e:
print(f"BlockingIOError.characters_written == {e.characters_written}")
written = e.characters_written

def close():
os.set_blocking(w, True)
f_w.close()
threading.Thread(target=close).start()

b = f_r.read()
f_r.close()

print(f"{written} characters correspond to {len(msg[:written].encode('utf-8'))} 
bytes in UTF-8")
print(f"{len(b)} bytes read")


Output:

BlockingIOError.characters_written == 81920
81920 characters correspond to 215040 bytes in UTF-8
81920 bytes read


I think it is confusing behavior.
If this is intended behavior, then it should be documented as such and I think 
'bytes_written' is more appropriate name.

--
components: IO
messages: 362611
nosy: msakai
priority: normal
severity: normal
status: open
title: BlockingIOError.characters_written represents number of bytes not 
characters

___
Python tracker 
<https://bugs.python.org/issue39745>
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue39745] BlockingIOError.characters_written represents number of bytes not characters

2020-02-24 Thread Masahiro Sakai


Change by Masahiro Sakai :


--
type:  -> behavior

___
Python tracker 
<https://bugs.python.org/issue39745>
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue39792] Two Ctrl+C is required to terminate when a pipe is blocking

2020-02-28 Thread Masahiro Sakai


New submission from Masahiro Sakai :

I noticed that two Ctrl+C instead of one are required to terminate following 
program on macOS and Linux.
I guess that the first Ctrl+C is ignored inside one of the finalizers.


import os

def main():
r, w = os.pipe()
f_w = os.fdopen(w, "w")
f_w.buffer.write(b"a" * 65536)
f_w.buffer.write(b"b")

main()


--
components: IO
messages: 362964
nosy: msakai
priority: normal
severity: normal
status: open
title: Two Ctrl+C is required to terminate when a pipe is blocking
type: behavior
versions: Python 3.6, Python 3.7, Python 3.8, Python 3.9

___
Python tracker 
<https://bugs.python.org/issue39792>
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com