Issue5211
This issue tracker has been migrated to GitHub,
and is currently read-only.
For more information,
see the GitHub FAQs in the Python's Developer Guide.
Created on 2009-02-10 23:19 by mark.dickinson, last changed 2022-04-11 14:56 by admin. This issue is now closed.
Files | ||||
---|---|---|---|---|
File name | Uploaded | Description | Edit | |
issue-5211-patch | meador.inge, 2010-02-06 15:11 | patch against 2.7 trunk | ||
unnamed | gumtree, 2010-11-28 22:40 |
Messages (25) | |||
---|---|---|---|
msg81612 - (view) | Author: Mark Dickinson (mark.dickinson) * | Date: 2009-02-10 23:19 | |
In the 'coercion rules' section of the reference manual, at: http://docs.python.org/dev/reference/datamodel.html#id5 it says: """Over time, the type complex may be fixed to avoid coercion.""" In 3.x, the complex type has (necessarily) been fixed to avoid coercion, and it ought to be a fairly easy task to backport that fix to 2.7, for someone who wants to get his or her feet wet with some CPython hacking. As far as I can see, there's no great benefit in such a change, except that the presence of coercion for the complex type causes confusion occasionally: see issue 3734 for an example of this. |
|||
msg81633 - (view) | Author: Mark Dickinson (mark.dickinson) * | Date: 2009-02-11 08:56 | |
Comment by gumtree copied from issue3734 discussion: > While Mark Dickinson's patch fixes the documentation, it does not offer > a solution to the original problem, which was rooted in a need to > provide special behaviour based on the numeric types. I made the > original posting because I hoped that this problem could be resolved. gumtree, would you be interested in working on a patch for this feature- request? As mentioned above, the necessary changes are already present in 3.x, so all that's entailed is figuring out which bits of the Object/complexobject.c in the py3k source need to be transferred to the trunk, and making sure that everything's properly tested. Alternatively, could you explain in a little more detail why this change is important to you? Subclassing complex doesn't seem like a very common thing to want to do, so I'm curious about your use case. |
|||
msg81694 - (view) | Author: Blair (gumtree) | Date: 2009-02-12 00:40 | |
I am happy to collaborate in finding a solution, but I do not have enough knowledge or skill to work with the code alone. Simply documenting it does not remove the frustration that a few people will enounter. The key point being that you can subclass the other numeric types, but not complex. Worse, you may think that you have succeeded in subclassing complex too, because it is only when the __ropn__ binary operators are used that the type reverts to the base class type. Would you want to subclass a numeric type? I agree, it is a bit obsure, but I did a search on this before making the post and there have been others who found the problem too. In my case, I think that the motivation may seem a bit obscure. I had developed some numerical-like types (from scratch -- no subclassing) and I wanted to be able to write functions taking as possible arguments these types and Python numerical types indifferently. I realised that I could not achieve exactly what I wanted, however, by subclassing float, int, etc I could add a few methods that would allow my generic functions to work with either my types or the subclassed Python types. At the same time, the subclassed numerical types could still be used as numerical quantities (float, int,...). It seemed like a pretty elegant solution. If that explanation does not make sense, then I suppose other simpler motivations could be, eg, to subclass float so that only positive values are acceptable; to subclass complex so that only values lying within the unit circle are acceptable, etc. That is, one might like to define a type that can only take on physically meaningful values (mass cannot be negative, a complex reflection coeffcieint cannot have a magnitude greater than unity, ..) So, my feeling is that this is worth fixing because the work done on float, int etc, is clearly useful and it appears (to me) that the complex case is an oversight. |
|||
msg98714 - (view) | Author: Meador Inge (meador.inge) * | Date: 2010-02-02 04:23 | |
Mark, Is this still of interest? I found the relevant changes in py3k, but I am not sure it is the behavior that gumtree is expecting. Since py3k removes coercion completely, the test case from issue 3734 would just issue: Traceback (most recent call last): File "test-5211.py", line 34, in <module> print type(z + xz) File "test-5211.py", line 5, in __coerce__ t = complex.__coerce__(self,other) AttributeError: type object 'complex' has no attribute '__coerce__' Where as I think gumtree wants the xcomplex case to behave as the xfloat case, e.g. <class '__main__.xfloat'> <class '__main__.xcomplex'> Since coercion is getting axed in py3k, I don't think it makes sense to provide this behavior. On the other hand, as you mentioned, the removal of coercion from complex could be backported. However, if we are going to do that then we might as well just backport the whole removal of coercion instead of just the bits from 'complexobject.c'. Bascially checkins r51431 and r58226. |
|||
msg98784 - (view) | Author: Mark Dickinson (mark.dickinson) * | Date: 2010-02-03 14:12 | |
Yes, I'd certainly be interested in reviewing a patch. Though the current behaviour is at most a minor wart, and since it's gone in Python 3.x the motivation to fix it isn't huge. :) > Where as I think gumtree wants the xcomplex case to behave as > the xfloat case, e.g. ... Yes, that was what I was proposing. But as you point out, the new behaviour wouldn't even match the behaviour of Python 3.x, so it really wouldn't be a terribly useful change. > However, if we are going to do that then we might as well just > backport the whole removal of coercion. That's not really an option: it has the potential to break existing code that uses coercion. Removing coercion in Python 2.x would require at least a PEP plus one version's worth of DeprecationWarning. And given that it currently looks as though Python 2.8 isn't likely to happen at all, that would likely be a wasted effort. |
|||
msg98798 - (view) | Author: Blair (gumtree) | Date: 2010-02-03 20:39 | |
I also agree that this bug was never more than a small wart. However, I'm now curious. If Python 3 does not support coercion, I think that it will not be possible to write something like my xfloat class, derived from float (i.e., some binary operations between an xfloat and a float would return a float instead of an xfloat). If I am correct in think that it would seem to be a step backward. Will Python 3 deal with mixed types in some other way, or has this problem been abandoned altogether? If it is the latter, I think it is a pity. |
|||
msg98810 - (view) | Author: Meador Inge (meador.inge) * | Date: 2010-02-04 02:54 | |
> Mark > > Yes, that was what I was proposing. As you pointed out in issue 3734, the patch is basically: =================================================================== --- Objects/complexobject.c (revision 77909) +++ Objects/complexobject.c (working copy) @@ -1282,7 +1282,8 @@ PyObject_GenericGetAttr, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES + | Py_TPFLAGS_BASETYPE, /* tp_flags */ complex_doc, /* tp_doc */ 0, /* tp_traverse */ 0, /* tp_clear */ plus the relevant test cases and documentation changes. > Mark > > That's not really an option: it has the potential to break existing > code that uses coercion. Removing coercion in Python 2.x would > require at least a PEP plus one version's worth of DeprecationWarning. Ah, good point. In that case I am -1 on changing the behavior at all. For the sole reason that cases like Blair originally reported would not work as expected in version < 2.7, then would work in 2.7, and then would break again in > 3.0. I think explaining and documenting the change in behavior would be really confusing. > Blair > > If I am correct in think that it would seem to be a step backward. I disagree. I think type coercion (or implicit conversions) is hard to follow and understand. I say this from many years of C and C++ programming. I see bugs all of the time in these languages due to conversions silently happening that the programmer was not aware of. Yes the feature is convenient, but documenting and explaining these rules to programmers becomes very tedious and requires that most programmers have deep understanding of the languages typing rules. This typically leads to books like "Effective C++" that catalog a list of things *not* to do in a language. The relevant case for C++ being to avoid user defined conversions and use explicit constructers. As such, I am definitely +1 on removing coercion. |
|||
msg98811 - (view) | Author: Blair (gumtree) | Date: 2010-02-04 03:48 | |
OK. I have gone back to the beginning to refresh my memory and I see a possible point of misunderstanding. I am not sure that we are really talking about the problem that prompted my initial report (msg72169, issue 3734). Immediately following my message, Daniel Diniz confirmed the bug and expanded on my code with an xfloat class of his own that uses __coerce__. In fact, if I had submitted an xfloat class it would have been the following class xfloat( float ): def __new__(cls,*args,**kwargs): return float.__new__(cls,*args,**kwargs) def __add__(self,x): return xfloat( float.__add__(self,x) ) def __radd__(self,x): return xfloat( float.__radd__(self,x) ) My xfloat works fine in 2.6.4 and it was my wish, at the time, to write a class for xcomplex that behaved in a similar way. According to the Python manual, that should have been possible, but it wasn't. So, I guess coercion is not really the problem. However, there does seem to be something wrong with the complex type. I have looked at the manual for Python 3 and see that the same rules apply for classes that emulate numeric types, namely: "If the right operand’s type is a subclass of the left operand’s type and that subclass provides the reflected method for the operation, this method will be called before the left operand’s non-reflected method. This behavior allows subclasses to override their ancestors’ operations." The question I have then is will the following work in Python 3 (it doesn't in 2.6.4)? class xcomplex( complex ): def __new__(cls,*args,**kwargs): return complex.__new__(cls,*args,**kwargs) ## def __coerce__(self,other): ## t = complex.__coerce__(self,other) ## try: ## return (self,xcomplex(t[1])) ## except TypeError: ## return t def __add__(self,x): return xcomplex( complex.__add__(self,x) ) def __radd__(self,x): return xcomplex( complex.__radd__(self,x) ) xz = xcomplex(1+2j) xy = float(10.0) z = complex(10+1j) print "would like xcomplex type each time" print type(xz + z) print type(xz + xy) print type(xz + 10) print type(xy + xz) print type(10 + xz) print type(z + xz) |
|||
msg98828 - (view) | Author: Mark Dickinson (mark.dickinson) * | Date: 2010-02-04 11:48 | |
Blair: I don't think you'll have any problems getting the behaviour you in Python 3. For example: Python 3.2a0 (py3k:77952, Feb 4 2010, 10:56:12) [GCC 4.2.1 (Apple Inc. build 5646) (dot 1)] on darwin Type "help", "copyright", "credits" or "license" for more information. >>> class xcomplex(complex): ... def __add__(self, other): return xcomplex(complex(self) + other) ... __radd__ = __add__ ... >>> xz = xcomplex(1+2j) >>> all(type(xz + y) is type(y + xz) is xcomplex for y in (1, 10.0, 10+1j, xz)) True So I don't consider that the removal of coerce and the __coerce__ magic method is a step backward: it still allows mixed-type operations, but without coerce the rules for those operations are significantly cleaner. The real problem case in 2.6.4 seems to be when doing <instance of complex> + <instance of xcomplex>: in this case, Python first calls complex.__coerce__ (which returns its arguments unchanged), then complex.__add__. None of the xcomplex methods even gets a look in, so there's no opportunity to force the return type to be xcomplex. If you look at the source (see particularly the binary_op1 function in Objects/abstract.c ) you can see where this behaviour is coming from. The complex type (along with its subclasses) is classified as an 'old-style' number, while ints, longs and floats are 'new-style' (note that this has nothing to do with the distinction between old-style and new-style classes). Operations between new-style numbers use the scheme described in the documentation, but where old-style numbers are involved there's an extra coercion step. In particular, when adding a complex to an xcomplex, the rule you quoted (about the case when the right operand is an instance of a subclass of the class of the left operand) isn't applied. It's too risky to change the general behaviour for old-style numbers: I don't think there are any old-style numbers besides complex in the Python code, but there may well be some in third party extensions. Certainly documenting it better would be an option, and making complex a new-style number for Python 2.7 seems like a reasonable thing to consider. |
|||
msg98829 - (view) | Author: Mark Dickinson (mark.dickinson) * | Date: 2010-02-04 11:52 | |
> As you pointed out in issue 3734, the patch is basically: > <snipped patch that adds Py_TPFLAGS_CHECKTYPES> Yes, that's the essence of it. In addition, each of the functions implementing a complex special method would need to do its own argument conversion. (Compare the implementation of complex_add in py3k with that in trunk.) |
|||
msg98830 - (view) | Author: Mark Dickinson (mark.dickinson) * | Date: 2010-02-04 11:59 | |
> Yes, that was what I was proposing. But as you point out, the new > behaviour wouldn't even match the behaviour of Python 3.x, so it really > wouldn't be a terribly useful change. Hmm. I take this back: if complex were made 'new-style' in 2.7, then it *would* be possible to write fairly obvious code (not using coerce or __coerce__) that operated in the same way in both 2.7 and 3.2. So I still think it's worth considering. |
|||
msg98941 - (view) | Author: Meador Inge (meador.inge) * | Date: 2010-02-06 15:11 | |
> if complex were made 'new-style' in 2.7, then it *would* be possible to > write fairly obvious code (not using coerce or __coerce__) that operated > in the same way in both 2.7 and 3.2. So I still think it's worth > considering. Agreed. I have attached a patch with src, test, and doc changes. |
|||
msg98971 - (view) | Author: Mark Dickinson (mark.dickinson) * | Date: 2010-02-06 23:26 | |
Thanks. I'll try to find time to look at this tomorrow. |
|||
msg99653 - (view) | Author: Mark Dickinson (mark.dickinson) * | Date: 2010-02-21 12:58 | |
Apologies for the delay; tomorrow was a long time coming... The patch looks great---thank you! I added a ".. versionchanged" note to the documentation, and fixed a couple of whitespace issues; apart from that I didn't change anything. Applied in r78280. |
|||
msg99691 - (view) | Author: Mark Dickinson (mark.dickinson) * | Date: 2010-02-21 22:15 | |
I must have been operating on autopilot; not only did I forget to put the issue number in the checkin message, but I forgot to acknowledge Meador Inge for the patch. Fixed now, with apologies to Meador. |
|||
msg99697 - (view) | Author: Meador Inge (meador.inge) * | Date: 2010-02-22 00:30 | |
> I added a ".. versionchanged" note to the documentation, and fixed a > couple of whitespace issues; Thanks. I checked out the changes you made so that I will know what to do next time :). > Fixed now, with apologies to Meador. No worries. Thanks for applying the patch! |
|||
msg106757 - (view) | Author: Mark Dickinson (mark.dickinson) * | Date: 2010-05-30 12:13 | |
r78280 didn't remove the implicit coercion for rich comparisons; that's now been done in r81606. |
|||
msg122432 - (view) | Author: Blair (gumtree) | Date: 2010-11-26 03:45 | |
Hi Mark, I thought that this had all been fixed, but it seems not. Consider the following: class xcomplex( complex ): def __new__(cls,*args,**kwargs): return complex.__new__(cls,*args,**kwargs) def __add__(self,x): return xcomplex( complex.__add__(self,x) ) def __radd__(self,x): print "larg: ", type(x),"returning: ", return xcomplex( complex.__radd__(self,x) ) class xfloat(float): def __new__(cls,*args,**kwargs): return float.__new__(cls,*args,**kwargs) def __add__(self,x): return xfloat( float.__add__(self,x) ) def __radd__(self,x): print "larg: ", type(x),"returning: ", return xfloat( float.__radd__(self,x) ) z = 1j xz = xcomplex(1j) f = 1.0 xf = xfloat(1.0) print print "-----------" print "expect xcomplex:", type(z + xz) print "expect xcomplex:", type(f + xz) print "expect xfloat:", type(f + xf) print "expect ???:", type(z + xf) When this runs, the first three conversions are fine, the last is not: there is no call to xfloat.__radd__. It seems that the builtin complex type simply thinks it is dealing with a float. Here is the output ----------- expect xcomplex: larg: <type 'complex'> returning: <class '__main__.xcomplex'> expect xcomplex: larg: <type 'float'> returning: <class '__main__.xcomplex'> expect xfloat: larg: <type 'float'> returning: <class '__main__.xfloat'> expect ???: <type 'complex'> The last line shows that no call to __radd__ occurred. Is there anything that can be done now about this now, or is it just too late? Regards Blair At 01:13 a.m. 31/05/2010, you wrote: Mark Dickinson <dickinsm@gmail.com> added the comment: r78280 didn't remove the implicit coercion for rich comparisons; that's now been done in r81606. ---------- _______________________________________ Python tracker <report@bugs.python.org> <http://bugs.python.org/issue5211> _______________________________________Python tracker < report@bugs.python.org> |
|||
msg122453 - (view) | Author: Mark Dickinson (mark.dickinson) * | Date: 2010-11-26 13:12 | |
I think that's expected behaviour. Note that int vs float behaves in the same way as float vs complex: >>> class xint(int): ... def __radd__(self, other): ... print "__radd__" ... return 42 ... >>> 3 + xint(5) __radd__ 42 >>> 3.0 + xint(5) # xint.__radd__ not called. 8.0 As with your example, the float.__add__ method is happy to deal with an int or an instance of any subclass of int. |
|||
msg122472 - (view) | Author: Blair (gumtree) | Date: 2010-11-26 18:41 | |
I see your point Mark, however it does not seem to be the right way to do this. Are you aware that Python has formally specified this behaviour somewhere? I could not find an explicit reference in the documentation. The problem that has been fixed is covered in the documentation: (3.4.8. Emulating numeric types: Note If the right operand’s type is a subclass of the left operand’s type and that subclass provides the reflected method for the operation, this method will be called before the left operand’s non-reflected method. This behavior allows subclasses to override their ancestors’ operations.) This rule is needed so that mixed-type arithmetic operations do not revert to the ancestor's type. However, one would expect that different numeric types (int float complex) would all behave in a similar way. For example, xi = xint(3) 3 + xi # is an xint(6) 3.0 + xi # is float(6) This is the same problem as the one that has been fixed from a practical point of view. Such behaviour is not going to be useful (IMO). It seems to me that xint.__radd__ would need to be called if the left operand is a subclass of any of the number types (in this case, isinstance(left_op,numbers.Complex) == True). Am I missing something? Mark Dickinson <dickinsm@gmail.com> added the comment: I think that's expected behaviour. Note that int vs float behaves in the same way as float vs complex: ... def __radd__(self, other): ... print "__radd__" ... return 42 ... >>> 3 + xint(5) __radd__ 42 >>> 3.0 + xint(5) # xint.__radd__ not called. 8.0 As with your example, the float.__add__ method is happy to deal with an int or an instance of any subclass of int. ---------- _______________________________________ Python tracker <report@bugs.python.org> <http://bugs.python.org/issue5211> _______________________________________ |
|||
msg122499 - (view) | Author: Blair (gumtree) | Date: 2010-11-27 02:05 | |
I'd like to add a few more observations to the mix. I have run the following in both 2.6.6 and in 2.7 class xfloat(float): def __new__(cls,x): return float.__new__(cls,x) def __radd__(self,lhs): print "__radd__ got: %s" % type(lhs) if isinstance(lhs,(int,float)): return xfloat( float(self) + lhs ) else: return NotImplemented xf = xfloat(9.0) cases = dict(int=1,float=1.0,complex=1.0+1j) for k,v in cases.items(): y = v + xf print "%s + xfloat" % k print type(y) print y In 2.7 this gives: __radd__ got: <type 'int'> int + xfloat <class '__main__.xfloat'> 10.0 __radd__ got: <type 'float'> float + xfloat <class '__main__.xfloat'> 10.0 complex + xfloat <type 'complex'> (10+1j) In 2.6.6 I get: __radd__ got: <type 'int'> int + xfloat <class '__main__.xfloat'> 10.0 __radd__ got: <type 'float'> float + xfloat <class '__main__.xfloat'> 10.0 __radd__ got: <type 'complex'> complex + xfloat <type 'complex'> (10+1j) They are the same except for the last case. My feeling is that the behaviour of 2.6.6 (for subclassing float) is correct. The behaviour of 2.6.6 is needed to enable you to implement the commutative property of addition (ie, you expect to get the same outcome from x+y or y+x), which I would say is a pretty fundamental requirement. I have also tried the following class xint(int): def __new__(cls,x): return int.__new__(cls,x) def __radd__(self,lhs): print "__radd__ got: %s" % type(lhs) if isinstance(lhs,(int,)): return xint( float(self) + lhs ) else: return NotImplemented print print "-------------------" xf = xint(9) cases = dict(int=1,float=1.0,complex=1.0+1j) for k,v in cases.items(): y = v + xf print "%s + xint" % k print type(y) print y In 2.6.6 I get __radd__ got: <type 'int'> int + xint <class '__main__.xint'> 10 float + xint <type 'float'> 10.0 __radd__ got: <type 'complex'> complex + xint <type 'complex'> (10+1j) and in 2.7 ------------------- __radd__ got: <type 'int'> int + xint <class '__main__.xint'> 10 float + xint <type 'float'> 10.0 complex + xint <type 'complex'> (10+1j) In my opinion, 2.6.6 was faulty in the float + xint case, for the same reasons as above, and 2.7 is faulty in both float + xint and complex + xint. |
|||
msg122659 - (view) | Author: Mark Dickinson (mark.dickinson) * | Date: 2010-11-28 14:34 | |
> In my opinion, 2.6.6 was faulty in the float + xint case, for the same > reasons as above, and 2.7 is faulty in both float + xint and complex + > xint. Well, I disagree: Python is behaving as designed and documented in these cases. If you want to argue that the *design* decisions are the wrong ones, then I'd suggest opening a discussion on the python-ideas mailing list, where more people are likely to get involved---this tracker isn't really the right place for that sort of discussion. Leaving complex out of the mix for the moment, it sounds to me as though you'd like, e.g., <float> + <subclass of int> to call the int subclass's __radd__ method (if it exists) before calling the float's __add__ method. Is that correct? Or are you suggesting that float's __add__ method shouldn't accept instances of subclasses of int at all? (i.e., that float.__add__ should return NotImplemented when given an instance of xint). In the first case, you need to come up with general semantics that would give you the behaviour you want for float and xint---e.g., when given numeric objects x and y, what general rule should Python apply to decide whether to call x.__add__ or y.__radd__ first? In the second case, I'd argue that you're going against the whole idea of object-oriented programming; by making xint a subclass of int, you're declaring that its instances *are* 'ints' in a very real sense, so it's entirely reasonable for float's __add__ method to accept them. In either case, note that Python 2.x is not open for behaviour changes, only for bugfixes. Since this isn't a bug (IMO), such changes could only happen in 3.x. Please take further discussion to the python-ideas mailing list. |
|||
msg122724 - (view) | Author: Blair (gumtree) | Date: 2010-11-28 20:32 | |
Just to keep this discussion as clear as possible Mark, it was your first option that I suggest is needed. When that is done (as it was for a subclass of float in 2.6.6) it is possible for the author of the subclass to implement commutative binary operations (like + and * that must behave the same regardless of argument order). Otherwise (as far as I can see) this cannot be done. On Mon, Nov 29, 2010 at 5:04 AM, Mark Dickinson <report@bugs.python.org>wrote: > > Changes by Mark Dickinson <dickinsm@gmail.com>: > > > Removed file: http://bugs.python.org/file19820/unnamed > > _______________________________________ > Python tracker <report@bugs.python.org> > <http://bugs.python.org/issue5211> > _______________________________________ > |
|||
msg122727 - (view) | Author: Mark Dickinson (mark.dickinson) * | Date: 2010-11-28 20:46 | |
> Just to keep this discussion as clear as possible Mark, it was your > first option that I suggest is needed. Okay, so you want <float instance> + <xint instance> to try xint.__radd__ before float.__add__. How do you propose this be achieved? Can you explain exactly what semantics you'd like to see? You've indicated what you want to happen for float and xint, but how should Python behave in general here? In particular, when evaluating 'x + y' for general Python objects x and y, what rule or rules should Python use to decide whether to try x.__add__(y) or y.__radd__(x) first? It seems you want some general mechanism that results in xint being 'preferred' to float, in the sense that xint.__radd__ and xint.__add__ will be tried in preference to float.__add__ and float.__radd__ (respectively). But it's not clear to me what criterion Python would use to determine which out of two types (neither one inheriting from the other) should be 'preferred' in this sense. |
|||
msg122742 - (view) | Author: Blair (gumtree) | Date: 2010-11-28 22:40 | |
I am not really the person (I don't know how Python is implemented) to explain how the correct behaviour should be achieved (sorry). I do appreciate that this may seem like exceptional behaviour. Numbers are a bit different. However, for what its worth, I think that the 'correct behaviour' was implemented for subclasses of float and was working in Python 2.6, but not now in 2.7. I don't know how the earlier implementation was done, but it does work (I have used it to develop a nice little math library). Would there be any documentation about the implementation? I would say that the semantics do not need to apply to arbitrary Python objects. The problem arises for numeric type subclasses when they are mixed with non-subclassed numeric types. In that case: For 'x opn y' any binary operator (like +,*, etc), if (and only if) 'x' is a built-in numeric type (int, long, float, complex) and 'y' is a subclass of a built-in numeric type, then y.__ropn__(x) (if it exists) should be called before x.__opn__(y). If that were done, then subclasses of number types can implement commutative operator properties. Otherwise, I don't think it works properly. I see this as 'special' behaviour required of the int, long, float and complex classes, rather than special behaviour for all Python objects. If both 'x' and 'y' are subclasses of built in number types the required behaviour seems too complicated to specify. I would be inclined to do nothing special. That is, if both 'x' and 'y' are derived from built in numeric classes (possibly different types) then x.__opn__(y) would be called. And should this apply to non-number types? I think not. Numbers deserve special treatment. I hope this helps. On Mon, Nov 29, 2010 at 9:48 AM, Mark Dickinson <report@bugs.python.org>wrote: > > Changes by Mark Dickinson <dickinsm@gmail.com>: > > > Removed file: http://bugs.python.org/file19859/unnamed > > _______________________________________ > Python tracker <report@bugs.python.org> > <http://bugs.python.org/issue5211> > _______________________________________ > |
History | |||
---|---|---|---|
Date | User | Action | Args |
2022-04-11 14:56:45 | admin | set | github: 49461 |
2010-11-28 22:40:11 | gumtree | set | files:
+ unnamed messages: + msg122742 |
2010-11-28 20:48:33 | mark.dickinson | set | files: - unnamed |
2010-11-28 20:46:15 | mark.dickinson | set | messages: + msg122727 |
2010-11-28 20:32:29 | gumtree | set | files:
+ unnamed messages: + msg122724 |
2010-11-28 16:04:10 | mark.dickinson | set | files: - unnamed |
2010-11-28 16:04:00 | mark.dickinson | set | files: - unnamed |
2010-11-28 16:03:47 | mark.dickinson | set | files: - unnamed |
2010-11-28 14:34:24 | mark.dickinson | set | messages: + msg122659 |
2010-11-27 02:05:06 | gumtree | set | files:
+ unnamed messages: + msg122499 |
2010-11-26 18:41:23 | gumtree | set | files:
+ unnamed messages: + msg122472 |
2010-11-26 13:12:33 | mark.dickinson | set | messages: + msg122453 |
2010-11-26 03:45:04 | gumtree | set | files:
+ unnamed messages: + msg122432 |
2010-05-30 12:13:29 | mark.dickinson | set | messages: + msg106757 |
2010-02-22 00:30:42 | meador.inge | set | messages: + msg99697 |
2010-02-21 22:15:01 | mark.dickinson | set | messages: + msg99691 |
2010-02-21 12:58:44 | mark.dickinson | set | status: open -> closed resolution: accepted messages: + msg99653 stage: resolved |
2010-02-06 23:26:57 | mark.dickinson | set | assignee: mark.dickinson messages: + msg98971 |
2010-02-06 15:11:09 | meador.inge | set | files:
+ issue-5211-patch messages: + msg98941 |
2010-02-04 11:59:21 | mark.dickinson | set | messages: + msg98830 |
2010-02-04 11:52:31 | mark.dickinson | set | messages: + msg98829 |
2010-02-04 11:49:00 | mark.dickinson | set | messages: + msg98828 |
2010-02-04 03:48:40 | gumtree | set | messages: + msg98811 |
2010-02-04 02:54:39 | meador.inge | set | messages: + msg98810 |
2010-02-03 20:39:41 | gumtree | set | messages: + msg98798 |
2010-02-03 14:12:08 | mark.dickinson | set | messages: + msg98784 |
2010-02-02 04:23:34 | meador.inge | set | nosy:
+ meador.inge messages: + msg98714 |
2009-02-12 00:40:48 | gumtree | set | messages: + msg81694 |
2009-02-11 08:56:53 | mark.dickinson | set | nosy:
+ gumtree messages: + msg81633 |
2009-02-10 23:19:22 | mark.dickinson | create |