twilio/twilio-python — Issue #33: Bug in TwiML Verb generation
Author: erikcw
Created: 2011-10-27 21:32:31+00:00
State: open

There is a bug in the __init__() method of Verb class on line 25 that is stripping valid attributes from the XML output.
https://github.com/twilio/twilio-python/blob/master/twilio/twiml.py

The problem is in this loop of __init__()

```python
for k, v in kwargs.items():
if k == "sender":
k = "from"
if v:
self.attrs[k] = v
```

That second conditional on the "v" variable drops all attributes that are False, 0, or an empty string (''). The Conference verb is supposed to accept both boolean values (for attributes such as beep) and emptry strings for waitUrl
http://www.twilio.com/docs/api/twiml/conference

A more correct implementation is probably something like this:

```python
import types

for k, v in kwargs.items():
if k == "sender":
k = "from"
if type(v) is not types.NoneType:
self.attrs[k] = v
```

Here is a unit test that demonstrates the problem:
https://gist.github.com/1320881

Additionally, the Verb.xml() method does not handle booleans correctly. All of the Twilio documentation illustrates booleans being expected in all lower case.

The xml() method however uses the following line to generate attributes:

```python
el.set(a, str(self.attrs[a]))
```

In Python, this converts True into "True" (not "true").

To produce XML output consistent with the Twilio documentation, you should do something like this:

```python
import types

def xml(self):
el = ET.Element(self.name)

keys = self.attrs.keys()
keys.sort()
for a in keys:
value = self.attrs[a]
if type(value) is bool:
value = str(value).lower()
elif type(value) is types.NoneType:
continue #skip attributes with a value of None
else:
value = str(value)
el.set(a, value)

if self.body:
el.text = self.body

for verb in self.verbs:
el.append(verb.xml())

return el
```