Closed mahdialibi closed 5 months ago
@mahdialibi Thank you for the patch! Do you have a small example that fails before the patch that could be used as a unit test?
When we create an iterator class for example :
class MyNumbers:
def __iter__(self):
self.a = 1
return self
def __next__(self):
if self.a <= 20:
x = self.a
self.a += 1
return x
else:
raise StopIteration
when we use this iterator in a template with for each directive
<li py:for="number in mynember"
we will have an error
Traceback (most recent call last): File "/.../py3_deps_pypi__Genshi_0_7_7/genshi/template/directives.py", line 584, in _generate next(stream) # skip start tag StopIteration
@mahdialibi I added your example as a test case, but it doesn't fail without your patch. Looking at the code, it is clear why -- the next(stream)
calls the stream iterator (not the special iterator created in the test) and the stream alway has a first item, namely the tag being stripped.
Could you fix the test so that if fails before the patch and passes afterwards?
It turns out that the problem is in another location ! I have this code in a template
<div class="classz">
<input class="" type="text" name="" value="${client.get('emailAddress')}" readonly="true" maxlength="255" />
<py:choose>
<py:when test="client.get('emailAddress')" py:strip=""></py:when>
<py:otherwise>
<div class="help-class"><i class="class2"></i> Help text.</div>
</py:otherwise>
</py:choose>
</div>
I get the error
To get rid of this error I change my code like this:
<div class="classz">
<input class="" type="text" name="" value="${client.get('emailAddress')}" readonly="true" maxlength="255" />
<py:choose>
<py:when test="client.get('emailAddress')" ></py:when>
<py:otherwise>
<div class="help-class"><i class="class2"></i> Help text.</div>
</py:otherwise>
</py:choose>
</div>
so basically I delete the strip and all work again. the same thing if we make modifications in genshi code I am using Genshi 0.7.7 So I Think it's linked to strip directive when accessing any iterator . Yo have patched the same method "_generate" in other directives but not in the "strip" directive.
I hope this explanation help you.
@mahdialibi Could you please try write a failing test? I can guess why the template above might fail, but without an example to run that fails I will be going exactly that -- just guessing. As I already explained, the strip direction cannot fail in the way your original example suggests, and copying changes from elsewhere for a fix to a different issue that cannot occur here doesn't seem likely to be correct.
My guess is that something happens when py:when and py:strip try to remove the same directive, but it's hard to be sure without having a concrete example. If that is the case, perhaps this fix will be correct, but for entirely different reasons to the reason in the example you gave initially.
I'm closing this as its been stale for two years. Happy to re-open it at any point if it becomes active again.
With Python 3.7 there was changes in handling StopIteration as described in https://peps.python.org/pep-0479/, Here a patch to make correction for this problem