[Python-Dev] PEP 435 - ref impl disc 2 (original) (raw)
Glenn Linderman v+python at g.nevcal.com
Tue May 7 05:35:54 CEST 2013
- Previous message: [Python-Dev] PEP 435 - ref impl disc 2
- Next message: [Python-Dev] PEP 435 - ref impl disc 2
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
On 5/6/2013 6:26 PM, Ethan Furman wrote:
On 05/05/2013 01:01 AM, Glenn Linderman wrote:
The bigger problem is that the arithmetic on enumeration items, which seems like it should be inherited from NamedInt (and seems to be, because the third value from each print is a NamedInt), doesn't pick up "x" or "y", nor does it pick up "the-x" or "the-y", but rather, it somehow picks up the str of the value. Indeed, the bigger problem is that we ended up have an (NamedInt, Enum) wrapping a NamedInt, so we had both NEI.x.intname /and/ NEI.x.value.intname, and it was just one big mess. But I think it is solved. Try the new code. Here's what your example should look like:
OK. I notice you changed some super()s to specific int calls; I think I understand why, having recently reread about the specific problem that super() solves regarding diamond inheritance, and with that understanding, it is clear that super() is not always the right thing to use, particularly when unrelated classes may still have particular methods with name clashes (dunder methods would commonly have the same names in unrelated classes). So my use of super likely contributed to the multiple wrappings that you allude to above, although I haven't (yet) tried to figure out the exact details of how that happened.
class NamedInt( int ): def new( cls, *args, **kwds ): args = args name, *args = args if len( args ) == 0: raise TypeError("name and value must be specified") self = int.new( cls, *args, **kwds ) self.intname = name return self @property def name( self ): return self.intname def repr( self ): # repr() is updated to include the name and type info return "{}({!r}, {})".format(type(self).name, self.name, int.repr(self)) def str( self ): # str() is unchanged, even if it relies on the repr() fallback base = int basestr = base.str if basestr.objclass is object: return base.repr(self) return basestr(self) # for testing, we only define one operator that propagates expressions def add(self, other): temp = int( self ) + int( other ) if isinstance( self, NamedInt ) and isinstance( other, NamedInt ): return NamedInt( '({0} + {1})'.format(self.name, other.name), temp ) else: return temp class NEI( NamedInt, Enum ): x = ('the-x', 1 ) y = ('the-y', 2 )
I had tried this sort of constructor, thinking it should work, but couldn't tell that it helped or hindered, but it probably took eliminating the super() problem earlier, and likely your preservation of new in your ref435 changes, to enable this syntax to do what I expected it might. This certainly does allow the name definitions to be better grouped, even though still somewhat redundant.
It may take a subclass of the enum_type, as Nick was suggesting, to make the NamedInt and the enumeration member actually share a single name... but this (after fleshing out NamedInt with more operators) would be a functional method of producing enumerations for the various flag parameters in the Python API (that are mostly inherited from wrapped C APIs, I suppose... at least, I haven't found a need or benefit of creating flag parameters in new Python APIs that I have created).
NEI.x + NEI.y
And this works as expected, now. Can't say I still fully understand the changes, but the test case works, and the constructors for the NamedInt inside the NEI class works, so this is pretty much what I was hoping to be able when I started down this path... but since it found some issues that you were able to fix in ref435, I guess I wasn't totally wasting your time presenting the issue. Thanks for investigating, and fixing, rather than blowing it off, even given my amateurish presentation.
And I should have called this NIE, not NEI, because it was intended to stand for NamedIntEnum... but it is just a name, so doesn't affect the functionality.
N.B. In your latest ref435.py code, line 105, should be "An Enum class is final..." rather than "in". -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.python.org/pipermail/python-dev/attachments/20130506/e02045cf/attachment-0001.html>
- Previous message: [Python-Dev] PEP 435 - ref impl disc 2
- Next message: [Python-Dev] PEP 435 - ref impl disc 2
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]