@@ -11,6 +11,8 @@ from gssapi.raw.oids cimport OID
1111
1212from gssapi.raw.types import MechType
1313
14+ from enum import EnumMeta, Enum
15+
1416
1517cdef extern from " python_gssapi.h" :
1618 OM_uint32 gss_display_status(OM_uint32 * minor_status,
@@ -329,3 +331,64 @@ class GSSError(Exception):
329331 maj_str = maj_str,
330332 min_stat = self .min_code,
331333 min_str = min_str)
334+
335+
336+ # WARNING: FOR YOUR OWN PERSONAL SANITY, DO NOT TRY THIS AT HOME
337+ # This allows things like extensions declaring their own RequirementFlags
338+ # without having to worry about import order. There *might* be a cleaner
339+ # way to do this, but most of the ways probably exploit the interals of Enum
340+ class _EnumExtension (EnumMeta ):
341+ def __new__ (metacls , name , bases , classdict ):
342+ # find the base class that this overrides
343+
344+ base_attr = classdict.get(' __base__' , None )
345+
346+ if len (bases) != 1 or bases[0 ] is not object or base_attr is None :
347+ raise TypeError (" Enumeration extensions must be created as "
348+ " `ClassName(object)` and must contain the "
349+ " `__base__` attribute" )
350+
351+ adds_to = base_attr
352+ del classdict[' __base__' ]
353+
354+ bases = adds_to.__bases__
355+
356+ # we need to have the same Enum type
357+ if not issubclass (adds_to, Enum):
358+ raise TypeError (" Enumeration extensions must extend a subtype "
359+ " of Enum or directly sublcass object" )
360+
361+ # roughly preserve insertion order in Python 3.4+
362+ # (actually preserving order would require using parts of the Enum
363+ # implementation that aren't part of the spec)
364+ old_classdict = classdict
365+ classdict = metacls.__prepare__(name, bases)
366+
367+ # NB(directxman12): we can't use update, because that doesn't
368+ # trigger __setitem__, which thus won't update the _EnumDict correctly
369+ base_members = adds_to.__members__
370+ for k, v in base_members.items():
371+ classdict[k] = v.value
372+
373+ for k, v in old_classdict.items():
374+ if k in base_members:
375+ raise AttributeError (" Enumeration extensions cannot override "
376+ " existing enumeration members" )
377+
378+ classdict[k] = v
379+
380+ res = super (_EnumExtension, metacls).__new__(metacls, name,
381+ bases, classdict)
382+
383+ # replace the old with the new
384+ for k, v in res.__dict__ .items():
385+ if (k not in (' __module__' , ' __qualname__' , ' __doc__' ) and
386+ k in adds_to.__dict__ ):
387+ setattr (adds_to, k, v)
388+
389+ # preserve enum semantics
390+ for member in adds_to.__members__ .values():
391+ member.__class__ = adds_to
392+
393+ # always return the original
394+ return adds_to
0 commit comments