Team Ai
Datasetpublic

codekingpro/portable-devtools

sourceHugging Faceupdated 5mo agoView on Hugging Face
1likes14kdownloads
enum.py2169 linesDownload Raw Back to Lib
1import sys2import builtins as bltns3from types import MappingProxyType, DynamicClassAttribute4 5 6__all__ = [7        'EnumType', 'EnumMeta', 'EnumDict',8        'Enum', 'IntEnum', 'StrEnum', 'Flag', 'IntFlag', 'ReprEnum',9        'auto', 'unique', 'property', 'verify', 'member', 'nonmember',10        'FlagBoundary', 'STRICT', 'CONFORM', 'EJECT', 'KEEP',11        'global_flag_repr', 'global_enum_repr', 'global_str', 'global_enum',12        'EnumCheck', 'CONTINUOUS', 'NAMED_FLAGS', 'UNIQUE',13        'pickle_by_global_name', 'pickle_by_enum_name',14        ]15 16 17# Dummy value for Enum and Flag as there are explicit checks for them18# before they have been created.19# This is also why there are checks in EnumType like `if Enum is not None`20Enum = Flag = EJECT = _stdlib_enums = ReprEnum = None21 22class nonmember(object):23    """24    Protects item from becoming an Enum member during class creation.25    """26    def __init__(self, value):27        self.value = value28 29class member(object):30    """31    Forces item to become an Enum member during class creation.32    """33    def __init__(self, value):34        self.value = value35 36def _is_descriptor(obj):37    """38    Returns True if obj is a descriptor, False otherwise.39    """40    return (41            hasattr(obj, '__get__') or42            hasattr(obj, '__set__') or43            hasattr(obj, '__delete__')44            )45 46def _is_dunder(name):47    """48    Returns True if a __dunder__ name, False otherwise.49    """50    return (51            len(name) > 4 and52            name[:2] == name[-2:] == '__' and53            name[2] != '_' and54            name[-3] != '_'55            )56 57def _is_sunder(name):58    """59    Returns True if a _sunder_ name, False otherwise.60    """61    return (62            len(name) > 2 and63            name[0] == name[-1] == '_' and64            name[1] != '_' and65            name[-2] != '_'66            )67 68def _is_internal_class(cls_name, obj):69    # do not use `re` as `re` imports `enum`70    if not isinstance(obj, type):71        return False72    qualname = getattr(obj, '__qualname__', '')73    s_pattern = cls_name + '.' + getattr(obj, '__name__', '')74    e_pattern = '.' + s_pattern75    return qualname == s_pattern or qualname.endswith(e_pattern)76 77def _is_private(cls_name, name):78    # do not use `re` as `re` imports `enum`79    pattern = '_%s__' % (cls_name, )80    pat_len = len(pattern)81    if (82            len(name) > pat_len83            and name.startswith(pattern)84            and (name[-1] != '_' or name[-2] != '_')85        ):86        return True87    else:88        return False89 90def _is_single_bit(num):91    """92    True if only one bit set in num (should be an int)93    """94    if num == 0:95        return False96    num &= num - 197    return num == 098 99def _make_class_unpicklable(obj):100    """101    Make the given obj un-picklable.102 103    obj should be either a dictionary, or an Enum104    """105    def _break_on_call_reduce(self, proto):106        raise TypeError('%r cannot be pickled' % self)107    if isinstance(obj, dict):108        obj['__reduce_ex__'] = _break_on_call_reduce109        obj['__module__'] = '<unknown>'110    else:111        setattr(obj, '__reduce_ex__', _break_on_call_reduce)112        setattr(obj, '__module__', '<unknown>')113 114def _iter_bits_lsb(num):115    # num must be a positive integer116    original = num117    if isinstance(num, Enum):118        num = num.value119    if num < 0:120        raise ValueError('%r is not a positive integer' % original)121    while num:122        b = num & (~num + 1)123        yield b124        num ^= b125 126def show_flag_values(value):127    return list(_iter_bits_lsb(value))128 129def bin(num, max_bits=None):130    """131    Like built-in bin(), except negative values are represented in132    twos-complement, and the leading bit always indicates sign133    (0=positive, 1=negative).134 135    >>> bin(10)136    '0b0 1010'137    >>> bin(~10)   # ~10 is -11138    '0b1 0101'139    """140 141    num = num.__index__()142    ceiling = 2 ** (num).bit_length()143    if num >= 0:144        s = bltns.bin(num + ceiling).replace('1', '0', 1)145    else:146        s = bltns.bin(~num ^ (ceiling - 1) + ceiling)147    sign = s[:3]148    digits = s[3:]149    if max_bits is not None:150        if len(digits) < max_bits:151            digits = (sign[-1] * max_bits + digits)[-max_bits:]152    return "%s %s" % (sign, digits)153 154class _not_given:155    def __repr__(self):156        return('<not given>')157_not_given = _not_given()158 159class _auto_null:160    def __repr__(self):161        return '_auto_null'162_auto_null = _auto_null()163 164class auto:165    """166    Instances are replaced with an appropriate value in Enum class suites.167    """168    def __init__(self, value=_auto_null):169        self.value = value170 171    def __repr__(self):172        return "auto(%r)" % self.value173 174class property(DynamicClassAttribute):175    """176    This is a descriptor, used to define attributes that act differently177    when accessed through an enum member and through an enum class.178    Instance access is the same as property(), but access to an attribute179    through the enum class will instead look in the class' _member_map_ for180    a corresponding enum member.181    """182 183    member = None184    _attr_type = None185    _cls_type = None186 187    def __get__(self, instance, ownerclass=None):188        if instance is None:189            if self.member is not None:190                return self.member191            else:192                raise AttributeError(193                        '%r has no attribute %r' % (ownerclass, self.name)194                        )195        if self.fget is not None:196            # use previous enum.property197            return self.fget(instance)198        elif self._attr_type == 'attr':199            # look up previous attribute200            return getattr(self._cls_type, self.name)201        elif self._attr_type == 'desc':202            # use previous descriptor203            return getattr(instance._value_, self.name)204        # look for a member by this name.205        try:206            return ownerclass._member_map_[self.name]207        except KeyError:208            raise AttributeError(209                    '%r has no attribute %r' % (ownerclass, self.name)210                    ) from None211 212    def __set__(self, instance, value):213        if self.fset is not None:214            return self.fset(instance, value)215        raise AttributeError(216                "<enum %r> cannot set attribute %r" % (self.clsname, self.name)217                )218 219    def __delete__(self, instance):220        if self.fdel is not None:221            return self.fdel(instance)222        raise AttributeError(223                "<enum %r> cannot delete attribute %r" % (self.clsname, self.name)224                )225 226    def __set_name__(self, ownerclass, name):227        self.name = name228        self.clsname = ownerclass.__name__229 230 231class _proto_member:232    """233    intermediate step for enum members between class execution and final creation234    """235 236    def __init__(self, value):237        self.value = value238 239    def __set_name__(self, enum_class, member_name):240        """241        convert each quasi-member into an instance of the new enum class242        """243        # first step: remove ourself from enum_class244        delattr(enum_class, member_name)245        # second step: create member based on enum_class246        value = self.value247        if not isinstance(value, tuple):248            args = (value, )249        else:250            args = value251        if enum_class._member_type_ is tuple:   # special case for tuple enums252            args = (args, )     # wrap it one more time253        if not enum_class._use_args_:254            enum_member = enum_class._new_member_(enum_class)255        else:256            enum_member = enum_class._new_member_(enum_class, *args)257        if not hasattr(enum_member, '_value_'):258            if enum_class._member_type_ is object:259                enum_member._value_ = value260            else:261                try:262                    enum_member._value_ = enum_class._member_type_(*args)263                except Exception as exc:264                    new_exc = TypeError(265                            '_value_ not set in __new__, unable to create it'266                            )267                    new_exc.__cause__ = exc268                    raise new_exc269        value = enum_member._value_270        enum_member._name_ = member_name271        enum_member.__objclass__ = enum_class272        enum_member.__init__(*args)273        enum_member._sort_order_ = len(enum_class._member_names_)274 275        if Flag is not None and issubclass(enum_class, Flag):276            if isinstance(value, int):277                enum_class._flag_mask_ |= value278                if _is_single_bit(value):279                    enum_class._singles_mask_ |= value280            enum_class._all_bits_ = 2 ** ((enum_class._flag_mask_).bit_length()) - 1281 282        # If another member with the same value was already defined, the283        # new member becomes an alias to the existing one.284        try:285            try:286                # try to do a fast lookup to avoid the quadratic loop287                enum_member = enum_class._value2member_map_[value]288            except TypeError:289                for name, canonical_member in enum_class._member_map_.items():290                    if canonical_member._value_ == value:291                        enum_member = canonical_member292                        break293                else:294                    raise KeyError295        except KeyError:296            # this could still be an alias if the value is multi-bit and the297            # class is a flag class298            if (299                    Flag is None300                    or not issubclass(enum_class, Flag)301                ):302                # no other instances found, record this member in _member_names_303                enum_class._member_names_.append(member_name)304            elif (305                    Flag is not None306                    and issubclass(enum_class, Flag)307                    and isinstance(value, int)308                    and _is_single_bit(value)309                ):310                # no other instances found, record this member in _member_names_311                enum_class._member_names_.append(member_name)312 313        enum_class._add_member_(member_name, enum_member)314        try:315            # This may fail if value is not hashable. We can't add the value316            # to the map, and by-value lookups for this value will be317            # linear.318            enum_class._value2member_map_.setdefault(value, enum_member)319            if value not in enum_class._hashable_values_:320                enum_class._hashable_values_.append(value)321        except TypeError:322            # keep track of the value in a list so containment checks are quick323            enum_class._unhashable_values_.append(value)324            enum_class._unhashable_values_map_.setdefault(member_name, []).append(value)325 326 327class EnumDict(dict):328    """329    Track enum member order and ensure member names are not reused.330 331    EnumType will use the names found in self._member_names as the332    enumeration member names.333    """334    def __init__(self, cls_name=None):335        super().__init__()336        self._member_names = {} # use a dict -- faster look-up than a list, and keeps insertion order since 3.7337        self._last_values = []338        self._ignore = []339        self._auto_called = False340        self._cls_name = cls_name341 342    def __setitem__(self, key, value):343        """344        Changes anything not dundered or not a descriptor.345 346        If an enum member name is used twice, an error is raised; duplicate347        values are not checked for.348 349        Single underscore (sunder) names are reserved.350        """351        if self._cls_name is not None and _is_private(self._cls_name, key):352            # do nothing, name will be a normal attribute353            pass354        elif _is_sunder(key):355            if key not in (356                    '_order_',357                    '_generate_next_value_', '_numeric_repr_', '_missing_', '_ignore_',358                    '_iter_member_', '_iter_member_by_value_', '_iter_member_by_def_',359                    '_add_alias_', '_add_value_alias_',360                    # While not in use internally, those are common for pretty361                    # printing and thus excluded from Enum's reservation of362                    # _sunder_ names363                    ) and not key.startswith('_repr_'):364                raise ValueError(365                        '_sunder_ names, such as %r, are reserved for future Enum use'366                        % (key, )367                        )368            if key == '_generate_next_value_':369                # check if members already defined as auto()370                if self._auto_called:371                    raise TypeError("_generate_next_value_ must be defined before members")372                _gnv = value.__func__ if isinstance(value, staticmethod) else value373                setattr(self, '_generate_next_value', _gnv)374            elif key == '_ignore_':375                if isinstance(value, str):376                    value = value.replace(',',' ').split()377                else:378                    value = list(value)379                self._ignore = value380                already = set(value) & set(self._member_names)381                if already:382                    raise ValueError(383                            '_ignore_ cannot specify already set names: %r'384                            % (already, )385                            )386        elif _is_dunder(key):387            if key == '__order__':388                key = '_order_'389        elif key in self._member_names:390            # descriptor overwriting an enum?391            raise TypeError('%r already defined as %r' % (key, self[key]))392        elif key in self._ignore:393            pass394        elif isinstance(value, nonmember):395            # unwrap value here; it won't be processed by the below `else`396            value = value.value397        elif _is_descriptor(value):398            pass399        elif self._cls_name is not None and _is_internal_class(self._cls_name, value):400            # do nothing, name will be a normal attribute401            pass402        else:403            if key in self:404                # enum overwriting a descriptor?405                raise TypeError('%r already defined as %r' % (key, self[key]))406            elif isinstance(value, member):407                # unwrap value here -- it will become a member408                value = value.value409            non_auto_store = True410            single = False411            if isinstance(value, auto):412                single = True413                value = (value, )414            if isinstance(value, tuple) and any(isinstance(v, auto) for v in value):415                # insist on an actual tuple, no subclasses, in keeping with only supporting416                # top-level auto() usage (not contained in any other data structure)417                auto_valued = []418                t = type(value)419                for v in value:420                    if isinstance(v, auto):421                        non_auto_store = False422                        if v.value == _auto_null:423                            v.value = self._generate_next_value(424                                    key, 1, len(self._member_names), self._last_values[:],425                                    )426                            self._auto_called = True427                        v = v.value428                        self._last_values.append(v)429                    auto_valued.append(v)430                if single:431                    value = auto_valued[0]432                else:433                    try:434                        # accepts iterable as multiple arguments?435                        value = t(auto_valued)436                    except TypeError:437                        # then pass them in singly438                        value = t(*auto_valued)439            self._member_names[key] = None440            if non_auto_store:441                self._last_values.append(value)442        super().__setitem__(key, value)443 444    @property445    def member_names(self):446        return list(self._member_names)447 448    def update(self, members, **more_members):449        try:450            for name in members.keys():451                self[name] = members[name]452        except AttributeError:453            for name, value in members:454                self[name] = value455        for name, value in more_members.items():456            self[name] = value457 458_EnumDict = EnumDict        # keep private name for backwards compatibility459 460 461class EnumType(type):462    """463    Metaclass for Enum464    """465 466    @classmethod467    def __prepare__(metacls, cls, bases, **kwds):468        # check that previous enum members do not exist469        metacls._check_for_existing_members_(cls, bases)470        # create the namespace dict471        enum_dict = EnumDict(cls)472        # inherit previous flags and _generate_next_value_ function473        member_type, first_enum = metacls._get_mixins_(cls, bases)474        if first_enum is not None:475            enum_dict['_generate_next_value_'] = getattr(476                    first_enum, '_generate_next_value_', None,477                    )478        return enum_dict479 480    def __new__(metacls, cls, bases, classdict, *, boundary=None, _simple=False, **kwds):481        # an Enum class is final once enumeration items have been defined; it482        # cannot be mixed with other types (int, float, etc.) if it has an483        # inherited __new__ unless a new __new__ is defined (or the resulting484        # class will fail).485        #486        if _simple:487            return super().__new__(metacls, cls, bases, classdict, **kwds)488        #489        # remove any keys listed in _ignore_490        classdict.setdefault('_ignore_', []).append('_ignore_')491        ignore = classdict['_ignore_']492        for key in ignore:493            classdict.pop(key, None)494        #495        # grab member names496        member_names = classdict._member_names497        #498        # check for illegal enum names (any others?)499        invalid_names = set(member_names) & {'mro', ''}500        if invalid_names:501            raise ValueError('invalid enum member name(s) %s'  % (502                    ','.join(repr(n) for n in invalid_names)503                    ))504        #505        # adjust the sunders506        _order_ = classdict.pop('_order_', None)507        _gnv = classdict.get('_generate_next_value_')508        if _gnv is not None and type(_gnv) is not staticmethod:509            _gnv = staticmethod(_gnv)510        # convert to normal dict511        classdict = dict(classdict.items())512        if _gnv is not None:513            classdict['_generate_next_value_'] = _gnv514        #515        # data type of member and the controlling Enum class516        member_type, first_enum = metacls._get_mixins_(cls, bases)517        __new__, save_new, use_args = metacls._find_new_(518                classdict, member_type, first_enum,519                )520        classdict['_new_member_'] = __new__521        classdict['_use_args_'] = use_args522        #523        # convert future enum members into temporary _proto_members524        for name in member_names:525            value = classdict[name]526            classdict[name] = _proto_member(value)527        #528        # house-keeping structures529        classdict['_member_names_'] = []530        classdict['_member_map_'] = {}531        classdict['_value2member_map_'] = {}532        classdict['_hashable_values_'] = []          # for comparing with non-hashable types533        classdict['_unhashable_values_'] = []       # e.g. frozenset() with set()534        classdict['_unhashable_values_map_'] = {}535        classdict['_member_type_'] = member_type536        # now set the __repr__ for the value537        classdict['_value_repr_'] = metacls._find_data_repr_(cls, bases)538        #539        # Flag structures (will be removed if final class is not a Flag540        classdict['_boundary_'] = (541                boundary542                or getattr(first_enum, '_boundary_', None)543                )544        classdict['_flag_mask_'] = 0545        classdict['_singles_mask_'] = 0546        classdict['_all_bits_'] = 0547        classdict['_inverted_'] = None548        try:549            classdict['_%s__in_progress' % cls] = True550            enum_class = super().__new__(metacls, cls, bases, classdict, **kwds)551            classdict['_%s__in_progress' % cls] = False552            delattr(enum_class, '_%s__in_progress' % cls)553        except Exception as e:554            # since 3.12 the note "Error calling __set_name__ on '_proto_member' instance ..."555            # is tacked on to the error instead of raising a RuntimeError, so discard it556            if hasattr(e, '__notes__'):557                del e.__notes__558            raise559        # update classdict with any changes made by __init_subclass__560        classdict.update(enum_class.__dict__)561        #562        # double check that repr and friends are not the mixin's or various563        # things break (such as pickle)564        # however, if the method is defined in the Enum itself, don't replace565        # it566        #567        # Also, special handling for ReprEnum568        if ReprEnum is not None and ReprEnum in bases:569            if member_type is object:570                raise TypeError(571                        'ReprEnum subclasses must be mixed with a data type (i.e.'572                        ' int, str, float, etc.)'573                        )574            if '__format__' not in classdict:575                enum_class.__format__ = member_type.__format__576                classdict['__format__'] = enum_class.__format__577            if '__str__' not in classdict:578                method = member_type.__str__579                if method is object.__str__:580                    # if member_type does not define __str__, object.__str__ will use581                    # its __repr__ instead, so we'll also use its __repr__582                    method = member_type.__repr__583                enum_class.__str__ = method584                classdict['__str__'] = enum_class.__str__585        for name in ('__repr__', '__str__', '__format__', '__reduce_ex__'):586            if name not in classdict:587                # check for mixin overrides before replacing588                enum_method = getattr(first_enum, name)589                found_method = getattr(enum_class, name)590                object_method = getattr(object, name)591                data_type_method = getattr(member_type, name)592                if found_method in (data_type_method, object_method):593                    setattr(enum_class, name, enum_method)594        #595        # for Flag, add __or__, __and__, __xor__, and __invert__596        if Flag is not None and issubclass(enum_class, Flag):597            for name in (598                    '__or__', '__and__', '__xor__',599                    '__ror__', '__rand__', '__rxor__',600                    '__invert__'601                ):602                if name not in classdict:603                    enum_method = getattr(Flag, name)604                    setattr(enum_class, name, enum_method)605                    classdict[name] = enum_method606        #607        # replace any other __new__ with our own (as long as Enum is not None,608        # anyway) -- again, this is to support pickle609        if Enum is not None:610            # if the user defined their own __new__, save it before it gets611            # clobbered in case they subclass later612            if save_new:613                enum_class.__new_member__ = __new__614            enum_class.__new__ = Enum.__new__615        #616        # py3 support for definition order (helps keep py2/py3 code in sync)617        #618        # _order_ checking is spread out into three/four steps619        # - if enum_class is a Flag:620        #   - remove any non-single-bit flags from _order_621        # - remove any aliases from _order_622        # - check that _order_ and _member_names_ match623        #624        # step 1: ensure we have a list625        if _order_ is not None:626            if isinstance(_order_, str):627                _order_ = _order_.replace(',', ' ').split()628        #629        # remove Flag structures if final class is not a Flag630        if (631                Flag is None and cls != 'Flag'632                or Flag is not None and not issubclass(enum_class, Flag)633            ):634            delattr(enum_class, '_boundary_')635            delattr(enum_class, '_flag_mask_')636            delattr(enum_class, '_singles_mask_')637            delattr(enum_class, '_all_bits_')638            delattr(enum_class, '_inverted_')639        elif Flag is not None and issubclass(enum_class, Flag):640            # set correct __iter__641            member_list = [m._value_ for m in enum_class]642            if member_list != sorted(member_list):643                enum_class._iter_member_ = enum_class._iter_member_by_def_644            if _order_:645                # _order_ step 2: remove any items from _order_ that are not single-bit646                _order_ = [647                        o648                        for o in _order_649                        if o not in enum_class._member_map_ or _is_single_bit(enum_class[o]._value_)650                        ]651        #652        if _order_:653            # _order_ step 3: remove aliases from _order_654            _order_ = [655                    o656                    for o in _order_657                    if (658                        o not in enum_class._member_map_659                        or660                        (o in enum_class._member_map_ and o in enum_class._member_names_)661                        )]662            # _order_ step 4: verify that _order_ and _member_names_ match663            if _order_ != enum_class._member_names_:664                raise TypeError(665                        'member order does not match _order_:\n  %r\n  %r'666                        % (enum_class._member_names_, _order_)667                        )668        #669        return enum_class670 671    def __bool__(cls):672        """673        classes/types should always be True.674        """675        return True676 677    def __call__(cls, value, names=_not_given, *values, module=None, qualname=None, type=None, start=1, boundary=None):678        """679        Either returns an existing member, or creates a new enum class.680 681        This method is used both when an enum class is given a value to match682        to an enumeration member (i.e. Color(3)) and for the functional API683        (i.e. Color = Enum('Color', names='RED GREEN BLUE')).684 685        The value lookup branch is chosen if the enum is final.686 687        When used for the functional API:688 689        `value` will be the name of the new class.690 691        `names` should be either a string of white-space/comma delimited names692        (values will start at `start`), or an iterator/mapping of name, value pairs.693 694        `module` should be set to the module this class is being created in;695        if it is not set, an attempt to find that module will be made, but if696        it fails the class will not be picklable.697 698        `qualname` should be set to the actual location this class can be found699        at in its module; by default it is set to the global scope.  If this is700        not correct, unpickling will fail in some circumstances.701 702        `type`, if set, will be mixed in as the first base class.703        """704        if cls._member_map_:705            # simple value lookup if members exist706            if names is not _not_given:707                value = (value, names) + values708            return cls.__new__(cls, value)709        # otherwise, functional API: we're creating a new Enum type710        if names is _not_given and type is None:711            # no body? no data-type? possibly wrong usage712            raise TypeError(713                    f"{cls} has no members; specify `names=()` if you meant to create a new, empty, enum"714                    )715        return cls._create_(716                class_name=value,717                names=None if names is _not_given else names,718                module=module,719                qualname=qualname,720                type=type,721                start=start,722                boundary=boundary,723                )724 725    def __contains__(cls, value):726        """Return True if `value` is in `cls`.727 728        `value` is in `cls` if:729        1) `value` is a member of `cls`, or730        2) `value` is the value of one of the `cls`'s members.731        3) `value` is a pseudo-member (flags)732        """733        if isinstance(value, cls):734            return True735        if issubclass(cls, Flag):736            try:737                result = cls._missing_(value)738                return isinstance(result, cls)739            except ValueError:740                pass741        return (742                value in cls._unhashable_values_    # both structures are lists743                or value in cls._hashable_values_744                )745 746    def __delattr__(cls, attr):747        # nicer error message when someone tries to delete an attribute748        # (see issue19025).749        if attr in cls._member_map_:750            raise AttributeError("%r cannot delete member %r." % (cls.__name__, attr))751        super().__delattr__(attr)752 753    def __dir__(cls):754        interesting = set([755                '__class__', '__contains__', '__doc__', '__getitem__',756                '__iter__', '__len__', '__members__', '__module__',757                '__name__', '__qualname__',758                ]759                + cls._member_names_760                )761        if cls._new_member_ is not object.__new__:762            interesting.add('__new__')763        if cls.__init_subclass__ is not object.__init_subclass__:764            interesting.add('__init_subclass__')765        if cls._member_type_ is object:766            return sorted(interesting)767        else:768            # return whatever mixed-in data type has769            return sorted(set(dir(cls._member_type_)) | interesting)770 771    def __getitem__(cls, name):772        """773        Return the member matching `name`.774        """775        return cls._member_map_[name]776 777    def __iter__(cls):778        """779        Return members in definition order.780        """781        return (cls._member_map_[name] for name in cls._member_names_)782 783    def __len__(cls):784        """785        Return the number of members (no aliases)786        """787        return len(cls._member_names_)788 789    @bltns.property790    def __members__(cls):791        """792        Returns a mapping of member name->value.793 794        This mapping lists all enum members, including aliases. Note that this795        is a read-only view of the internal mapping.796        """797        return MappingProxyType(cls._member_map_)798 799    def __repr__(cls):800        if Flag is not None and issubclass(cls, Flag):801            return "<flag %r>" % cls.__name__802        else:803            return "<enum %r>" % cls.__name__804 805    def __reversed__(cls):806        """807        Return members in reverse definition order.808        """809        return (cls._member_map_[name] for name in reversed(cls._member_names_))810 811    def __setattr__(cls, name, value):812        """813        Block attempts to reassign Enum members.814 815        A simple assignment to the class namespace only changes one of the816        several possible ways to get an Enum member from the Enum class,817        resulting in an inconsistent Enumeration.818        """819        member_map = cls.__dict__.get('_member_map_', {})820        if name in member_map:821            raise AttributeError('cannot reassign member %r' % (name, ))822        super().__setattr__(name, value)823 824    def _create_(cls, class_name, names, *, module=None, qualname=None, type=None, start=1, boundary=None):825        """826        Convenience method to create a new Enum class.827 828        `names` can be:829 830        * A string containing member names, separated either with spaces or831          commas.  Values are incremented by 1 from `start`.832        * An iterable of member names.  Values are incremented by 1 from `start`.833        * An iterable of (member name, value) pairs.834        * A mapping of member name -> value pairs.835        """836        metacls = cls.__class__837        bases = (cls, ) if type is None else (type, cls)838        _, first_enum = cls._get_mixins_(class_name, bases)839        classdict = metacls.__prepare__(class_name, bases)840 841        # special processing needed for names?842        if isinstance(names, str):843            names = names.replace(',', ' ').split()844        if isinstance(names, (tuple, list)) and names and isinstance(names[0], str):845            original_names, names = names, []846            last_values = []847            for count, name in enumerate(original_names):848                value = first_enum._generate_next_value_(name, start, count, last_values[:])849                last_values.append(value)850                names.append((name, value))851        if names is None:852            names = ()853 854        # Here, names is either an iterable of (name, value) or a mapping.855        for item in names:856            if isinstance(item, str):857                member_name, member_value = item, names[item]858            else:859                member_name, member_value = item860            classdict[member_name] = member_value861 862        if module is None:863            try:864                module = sys._getframemodulename(2)865            except AttributeError:866                # Fall back on _getframe if _getframemodulename is missing867                try:868                    module = sys._getframe(2).f_globals['__name__']869                except (AttributeError, ValueError, KeyError):870                    pass871        if module is None:872            _make_class_unpicklable(classdict)873        else:874            classdict['__module__'] = module875        if qualname is not None:876            classdict['__qualname__'] = qualname877 878        return metacls.__new__(metacls, class_name, bases, classdict, boundary=boundary)879 880    def _convert_(cls, name, module, filter, source=None, *, boundary=None, as_global=False):881        """882        Create a new Enum subclass that replaces a collection of global constants883        """884        # convert all constants from source (or module) that pass filter() to885        # a new Enum called name, and export the enum and its members back to886        # module;887        # also, replace the __reduce_ex__ method so unpickling works in888        # previous Python versions889        module_globals = sys.modules[module].__dict__890        if source:891            source = source.__dict__892        else:893            source = module_globals894        # _value2member_map_ is populated in the same order every time895        # for a consistent reverse mapping of number to name when there896        # are multiple names for the same number.897        members = [898                (name, value)899                for name, value in source.items()900                if filter(name)]901        try:902            # sort by value903            members.sort(key=lambda t: (t[1], t[0]))904        except TypeError:905            # unless some values aren't comparable, in which case sort by name906            members.sort(key=lambda t: t[0])907        body = {t[0]: t[1] for t in members}908        body['__module__'] = module909        tmp_cls = type(name, (object, ), body)910        cls = _simple_enum(etype=cls, boundary=boundary or KEEP)(tmp_cls)911        if as_global:912            global_enum(cls)913        else:914            sys.modules[cls.__module__].__dict__.update(cls.__members__)915        module_globals[name] = cls916        return cls917 918    @classmethod919    def _check_for_existing_members_(mcls, class_name, bases):920        for chain in bases:921            for base in chain.__mro__:922                if isinstance(base, EnumType) and base._member_names_:923                    raise TypeError(924                            "<enum %r> cannot extend %r"925                            % (class_name, base)926                            )927 928    @classmethod929    def _get_mixins_(mcls, class_name, bases):930        """931        Returns the type for creating enum members, and the first inherited932        enum class.933 934        bases: the tuple of bases that was given to __new__935        """936        if not bases:937            return object, Enum938        # ensure final parent class is an Enum derivative, find any concrete939        # data type, and check that Enum has no members940        first_enum = bases[-1]941        if not isinstance(first_enum, EnumType):942            raise TypeError("new enumerations should be created as "943                    "`EnumName([mixin_type, ...] [data_type,] enum_type)`")944        member_type = mcls._find_data_type_(class_name, bases) or object945        return member_type, first_enum946 947    @classmethod948    def _find_data_repr_(mcls, class_name, bases):949        for chain in bases:950            for base in chain.__mro__:951                if base is object:952                    continue953                elif isinstance(base, EnumType):954                    # if we hit an Enum, use it's _value_repr_955                    return base._value_repr_956                elif '__repr__' in base.__dict__:957                    # this is our data repr958                    # double-check if a dataclass with a default __repr__959                    if (960                            '__dataclass_fields__' in base.__dict__961                            and '__dataclass_params__' in base.__dict__962                            and base.__dict__['__dataclass_params__'].repr963                        ):964                        return _dataclass_repr965                    else:966                        return base.__dict__['__repr__']967        return None968 969    @classmethod970    def _find_data_type_(mcls, class_name, bases):971        # a datatype has a __new__ method, or a __dataclass_fields__ attribute972        data_types = set()973        base_chain = set()974        for chain in bases:975            candidate = None976            for base in chain.__mro__:977                base_chain.add(base)978                if base is object:979                    continue980                elif isinstance(base, EnumType):981                    if base._member_type_ is not object:982                        data_types.add(base._member_type_)983                        break984                elif '__new__' in base.__dict__ or '__dataclass_fields__' in base.__dict__:985                    data_types.add(candidate or base)986                    break987                else:988                    candidate = candidate or base989        if len(data_types) > 1:990            raise TypeError('too many data types for %r: %r' % (class_name, data_types))991        elif data_types:992            return data_types.pop()993        else:994            return None995 996    @classmethod997    def _find_new_(mcls, classdict, member_type, first_enum):998        """999        Returns the __new__ to be used for creating the enum members.1000 1001        classdict: the class dictionary given to __new__1002        member_type: the data type whose __new__ will be used by default1003        first_enum: enumeration to check for an overriding __new__1004        """1005        # now find the correct __new__, checking to see of one was defined1006        # by the user; also check earlier enum classes in case a __new__ was1007        # saved as __new_member__1008        __new__ = classdict.get('__new__', None)1009 1010        # should __new__ be saved as __new_member__ later?1011        save_new = first_enum is not None and __new__ is not None1012 1013        if __new__ is None:1014            # check all possibles for __new_member__ before falling back to1015            # __new__1016            for method in ('__new_member__', '__new__'):1017                for possible in (member_type, first_enum):1018                    target = getattr(possible, method, None)1019                    if target not in {1020                            None,1021                            None.__new__,1022                            object.__new__,1023                            Enum.__new__,1024                            }:1025                        __new__ = target1026                        break1027                if __new__ is not None:1028                    break1029            else:1030                __new__ = object.__new__1031 1032        # if a non-object.__new__ is used then whatever value/tuple was1033        # assigned to the enum member name will be passed to __new__ and to the1034        # new enum member's __init__1035        if first_enum is None or __new__ in (Enum.__new__, object.__new__):1036            use_args = False1037        else:1038            use_args = True1039        return __new__, save_new, use_args1040 1041    def _add_member_(cls, name, member):1042        # _value_ structures are not updated1043        if name in cls._member_map_:1044            if cls._member_map_[name] is not member:1045                raise NameError('%r is already bound: %r' % (name, cls._member_map_[name]))1046            return1047        #1048        # if necessary, get redirect in place and then add it to _member_map_1049        found_descriptor = None1050        descriptor_type = None1051        class_type = None1052        for base in cls.__mro__[1:]:1053            attr = base.__dict__.get(name)1054            if attr is not None:1055                if isinstance(attr, (property, DynamicClassAttribute)):1056                    found_descriptor = attr1057                    class_type = base1058                    descriptor_type = 'enum'1059                    break1060                elif _is_descriptor(attr):1061                    found_descriptor = attr1062                    descriptor_type = descriptor_type or 'desc'1063                    class_type = class_type or base1064                    continue1065                else:1066                    descriptor_type = 'attr'1067                    class_type = base1068        if found_descriptor:1069            redirect = property()1070            redirect.member = member1071            redirect.__set_name__(cls, name)1072            if descriptor_type in ('enum', 'desc'):1073                # earlier descriptor found; copy fget, fset, fdel to this one.1074                redirect.fget = getattr(found_descriptor, 'fget', None)1075                redirect._get = getattr(found_descriptor, '__get__', None)1076                redirect.fset = getattr(found_descriptor, 'fset', None)1077                redirect._set = getattr(found_descriptor, '__set__', None)1078                redirect.fdel = getattr(found_descriptor, 'fdel', None)1079                redirect._del = getattr(found_descriptor, '__delete__', None)1080            redirect._attr_type = descriptor_type1081            redirect._cls_type = class_type1082            setattr(cls, name, redirect)1083        else:1084            setattr(cls, name, member)1085        # now add to _member_map_ (even aliases)1086        cls._member_map_[name] = member1087 1088    @property1089    def __signature__(cls):1090        from inspect import Parameter, Signature1091        if cls._member_names_:1092            return Signature([Parameter('values', Parameter.VAR_POSITIONAL)])1093        else:1094            return Signature([Parameter('new_class_name', Parameter.POSITIONAL_ONLY),1095                              Parameter('names', Parameter.POSITIONAL_OR_KEYWORD),1096                              Parameter('module', Parameter.KEYWORD_ONLY, default=None),1097                              Parameter('qualname', Parameter.KEYWORD_ONLY, default=None),1098                              Parameter('type', Parameter.KEYWORD_ONLY, default=None),1099                              Parameter('start', Parameter.KEYWORD_ONLY, default=1),1100                              Parameter('boundary', Parameter.KEYWORD_ONLY, default=None)])1101 1102 1103EnumMeta = EnumType         # keep EnumMeta name for backwards compatibility1104 1105 1106class Enum(metaclass=EnumType):1107    """1108    Create a collection of name/value pairs.1109 1110    Example enumeration:1111 1112    >>> class Color(Enum):1113    ...     RED = 11114    ...     BLUE = 21115    ...     GREEN = 31116 1117    Access them by:1118 1119    - attribute access:1120 1121      >>> Color.RED1122      <Color.RED: 1>1123 1124    - value lookup:1125 1126      >>> Color(1)1127      <Color.RED: 1>1128 1129    - name lookup:1130 1131      >>> Color['RED']1132      <Color.RED: 1>1133 1134    Enumerations can be iterated over, and know how many members they have:1135 1136    >>> len(Color)1137    31138 1139    >>> list(Color)1140    [<Color.RED: 1>, <Color.BLUE: 2>, <Color.GREEN: 3>]1141 1142    Methods can be added to enumerations, and members can have their own1143    attributes -- see the documentation for details.1144    """1145 1146    def __new__(cls, value):1147        # all enum instances are actually created during class construction1148        # without calling this method; this method is called by the metaclass'1149        # __call__ (i.e. Color(3) ), and by pickle1150        if type(value) is cls:1151            # For lookups like Color(Color.RED)1152            return value1153        # by-value search for a matching enum member1154        # see if it's in the reverse mapping (for hashable values)1155        try:1156            return cls._value2member_map_[value]1157        except KeyError:1158            # Not found, no need to do long O(n) search1159            pass1160        except TypeError:1161            # not there, now do long search -- O(n) behavior1162            for name, unhashable_values in cls._unhashable_values_map_.items():1163                if value in unhashable_values:1164                    return cls[name]1165            for name, member in cls._member_map_.items():1166                if value == member._value_:1167                    return cls[name]1168        # still not found -- verify that members exist, in-case somebody got here mistakenly1169        # (such as via super when trying to override __new__)1170        if not cls._member_map_:1171            if getattr(cls, '_%s__in_progress' % cls.__name__, False):1172                raise TypeError('do not use `super().__new__; call the appropriate __new__ directly') from None1173            raise TypeError("%r has no members defined" % cls)1174        #1175        # still not found -- try _missing_ hook1176        try:1177            exc = None1178            result = cls._missing_(value)1179        except Exception as e:1180            exc = e1181            result = None1182        try:1183            if isinstance(result, cls):1184                return result1185            elif (1186                    Flag is not None and issubclass(cls, Flag)1187                    and cls._boundary_ is EJECT and isinstance(result, int)1188                ):1189                return result1190            else:1191                ve_exc = ValueError("%r is not a valid %s" % (value, cls.__qualname__))1192                if result is None and exc is None:1193                    raise ve_exc1194                elif exc is None:1195                    exc = TypeError(1196                            'error in %s._missing_: returned %r instead of None or a valid member'1197                            % (cls.__name__, result)1198                            )1199                if not isinstance(exc, ValueError):1200                    exc.__context__ = ve_exc

Showing the first 1,200 of 2169 lines. Download the file for the rest.

codekingpro/portable-devtools · Team Ai