Closed bradharmon closed 11 years ago
Hi Brad,
Please try this:
namespace = conn.eval("{}")
conn.execute(source, globals=namespace) # locals defaults to globals
The CPython runtime doesn't like it when you try to use a foreign dictionary object as the globals parameter to eval. The change I've suggested creates a dictionary in the remote process, and then calls eval with that; thus when eval is called in the remote process it is operating on a dictionary local to its interpreter (hope that makes sense!)
Thanks for filing the issue. Please let me know how you get on.
Cheers, Andrew
This worked great! Thanks
Along the same lines, I'm having difficulty loading remote code into a local module:
source = """
import math
def sqrt(x):
return math.sqrt(x)
"""
module = conn.modules.imp.new_module('test')
conn.execute(source, globals=module.__dict__)
module.sqrt(144)
pushy.protocol.proxy.ExceptionProxy: 'module' object has no attribute 'sqrt'
I've also tried to execute it with 'globals=namespace' and then load that dict into a local module, but that has issues as well:
module = imp.new_module('test')
namespace = conn.eval("{}")
conn.execute(source, globals=namespace)
module.__dict__ = namespace
module.__dict__ = namespace
TypeError: readonly attribute
What are your suggestions for this use case? I really appreciate the help.
Thanks,
Brad
manually copying all values from the namespace dict into module.dict seems to work. Is this the suggested method for accomplishing this?
import pushy
import imp
source = """
import math
def sqrt(x):
return math.sqrt(x)
"""
conn = pushy.connect("local:")
namespace = conn.eval("{}")
conn.execute(source, globals=namespace)
#create new module and copy namespace dict into module dict
module = imp.new_module('test')
for key, value in namespace.items():
module.__dict__[key] = value
del namespace
print module.sqrt(144)
conn.close()
Just so I'm clear on the intentions of the code: you're trying to create a module in process A that contains methods that will be executed in process B?
It's a bit ugly IMHO, but that's pretty much how it goes. Ideally you'd just set globals=module.dict, but then you have the problem of it not being a real dict in the remote process.
Yes, that's the goal. I want the ability to remotely import local code. I have code where multiple classes need to interact on a remote box and this seems like the easiest way
Okey dokey. I haven't personally done (exactly) this before, so you may come against more ugliness along the way. I'll leave this issue open a while longer in case you want some more input.
I assume this can be closed now, please reopen if you encounter any more problems.
Maybe I'm missing something really basic, but executing code with imports fails with an error saying that the import is not defined
pushy.protocol.proxy.ExceptionProxy: global name 'math' is not defined
However if I run it with 'source' modified slightly, it works fine:
I would like to be able to get rid of the extra 'global' declaration, however nothing I've tried seems to work.