[Bf-committers] [Bf-blender-cvs] SVN commit: /data/svn/bf-blender [24629] trunk/blender: - rna attribute setting problem, class instances could not set their own attributes because they are blocked by our own internal setattr .

Campbell Barton ideasman42 at gmail.com
Wed Nov 18 10:31:04 CET 2009


StructRNA is the base class of all RNA PyObjects in 2.5...
the upshot is we end up with the same base class for a python mesh
instance and a povray render engine instance.

supporting everything is becoming a balancing act :/

My rationale is this...
ob.foo = 1

Allowing this just asks for troubles, it works but not how you would
want in most cases.

C.active_object.foo = 1
print(C.active_object.foo) # raises an error because they are
different PyObjects

ob.foo = 1
print(ob.foo) # works and could be useful BUT...
ob.active_materials = mat # typo's pass by too easy...

for an mesh/group/scene I think its fine to disallow direct attribute
assignment, attributes are for RNA, otherwise custom ID props are
saved with the file and more useful.
ob["foo"] = 1

the exception is with a class instance, render engine, operators etc.
These too have a StructRNA base class.
This can be done if we subclass StructRNA via C, but it complicates
the API a bit too, so Id like to avoid for now.

using self._somevar is python convention for private attributes. but
agree its annoying that there is no obvious way to know this unless
you look at the internal api.
if this is kept longer term it could be noted in the setattr exception.

On Wed, Nov 18, 2009 at 10:03 AM, joe <joeedh at gmail.com> wrote:
> That seems a little unobvious to me. . .do we really need to support
> this at all?
>
> Joe
>
>
> On Wed, Nov 18, 2009 at 12:40 AM, Campbell Barton <ideasman42 at gmail.com> wrote:
>> Revision: 24629
>>          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=24629
>> Author:   campbellbarton
>> Date:     2009-11-18 09:40:18 +0100 (Wed, 18 Nov 2009)
>>
>> Log Message:
>> -----------
>> - rna attribute setting problem, class instances could not set their own attributes because they are blocked by our own internal setattr.
>>  this could be supported again easily however it leads typo's & api changes not showing any errors.
>>
>>  This broke povray export.
>>  Solution for now is to allow setting private properties starting with '_'
>>
>>  eg,
>>    ob = bpy.context.object
>>
>>    ob._foo = [1,2,3] # this is a python list, it will stay only as long as this PyObject is active
>>    ob.foo = 1 # raises an error!, only for rna properties
>>    ob["foo"] = 1 # converts to an ID property and is saved
>>
>>    using the underscore like this should really be used for classes internally.
>>
>> - povray failed on armatures
>>
>> - menu key wasn't using WM_keymap_add_menu
>>
>> Modified Paths:
>> --------------
>>    trunk/blender/release/scripts/io/engine_render_pov.py
>>    trunk/blender/release/scripts/modules/rna_prop_ui.py
>>    trunk/blender/source/blender/editors/curve/curve_ops.c
>>    trunk/blender/source/blender/python/intern/bpy_rna.c
>>
>> Modified: trunk/blender/release/scripts/io/engine_render_pov.py
>> ===================================================================
>> --- trunk/blender/release/scripts/io/engine_render_pov.py       2009-11-18 05:11:16 UTC (rev 24628)
>> +++ trunk/blender/release/scripts/io/engine_render_pov.py       2009-11-18 08:40:18 UTC (rev 24629)
>> @@ -285,7 +285,7 @@
>>                for ob in sel:
>>                        ob_num+= 1
>>
>> -                       if ob.type in ('LAMP', 'CAMERA', 'EMPTY', 'META'):
>> +                       if ob.type in ('LAMP', 'CAMERA', 'EMPTY', 'META', 'ARMATURE'):
>>                                continue
>>
>>                        me = ob.data
>> @@ -722,26 +722,26 @@
>>        def _export(self, scene):
>>                import tempfile
>>
>> -               self.temp_file_in = tempfile.mktemp(suffix='.pov')
>> -               self.temp_file_out = tempfile.mktemp(suffix='.tga')
>> -               self.temp_file_ini = tempfile.mktemp(suffix='.ini')
>> +               self._temp_file_in = tempfile.mktemp(suffix='.pov')
>> +               self._temp_file_out = tempfile.mktemp(suffix='.tga')
>> +               self._temp_file_ini = tempfile.mktemp(suffix='.ini')
>>                '''
>> -               self.temp_file_in = '/test.pov'
>> -               self.temp_file_out = '/test.tga'
>> -               self.temp_file_ini = '/test.ini'
>> +               self._temp_file_in = '/test.pov'
>> +               self._temp_file_out = '/test.tga'
>> +               self._temp_file_ini = '/test.ini'
>>                '''
>>
>>                def info_callback(txt):
>>                        self.update_stats("", "POVRAY: " + txt)
>>
>> -               write_pov(self.temp_file_in, scene, info_callback)
>> +               write_pov(self._temp_file_in, scene, info_callback)
>>
>>        def _render(self):
>>
>> -               try:            os.remove(self.temp_file_out) # so as not to load the old file
>> +               try:            os.remove(self._temp_file_out) # so as not to load the old file
>>                except: pass
>>
>> -               write_pov_ini(self.temp_file_ini, self.temp_file_in, self.temp_file_out)
>> +               write_pov_ini(self._temp_file_ini, self._temp_file_in, self._temp_file_out)
>>
>>                print ("***-STARTING-***")
>>
>> @@ -757,15 +757,15 @@
>>                                pov_binary = winreg.QueryValueEx(regKey, 'Home')[0] + '\\bin\\pvengine'
>>
>>                if 1:
>> -                       self.process = subprocess.Popen([pov_binary, self.temp_file_ini]) # stdout=subprocess.PIPE, stderr=subprocess.PIPE
>> +                       self._process = subprocess.Popen([pov_binary, self._temp_file_ini]) # stdout=subprocess.PIPE, stderr=subprocess.PIPE
>>                else:
>>                        # This works too but means we have to wait until its done
>> -                       os.system('%s %s' % (pov_binary, self.temp_file_ini))
>> +                       os.system('%s %s' % (pov_binary, self._temp_file_ini))
>>
>>                print ("***-DONE-***")
>>
>>        def _cleanup(self):
>> -               for f in (self.temp_file_in, self.temp_file_ini, self.temp_file_out):
>> +               for f in (self._temp_file_in, self._temp_file_ini, self._temp_file_out):
>>                        try:            os.remove(f)
>>                        except: pass
>>
>> @@ -785,19 +785,19 @@
>>                y= int(r.resolution_y*r.resolution_percentage*0.01)
>>
>>                # Wait for the file to be created
>> -               while not os.path.exists(self.temp_file_out):
>> +               while not os.path.exists(self._temp_file_out):
>>                        if self.test_break():
>> -                               try:            self.process.terminate()
>> +                               try:            self._process.terminate()
>>                                except: pass
>>                                break
>>
>> -                       if self.process.poll() != None:
>> +                       if self._process.poll() != None:
>>                                self.update_stats("", "POVRAY: Failed")
>>                                break
>>
>>                        time.sleep(self.DELAY)
>>
>> -               if os.path.exists(self.temp_file_out):
>> +               if os.path.exists(self._temp_file_out):
>>
>>                        self.update_stats("", "POVRAY: Rendering")
>>
>> @@ -807,7 +807,7 @@
>>                                result = self.begin_result(0, 0, x, y)
>>                                lay = result.layers[0]
>>                                # possible the image wont load early on.
>> -                               try:            lay.load_from_file(self.temp_file_out)
>> +                               try:            lay.load_from_file(self._temp_file_out)
>>                                except: pass
>>                                self.end_result(result)
>>
>> @@ -815,23 +815,23 @@
>>                        while True:
>>
>>                                # test if povray exists
>> -                               if self.process.poll() != None:
>> +                               if self._process.poll() != None:
>>                                        update_image();
>>                                        break
>>
>>                                # user exit
>>                                if self.test_break():
>> -                                       try:            self.process.terminate()
>> +                                       try:            self._process.terminate()
>>                                        except: pass
>>
>>                                        break
>>
>>                                # Would be nice to redirect the output
>> -                               # stdout_value, stderr_value = self.process.communicate() # locks
>> +                               # stdout_value, stderr_value = self._process.communicate() # locks
>>
>>
>>                                # check if the file updated
>> -                               new_size = os.path.getsize(self.temp_file_out)
>> +                               new_size = os.path.getsize(self._temp_file_out)
>>
>>                                if new_size != prev_size:
>>                                        update_image()
>>
>> Modified: trunk/blender/release/scripts/modules/rna_prop_ui.py
>> ===================================================================
>> --- trunk/blender/release/scripts/modules/rna_prop_ui.py        2009-11-18 05:11:16 UTC (rev 24628)
>> +++ trunk/blender/release/scripts/modules/rna_prop_ui.py        2009-11-18 08:40:18 UTC (rev 24629)
>> @@ -100,7 +100,7 @@
>>             if convert_to_pyobject and not hasattr(val_orig, "len"):
>>                 row.itemL(text=val_draw)
>>             else:
>> -                row.itemR(rna_item, '["' + key + '"]', text="")
>> +                row.itemR(rna_item, '["%s"]' % key, text="")
>>
>>
>>             row = split.row(align=True)
>>
>> Modified: trunk/blender/source/blender/editors/curve/curve_ops.c
>> ===================================================================
>> --- trunk/blender/source/blender/editors/curve/curve_ops.c      2009-11-18 05:11:16 UTC (rev 24628)
>> +++ trunk/blender/source/blender/editors/curve/curve_ops.c      2009-11-18 08:40:18 UTC (rev 24629)
>> @@ -164,7 +164,7 @@
>>  void ED_keymap_curve(wmKeyConfig *keyconf)
>>  {
>>        wmKeyMap *keymap;
>> -       wmKeyMapItem *kmi;
>> +//     wmKeyMapItem *kmi;
>>
>>        keymap= WM_keymap_find(keyconf, "Font", 0, 0);
>>        keymap->poll= ED_operator_editfont;
>> @@ -251,7 +251,7 @@
>>        WM_keymap_add_item(keymap, "CURVE_OT_specials_menu", WKEY, KM_PRESS, 0, 0);
>>
>>        /* menus */
>> -       WM_keymap_add_item(keymap, "VIEW3D_MT_hook", HKEY, KM_PRESS, KM_CTRL, 0);
>> +       WM_keymap_add_menu(keymap, "VIEW3D_MT_hook", HKEY, KM_PRESS, KM_CTRL, 0);
>>
>>        ED_object_generic_keymap(keyconf, keymap, TRUE);
>>  }
>>
>> Modified: trunk/blender/source/blender/python/intern/bpy_rna.c
>> ===================================================================
>> --- trunk/blender/source/blender/python/intern/bpy_rna.c        2009-11-18 05:11:16 UTC (rev 24628)
>> +++ trunk/blender/source/blender/python/intern/bpy_rna.c        2009-11-18 08:40:18 UTC (rev 24629)
>> @@ -1625,11 +1625,10 @@
>>        if (prop==NULL) {
>>                // XXX - This currently allows anything to be assigned to an rna prop, need to see how this should be used
>>                // but for now it makes porting scripts confusing since it fails silently.
>> -#if 0
>> -               if (!BPy_StructRNA_CheckExact(self) && PyObject_GenericSetAttr((PyObject *)self, pyname, value) >= 0) {
>> +               // edit: allowing this for setting classes internal attributes.
>> +               if (name[0]=='_' && !BPy_StructRNA_CheckExact(self) && PyObject_GenericSetAttr((PyObject *)self, pyname, value) >= 0) {
>>                        return 0;
>>                } else
>> -#endif
>>                {
>>                        PyErr_Format( PyExc_AttributeError, "StructRNA - Attribute \"%.200s\" not found", name);
>>                        return -1;
>>
>>
>> _______________________________________________
>> Bf-blender-cvs mailing list
>> Bf-blender-cvs at blender.org
>> http://lists.blender.org/mailman/listinfo/bf-blender-cvs
>>
> _______________________________________________
> Bf-committers mailing list
> Bf-committers at blender.org
> http://lists.blender.org/mailman/listinfo/bf-committers
>



-- 
- Campbell


More information about the Bf-committers mailing list