Thread: Re: [Pyobjc-dev] Auto bridging instances by conversion (Page 2)
Brought to you by:
ronaldoussoren
From: Ronald O. <ous...@ci...> - 2003-02-04 07:04:10
|
On Monday, Feb 3, 2003, at 21:10 Europe/Amsterdam, Bob Ippolito wrote: [ interesting text removed] > Unfortunately this _still_ won't work with re.match (at least in > Jaguar's 2.2.0, I'd consider this a bug in re.match), but it *does* > work with open() Be warned that some (many?) C functions assume that if an object is an instance of PyString_Type (either directly or an instance of a subclass of str) they can use PyString_AS_STRING on it. The same thing is true for most other buildin types. This means the NS* types can never be a full substitute for native python types (which is really too bad). Ronald |
From: David E. <epp...@ic...> - 2003-02-04 07:37:49
|
On 2/4/03 8:03 AM +0100 Ronald Oussoren <ous...@ci...> wrote: > Be warned that some (many?) C functions assume that if an object is an > instance of PyString_Type (either directly or an instance of a subclass > of str) they can use PyString_AS_STRING on it. The same thing is true for > most other buildin types. This means the NS* types can never be a full > substitute for native python types (which is really too bad). What about the new Python 2.3 basestring type? Would inheriting from that convince callers that it's a string without letting them think they can use low-level string representation details? Of course, it would be bad if pyobjc required 2.3... -- David Eppstein UC Irvine Dept. of Information & Computer Science epp...@ic... http://www.ics.uci.edu/~eppstein/ |
From: <bb...@ma...> - 2003-02-03 15:02:56
|
We need unit tests. David: do you have a test case that demonstrates the mishandling of integers with NSUndoManager? If you could send it to me, I will integrate it into the test_nsundomanager.py in Lib/Foundation/test/. A unit test demonstrating the problem will ensure that we are all talking about the problem using the same vocabulary and expectations. On Monday, Feb 3, 2003, at 02:13 US/Eastern, Ronald Oussoren wrote: > Not too hard. There are (at least) two possible solutions: > > - David could use objc.selector to specify a signature that is more to > its liking (e.g. one of the > arguments is an int instead of an object). I don't really like this, > mostly because of the arcane > interface of selector() Wouldn't this require applying the objc.selector() to the undo manager? That seems problematic for a number of reasons. Of course, if David were to subclass NSUndoManager and apply the objc.selector() calls to that subclass, it wouldn't be a problem. I.e.: class FundoManager(NSUndoManager): setColorCount_ = objc.selector(None, selector="setColorCount:", signature="v@:i") If that is the case, it is a bummer, but not altogether too ugly save for the 'signature' argument. If we were to declare a handful of our own types, the signature could be defined as an array of type objects. Something like: signature = [VoidType, IDType, SelectorType, IntType] Actually, it really should be two different arguments to selector(): objc.selector(None, selector="setColorCount:", returnType=VoidType, argumentTypes=[IntType]) We can drop the IDType and SelectorType specs because every selector must take (id) and (SEL) as the first two arguments. > - We could treat NSNumber like a Python number when translating > arguments to Objective-C values. Doing > that would not be too hard. Or we could translate NSNumbers to > Python numbers when translating from > Objective-C values to Python values, but I don't think we should do > that. [For the following, the exact same discussion could be applied to floats/doubles] There are two distinct problems associated with handling integer types as a result of their being three different means of encapsulating an integer within a PyObjC based application. There is the native C (int) type, a Python IntType, and NSValue/NSNumber instances. The first problem is associated with converting (int) to Python IntTypes and back. This generally works fine in the current code base. Where it falls apart is in cases like the one David is describing with NSUndoManager. That is, when a method that takes an integer argument is invoked through the bridge against a proxy object that does not contain the signature of the method to be invoked. If the aforementioned potential fix doesn't work, I'm not sure what will. The second problem involves the bridging of NSNumber into Python numbers and vice versa. Currently, this doesn't appear to be broken. It is also not an issue in the context of David's problem. There may be some subtleties that could be cleaned up in this context, though. As mentioned in the "autobridging by conversion" message, it may be useful to create a custom subclass of NSValue that can encapsulate the various Python number types. This would allow us to preserve the python instance when a number comes back across the bridge. Not only does this increase transparency of the bridge, but it may also reduce memory footprint and increase performance [in that we would just recycle the python instance coming back]. b.bum |
From: Ronald O. <ous...@ci...> - 2003-02-03 15:56:17
|
On Monday, Feb 3, 2003, at 15:02 Europe/Amsterdam, bb...@ma... wrote: > We need unit tests. David: do you have a test case that > demonstrates the mishandling of integers with NSUndoManager? > > If you could send it to me, I will integrate it into the > test_nsundomanager.py in Lib/Foundation/test/. > > A unit test demonstrating the problem will ensure that we are all > talking about the problem using the same vocabulary and expectations. > > On Monday, Feb 3, 2003, at 02:13 US/Eastern, Ronald Oussoren wrote: >> Not too hard. There are (at least) two possible solutions: >> >> - David could use objc.selector to specify a signature that is more >> to its liking (e.g. one of the >> arguments is an int instead of an object). I don't really like >> this, mostly because of the arcane >> interface of selector() > > Wouldn't this require applying the objc.selector() to the undo > manager? That seems problematic for a number of reasons. Of > course, if David were to subclass NSUndoManager and apply the > objc.selector() calls to that subclass, it wouldn't be a problem. > > I.e.: > > class FundoManager(NSUndoManager): > setColorCount_ = objc.selector(None, selector="setColorCount:", > signature="v@:i") > It wouldn't be necessary, from what I understand the NSUndoManager will forward calls to methodSignatureForSelector: to the current target, e.g. you have to use the call to selector in the class that defines 'setColurCount:'. > If that is the case, it is a bummer, but not altogether too ugly save > for the 'signature' argument. If we were to declare a handful of our > own types, the signature could be defined as an array of type objects. > Something like: > > signature = [VoidType, IDType, SelectorType, IntType] > > Actually, it really should be two different arguments to selector(): > > objc.selector(None, selector="setColorCount:", > returnType=VoidType, argumentTypes=[IntType]) > > We can drop the IDType and SelectorType specs because every selector > must take (id) and (SEL) as the first two arguments. You can already use a variation on this theme: use 'return_type' and 'argument_types'. Both are specified using a subset of the Py_BuildValue syntax, argument_types should not describe self and _cmd. I prefer this to your proposal because Py_BuildValue will be familiar to at least some python programmers. BTW. We do have documentation for this (-: >>> import objc >>> help(objc.selector) Help on class selector in module objc: class selector(__builtin__.object) | selector(function, [, signature] [, selector] [, class_method=0] | [, return_type] [, argument_types] [, required=True]) -> selector | | Return an Objective-C method from a function. The other arguments | specify attributes of the Objective-C method. | | function: | A function object with at least one argument. The first argument will | be used to pass 'self'. This argument may be non when defineing an | informal_protocol object. | selector: | The name of the Objective-C method. The default value of this | attribute is the name of the function, with all underscores replaced | by colons. | signature: | Method signature for the Objective-C method. This should be a raw | Objective-C method signature, including specifications for 'self' and | '_cmd'. The default value a signature that describes a method with | arguments of type 'id' and a return-value of the same type. | argument_types, return_type: | Alternative method for specifying the method signature. Return_type is | return type and argument_types describes the list of arguments. The | return_type is optional and defaults to 'void' (e.g. no return value). | Both are specified using a subset of the Py_BuildValue syntax: | - s, z, S: an NSString (id) | - b: a byte (char) | - h: a short integer (short int) | - i: an integer (int) | - l: a long integer (long int) | - c: a single character (char) | - f: a single precision float (float) | - d: a double precision float (double) | - O: any object (id) | It is not allowed to specify both 'argument_types' and 'signature' | class_method: | True if the method is a class method, false otherwiserequired: | True if this is a required method in an informal protocol, false | otherwise. The default value is 'True'. This argument is only used | when defining an 'informal_protocol' object. | > >> - We could treat NSNumber like a Python number when translating >> arguments to Objective-C values. Doing >> that would not be too hard. Or we could translate NSNumbers to >> Python numbers when translating from >> Objective-C values to Python values, but I don't think we should do >> that. > > [For the following, the exact same discussion could be applied to > floats/doubles] > > There are two distinct problems associated with handling integer types > as a result of their being three different means of encapsulating an > integer within a PyObjC based application. There is the native C > (int) type, a Python IntType, and NSValue/NSNumber instances. > > The first problem is associated with converting (int) to Python > IntTypes and back. This generally works fine in the current code > base. Where it falls apart is in cases like the one David is > describing with NSUndoManager. That is, when a method that takes an > integer argument is invoked through the bridge against a proxy object > that does not contain the signature of the method to be invoked. That is not a problem with the bridge, but in the way it is used: The bridge cannot know that the user expects an int/float instead of an object unless it is told so. > > If the aforementioned potential fix doesn't work, I'm not sure what > will. > > The second problem involves the bridging of NSNumber into Python > numbers and vice versa. Currently, this doesn't appear to be broken. > It is also not an issue in the context of David's problem. There > may be some subtleties that could be cleaned up in this context, > though. As mentioned in the "autobridging by conversion" message, it > may be useful to create a custom subclass of NSValue that can > encapsulate the various Python number types. This would allow us to > preserve the python instance when a number comes back across the > bridge. Not only does this increase transparency of the bridge, but > it may also reduce memory footprint and increase performance [in that > we would just recycle the python instance coming back]. This *is* a problem in the context of David's problem. He is passing an object ("coincidently" an Python int) through the Objective-C runtime from Python to Python. In the process this object is translated into a completely different object. We could automaticly translate NSNumber objects to Python numbers, that would solve most, if not all, problems with passing numbers 'through' Objective-C. However, this is not entirely trivial: You must take care to extract the right kind of basic type from the NSNumber otherwise you'd loose information. BTW. If we do this some of the unit tests will fail (those that abuse NSArray to create NSNumber objects). Hmm, that is not really a problem: NSNumber objects would completely disappear from user code. Ronald |
From: David E. <epp...@ic...> - 2003-02-03 16:00:03
|
On 2/3/03 9:02 AM -0500 bb...@ma... wrote: > We need unit tests. David: do you have a test case that demonstrates > the mishandling of integers with NSUndoManager? > > If you could send it to me, I will integrate it into the > test_nsundomanager.py in Lib/Foundation/test/. I can write a test, but first I have to know what I am testing for. Is it a bug that undoManager converts int to Cocoa integer? That Cocoa integers remain unconverted when sent back to the Python side? Or that I can't send a Cocoa integer to a method that expects an int? My feeling is that the first two are ok and the third is a problem, but I'm not seeing a concensus on this. -- David Eppstein UC Irvine Dept. of Information & Computer Science epp...@ic... http://www.ics.uci.edu/~eppstein/ |
From: <bb...@ma...> - 2003-02-03 16:38:44
|
On Monday, Feb 3, 2003, at 10:59 US/Eastern, David Eppstein wrote: > I can write a test, but first I have to know what I am testing for. > Is it a bug that undoManager converts int to Cocoa integer? > That Cocoa integers remain unconverted when sent back to the Python > side? > Or that I can't send a Cocoa integer to a method that expects an int? If you aren't sure, don't worry about it.... Just write a test that demonstrates the problem that you are experiencing. The development team can figure out what the bug is and break up the test for clarification, if necessary, or fix the problem directly. Some testing is better than no testing at all, even if the test is not of the same granularity as the underlying code/problem/feature it is testing. b.bum |