2

Trying to subclass mechanize.Browser class:

from mechanize import Browser

class LLManager(Browser, object):
    IS_AUTHORIZED = False
    def __init__(self, login = "", passw = "", *args, **kwargs):
        super(LLManager, self).__init__(*args, **kwargs)
        self.set_handle_robots(False)

But when I make something like this:

lm["Widget[LinksList]_link_1_title"] = anc

then I get an error:

Traceback (most recent call last):
  File "<pyshell#8>", line 1, in <module>
    lm["Widget[LinksList]_link_1_title"] = anc
TypeError: 'LLManager' object does not support item assignment

Browser class have overridden method __getattr__ as shown:

def __getattr__(self, name):
    # pass through _form.HTMLForm methods and attributes
    form = self.__dict__.get("form")
    if form is None:
        raise AttributeError(
            "%s instance has no attribute %s (perhaps you forgot to "
            ".select_form()?)" % (self.__class__, name))
    return getattr(form, name)

Why my class or instance don't get this method as in parent class?

SilentGhost
  • 307,395
  • 66
  • 306
  • 293
Крайст
  • 776
  • 1
  • 9
  • 22

3 Answers3

1

You need to override __setattr__ to support assignment in this fashion. __getattr__ is only for retrieval

Daniel DiPaolo
  • 55,313
  • 14
  • 116
  • 115
  • Browser class have no `__setattr__` methods. – Крайст Feb 03 '11 at 15:21
  • That's fine, you can create your own if you want. But this may be a clue that you may not *want* to do that because there's probably a good reason they only have one and not the other. – Daniel DiPaolo Feb 03 '11 at 15:22
  • What if I want same behaviour as in the parent class? I simply write: `br = Browser(); ...; br["some_input_name"] = "Blah..";` and it works finely for me. – Крайст Feb 03 '11 at 15:28
  • Pardon.. As **Rosh Oxymoron** said, my target methods are named `__getitem__` and `__setitem__`. – Крайст Feb 03 '11 at 15:38
1

There's difference between items and attributes. Items are accessed using ob[item], while attributes are accessed using ob.item. The methods that define item assignment are __getitem__ and __setitem__, and the second is required if you're going to set items, not only access them. The methods __getattr__, __setattr__ and __getattribute__ deal with attributes, and don't help you here, and besides, the last two should be avoided because they complicate the creation of your class too much.

Rosh Oxymoron
  • 20,355
  • 6
  • 41
  • 43
1

Don't inherit from object, mechanize.Browser doesn't use new style classes. This should work as expected.

from mechanize import Browser

class LLManager(Browser):
    IS_AUTHORIZED = False
    def __init__(self, login = "", passw = "", *args, **kwargs):
        mechanize.Browser.__init__(self, *args, **kwargs)
        self.set_handle_robots(False)
cerberos
  • 7,705
  • 5
  • 41
  • 43