Skip to content

Commit

Permalink
Use well-defined enum representation
Browse files Browse the repository at this point in the history
Python 3.10 changed enum's object and string representation. PyCA
cryptography now uses a custom subclass of enum.Enum() will well-defined
__repr__ and __str__ from Python 3.9.

Related: https://bugs.python.org/issue40066
Fixes: #5995
Signed-off-by: Christian Heimes <[email protected]>
  • Loading branch information
tiran committed May 11, 2021
1 parent 29cf9b8 commit 2adb971
Show file tree
Hide file tree
Showing 12 changed files with 54 additions and 32 deletions.
13 changes: 7 additions & 6 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,16 @@ jobs:
- {VERSION: "3.9", TOXENV: "flake,rust,docs", COVERAGE: "false"}
- {VERSION: "pypy3", TOXENV: "pypy3"}
- {VERSION: "3.9", TOXENV: "py39", OPENSSL: {TYPE: "openssl", VERSION: "1.1.0l"}}
- {VERSION: "3.9", TOXENV: "py39", OPENSSL: {TYPE: "openssl", VERSION: "1.1.1j"}}
- {VERSION: "3.9", TOXENV: "py39-ssh", OPENSSL: {TYPE: "openssl", VERSION: "1.1.1j"}}
- {VERSION: "3.9", TOXENV: "py39", OPENSSL: {TYPE: "openssl", VERSION: "1.1.1j", CONFIG_FLAGS: "no-engine no-rc2 no-srtp no-ct"}}
- {VERSION: "3.9", TOXENV: "py39", OPENSSL: {TYPE: "openssl", VERSION: "3.0.0-alpha15"}}
- {VERSION: "3.9", TOXENV: "py39", OPENSSL: {TYPE: "openssl", VERSION: "1.1.1k"}}
- {VERSION: "3.9", TOXENV: "py39-ssh", OPENSSL: {TYPE: "openssl", VERSION: "1.1.1k"}}
- {VERSION: "3.9", TOXENV: "py39", OPENSSL: {TYPE: "openssl", VERSION: "1.1.1k", CONFIG_FLAGS: "no-engine no-rc2 no-srtp no-ct"}}
- {VERSION: "3.9", TOXENV: "py39", OPENSSL: {TYPE: "openssl", VERSION: "3.0.0-alpha16"}}
- {VERSION: "3.9", TOXENV: "py39", OPENSSL: {TYPE: "libressl", VERSION: "2.9.2"}}
- {VERSION: "3.9", TOXENV: "py39", OPENSSL: {TYPE: "libressl", VERSION: "3.0.2"}}
- {VERSION: "3.9", TOXENV: "py39", OPENSSL: {TYPE: "libressl", VERSION: "3.1.5"}}
- {VERSION: "3.9", TOXENV: "py39", OPENSSL: {TYPE: "libressl", VERSION: "3.2.3"}}
- {VERSION: "3.9", TOXENV: "py39", OPENSSL: {TYPE: "libressl", VERSION: "3.3.1"}}
- {VERSION: "3.9", TOXENV: "py39", OPENSSL: {TYPE: "libressl", VERSION: "3.2.5"}}
- {VERSION: "3.9", TOXENV: "py39", OPENSSL: {TYPE: "libressl", VERSION: "3.3.2"}}
- {VERSION: "3.10-dev", TOXENV: "py310"}
RUST:
- stable
name: "${{ matrix.PYTHON.TOXENV }} ${{ matrix.PYTHON.OPENSSL.TYPE }} ${{ matrix.PYTHON.OPENSSL.VERSION }} ${{ matrix.PYTHON.OPENSSL.CONFIG_FLAGS }}"
Expand Down
4 changes: 2 additions & 2 deletions src/cryptography/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@
# for complete details.


from enum import Enum
from cryptography import utils


class _Reasons(Enum):
class _Reasons(utils.Enum):
BACKEND_MISSING_INTERFACE = 0
UNSUPPORTED_HASH = 1
UNSUPPORTED_CIPHER = 2
Expand Down
11 changes: 6 additions & 5 deletions src/cryptography/hazmat/primitives/_serialization.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,14 @@
# for complete details.

import abc
from enum import Enum

from cryptography import utils

# This exists to break an import cycle. These classes are normally accessible
# from the serialization module.


class Encoding(Enum):
class Encoding(utils.Enum):
PEM = "PEM"
DER = "DER"
OpenSSH = "OpenSSH"
Expand All @@ -18,14 +19,14 @@ class Encoding(Enum):
SMIME = "S/MIME"


class PrivateFormat(Enum):
class PrivateFormat(utils.Enum):
PKCS8 = "PKCS8"
TraditionalOpenSSL = "TraditionalOpenSSL"
Raw = "Raw"
OpenSSH = "OpenSSH"


class PublicFormat(Enum):
class PublicFormat(utils.Enum):
SubjectPublicKeyInfo = "X.509 subjectPublicKeyInfo with PKCS#1"
PKCS1 = "Raw PKCS#1"
OpenSSH = "OpenSSH"
Expand All @@ -34,7 +35,7 @@ class PublicFormat(Enum):
UncompressedPoint = "X9.62 Uncompressed Point"


class ParameterFormat(Enum):
class ParameterFormat(utils.Enum):
PKCS3 = "PKCS3"


Expand Down
5 changes: 2 additions & 3 deletions src/cryptography/hazmat/primitives/kdf/kbkdf.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@


import typing
from enum import Enum

from cryptography import utils
from cryptography.exceptions import (
Expand All @@ -19,11 +18,11 @@
from cryptography.hazmat.primitives.kdf import KeyDerivationFunction


class Mode(Enum):
class Mode(utils.Enum):
CounterMode = "ctr"


class CounterLocation(Enum):
class CounterLocation(utils.Enum):
BeforeFixed = "before_fixed"
AfterFixed = "after_fixed"

Expand Down
4 changes: 2 additions & 2 deletions src/cryptography/hazmat/primitives/serialization/pkcs7.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
# for complete details.

import typing
from enum import Enum

from cryptography import utils
from cryptography import x509
from cryptography.hazmat.backends import _get_backend
from cryptography.hazmat.primitives import hashes, serialization
Expand Down Expand Up @@ -35,7 +35,7 @@ def load_der_pkcs7_certificates(data: bytes) -> typing.List[x509.Certificate]:
]


class PKCS7Options(Enum):
class PKCS7Options(utils.Enum):
Text = "Add text/plain MIME type"
Binary = "Don't translate input data into canonical MIME format"
DetachedSignature = "Don't embed data in the PKCS7 structure"
Expand Down
11 changes: 11 additions & 0 deletions src/cryptography/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@


import abc
import enum
import inspect
import sys
import typing
Expand Down Expand Up @@ -162,3 +163,13 @@ def inner(instance):
"int_from_bytes is deprecated, use int.from_bytes instead",
DeprecatedIn34,
)


# Python 3.10 changed representation of enums. We use well-defined object
# representation and string representation from Python 3.9.
class Enum(enum.Enum):
def __repr__(self):
return f"<{self.__class__.__name__}.{self._name_}: {self._value_!r}>"

def __str__(self):
return f"{self.__class__.__name__}.{self._name_}"
4 changes: 2 additions & 2 deletions src/cryptography/x509/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@
import datetime
import os
import typing
from enum import Enum

from cryptography import utils
from cryptography.hazmat._types import _PRIVATE_KEY_TYPES, _PUBLIC_KEY_TYPES
from cryptography.hazmat.backends import _get_backend
from cryptography.hazmat.primitives import hashes, serialization
Expand Down Expand Up @@ -66,7 +66,7 @@ def _convert_to_naive_utc_time(time: datetime.datetime) -> datetime.datetime:
return time


class Version(Enum):
class Version(utils.Enum):
v1 = 0
v3 = 2

Expand Down
7 changes: 4 additions & 3 deletions src/cryptography/x509/certificate_transparency.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,16 @@

import abc
import datetime
from enum import Enum

from cryptography import utils

class LogEntryType(Enum):

class LogEntryType(utils.Enum):
X509_CERTIFICATE = 0
PRE_CERTIFICATE = 1


class Version(Enum):
class Version(utils.Enum):
v1 = 0


Expand Down
5 changes: 2 additions & 3 deletions src/cryptography/x509/extensions.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
import hashlib
import ipaddress
import typing
from enum import Enum

from cryptography import utils
from cryptography.hazmat._der import (
Expand Down Expand Up @@ -634,7 +633,7 @@ def __hash__(self):
crl_issuer = utils.read_only_property("_crl_issuer")


class ReasonFlags(Enum):
class ReasonFlags(utils.Enum):
unspecified = "unspecified"
key_compromise = "keyCompromise"
ca_compromise = "cACompromise"
Expand Down Expand Up @@ -978,7 +977,7 @@ def __hash__(self):
return hash(tuple(self._features))


class TLSFeatureType(Enum):
class TLSFeatureType(utils.Enum):
# status_request is defined in RFC 6066 and is used for what is commonly
# called OCSP Must-Staple when present in the TLS Feature extension in an
# X.509 certificate.
Expand Down
3 changes: 1 addition & 2 deletions src/cryptography/x509/name.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,13 @@
# for complete details.

import typing
from enum import Enum

from cryptography import utils
from cryptography.hazmat.backends import _get_backend
from cryptography.x509.oid import NameOID, ObjectIdentifier


class _ASN1Type(Enum):
class _ASN1Type(utils.Enum):
UTF8String = 12
NumericString = 18
PrintableString = 19
Expand Down
8 changes: 4 additions & 4 deletions src/cryptography/x509/ocsp.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
import abc
import datetime
import typing
from enum import Enum

from cryptography import utils
from cryptography import x509
from cryptography.hazmat.primitives import hashes, serialization
from cryptography.x509.base import (
Expand All @@ -27,12 +27,12 @@
}


class OCSPResponderEncoding(Enum):
class OCSPResponderEncoding(utils.Enum):
HASH = "By Hash"
NAME = "By Name"


class OCSPResponseStatus(Enum):
class OCSPResponseStatus(utils.Enum):
SUCCESSFUL = 0
MALFORMED_REQUEST = 1
INTERNAL_ERROR = 2
Expand All @@ -58,7 +58,7 @@ def _verify_algorithm(algorithm):
)


class OCSPCertStatus(Enum):
class OCSPCertStatus(utils.Enum):
GOOD = 0
REVOKED = 1
UNKNOWN = 2
Expand Down
11 changes: 11 additions & 0 deletions tests/test_cryptography_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
# 2.0, and the BSD License. See the LICENSE file in the root of this repository
# for complete details.

import enum
import typing

import pytest
Expand Down Expand Up @@ -51,3 +52,13 @@ def t(self):
assert len(accesses) == 1
assert t.t == 14
assert len(accesses) == 1


def test_enum():
class TestEnum(utils.Enum):
value = "something"

assert issubclass(TestEnum, enum.Enum)
assert isinstance(TestEnum.value, enum.Enum)
assert repr(TestEnum.value) == "<TestEnum.value: 'something'>"
assert str(TestEnum.value) == "TestEnum.value"

0 comments on commit 2adb971

Please sign in to comment.