entering console inputs from within python file
Question: In my python file, I have made a GUI widget that takes some inputs from user.
I have imported a python module in my python file that takes some input using
raw_input(). I have to use this module as it is, I have no right to change it.
When I run my python file, it ask me for the inputs (due to raw_input() of
imported module). I want to use GUI widget inputs in that place. How can I
pass the user input (that we take from widget) as raw_input() of imported
module?


Answer: First, if `import`ing it directly into your script isn't actually a
requirement (and it's hard to imagine why it would be), you can just run the
module (or a simple script wrapped around it) as a separate process, using
`subprocess` or `pexpect`.

Let's make this concrete. Say you want to use this silly module `foo.py`:

    
    
    def bar():
        x = raw_input("Gimme a string")
        y = raw_input("Gimme another")
        return 'Got two strings: {}, {}'.format(x, y)
    

First write a trivial `foo.wrapper.py`:

    
    
    import foo
    print(foo.bar())
    

Now, instead of calling `foo.do_thing()` directly in your real script, run
`foo_wrapper` as a child process.

I'm going to assume that you already have the input you want to send it in a
string, because that makes the irrelevant parts of the answer simpler (in
fact, it makes them possible—if you wanted to use some GUI code for that,
there's really no way I could show you how unless you first tell us which GUI
library you're using).

So:

    
    
    foo_input = 'String 1\nString 2\n'
    
    with subprocess.Popen([sys.executable, 'foo_wrapper.py'],
                          stdin=subprocess.PIPE, stdout=subprocess.PIPE) as p:
        foo_output, _ = p.communicate(foo_input)
    

Of course in real life you'll want to use an appropriate path for
`foo_wrapper.py` instead of assuming that it's in the current working
directory, but this should be enough to illustrate the idea.

* * *

Meanwhile, if "I have no right to change it" just means "I don't (and
shouldn't) have checkin rights to the foo project's github site or the
relevant subtree on our company's P4 server" or whatever, there's a really
easy answer: Fork it, and change the fork.

Even if it's got a weak copyleft license like LGPL: fork it, change the fork,
publish your fork under the same license as the original, then use your fork.

If you're depending on the foo package being installed on every target system,
and can't depend on your replacement foo being installed instead, that's a bit
more of a problem. But if the function or method that actually calls
`raw_input` is just a small fraction of the actual code in `foo`, you can fix
that by monkeypatching `foo` at runtime.

* * *

And that leads to the last-ditch possibility: You can always monkeypatch
`raw_input` itself.

Again, I'm going to assume that you already have the input you need to give it
to make things simpler.

So, first you write a replacement function:

    
    
    foo_input = ['String 1\n', 'String 2\n']
    def fake_raw_input(prompt):
        global foo_input
        return foo_input.pop()
    

Now, there are two ways you can patch this in. Usually, you want to do this:

    
    
    import foo
    foo.raw_input = fake_raw_input
    

This means any code in `foo` that calls `raw_input` will see the function you
crammed into its module globals instead of the normal builtin. Unless it does
something really funky (like looking up the builtin directly and copying it to
a local variable or something), this is the answer.

If you need to handle one of those really funky edge cases, and you don't mind
doing something questionable, you can do this:

    
    
    import __builtin__
    __builtin__.raw_input = fake_raw_input
    

You must do this before the first `import foo` anywhere in your problem. Also,
it's not clear whether this is intentionally guaranteed to work, accidentally
guaranteed to work (and should be fixed in the future), or not guaranteed to
work. But it does work (at least for CPython 2.5-2.7, which is what you're
probably using).

