@@ -18,23 +18,26 @@ def __init__(cls, name, bases, attrs, **kw):
1818 # We also include cls[None] -> primary class to "exit" a version class
1919 if getattr (cls , '_class_version' , None ) is None :
2020 cls ._class_version = None
21- cls ._VERSIONS = {None : weakref . proxy ( cls ) }
21+ cls ._VERSIONS = {}
2222
2323 def __getitem__ (cls , version ):
2424 # Use [] lookups to move from primary class to "versioned" classes
2525 # which are simple wrappers around the primary class but with a _version attr
2626 if cls ._class_version is not None :
27- return cls ._VERSIONS [None ][version ]
27+ primary_cls = cls .mro ()[1 ]
28+ if version is None :
29+ return primary_cls
30+ return primary_cls [version ]
2831 if cls ._valid_versions is not None :
2932 if version < 0 :
3033 version += 1 + cls .max_version # support negative index, e.g., [-1]
3134 if not cls .min_version <= version <= cls .max_version :
3235 raise ValueError ('Invalid version! min=%d, max=%d' % (cls .min_version , cls .max_version ))
36+ if version in cls ._VERSIONS :
37+ return cls ._VERSIONS [version ]
3338 klass_name = cls .__name__ + '_v' + str (version )
34- if klass_name in cls ._VERSIONS :
35- return cls ._VERSIONS [klass_name ]
36- cls ._VERSIONS [klass_name ] = type (klass_name , tuple (cls .mro ()), {'_class_version' : version }, init = False )
37- return cls ._VERSIONS [klass_name ]
39+ cls ._VERSIONS [version ] = type (klass_name , tuple (cls .mro ()), {'_class_version' : version }, init = False )
40+ return cls ._VERSIONS [version ]
3841
3942 def __len__ (cls ):
4043 # Maintain compatibility
@@ -84,10 +87,19 @@ def __init_subclass__(cls, **kw):
8487 if not cls .is_request ():
8588 ResponseClassRegistry .register_response_class (weakref .proxy (cls ))
8689
90+ def __new__ (cls , * args , ** kwargs ):
91+ # Translate "versioned" classes back to primary w/ version= kwarg on construction
92+ if cls ._class_version is not None :
93+ if kwargs .get ('version' , cls ._class_version ) != cls ._class_version : # pylint: disable=E1101
94+ raise ValueError ("Version has already been set by class" )
95+ kwargs ['version' ] = cls ._class_version
96+ instance = super ().__new__ (cls [None ])
97+ instance .__init__ (* args , ** kwargs )
98+ return instance
99+ return super ().__new__ (cls )
100+
87101 def __init__ (self , * args , ** kwargs ):
88102 self ._header = None
89- if 'version' not in kwargs :
90- kwargs ['version' ] = self ._class_version # pylint: disable=E1101
91103 super ().__init__ (* args , ** kwargs )
92104
93105 @classproperty
@@ -141,8 +153,6 @@ def API_VERSION(self):
141153
142154 @API_VERSION .setter
143155 def API_VERSION (self , version ):
144- if self ._class_version is not None and self ._class_version != version : # pylint: disable=E1101
145- raise ValueError ("Version has already been set by class" )
146156 if not 0 <= version <= self .max_version :
147157 raise ValueError ('Invalid version %s (max version is %s).' % (version , self .max_version ))
148158 self ._version = version
0 commit comments