1
$\begingroup$

I have a script that watches for changes in another script, and re-runs the latter if it's changed. Gist here. It's run like this:

~/blender/blender-2.92.0-linux64/blender --python script_watcher.py -- test_group.py

It worked ok until I used the reduce() function in the watched script - snippet here (union() is a function that creates the union of two objects):

def all_union(first, *others, **kwargs):
    def _(a, b):
        return union(a, b)
    r = reduce(_, others, first)
    return r

then I get an error message like this:

NameError: name 'reduce' is not defined 

I tried replacing the timer script with one that runs only once - like this:

import bpy
import sys
import os
import traceback

prev = ""
curr = open(sys.argv[-1]).read()
if not prev==curr:
    print("%s changed" % sys.argv[-1])
    try:
        exec(curr)
    except Exception as e:
        exc_type, exc_obj, exc_tb = sys.exc_info()
        print(traceback.format_exc())

and it runs perfectly - no error.

So why is reduce() not not working under the timer? or is the issue somewhere else?

$\endgroup$
5
  • 2
    $\begingroup$ "Why does reduce fail when run inside a timer?" - does reduce not fail when run outside a timer? Have you tried to use it outside a timer? Your code doesn't show that. The error message says the name is not defined, that is, Python interpreter doesn't recognize the name because it wasn't imported. You probably need from functools import reduce. Also this question is probably offtopic - not about Blender, but about Python. $\endgroup$ Aug 7, 2021 at 8:49
  • $\begingroup$ @MarkusvonBroady - hi! yes, I did run the code outside the timer, that's what I tried to say at "I tried stripping everything from the timer script". Maybe it wasn't crystal clear, I tried to improve in the edit. And test_script.py does have from functools import reduce right at the top. $\endgroup$
    – simone
    Aug 7, 2021 at 8:57
  • $\begingroup$ Did you try to reimport immediately before using it inside the timer? $\endgroup$ Aug 7, 2021 at 9:32
  • $\begingroup$ @MarkusvonBroady - if I do from functools import reduce inside the function definiton everything works ok. Also, using functools.reduce() works ok $\endgroup$
    – simone
    Aug 7, 2021 at 9:45
  • 2
    $\begingroup$ IMO the elephant in the room here is how you set up timer call via bpy.app.timers.register . Given error message the method passed, when run from timer thread, has no idea of the locals. As MB says simply import in the function. Consider looking at when file was last touched, rather than constantly testing content for equality. Recommend pathlib for statting and reading text files. Also have a look at script stub template. $\endgroup$
    – batFINGER
    Aug 7, 2021 at 10:01

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.