Daemon context won't run inside function - python

I'm creating a python bridge to a program. I'm using the pipi daemon module to prevent lockups.
http://pypi.python.org/pypi/python-daemon/
I basically want to eventually put this in a module for easy reuse and to build a python wrapper.
In testing, if I put the daemon context inside a function it won't work.
If I put it outside the function, it works flawlessly.
def createCube():
prog('create cube/params')
def runFunc(func):
with daemon.DaemonContext():
prog = createConnection().command #our port connection system
func()
sys.exit()
runFunc(createCube)
I can't think of a reason why it wouldn't work inside a function when it works fine outside of it, unless it's looking for a namespace perchance?
Any help would be appreciated. Thank you very much!

Related

running imported module functions through sockets in Maya (Python)

I have a problem and I am not sure what is going on, I have created a 'userSetup.py' file and placed it in the script folder (C:\Users*user*\Documents\maya\2022\scripts)
This is my userSetup.py file:
def importPy():
### import modules and open a command port ###
exec("import my_module", globals())
exec("cmds.commandPort(name=':1234', sourceType = 'python')")
exec("print('FINISHED')")
def tryImport():
"""
execute importPy when Maya is idle
"""
from maya.utils import executeDeferred
executeDeferred("importPy()")
tryImport()
now I have created a file 'my_module.py' and placed it in the same script folder
this is the my_module.py file:
print("my_module loaded")
def function_print(statement: str):
print(statement)
I know this is working on startup as the console in Maya reads:
my_module loaded
FINISHED
I have a successfully sent over simple commands like:
cmds.polyCube()
it works fine even returns fine which I found odd since I am not echoing the output, so the socket server is working as intended. But if I send:
my_module.function_print("please print this")
it doesn't work, but it will work if I write that exact same line in the python command line within Maya.
This doesn't really make sense to me, I am fairly new to python so I may be missing something obvious here. But all I can think is that the socket commands somehow don't have access to the global scope.
If anyone knows what's up with this, it would be much appreciated.
Thanks,
Brendan
P.S. the names to my modules and functions have been made up for this example. If that wasn't obvious.

Function not defined when Importing Maya Python Script

I have a tool I wrote in python that works completely fine when running in the maya script editor. However, I want to be able to import the script from the script directory. Which should be simple, and I am shocked I can't find the solution while searching the web.
My script format is like this example:
import maya.cmds as cmds
# GUI code with buttons, they call the functions below.
#
#
def function1():
#commands that do things
def function2():
#commands that do things
#List of functions continues
Like I said, the program functions perfectly when run in the script editor. When saving the script to the directory and using this method:
import module
reload (module)
module.function()
The GUI loads fine, but then when pushing the gui buttons, it says the functions are not defined. I don't understand what I am missing? If the script was loaded, shouldn't the functions be defined? Any help would be greatly appreciated, thank you!
Just because the GUI loads doesn't mean that all of your functions loaded properly. You need to put your file, (module.py) in a directory that is visible to your PYTHONPATH. If you're in Maya, you can also put it in the MAYA_SCRIPT_PATH
The PYTHONPATH / MAYA_SCRIPT_PATH are environment variables that you set before launching Maya. In a default Maya installation, some places where you could put your module.py file would be:
(Windows) C:\Users\YOUR_USER_NAME\Documents\maya\scripts
(Linux) ~/maya/scripts
(Mac) - Not sure, put probably also ~/maya/scripts
If you want to know where else you can place it, you run this
import os
print(os.getenv('MAYA_SCRIPT_PATH', ''))
print(os.getenv('PYTHONPATH', ''))
Any location in that list that you have write permissions to is OK to add your module.py file.
Also, it's worth noting that in your example module.function() would fail. It'd need to be module.function1() or module.function2() but I assume you know that. Hope this helps
Sup guys
So i know this is an old question that has already been answered but I have some extra information that helps in regards to GUI functions not working. (same error)
and there's basically nothing on this anywhere.
so the script director only helps when loading in the module through the shelf but will still return the same error "fuction is not defined"
this has todo with how the function is called through the UI element.
example.
this is will allow you to call function in the script editor
but gives you the function not defined error when the module is imported
def GUI_function():
pm.button( command = "function()")
def function():
do stuff
this on the other hand works.
def GUI_function():
pm.button( command = function)
def function(*_):
do stuff
i don't know why but maya tends to think function() is a nodetype
so remove the brackets if you not using arguments and you good to go

How to pass args to embedded python sub-interpreter?

I need to interpret few files (scripts) by embedded python interpreter concurrently (to be more detailed one script executes another script as Popen and my app intercepts it and executes it itself). I've found it's called sub-interpreter and i'm going to use it. But i've read sub-interpreter does not have sys.argv:
The new environment has no sys.argv variable
I need to pass argv anyway so how can i do it?
You might find it easier to modify each of the scripts follow the pattern:
def run(*posargs, **argdict):
"""
This does the work and can be called with:
import scriptname
scriptname.run(someargs)
"""
# Code goes here and uses posargs[n] where it would use sys.argv[n+1]
if __name__ == "__main__":
import sys
run(sys.argv[1:])
Then your main script can just call each of the subscripts in turn by simply calling the run method.
You can use environment variables. Have the parent set them by updating the dict os.environ if it's in Python, or setenv() if in C or C++ etc. Then the children can read os.environ to get whatever strings they need.

Using object in different module than original script

I just started with Python and I'm having some problems. I've written already a few scripts for ArcGIS and had some recurring stuff. So I thought it would be smart to put that in modules which I can easily use again.
So now I have two scripts, script.py and toolbox.py.
My script was working fine so I copied and paste the part I needed, edited it a bit and everything goes well except for the messages created with gp.Addmessage
script.py will create the message "Hello Stackoverflow" but the messages from toolbox.py doesn't show up. Why is that? It loads the toolbox because I can use it later on, so it regocnizes the gp object.
I'm kind of stuck here, would love to be able to print messages from inside the modules to inform the user of the tool what is happening.
script.py:
import os, sys, arcgisscripting
# Create the Geoprocessor object
gp = arcgisscripting.create()
gp.AddMessage("# Hello Stackoverflow")
import toolbox
toolbox.loadToolbox
toolbox.py:
def loadToolbox:
try:
some code
gp.AddToolbox(path)
gp.AddMessage("# Toolbox loaded")
except:
gp.AddMessage("# Toolbox not found")
You have two problems with your code:
You never call the loadToolBox method, you only refer to it. Add ():
toolbox.loadToolbox()
Your loadToolbox() function doesn't take gp as an argument. If gp is meant to be a global, then it won't be visible to the toolbox module (globals are only visible in the current module).
Add gp as a parameter and pass it in when calling loadToolbox. In script.py:
toolbox.loadToolbox(gp)
and in toolbox.py:
def loadToolbox(gp):
# rest of function

Python getopt() in __main__

I'm a Python beginner and have successfully gotten my first program with CLI parameters passed in to run. Got lots of help from this Handling command line options.
My question is: Why in Example 5.45 a separate def main(argv) has been used, instead of calling the try/except block within __main__ itself.
Example 5.45
def main(argv):
grammar = "kant.xml"
try:
opts, args = getopt.getopt(argv, "hg:d", ["help", "grammar="]) 2
except getopt.GetoptError:
usage()
sys.exit(2)
...
if __name__ == "__main__":
main(sys.argv[1:])
Hope someone versed in Python could share your wisdom.
TIA -
Ashant
There is no strict technical reason, but it is quite idiomatic to keep the code outside functions as short as possible. Specifically, putting the code into the module scope would turn the variables grammar, opts and args into global public variables, even though they are only required inside the main code. Furthermore, using a dedicated main function simplifies unit-testing this function.
One advantage of using a main function is that it allows for easy code re-use:
import sys
import script
script.main(sys.argv[1:])
# or, e.g. script.main(['-v', 'file.txt']), etc
Any code in the script's __main__ block won't be run if it is imported as a module. So the main function acts as a simple interface providing access to all the normal functionality of the script. The __main__ block will then usually contain just a single call to main, plus any other non-essential code (such as tests).
Some tips from the author of Python on how to write a good main function can be found here.

Categories