New field on a dexterity behavior not showing up

Let me explain it:

I have a dexterity content type (IArticle) which has a behavior (INewspaperIssue). There are a lot of IArticle objects created in production and working.

Now I just added (on my laptop) a new field to INewspaperIssue, and if I get with a pdb on an IArticle object typing obj.my_new_field returns an AttributeError, while adding a new field on the IArticle interface does return None.

Is this behavior (pun not intended) expected? I just need to guard all accesses to my_new_field with a getattr(obj, 'my_new_field', None)?

Any help/pointers is gladly appreciated.

Check the usage of the context_property() implemenation. Passing a default value to the getter()
implementation and the underlaying getattr() call might help you.


Generally speaking, you can't assume that you can access a behavior's
field values via attribute access on the content item. The behavior
adapter has the right to store the data somewhere else if it wants. The
correct way to access the field is INewspaperIssue(obj).my_new_field

The correct way is also the broken-by-design way. But we had already this discussion with about how a natural API from a developers point must look like and how it is actually implemented in reality.
So when a content-types is composed of multiple behaviors then you have to figure out as a developer which is is handled by which interface..that's programming nightmare and against the keep-it-simple principle. I thought we wanted to make Plone more approachable for new developers but the opposite is happening. You really cannot communicate such a programming approach for composite types to non-Plone developers. Either they laugh at you or they cry.

@gforcada: for the sake of simplicity: attribute access is fine as long as you know how the behavior is implemented.


Do you have specific ideas about how to fix it? Or are you just
complaining? I don't really like it either, but changing it at this
point is not trivial.

In doubt add old-style set(key, value) and get(key) methods hiding the behavior lookup...but this is not my point. I made my point multiple times clearly. There is a problem with marketing Plone to non-Plone developers. The promise of Dexterity was to be more consistent, more easy, more Pythonic and in particular a better learning experience than with Archetypes. For exactly those reason a customer with its own dev team decided to go from Plone 2.X to Plone 4.3 with Dexerity. Disillusion and frustration bring the mood of the customer to the point. In this particular case the official way for dealing with behaviors can not be called pythonic. It works this way because we are still addicted by the ZCA. The ZCA might work well as long as you don't expose it to public as part of a somewhat public API. By public API I mean: something that an average programmer would use - something in the league of plone.api.. Those behavior adapters should never ever be visible to average programmers - they ruin the programmer experience. They lead to frustrated programmers and frustrated programmers spread a bad word Plone - and it is hard to convince people staying with Plone. And this is exactly one reason of the reasons why Plone is stagnating. Many customers no longer see Plone as a viable options and switch to other systems. I could name at least five. Not to mention the various issues with, and - intended for Plone 4.3 or not - customer frustration was noticable.


On 03-07-14 18:33, davisagli wrote:

Do you have specific ideas about how to fix it?

In the meantime a useful workaround for this can be to provide an
upgrade step that initializes the new "behavior field" on the context
objects. I.e. if a behavior introduces a new attribute .foo and stores
that on the context as, loop over all existing objects which
have the behavior applied and make sure is initialized.

At least that's what I'm doing on my projects to keep the
accessor illusion intact.


 Guido Stevens  |  +31.43.3618933  |

 s o c i a l   k n o w l e d g e   t e c h n o l o g y