jsocol/bleach — pull request #136 by GVRV (2014-12-10 03:54:38+00:00)
Title: Fix edge cases where anchor element occurs as the first element within a...

... parent element.

This fixes a not-so-obscure edge case where an anchor element can be present as the first element within any other element. The data below can illustrate the point better.

Let my text be:
`text = '

Something

'`

And my custom callback be:
```python
def attr_callback(attrs, new):
if '/buy/' in attrs.get('href', '') or '/shop/' in attrs.get('href', ''):
attrs['_text'] = ''
return None
```

When I run `bleach.linkify(text, callbacks=[attr_callback])`

Without the patch, I get:

```python
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
in ()
----> 1 bleach.linkify(text, callbacks=[attr_callback])

/home/gaurav/.virtualenvs/k3/local/lib/python2.7/site-packages/bleach/__init__.pyc in linkify(text, callbacks, skip_pre, parse_email, tokenizer)
357
358 try:
--> 359 linkify_nodes(forest)
360 except RuntimeError as e:
361 # If we hit the max recursion depth, just return what we've got.

/home/gaurav/.virtualenvs/k3/local/lib/python2.7/site-packages/bleach/__init__.pyc in linkify_nodes(tree, parse_text)
296 linkify_nodes(node, False)
297 elif not (node in _seen):
--> 298 linkify_nodes(node, True)
299
300 current_child += 1

/home/gaurav/.virtualenvs/k3/local/lib/python2.7/site-packages/bleach/__init__.pyc in linkify_nodes(tree, parse_text)
275 # tag replaced by the text within it
276 adj = replace_nodes(tree, _text, node,
--> 277 current_child)
278 current_child -= 1
279 # pull back current_child by 1 to scan the

/home/gaurav/.virtualenvs/k3/local/lib/python2.7/site-packages/bleach/__init__.pyc in replace_nodes(tree, new_frag, node, index)
146 if new_tree.text:
147 if index == 0:
--> 148 tree.text += new_tree.text
149 else:
150 tree[index-1].tail += new_tree.text

TypeError: unsupported operand type(s) for +=: 'NoneType' and 'unicode'
```

With the patch, I get:

`u'

Something

'`

Which is what I understand I should be getting according to the documentation. I can add the test case for this case if indeed it is the intended behaviour. Else, it would be nice to change the documentation to make it clearer how we'd go about such a case.