evanunderscore / print_statement

from __past__ import print_statement
GNU General Public License v3.0
22 stars 1 forks source link

Doesn't work in PYTHONSTARTUP #1

Open csm10495 opened 6 years ago

csm10495 commented 6 years ago

I have a python startup file that I use to do a couple things on startup. For some reason if I do this:

import print_statement
print_statement.install()
from __past__ import print_statement

we get a traceback with:

Traceback (most recent call last):
  File "C:\Users\csm10495\pystartup.py", line 81, in <module>
    from __past__ import print_statement
ModuleNotFoundError: No module named '__past__'

Though if I do the import in interactive later, it works. Does this have to do with this not working in modules? Can we make this work here? Thanks!

evanunderscore commented 6 years ago

Thanks for the report.

It seems that install() doesn't work that early, and even if it did, the special import wouldn't be processed properly inside the startup file. If you could somehow delay calling install(), you could cheat the other part with print_statement._printerpreter._print_statement = True. Unfortunately I won't have any time to work on this myself in the near future.

csm10495 commented 6 years ago

Is it a matter of calling install() later in time or at a later place in startup? I could just have a thread go and do it after some amount of time if you think that would work.

evanunderscore commented 6 years ago

It needs to be done after the startup file runs. If you're looking for something quick and dirty, this works for me:

import print_statement
import threading
import time
def install():
    time.sleep(1)
    print_statement.install()
    print_statement._printerpreter._print_statement = True
threading.Thread(target=install).start()

Note that this won't work for the very first thing you execute, but it will work for subsequent things.

>>> print 1
  File "<stdin>", line 1
    print 1
          ^
SyntaxError: Missing parentheses in call to 'print'
>>> print 1
1
csm10495 commented 6 years ago

Interesting. Can you elaborate a bit on why it doesn't work for the first one? I'm just curious.

evanunderscore commented 6 years ago

It intercepts text typed into the interpreter by hooking PyOS_ReadlineFunctionPointer, the function responsible for displaying the prompt and taking a line of input from the user, like input() does. When you're able to type, the original function has already been called, so hooking it at that point only affects subsequent lines.

For whatever reason, when run in the startup file, this function pointer is NULL, and since we need to call the original function to actually get the text, we can't hook it at that point.

If you can find a better way of hooking the input, these problems might go away.