2
$\begingroup$

Not sure if somebody has any information about this.

I've been using a lot of asserts to catch erros and document my code during production. But I was wondering if I should better delete them when finishing my addon mostly for performance reasons.

I'm kinda new, but I've learned that in "normal" python packages, we can decide the optimize level of our compiled code (and depending on that, our asserts will be "ignored" automatically).

But I was wondering how Blender works with them. I don't know how they compile the addon (I guess it dont ignore the asserts, since well, I can trigger them).

So I was wondering if I better delete them.

Thank you so much for the help!

$\endgroup$
0

2 Answers 2

6
$\begingroup$

Assertions are a feature specifically designed to allow to easily disable the checks in the production code. You can do so by compiling your Python code to a .pyc file with -O or -OO flags. You can also run Python code with the PYTHONOPTIMIZE environment variable set to non-zero value to get that optimization.

For the most part, it doesn't really matter, you should only really care if you have a tight loop with thousands of asserts per second or more. Other than that, some assertion comparisons, like collections, could be so expensive, that even making one could have a significant cost. If something like this happens in your code, you might want to get rid of it in the way mentioned or otherwise (for open-source reasons you might want to just remove it with e.g. regex).

Those assertions that aren't computationally expensive, could remain useful in production, because bugs happen in production as well - but in such case convert them to normal if checks and raise exceptions.

PYTHONOPTIMIZE Environment Variable Example

Set the environment variable PYTHONOPTIMIZE to a non-zero value, then run Blender:

C:\Users\w10>e:

E:\>cd E:\Program Files\Blenders\stable\blender-3.6.2+stable.e53e55951e7a

E:\Program Files\Blenders\stable\blender-3.6.2+stable.e53e55951e7a>set PYTHONOPTIMIZE=1

E:\Program Files\Blenders\stable\blender-3.6.2+stable.e53e55951e7a>echo %PYTHONOPTIMIZE%
1

E:\Program Files\Blenders\stable\blender-3.6.2+stable.e53e55951e7a>blender
Read prefs: "C:\Users\w10\AppData\Roaming\Blender Foundation\Blender\3.6\config\userpref.blend"

Then go to the Scripting tab and confirm in the Python console that the environment variable is set:

>>> import os
>>> os.getenv('PYTHONOPTIMIZE')
'1'

Now in the text block area, from menu Templates choose PythonAddon Add Object, and modify the add_object function to simply:

def add_object(self, context):
    print("normal print")
    assert 1 == 2, "this assert should always report an error"

now run the script, and use the new operator:

You won't see the assertion error, only normal print in the system console.

$\endgroup$
2
  • $\begingroup$ Thanks mate. "You can do so by compiling your Python code to a .pyc file with -O or -OO flags. You can also run Python code with the PYTHONOPTIMIZE environment variable set to non-zero value to get that optimization." Yeah, but as far as I know, this is for python packages. How does that translate to Blender? If Im not wrong, we are not able to compile our addon, and Im not sure if Blender compiles our code, and if we can decite the PYTHONOPTIMIZE level. $\endgroup$
    – Ommadawn
    Commented Sep 15, 2023 at 11:55
  • $\begingroup$ Saw the edit. Thank you so much friend, super useful! $\endgroup$
    – Ommadawn
    Commented Sep 15, 2023 at 14:07
1
$\begingroup$

A different solution: turn it into a debug feature in your addon.

In my addon convertRotationMode, I started development using prints everywhere to monitor how things went, and even though it absolutely kills performance very easily due to the nature of the operations done, it's a very useful feature which I deemed would be useful if anyone wanted to debug any issue.

So, what I did is, made my own developer function in the operator, that picks up a string and prints it only if the addon's developer mode is enabled:

class CRM_OT_convert_rotation_mode(Operator):
    (...)

    def devOut(self, context, msg):
        if context.preferences.addons[__name__].preferences.devMode == True:
            print(msg)

Then, anytime I need to print something:

self.devOut(context, f'This is my developper message with {variables}')

Finally, in the addon's preferences, I create the BoolProperty that will be checked by the function, and the checkbox to toggle it ON/OFF:

class AddonPreferences(AddonPreferences, Panel):
    # this must match the addon name, use '__package__'
    # when defining this in a submodule of a python package.
    bl_idname = __name__

    devMode: BoolProperty(
        name="Developer Mode",
        description='Enables all error tracking messages.',
        default= False,
        )

    def draw(self, context):
        layout = self.layout

        row = layout.row()
        row.prop(self, "category")
        row.label(text="")
        row.prop(self, "devMode")
$\endgroup$
2
  • $\begingroup$ BTW, I said how one needs thousands of asserts per second to really make a difference, but with prints it's different - printing to console is somewhat slow (hundreds of prints per second can make a difference) $\endgroup$ Commented Sep 16, 2023 at 9:03
  • $\begingroup$ Yup, that's one of the reasons i made it optional to begin with ;) But whether it's asserts or prints, I think the same principle can be applied: instead of getting rig of everything needed for debugging because of its performance, make it optional, it can be useful. $\endgroup$
    – Lauloque
    Commented Sep 16, 2023 at 22:33

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .