Repository: MechanicalSoup/MechanicalSoup

Issue:
Crash on input without name in form
I am currently dealing with a form containing a submit button without a name. When submitting this form (with multiple submit buttons) via
```
browser.submit_selected(btnName='name')
```
this causes a crash in `Form.choose_submit()` since the attribute `name` is not present, [here](https://github.com/MechanicalSoup/MechanicalSoup/blob/master/mechanicalsoup/form.py#L310).

I now that inputs without a name do not make any sense, but it would be nice to harden MechanicalSoup against websites out there in the wild... :)

Discussion:

Patch:
diff --git a/mechanicalsoup/form.py b/mechanicalsoup/form.py
index 7819535..285fac6 100644
--- a/mechanicalsoup/form.py
+++ b/mechanicalsoup/form.py
@@ -307,7 +307,8 @@ class Form(object):
         found = False
         inps = self.form.select('input[type="submit"], button[type="submit"]')
         for inp in inps:
-            if inp == submit or inp['name'] == submit:
+            if inp == submit or (inp.has_attr('name') and
+                                 inp['name'] == submit):
                 if found:
                     raise LinkNotFoundError(
                         "Multiple submit elements match: {0}".format(submit)


Test patch:
diff --git a/tests/test_form.py b/tests/test_form.py
index 4f89422..a97a5b4 100644
--- a/tests/test_form.py
+++ b/tests/test_form.py
@@ -350,5 +350,21 @@ def test_form_print_summary(capsys):
     assert err == ""
 
 
+def test_issue180():
+    """Test that a KeyError is not raised when Form.choose_submit is called
+    on a form where a submit element is missing its name-attribute."""
+    browser = mechanicalsoup.StatefulBrowser()
+    html = '''
+<form>
+  <input type="submit" value="Invalid" />
+  <input type="submit" name="valid" value="Valid" />
+</form>
+'''
+    browser.open_fake_page(html)
+    form = browser.select_form()
+    with pytest.raises(mechanicalsoup.utils.LinkNotFoundError):
+        form.choose_submit('not_found')
+
+
 if __name__ == '__main__':
     pytest.main(sys.argv)