Repository: MechanicalSoup/MechanicalSoup

Issue:
Allow passing a Tag object to StatefulBrowser.select_form
Hi,
I've recently had to select a form based on its children and the only way I found to do that is:
```py
buttons = browser.get_current_page().select("form > button[name=apply]")
browser._StatefulBrowser__current_form = mechanicalsoup.Form(buttons[0].parent)
browser.submit_selected()
```
Could you consider adding something like `if isinstance(selector, bs4.element.Tag): …` to `select_form` ?

Discussion:
moy: Looks good to me.

Patch:
diff --git a/mechanicalsoup/stateful_browser.py b/mechanicalsoup/stateful_browser.py
index a233f6d..b96dc1b 100644
--- a/mechanicalsoup/stateful_browser.py
+++ b/mechanicalsoup/stateful_browser.py
@@ -177,7 +177,8 @@ class StatefulBrowser(Browser):
     def select_form(self, selector="form", nr=0):
         """Select a form in the current page.
 
-        :param selector: CSS selector to identify the form to select.
+        :param selector: CSS selector or a bs4.element.Tag object to identify
+            the form to select.
             If not specified, ``selector`` defaults to "form", which is
             useful if, e.g., there is only one form on the page.
             For ``selector`` syntax, see the `.select() method in BeautifulSoup
@@ -191,8 +192,17 @@ class StatefulBrowser(Browser):
         :return: The selected form as a soup object. It can also be
             retrieved later with :func:`get_current_form`.
         """
-        # nr is a 0-based index for consistency with mechanize
-        found_forms = self.get_current_page().select(selector, limit=nr + 1)
+        if isinstance(selector, bs4.element.Tag):
+            if selector.name == "form":
+                self.__state.form = Form(selector)
+                return self.get_current_form()
+            else:
+                raise LinkNotFoundError()
+        else:
+            # nr is a 0-based index for consistency with mechanize
+            found_forms = self.get_current_page().select(selector,
+                                                         limit=nr + 1)
+
         if len(found_forms) != nr + 1:
             if self.__debug:
                 print('select_form failed for', selector)


Test patch:
diff --git a/tests/test_stateful_browser.py b/tests/test_stateful_browser.py
index 942ea0b..fba91c9 100644
--- a/tests/test_stateful_browser.py
+++ b/tests/test_stateful_browser.py
@@ -353,6 +353,18 @@ def test_select_form_nr():
             browser.select_form(nr=3)
 
 
+def test_select_form_tag_object():
+    """Test tag object as selector parameter type"""
+    forms = """<form id="a"></form><form id="b"></form><p></p>"""
+    soup = BeautifulSoup(forms, "lxml")
+    with mechanicalsoup.StatefulBrowser() as browser:
+        browser.open_fake_page(forms)
+        form = browser.select_form(soup.find("form", {"id": "b"}))
+        assert form.form['id'] == "b"
+        with pytest.raises(mechanicalsoup.LinkNotFoundError):
+            browser.select_form(soup.find("p"))
+
+
 def test_referer_follow_link(httpbin):
     browser = mechanicalsoup.StatefulBrowser()
     browser.open(httpbin.url)