1

In python I have a function which has an input statement, and assume that the function is a blackbox so I cannot edit the function. Instead of letting users to type and input, I want to feed a string to the input statement.

I have found a way to do so by starting a subprocess to run the function and feed the string as stdin.

Another approach is just using PIPE.

Is there any purely python way to achieve it?

Tong Tony
  • 43
  • 1
  • 7
  • 2
    If you can override `input` before calling it, you can use this: https://stackoverflow.com/a/63522511/8612463 – Mohammad Jafari Jan 02 '22 at 15:10
  • the situation is unclear, please provide some code to make it easier for us – Feras Alfrih Jan 02 '22 at 15:10
  • You should consider rewriting the function with parameters instead of asking for input. It is a better practice and more reusable if you do so. – Malo Jan 02 '22 at 15:14
  • @Malo thanks, but I have mentioned that I don't want to rewrite the function. I know it's a good practice to use parameters instead of inputs, but I just want to find a solution to solve this corner case. – Tong Tony Jan 02 '22 at 19:23
  • Does this answer your question? [How to use a string as stdin](https://stackoverflow.com/questions/5062895/how-to-use-a-string-as-stdin) – Tomerikoo Jan 03 '22 at 07:15
  • @Tomerikoo yes, as I mentioned, setting stdin is an approach. I want to find a more python way to do so, as some other people answered, for example, overwriting the input. – Tong Tony Jan 03 '22 at 12:16

2 Answers2

1

You can patch the module's function e.g. mymodule.input = myfunc, then your function will be called and afterwards just return a string from your function.

# mymodule
def func():
    print(input())
# main
import mymodule

def custom():
    return "my custom input"

mymodule.input = custom
mymodule.func()

however this might need to happen before mymodule is imported anywhere else. Depending on how the input() is called (e.g. as a global call in a module thus (import module already calling it indirectly) vs in a function, when it'd look into the globals() which would be patched)

Now, there's an alternative with deeper patching, but we can't do much as input() is a built-in and implemented in C (so not much of a patching available :( ). We can, however, utilize a custom sys.stdin such as io.StringIO() by which you can write to own "stdin" (it's not the real process' STDIN, just a buffer replacement, but that doesn't matter for this use-case).

Then a simple sys.stdin.write() with rewinding will do (again, has to happen before input() is called:

import sys
from io import StringIO
sys.stdin = StringIO()
sys.stdin.write("myinput")
sys.stdin.seek(0)  # rewind, so input() can read
text = input()
print(f"{text=}")

Between processes, as you've mentioned, use PIPE from subprocess or similar module.

Peter Badida
  • 11,310
  • 10
  • 44
  • 90
0
import mymodule
class Person:
    def __init__(self, name):
        self.name = name
    @property
    def email(self):
        return f"{name}@gmail.com}"
P = Person("Praddyumn")
mymodule.email = p.email

Here mymodule is an example of a module that takes email as an argument, but in class Person we have email as a function, but by using the @property decorator this function email becomes an atribute, so you can use this with pure Python.

ZygD
  • 22,092
  • 39
  • 79
  • 102