Import from global and project script library failing randomly

Hello,

Every so often I get an error when importing a script module stored in the gateway global script library. The error is ImportError: No module named shared

	from shared.util.MWESLogging import getLog
	import sys

I have also tried to use import shared.util.MWESLogging as mwesLogging and called the method with mwesLogging.getLog because I read in one of the other posts that the “from” method of importing sometimes has issues. But I get the same error.

Usually the methods work, but sometimes it fails and I’d like to know why. I tried putting it in the project script library but then it just said it couldn’t find the “project” module instead of the “shared” module.

I have attempted to move at least this code which is used all over the place! into a custom method attached to the project’s header line window or navigation window and while that works somewhat it complains at startup of the project because those windows are not always started first.

I have complained to IA about this problem with a different project that was using mostly server side scripts called from blocks in the SFC charting, but did not get a resolution to that problem.

I’ve got one window with multiple reused sub components (templates) where I get 300-400 errors, that I switched over to a combination of

win=system.gui.getWindow("Header Line")
logger=win.getLogger(....)

The window getLogger method does the EXACT SAME IMPORT, and it works there!

The additional problem is that this isn’t the only method I have in the shared script libraries, it’s just the method used the most. I am having similar issues with other methods, where I’ve just copied them into the window elements as custom methods which is not really nice.

Try not importing it at all. Just call shared.util.MWESLogging.getLog(). Due to object lifetimes in the gateway, it is unwise to ever import anything from shared.* or project.*. Just use the full names wherever you need them. It shouldn't be a problem in the client either, but the designer also has weirdness.

Import all you want from java. That is a pure jython operation and is effectively bulletproof. Other than the fact you can't use wildcards.

See this topic:

I have tried that also with mixed success… I found another post indicating that there may be problems with names that start with upper case letters. So I’m attempting to move to project script library with all lower case names to see if things become a bit more stable.

Thank you for your quick reply!

Ok, I switched ALL my custom methods and event handlers to do something like this:

self = event.source
logger = project.util.logging.getLog(method="propertyChange", lib=self.LibraryName, src=self.SourceName)

and

	logger = project.util.logging.getLog(lib=self.LibraryName, src=self.SourceName, useStack=True)
	project.util.logging.logMethodStartup ( logger ) 	

and now SOMETIMES I’m getting the following error

NameError: global name 'project' is not defined

This is very frustrating.

Some events (I don’t recall which) use a legacy python scope where system, shared, and project names exist only at the top level, and have to be imported individually in any nested functions. The best way to deal with this is to avoid defining functions and classes in event scripts themselves – always do that in script modules where modern scoping is reliable.

I’m not entirely sure what you are talking about here. Can you provide examples of what you mean?

I’ve seen this error both in the custom methods and at the event handler level. And it works sometimes and other times it won’t.

Phil is referring to the fact that in “legacy scoping”, the following happens:

# event, project, shared, system are available here
def foo():
    # but they are not available here unless you import them

In “standard scoping” this works correctly. You should always use standard scoping where available - there is no reason to use legacy scoping. Unfortunately event scripts and tag change scripts use legacy scoping and there is no option to change it. To be honest, I don’t understand why they’ve even made this an option - they should have just changed it everywhere. I cannot think of any case where this would break backwards compatibility.

However, you appear to be running into a long-standing bug with custom functions that keeps tripping me up. A custom function called from visionWindowOpened (even indirectly or via invokeLater) will get an uninitialised reference to project/shared/system, and will be unable to use them. There may also be other cases where this does not work properly, but I’m not sure of the details.

3 Likes