Børge Kjeldstad wrote at 2011-7-4 23:21 +0200:
>Anyway: I did your:
> > putting a breakpoint ("import pdb; pdb.set_trace()")
> > into the "except TypeError" block of
> > "plone.app.folder.nextprevious(getNextItem)"
>It gave the following results:
>2011-07-04 23:01:01 INFO Zope Ready to handle requests
>-> next = ordering.idsInOrder()[pos + 1]
> 26 try:
> 27 try: # first try `__getitem__`
> 28 next = ordering[pos + 1]
> 29 except TypeError:
> 30 import pdb; pdb.set_trace()
> 31 -> next = ordering.idsInOrder()[pos + 1]
> 32 return self.getData(self.context[next])
> 33 except IndexError: # in case next > len(folder)
> 34 return None
> 36 def getPreviousItem(self, obj):
>['obj', 'ordering', 'pdb', 'pos', 'self']
This proves the hypothesis that "pos" (wrongly) is "None".
To find out why, you can use one of the PDB "debug" or "j[ump]" commands.
"debug" allows you to interactively examine the evaluation of a command.
In your case, this would be the command that has produced the wrong
value for "pos".
"jump" allows you to transfer (execution) control to a different line (with
some restrictions). You may be able to use it to reexecute the
wrong "pos = ..." assignment under your control and examine it.
After both "debug" and "jump", you would use "s[tep]" (step into function
call) "n[ext]" (step over function call), "r[eturn]" (leave function call)
to control the execution and "p[rint]", "pp" (pretty print),
"args" to examine the state.
><plone.app.folder.nextprevious.NextPrevious object at 0x7a3ac90>
>....end of snip...
>I then opened the file
>It's content is :
>from Acquisition import aq_base
>from zope.interface import implements
>from zope.component import adapts
>from plone.folder.interfaces import IOrdering, IOrderableFolder
> """ This implementation provides no ordering. """
>There I see:
> return None
This may explain the wrong "None" which is causing the difficulty
For me, this looks like a bug in "plone.app.folder".
When Plone expects that some folders do not support the next/previous
functionality (because they are unordered), this functionality
should be automatically disabled for those folders.
You could try to add as a workaround a line:
if pos is None: return None
after the "pos" assignment in "nextprevious".
If this solves your problem, please file a bug report against
>Can this be the error? Maybe I should comment out the "return None" and
>see what happens?
>By the way: I also googled your function "definedBy". Is it this one
>(and how is it used)?:
>def definedBy(name, class_):
> '''return *class_* base class defining *name*.
> *class_* may (now) also be an object. In this case, its class is used.
It is. However, it might be an old version (one which does not
yet use the method resolution order in newer Python versions).
Should you see problems, you may tell me and I will look whether
I can provide a newer version.
How is it used?
Well, I am a strong protagonist of well chosen names
and terse but concise documentation. Usually, you can have
confidence in the names I have chosen.
You see here a function with name "definedBy" and arguments
"name" and "class_". Its name suggests that "definedBy(name, cls)"
tells you where "name" is defined in the context of "cls".
The function's docstring tells you that the result is the defining
class (from which you can ask the module, the class is defined in).
The docstring also tells you that you can pass an object rather
than a class and that the object's class is used in this case.
As an example: in order to find out which class
defines "idsInOrder" after you entered your breakpoint above,
you could use "!import DUtils; DUtils.definedBy('idsInOrder', ordering)"
(this assumes, that "DUtils.py" has been placed somewhere where
Python looks for modules, e.g. the current working directory).
If you have the class, its "__module__" attribute tells you the module.