Commit Graph

108 Commits

Author SHA1 Message Date
Ethan Furman a02cb474f9
bpo-38659: [Enum] add _simple_enum decorator (GH-25497)
add:

* `_simple_enum` decorator to transform a normal class into an enum
* `_test_simple_enum` function to compare
* `_old_convert_` to enable checking `_convert_` generated enums

`_simple_enum` takes a normal class and converts it into an enum:

    @simple_enum(Enum)
    class Color:
        RED = 1
        GREEN = 2
        BLUE = 3

`_old_convert_` works much like` _convert_` does, using the original logic:

    # in a test file
    import socket, enum
    CheckedAddressFamily = enum._old_convert_(
            enum.IntEnum, 'AddressFamily', 'socket',
            lambda C: C.isupper() and C.startswith('AF_'),
            source=_socket,
            )

`_test_simple_enum` takes a traditional enum and a simple enum and
compares the two:

    # in the REPL or the same module as Color
    class CheckedColor(Enum):
        RED = 1
        GREEN = 2
        BLUE = 3

    _test_simple_enum(CheckedColor, Color)

    _test_simple_enum(CheckedAddressFamily, socket.AddressFamily)

Any important differences will raise a TypeError
2021-04-21 10:20:44 -07:00
Ethan Furman 503cdc7c12
Revert "bpo-38659: [Enum] add _simple_enum decorator (GH-25285)" (GH-25476)
This reverts commit dbac8f40e8.
2021-04-19 19:12:24 -07:00
Ethan Furman dbac8f40e8
bpo-38659: [Enum] add _simple_enum decorator (GH-25285)
add:

_simple_enum decorator to transform a normal class into an enum
_test_simple_enum function to compare
_old_convert_ to enable checking _convert_ generated enums
_simple_enum takes a normal class and converts it into an enum:

@simple_enum(Enum)
class Color:
    RED = 1
    GREEN = 2
    BLUE = 3

_old_convert_ works much like _convert_ does, using the original logic:

# in a test file
import socket, enum
CheckedAddressFamily = enum._old_convert_(
        enum.IntEnum, 'AddressFamily', 'socket',
        lambda C: C.isupper() and C.startswith('AF_'),
        source=_socket,
        )

test_simple_enum takes a traditional enum and a simple enum and
compares the two:

# in the REPL or the same module as Color
class CheckedColor(Enum):
    RED = 1
    GREEN = 2
    BLUE = 3

_test_simple_enum(CheckedColor, Color)

_test_simple_enum(CheckedAddressFamily, socket.AddressFamily)

Any important differences will raise a TypeError
2021-04-19 18:04:53 -07:00
Ethan Furman ec09973f5b
bpo-43744: [Enum] fix ``_is_private`` (GH-25349)
``_is_private`` now returns ``False`` instead of raising an exception when enum name matches beginning of class name
as used in a private variable
2021-04-15 06:58:33 -07:00
Ethan Furman 0dca5eb54b
[Enum] fix doc string (GH-25376) 2021-04-15 06:49:54 -07:00
Ethan Furman 8c14f5a787
bpo-42248: [Enum] ensure exceptions raised in ``_missing_`` are released (GH-25350) 2021-04-12 08:51:20 -07:00
Ethan Furman b775106d94
bpo-40066: Enum: modify `repr()` and `str()` (GH-22392)
* Enum: streamline repr() and str(); improve docs

- repr() is now ``enum_class.member_name``
- stdlib global enums are ``module_name.member_name``
- str() is now ``member_name``
- add HOW-TO section for ``Enum``
- change main documentation to be an API reference
2021-03-30 21:17:26 -07:00
Ethan Furman 44e580f448
bpo-43162: [Enum] update docs, renable doc tests (GH-24487)
* update docs, renable doc tests
* make deprecation warning active for two releases
2021-03-03 09:54:30 -08:00
Ethan Furman d65b9033d6
bpo-43162: [Enum] deprecate enum member.member access (GH-24486)
In 3.5 (?) a speed optimization made it possible to access members as
attributes of other members, i.e. ``Color.RED.BLUE``.  This was always
discouraged in the docs, and other recent optimizations has made that
one no longer necessary.  Because some may be relying on it anyway, it
is being deprecated in 3.10, and will be removed in 3.11.
2021-02-08 17:32:38 -08:00
Ethan Furman 7aaeb2a3d6
bpo-38250: [Enum] single-bit flags are canonical (GH-24215)
Flag members are now divided by one-bit verses multi-bit, with multi-bit being treated as aliases. Iterating over a flag only returns the contained single-bit flags.

Iterating, repr(), and str() show members in definition order.

When constructing combined-member flags, any extra integer values are either discarded (CONFORM), turned into ints (EJECT) or treated as errors (STRICT). Flag classes can specify which of those three behaviors is desired:

>>> class Test(Flag, boundary=CONFORM):
...     ONE = 1
...     TWO = 2
...
>>> Test(5)
<Test.ONE: 1>

Besides the three above behaviors, there is also KEEP, which should not be used unless necessary -- for example, _convert_ specifies KEEP as there are flag sets in the stdlib that are incomplete and/or inconsistent (e.g. ssl.Options). KEEP will, as the name suggests, keep all bits; however, iterating over a flag with extra bits will only return the canonical flags contained, not the extra bits.

Iteration is now in member definition order.  If member definition order
matches increasing value order, then a more efficient method of flag
decomposition is used; otherwise, sort() is called on the results of
that method to get definition order.


``re`` module:

repr() has been modified to support as closely as possible its previous
output; the big difference is that inverted flags cannot be output as
before because the inversion operation now always returns the comparable
positive result; i.e.

   re.A|re.I|re.M|re.S is ~(re.L|re.U|re.S|re.T|re.DEBUG)

in both of the above terms, the ``value`` is 282.

re's tests have been updated to reflect the modifications to repr().
2021-01-25 14:26:19 -08:00
Ethan Furman c314e60388
bpo-42901: [Enum] move member creation to `__set_name__` (GH-24196)
`type.__new__` calls `__set_name__` and `__init_subclass__`, which means
that any work metaclasses do after calling `super().__new__()` will not
be available to those two methods.  In particular, `Enum` classes that
want to make use of `__init_subclass__` will not see any members.

Almost all customization is therefore moved to before the
`type.__new__()` call, including changing all members to a proto member
descriptor with a `__set_name__` that will do the final conversion of a
member to be an instance of the `Enum` class.
2021-01-12 23:47:57 -08:00
Ethan Furman a581a868d9
bpo-42851: [Enum] remove brittle __init_subclass__ support (GH-24154)
Solution to support calls to `__init_subclass__` with members defined is too brittle and breaks with certain mixins.
2021-01-07 13:17:55 -08:00
Ethan Furman 786d97a66c
bpo-42727: [Enum] use super() and include **kwds (GH-23927)
for multiple inheritance support:

use super().new
pass **kwds to super().new
2020-12-24 19:31:10 -08:00
Ethan Furman 6ec0adefad
[Enum] EnumMeta.__prepare__ now accepts **kwds (#23917) 2020-12-24 10:05:02 -08:00
Ethan Furman a658287179
bpo-34750: [Enum] add `_EnumDict.update()` support (GH-23725)
This allows easier Enum construction in unusual cases, such as including dynamic member definitions into a class definition:

# created dynamically
foo_defines = {'FOO_CAT': 'aloof', 'BAR_DOG': 'friendly', 'FOO_HORSE': 'big'}

class Foo(Enum):
    vars().update({
            k: v
            for k, v in foo_defines.items()
            if k.startswith('FOO_')
            })
    def upper(self):
        # example method
        return self.value.upper()
2020-12-10 13:07:00 -08:00
Ethan Furman efb13be72c
bpo-42385: [Enum] add `_generate_next_value_` to StrEnum (GH-23735)
The default for auto() is to return an integer, which doesn't work for `StrEnum`.  The new `_generate_next_value_` for `StrEnum` returns the member name, lower cased.
2020-12-10 12:20:06 -08:00
Ethan Furman 7cf0aad96d
bpo-42517: [Enum] do not convert private names into members (GH-23722)
private names, such as `_Color__hue` and `_Color__hue_` are now normal attributes, and do not become members nor raise exceptions
2020-12-09 17:12:11 -08:00
Ethan Furman 6bd94de168
bpo-42567: [Enum] call __init_subclass__ after members are added (GH-23714)
When creating an Enum, type.__new__ calls __init_subclass__, but at that point the members have not been added.

This patch suppresses the initial call, then manually calls the ancestor __init_subclass__ before returning the new Enum class.
2020-12-09 16:41:22 -08:00
Ethan Furman 6d3dfee271
[Enum] reformat and add doc strings (GH-23705) 2020-12-08 12:26:56 -08:00
Ethan Furman 37440eef7f
bpo-41907: [Enum] fix format() behavior for IntFlag (GH-22497) 2020-12-08 11:14:10 -08:00
Ethan Furman c266736ec1
bpo-41889: [Enum] fix multiple-inheritance regression (GH-22487) 2020-12-07 00:17:31 -08:00
Ethan Furman d986d1657e
bpo-41816: `StrEnum.__str__` is `str.__str__` (GH-22362)
use `str.__str__` for `StrEnum` so that `str(StrEnum.member)` is the same as directly accessing the string value of the `StrEnum` member
2020-09-22 13:00:07 -07:00
Ethan Furman 0063ff4e58
bpo-41816: add `StrEnum` (GH-22337)
`StrEnum` ensures that its members were already strings, or intended to
be strings.
2020-09-21 17:23:13 -07:00
Angelin BOOZ 68526fe258
bpo-40084: Enum - dir() includes member attributes (GH-19219) 2020-09-21 06:11:06 -07:00
Ethan Furman 7219e27087
Enum: make `Flag` and `IntFlag` members iterable (GH-22221) 2020-09-16 13:01:00 -07:00
Ethan Furman fc23a9483e
_auto_called cleanup (GH-22285) 2020-09-16 12:37:54 -07:00
Ethan Furman c95ad7a91f
bpo-39728: Enum: fix duplicate `ValueError` (GH-22277)
fix default `_missing_` to return `None` instead of raising a `ValueError`
Co-authored-by: Andrey Darascheka <andrei.daraschenka@leverx.com>
2020-09-16 10:26:50 -07:00
Ethan Furman 3064dbf5df
bpo-41517: do not allow Enums to be extended (#22271)
fix bug that let Enums be extended via multiple inheritance
2020-09-16 07:11:57 -07:00
Ethan Furman 22415ad625
bpo-41789: honor object overrides in Enum classes (GH-22250)
EnumMeta double-checks that `__repr__`, `__str__`, `__format__`, and `__reduce_ex__` are not the same as `object`'s, and replaces them if they are -- even if that replacement was intentionally done in the Enum being constructed.  This patch fixes that.

Automerge-Triggered-By: @ethanfurman
2020-09-15 16:28:25 -07:00
Ethan Furman bff01f3a3a
bpo-39587: Enum - use correct mixed-in data type (GH-22263) 2020-09-15 15:56:26 -07:00
Zackery Spytz 2ec67526a6
bpo-38967: Improve the error msg for reserved _sunder_ names in enum (GH-18370) 2020-09-13 13:27:51 -07:00
Ethan Onstott d9a43e20fa
bpo-40025: Require _generate_next_value_ to be defined before members (GH-19098)
require `_generate_next_value_` to be defined before members
2020-04-28 10:20:55 -07:00
HongWeipeng 0b41a922f9 bpo-38045: Improve the performance of _decompose() in enum.py (GH-16483)
* Improve the performance of _decompose() in enum.py

Co-Authored-By: Brandt Bucher <brandtbucher@gmail.com>
2019-11-26 14:36:02 -08:00
Pablo Galindo 293dd23477
Remove binding of captured exceptions when not used to reduce the chances of creating cycles (GH-17246)
Capturing exceptions into names can lead to reference cycles though the __traceback__ attribute of the exceptions in some obscure cases that have been reported previously and fixed individually. As these variables are not used anyway, we can remove the binding to reduce the chances of creating reference cycles.

See for example GH-13135
2019-11-19 21:34:03 +00:00
HongWeipeng bb16fb2cb8 Doc: Fix spelling errors of 'initial' in enum.py (GH-16314) 2019-09-21 07:22:54 +02:00
Walter Dörwald 323842c279 bpo-34443: Use __qualname__ instead of __name__ in enum exception messages. (GH-14809)
* Use __qualname__ instead of __name__ in enum exception messages.
2019-07-18 11:37:13 -07:00
thatneat 2f19e82fbe bpo-37479: on Enum subclasses with mixins, __format__ uses overridden __str__ (GH-14545)
* bpo-37479: on Enum subclasses with mixins, __format__ uses overridden __str__
2019-07-04 11:28:37 -07:00
Zachary Ware 19a1e1eb86 bpo-34282: Remove deprecated enum _convert method (GH-13823) 2019-06-04 23:03:10 +02:00
Brennan D Baraban 8b914d2767 bpo-35899: Fix Enum handling of empty and weird strings (GH-11891)
Co-authored-by: Maxwell <maxwellpxt@gmail.com>
Co-authored-by: Stéphane Wirtel <stephane@wirtel.be>





https://bugs.python.org/issue35899
2019-03-03 14:09:11 -08:00
Rémi Lapeyre 1fd06f1eca bpo-35717: Fix KeyError exception raised when using enums and compile (GH-11523)
https://bugs.python.org/issue17467
2019-01-24 11:43:13 -08:00
Andrew Svetlov 34ae04f74d Speed-up building enums by value, e.g. http.HTTPStatus(200) (#11318)
bpo-35585: Speed up enum by-value lookup
2018-12-26 10:45:33 -08:00
Ethan Furman cd45385ffa
bpo-34909: keep searching mixins until base class is found (GH-9737) 2018-10-05 23:29:36 -07:00
Ethan Furman 5bdab641da
bpo-29577: Enum: mixin classes don't mix well with already mixed Enums (GH-9328)
* bpo-29577: allow multiple mixin classes
2018-09-21 19:03:09 -07:00
Ethan Furman 019f0a0cb8
bpo-34536: raise error for invalid _missing_ results (GH-9147)
* raise exception if _missing_ returns None or invalid type
2018-09-12 11:43:34 -07:00
orlnub123 0fb9fadd3b bpo-34282: Fix Enum._convert shadowing members named _convert (GH-8568)
* Fix enum members getting shadowed by parent attributes
* Move Enum._convert to EnumMeta._convert_
* Deprecate _convert
2018-09-12 10:28:53 -07:00
Rahul Jha 9430652535 bpo-33217: Raise TypeError for non-Enum lookups in Enums (GH-6651)
* bpo-33217: Raise TypeError for non-Enum lookups in Enums
2018-09-10 11:21:04 -07:00
INADA Naoki e57f91a0f0
bpo-33866: enum: Stop using OrderedDict (GH-7698) 2018-06-19 01:14:26 +09:00
anentropic b8e21f1289 bpo-31947: remove None default for names param in Enum._create_ (GH-4288) 2018-04-15 20:40:35 -07:00
Ethan Furman a4b1bb4801
bpo-31801: Enum: add _ignore_ as class option (#5237)
* bpo-31801:  Enum:  add _ignore_ as class option

_ignore_ is a list, or white-space seperated str, of names that will not
be candidates for members; these names, and _ignore_ itself, are removed
from the final class.

* bpo-31801:  Enum:  add documentation for _ignore_

* bpo-31801: Enum: remove trailing whitespace

* bpo-31801: Enum: fix bulleted list format

* bpo-31801: add version added for _ignore_
2018-01-22 07:56:37 -08:00
Serhiy Storchaka 81108375d9 bpo-30152: Reduce the number of imports for argparse. (#1269) 2017-09-26 00:55:55 +03:00