Winloop icon indicating copy to clipboard operation
Winloop copied to clipboard

Strange side-effect on help()

Open lschoe opened this issue 10 months ago • 8 comments

Hi, here's a thing I noticed a while ago when using the Python REPL in combination with winloop.

The problem is that certain calls to the built-in help() function don't work anymore, something to do with a redirection of stdout maybe.

import asyncio
from winloop import EventLoopPolicy
asyncio.set_event_loop_policy(EventLoopPolicy())  # 1st critical line for the problem to occur

print('1' * 80)    
help(pow)  # prints just fine
print('1' * 80)

asyncio.get_event_loop()  # 2nd critical line for the problem to occur

print('2' * 80)    
help(pow)  # only prints a blank line
print('2' * 80)

Running this code will produce:

11111111111111111111111111111111111111111111111111111111111111111111111111111111
Help on built-in function pow in module builtins:

pow(base, exp, mod=None)
    Equivalent to base**exp with 2 arguments or base**exp % mod with 3 arguments

    Some types, such as ints, are able to use a more efficient algorithm when
    invoked using the three argument form.

11111111111111111111111111111111111111111111111111111111111111111111111111111111
22222222222222222222222222222222222222222222222222222222222222222222222222222222

22222222222222222222222222222222222222222222222222222222222222222222222222222222

By omitting either (or both) critical lines, the problem disappears, and the help(pow) message will be printed in twice.

The actual use case for this problem is when I run the Python REPL using winloop (in combination with MPyC), which looks like this:

>python -m mpyc
asyncio REPL 3.11.8 (tags/v3.11.8:db85d51, Feb  6 2024, 22:03:32) [MSC v.1937 64 bit (AMD64)] on win32
Use "await" directly instead of "asyncio.run()".
Type "help", "copyright", "credits" or "license" for more information.
>>> import asyncio
>>> from mpyc.runtime import mpc
>>> secint = mpc.SecInt()
>>> secfxp = mpc.SecFxp()
>>> secflt = mpc.SecFlt()
>>> secfld127 = mpc.SecFld(127)
>>> secfld256 = mpc.SecFld(2**8)
>>> secsym = mpc.SecSymmetricGroup(5)
>>> secqr = mpc.SecQuadraticResidues(11)
>>> secsg = mpc.SecSchnorrGroup(l=1024)
>>> secec = mpc.SecEllipticCurve('Ed25519')
>>> seccl = mpc.SecClassGroup(-23)
>>> help(pow)

>>>

By disabling the use of winloop the problem disappears. Also, the problem does not occur on Linux using uvloop.

Do you have a clue about the cause? Something "bad" happens in the C(ython) code executed for the asyncio.get_event_loop() call.

lschoe avatar Mar 28 '24 17:03 lschoe