[Pyobjc-dev] Fwd: TypeError: cannot change a method
Brought to you by:
ronaldoussoren
From: Ronald O. <ron...@ma...> - 2009-07-17 06:09:08
|
Begin forwarded message: > From: Ronald Oussoren <ron...@ma...> > Date: 17 July, 2009 6:53:01 GMT+02:00 > To: Daniel Miller <mil...@gm...> > Subject: Re: [Pyobjc-dev] TypeError: cannot change a method > > > On 17 Jul, 2009, at 3:09, Daniel Miller wrote: >>> >> >> I'm not quite sure what to say other than I'll need to look into >> rewriting my test framework. FWIW, it seems to be possible to >> replace a method directly on the PyObjC type. For example: >> >> # this works >> fake = descriptor_mock() >> NSDocument.removeWindowController_ = fake >> >> Assuming the 'fake' object implements the descriptor protocol, the >> fake/mocked method will get called as expected. >> But it then it fails when trying to restore the original method: >> >> NSDocument.removeWindowController_ = original >> # TypeError: Assigning native selectors is not supported >> >> However, this seems to restore the original: >> >> del NSDocument.removeWindowController_ >> >> Strange... while I may be able to use this approach, it has the >> disadvantage of replacing the method on ALL instances of the type >> rather than on just a the instance that I'm testing--I may need to >> rewrite some tests to work with that restriction, but it probably >> wouldn't be the end of the world. > > You're not going to like this, but the behaviour you describe here > sounds like a bug. In particular, it is possible to overwrite an > existing method using a new function object but it should not be > possible to overwrite it with something else. Removing the fake > descriptor should also not result in revival of the original method > because a replacement method should result in a changed method in > the ObjC runtime. > > I need to think about your testing needs, if it is possible to > support those and if so how. > > A number of limititations in PyObjC, such as this one, are caused by > the need to interact with the Objective-C runtime. In particular > "objc.selector" objects for native methods are basicly references to > a named selector on the ObjC class, they do not contain a reference > to the code that will be called when you call the method. That's why > it is not possible to assign objc.selector instances to a class > attribute. > > BTW. How does your mocking library deal with other native types: > > >>> l = list() > >>> l.append = 42 > Traceback (most recent call last): > File "<stdin>", line 1, in <module> > AttributeError: 'list' object attribute 'append' is read-only > >>> > > Or more interesting, how does it deal with special methods like > __getitem__, those always get resolved through the class: > > >>> class List (list): pass > ... > >>> l = List() > >>> l.append(42) > >>> l[0] > 42 > >>> l.__getitem__ = 42 > >>> l[0] > 42 > >>> > > As you can see setting __getitem__ on an instance has no effect on > which special method is actually used. > > Ronald >> >> ~ Daniel >> > |