Skip to content
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

Strange side-effect on help() #18

Closed
lschoe opened this issue Mar 28, 2024 · 8 comments
Closed

Strange side-effect on help() #18

lschoe opened this issue Mar 28, 2024 · 8 comments
Labels
bug Something isn't working

Comments

@lschoe
Copy link
Collaborator

lschoe commented Mar 28, 2024

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.

@Vizonex
Copy link
Owner

Vizonex commented Mar 31, 2024

@lschoe I have no idea on how this could happen. If I'm going to be absolutely honest with you. But this does seem to be very bad. A fix as well as debugging the problem would be a good idea but I do not know where we would start. There is a macro in the program you could try enabling that and compiling the project with debugging turned on and start tracking the bug.

@Vizonex Vizonex added the bug Something isn't working label Mar 31, 2024
@lschoe
Copy link
Collaborator Author

lschoe commented Apr 3, 2024

I've tracked the problem down to a call to os.system(). A call like help(pow) is handled by pydoc and on Windows ends up calling pydoc.tempfilepager(). At the end of that function the call os.system(cmd + ' "' + filename + '"') fails with exit code 1.

The same can be experienced in the examples above. For example, in the Python REPL instead of >>> help(pow) now do:

>>> import os; os.system('path')
1

Maybe this gives you a clue where to look?

@Vizonex
Copy link
Owner

Vizonex commented Apr 5, 2024 via email

@lschoe
Copy link
Collaborator Author

lschoe commented May 5, 2024

Hi @Vizonex, can you drop me an email at l.a.m.schoenmakers@tue.nl regarding the invitation?

@lschoe
Copy link
Collaborator Author

lschoe commented May 14, 2024

To investigate this issue, I've started to remove nonessential differences between (the current versions of) winloop and uvloop.

Removing these differences is also helpful to prepare for the ultimate thing: merging winloop into uvloop.

The latest commit b5946ea also suggests removing differences that are present for performance reasons. Leaving out "noexcept" seems to be no problem? Or is it essential to use "noexcept".

@Vizonex
Copy link
Owner

Vizonex commented May 14, 2024 via email

@lschoe
Copy link
Collaborator Author

lschoe commented May 14, 2024

So, is it OK to remove these "noexcept"s throughout the code (but make a note of it) to unify the code with uvloop's code?

For example, removing "noexcept" from sslproto.pyx and sslproto.pxd makes these source files identical to their counterparts in uvloop.

lschoe added a commit that referenced this issue May 18, 2024
Is calling uv.uv_disable_stdio_inheritance() needed at all?
@lschoe
Copy link
Collaborator Author

lschoe commented May 18, 2024

Hi @Vizonex , finally found the cause for this issue. I have made a PR, where the call to uv.uv_disable_stdio_inheritance() is commented out.

Can you reconsider the need for this call? Would be nice if it can be avoided.

Vizonex added a commit that referenced this issue May 18, 2024
@lschoe lschoe closed this as completed May 19, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants