Page MenuHome

getattr and hasattr not working on bpy.ops
Closed, ArchivedPublic

Description

System Information
WinXP Pro SP3 32Bit
Nvidia EVGA 8800 GTS 512

Blender Version
2.68, 2.69 Maybe earlier versions also.

Short description of error
getattr and hasattr is obviously acting wrong and is causing my plugin/addon code(and probably blender core) to give undesired results. Everything returns True

Exact steps for others to reproduce the error

PYTHON INTERACTIVE CONSOLE 3.3.0 (default, Nov 26 2012, 17:23:29) [MSC v.1500 32 bit (Intel)]

Command History:     Up/Down Arrow
Cursor:              Left/Right Home/End
Remove:              Backspace/Delete
Execute:             Enter
Autocomplete:        Ctrl-Space
Zoom:                Ctrl +/-, Ctrl-Wheel
Builtin Modules:     bpy, bpy.data, bpy.ops, bpy.props, bpy.types, bpy.context, bpy.utils, bgl, blf, mathutils
Convenience Imports: from mathutils import *; from math import *
Convenience Variables: C = bpy.context, D = bpy.data

>>> import bpy
>>> getattr(bpy.ops, 'whatTheF***')
<module like class 'bpy.ops.whatTheF***'>

>>> hasattr(bpy.ops, 'whatTheF***')
True

Event Timeline

edg (Metallicow) raised the priority of this task from to 90.
edg (Metallicow) updated the task description. (Show Details)
edg (Metallicow) edited a custom field.
Brecht Van Lommel (brecht) renamed this task from getattr and hasattr is foobar to getattr and hasattr not working on bpy.ops.Jan 8 2014, 4:53 PM
Brecht Van Lommel (brecht) lowered the priority of this task from 90 to 50.
Campbell Barton (campbellbarton) changed the task status from Unknown Status to Archived.Jan 8 2014, 5:15 PM

This is how its intended to work, bpy.ops is exposed in a module like way, but in fact constructs the operator name using 2x attribute lookups.

bpy.ops.foobar <- is accepted

bpy.ops.foobar.operator <- fails

The alternative would be to validate the prefix on every access which would mean searching through over ~1500 operators, I don't think its worth it.

If you really need this functionality you can replace...

hasattr(bpy.ops, "object")

with...

"object" in dir(bpy.ops)

Ahhh, I see now... after looking into the code further.

"object" in dir([object])

is more pythonic anyway. Thanks for the info. Code works fine now.

@edg (Metallicow) - I wouldnt say dir() is more pythonic, both should work ideally.

I just don't think the tradeoff of slower access is worth it in this case to make hasattr work here, seeing as an invalid operator will raise an error on accessing its full name anyway.