[wwwsearch-commits] r35825 - in wwwsearch/mechanize/trunk: . mechanize test
jjlee at codespeak.net
jjlee at codespeak.net
Sat Dec 16 03:04:56 CET 2006
Author: jjlee
Date: Sat Dec 16 03:04:49 2006
New Revision: 35825
Modified:
wwwsearch/mechanize/trunk/mechanize/_html.py
wwwsearch/mechanize/trunk/mechanize/_mechanize.py
wwwsearch/mechanize/trunk/setup.py
wwwsearch/mechanize/trunk/test/test_browser.doctest
Log:
Add .global_form() method to Browser to support form controls whose HTML elements are not descendants of any FORM element
Modified: wwwsearch/mechanize/trunk/mechanize/_html.py
==============================================================================
--- wwwsearch/mechanize/trunk/mechanize/_html.py (original)
+++ wwwsearch/mechanize/trunk/mechanize/_html.py Sat Dec 16 03:04:49 2006
@@ -165,6 +165,9 @@
"""Makes a sequence of objects satisfying ClientForm.HTMLForm interface.
+ After calling .forms(), the .global_form attribute is a form object
+ containing all controls not a descendant of any FORM element.
+
For constructor argument docs, see ClientForm.ParseResponse
argument docs.
@@ -187,25 +190,28 @@
self.backwards_compat = backwards_compat
self._response = None
self.encoding = None
+ self.global_form = None
def set_response(self, response, encoding):
self._response = response
self.encoding = encoding
+ self.global_form = None
def forms(self):
import ClientForm
encoding = self.encoding
- return ClientForm.ParseResponse(
+ forms = ClientForm.ParseResponseEx(
self._response,
select_default=self.select_default,
form_parser_class=self.form_parser_class,
request_class=self.request_class,
- backwards_compat=self.backwards_compat,
encoding=encoding,
_urljoin=_rfc3986.urljoin,
_urlparse=_rfc3986.urlsplit,
_urlunparse=_rfc3986.urlunsplit,
)
+ self.global_form = forms[0]
+ return forms[1:]
class TitleFactory:
def __init__(self):
@@ -416,6 +422,9 @@
is_html: true if response contains an HTML document (XHTML may be
regarded as HTML too)
title: page title, or None if no title or not HTML
+ global_form: form object containing all controls that are not descendants
+ of any FORM element, or None if the forms_factory does not support
+ supplying a global form
"""
@@ -461,7 +470,7 @@
self._response = response
self._forms_genf = self._links_genf = None
self._get_title = None
- for name in ["encoding", "is_html", "title"]:
+ for name in ["encoding", "is_html", "title", "global_form"]:
try:
delattr(self, name)
except AttributeError:
@@ -485,14 +494,21 @@
else:
self.title = None
return self.title
+ elif name == "global_form":
+ self.forms()
+ return self.global_form
finally:
self._response.seek(0)
def forms(self):
"""Return iterable over ClientForm.HTMLForm-like objects."""
+ # this implementation sets .global_form as a side-effect, for benefit
+ # of __getattr__ impl
if self._forms_genf is None:
self._forms_genf = CachingGeneratorFunction(
self._forms_factory.forms())
+ self.global_form = getattr(
+ self._forms_factory, "global_form", None)
return self._forms_genf()
def links(self):
Modified: wwwsearch/mechanize/trunk/mechanize/_mechanize.py
==============================================================================
--- wwwsearch/mechanize/trunk/mechanize/_mechanize.py (original)
+++ wwwsearch/mechanize/trunk/mechanize/_mechanize.py Sat Dec 16 03:04:49 2006
@@ -347,6 +347,24 @@
raise BrowserStateError("not viewing HTML")
return self._factory.forms()
+ def global_form(self):
+ """Return the global form object, or None if the factory implementation
+ did not supply one.
+
+ The "global" form object contains all controls that are not descendants of
+ any FORM element.
+
+ The returned form object implements the ClientForm.HTMLForm interface.
+
+ This is a separate method since the global form is not regarded as part
+ of the sequence of forms in the document -- mostly for
+ backwards-compatibility.
+
+ """
+ if not self.viewing_html():
+ raise BrowserStateError("not viewing HTML")
+ return self._factory.global_form
+
def viewing_html(self):
"""Return whether the current response contains HTML data."""
if self._response is None:
@@ -379,6 +397,10 @@
interface, so you can call methods like .set_value(), .set(), and
.click().
+ Another way to select a form is to assign to the .form attribute. The
+ form assigned should be one of the objects returned by the .forms()
+ method.
+
At least one of the name, predicate and nr arguments must be supplied.
If no matching form is found, mechanize.FormNotFoundError is raised.
Modified: wwwsearch/mechanize/trunk/setup.py
==============================================================================
--- wwwsearch/mechanize/trunk/setup.py (original)
+++ wwwsearch/mechanize/trunk/setup.py Sat Dec 16 03:04:49 2006
@@ -53,7 +53,7 @@
## open("mechanize/_mechanize.py").read())
## VERSION = unparse_version(str_to_tuple(VERSION_MATCH.group(1)))
VERSION = "0.1.6b"
-INSTALL_REQUIRES = ["ClientForm>=0.2.5, ==dev"]
+INSTALL_REQUIRES = ["ClientForm>=0.2.6, ==dev"]
NAME = "mechanize"
PACKAGE = True
LICENSE = "BSD" # or ZPL 2.1
Modified: wwwsearch/mechanize/trunk/test/test_browser.doctest
==============================================================================
--- wwwsearch/mechanize/trunk/test/test_browser.doctest (original)
+++ wwwsearch/mechanize/trunk/test/test_browser.doctest Sat Dec 16 03:04:49 2006
@@ -98,3 +98,27 @@
>>> r = br.open(req)
>>> test_state(br)
True
+
+
+.global_form() is separate from the other forms (partly for backwards-
+compatibility reasons).
+
+>>> from mechanize._response import test_response
+>>> br = TestBrowser2()
+>>> html = """\
+... <html><body>
+... <input type="text" name="a" />
+... <form><input type="text" name="b" /></form>
+... </body></html>
+... """
+>>> response = test_response(html, headers=[("Content-type", "text/html")])
+>>> br.global_form()
+Traceback (most recent call last):
+BrowserStateError: not viewing any document
+>>> br.set_response(response)
+>>> len(list(br.forms()))
+1
+>>> iter(br.forms()).next().find_control(nr=0).name
+'b'
+>>> br.global_form().find_control(nr=0).name
+'a'
More information about the wwwsearch-commits
mailing list