2.80 using multiple internal scripts breaking change

We have several .blends that have multiple embedded python scripts for doing various tasks. Prior to April 2019 builds of 2.80 we never had issues loading this scripts. Now, however, the way in which these scripts are loaded has changed.

Let’s say we have 2 scripts in blender. One is called first.py and the other is called second.py. In previous versions of 2.80 we would open our .blend and “Run Script” on first.py. It has the following:

import second

second.func()

This worked great. Post April 2019 versions of 2.80 started failing with

Traceback (most recent call last):
  File "J:\script_example.blend\first.py", line 1, in <module>
ModuleNotFoundError: No module named 'second'
Error: Python script failed, check the message in the system console

After some digging around we discovered that this feature we relied on was changed: PyAPI: remove support for importing text blocks as modules

So now, we’ve modified our .blend scripts to the following:

import bpy
second = bpy.data.texts["second.py"].as_module()

second.func()

This is not a huge change, but I thought I’d put it in a post here so that if others are having the same issue they won’t have to spend a few hours trying to find a workaround.

Thanks,
-Alan

6 Likes

In my code I use the form:

from MyModule import *

How could I achieve this in this new version of 2.8?

from . mymodule import *

also, in the future make your own thread- your question doesn’t appear to be relevant to the original post.

2 Likes

“from second import *” eliminates the need to name the module when calling the function.
Is there way to just write func() instead of second.func() with the new way modules are loaded?

Yep, don’t use wildcard imports, it’s not pep compliant anyway. from . second import func, you don’t have to specify the module if you import the function.

1 Like

I simply get the error when I try that
ModuleNotFoundError: No module named ‘module1’

I have two text blocks, one named main with:
import bpy
module1=bpy.data.texts[‘module1’].as_module()
from . module1 import func1
func1(“test”)

and the one named module1:
import bpy
def func1(mystring):
print(mystring)

I tried with absolut and relative paths.

Found a solution for don’t having to write the module name before every function.
Import it as globals().update(bpy.data.texts['something.py'].as_module().__dict__)