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?

6
  • 2
    If you can override input before calling it, you can use this: stackoverflow.com/a/63522511/8612463 Commented Jan 2, 2022 at 15:10
  • the situation is unclear, please provide some code to make it easier for us Commented Jan 2, 2022 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. Commented Jan 2, 2022 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. Commented Jan 2, 2022 at 19:23
  • Does this answer your question? How to use a string as stdin Commented Jan 3, 2022 at 7:15

2 Answers 2

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.

Sign up to request clarification or add additional context in comments.

1 Comment

@TongTony Check the answer again, example with sys.stdin included.
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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.