Reputation: 5465
I'm attempting to use mechanize (v0.2.5) to work with a form on a page that has a disabled image as one of the form elements. When I try to select the form, mechanize raises an AttributeError: control 'test' is disabled
where test
is the name of the disabled control. For example,
br = mechanize.Browser(factory=mechanize.RobustFactory())
br.open("http://whatever...")
br.select_form(nr=0)
Leads to this stack trace:
br.select_form(nr=0)
File "build\bdist.win32\egg\mechanize\_mechanize.py", line 499, in select_form
File "build\bdist.win32\egg\mechanize\_html.py", line 544, in __getattr__
File "build\bdist.win32\egg\mechanize\_html.py", line 557, in forms
File "build\bdist.win32\egg\mechanize\_html.py", line 237, in forms
File "build\bdist.win32\egg\mechanize\_form.py", line 844, in ParseResponseEx
File "build\bdist.win32\egg\mechanize\_form.py", line 1017, in _ParseFileEx
File "build\bdist.win32\egg\mechanize\_form.py", line 2735, in new_control
File "build\bdist.win32\egg\mechanize\_form.py", line 2336, in __init__
File "build\bdist.win32\egg\mechanize\_form.py", line 1221, in __setattr__
AttributeError: control 'test' is disabled
Examining the mechanize source code, it looks as if this error will always be raised when there is any form element that evaluates to a mechanize.SubmitControl
and that has no pre-defined value
attribute. For example, the following form would raise the same error:
<form action="http://whatever" method="POST">
<input name="test" type="submit" disabled="disabled" />
</form>
I'm not sure if this should count as a bug, but in any case is there a workaround? For instance, is there a way I can alter the HTML of the target page to enable the disabled controls before I call br.select_form()
?
EDIT
I've submitted a patch to mechanize that fixes this problem.
Upvotes: 9
Views: 2786
Reputation: 20476
Sadly it's been more than a year and the mechanize upstream has still not merged the pull request.
Meanwhile you can use this monkey-patch I wrote to work around the bug without needing to manually install a patched version. Hopefully this bug will be resolved when (if) 0.2.6 is released, so the patch only applies to versions 0.2.5 and earlier.
def monkeypatch_mechanize():
"""Work-around for a mechanize 0.2.5 bug. See: https://github.com/jjlee/mechanize/pull/58"""
import mechanize
if mechanize.__version__ < (0, 2, 6):
from mechanize._form import SubmitControl, ScalarControl
def __init__(self, type, name, attrs, index=None):
ScalarControl.__init__(self, type, name, attrs, index)
# IE5 defaults SUBMIT value to "Submit Query"; Firebird 0.6 leaves it
# blank, Konqueror 3.1 defaults to "Submit". HTML spec. doesn't seem
# to define this.
if self.value is None:
if self.disabled:
self.disabled = False
self.value = ""
self.disabled = True
else:
self.value = ""
self.readonly = True
SubmitControl.__init__ = __init__
Upvotes: 8
Reputation: 6987
This is definitely a bug, reporting it upstream, making a patch, submitting it upstream and using patched version in the meantime is fairly right way to deal with it. (Thanks for choosing that way.)
As you mentioned, another approach is working it around by pre-processing source HTML (that may be useful if you're in hurry, or can't/don't want to use patched version for some reason, but note that workarounds doesn't help the community). For post-processing, any suitable method can be used - ranging from str.replace() to DOM-level processing with BeautifulSoup or lxml.
Upvotes: 0