4
$\begingroup$

Seems that this question was asked before but was not answered.

I already found this answer, where it was suggested that if you send an empty dictionary as override, it's supposed to show you what context elements are required to run the operator.

But this didn't work for the operator I'm interested in:

bpy.ops.cycles.use_shading_nodes({})

Traceback (most recent call last):
  File "<blender_console>", line 1, in <module>
  File "C:\Program Files\Blender Foundation\Blender\2.74\scripts\modules\bpy\ops.py", line 187, in __call__
    ret = op_call(self.idname_py(), C_dict, kw, C_exec, C_undo)
RuntimeError: Operator bpy.ops.mesh.select_all.poll() failed, context is incorrect

So my question is, is there a reliable way to find out what the required context is for an operator? (The docs are no help here. Source might be, but I'd rather avoid that search for a needle in a haystack unless I'm really desperate...)

$\endgroup$
  • $\begingroup$ Yeah the source is the definitive answer: I think you allude to this question ( blender.stackexchange.com/questions/30364/… ) . But you probably don't want this in the first place. Is your real problem ' i want to create a material and set it to use shader nodes - via script ' ? $\endgroup$ – zeffii Aug 13 '15 at 15:51
  • $\begingroup$ Thanks. Unfortunately I do indeed want to set the background material to use nodes via a script... I hope someone will have another idea that doesn't involved delving into the source, but if there's no choice, it won't stop me :) $\endgroup$ – TLousky Aug 13 '15 at 15:55
  • $\begingroup$ It really comes down to people trying to use operators that aren't intended to be used anywhere other than as a response to a user clicking a menu item. During that menu interaction the operator has the correct context, but outside of it.. in a script for instance..which tends to have a sort of 'no-mans-land' (or very often the wrong ) context.. it will fail. Looking for a way to override the context, for every possible operator, is not necessary, as the context limitation is often mitigated by using more low level bpy calls. (In the end also this results in more manageable code.. ) $\endgroup$ – zeffii Aug 13 '15 at 16:17
  • $\begingroup$ This ties into my "bpy.ops has cooties" philosophy. In an ideal world each function in bpy.ops would clearly document the context it requires, but it would be a major effort to update all the docs. Even requiring that documentation for new operators would encounter resistance from the coders who are working full-tilt to keep the bugs under control while adding important new features. $\endgroup$ – Mutant Bob Aug 13 '15 at 17:45
4
$\begingroup$

Asking for a way to find the context for all possible operators that need such an override is at the same time ignoring all the responses to people looking for their specific override for their needs.

As is often the case with 'context is incorrect', there is a solution that's much simpler and (more) logical than the potential workaround using context overrides. While most operators can take an override context, you will invariably (if you dig deep enough) find several that can't. You will also find operators which are the only way to achieve some goal.

For all other cases where there's a better way to do it without the operator in question, you simply use the lower level bpy code. Ask, we will always give an answer, or dig using the Info console and track the changes in bpy.data to see what got added and which parameters are adjusted after a manual Operator invoke (ie you click a button, and that calls the operator in question).

(Sometimes a context override is the only way, but not this time)

Make a new world material.

>>> m = bpy.data.worlds.new('amazon')
>>> m.use_nodes = True
>>> m.node_tree
bpy.data.node_groups['Shader Nodetree']

>>> m.node_tree.nodes['Background'].color
Color((0.608, 0.608, 0.608))

# setting current scene world
>>> bpy.context.scene.world = bpy.data.worlds['amazon']
$\endgroup$
  • $\begingroup$ Thanks, this will probably solve my specific problem (will update). And I agree that overriding context isn't a solution for everything. But it would be nice to hear some additional thoughts about methods for finding the context for an operator though :) $\endgroup$ – TLousky Aug 13 '15 at 16:27
  • $\begingroup$ I don't know what to say.. To my mind the links you listed and the one I mention about the source code , cover this concept exhaustively. There's not a lot extra to add. But maybe we have failed to communicate some essence here.. $\endgroup$ – zeffii Aug 13 '15 at 16:35
  • $\begingroup$ They do, and it's much appreciated! I don't doubt that you can find an answer to most any question about operator context with them. But if there's something I've learned, it's that sometimes there's a faster trick lying in hiding. Since there's a big bunch of smart experienced people writing here, I still have a sliver of hope that this kind of trick might be revealed. If there's nothing in a couple of days, I'll wave the white flag and mark this as question as closed :) $\endgroup$ – TLousky Aug 13 '15 at 16:42
  • $\begingroup$ well, this question has plagued new Blender scripters since 2009 (Blender 2.5 onwards...) know that. ..and if you don' t get an answer that satisfies, it's not because we don't want to share some secret :) $\endgroup$ – zeffii Aug 13 '15 at 16:46
  • 2
    $\begingroup$ The only definitive way to find out why an operator fails is to read the source code indeed, which is said in the docs by the developer that knows the most about Blender Python API. A blank dict is a hack that works sometimes, but other than that, there's no way to tell from Python. Operators are like blackboxes. $\endgroup$ – CoDEmanX Aug 14 '15 at 7:36

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.