Skip to content

Commit 1b2b0ed

Browse files
authored
Use type-level deprecations (#1389)
1 parent 70e2835 commit 1b2b0ed

File tree

3 files changed

+40
-70
lines changed

3 files changed

+40
-70
lines changed

setup.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,10 @@ def find_meta(meta):
9595
package_dir={"": "src"},
9696
install_requires=[
9797
"cryptography>=41.0.5,<45",
98+
(
99+
"typing-extensions>=4.9; "
100+
"python_version < '3.13' and python_version >= '3.8'"
101+
),
98102
],
99103
extras_require={
100104
"test": ["pytest-rerunfailures", "pretend", "pytest>=3.0.1"],

src/OpenSSL/crypto.py

Lines changed: 35 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import calendar
44
import datetime
55
import functools
6+
import sys
67
import typing
78
import warnings
89
from base64 import b16encode
@@ -14,6 +15,16 @@
1415
Union,
1516
)
1617

18+
if sys.version_info >= (3, 13):
19+
from warnings import deprecated
20+
elif sys.version_info < (3, 8):
21+
_T = typing.TypeVar("T")
22+
23+
def deprecated(msg: str, **kwargs: object) -> Callable[[_T], _T]:
24+
return lambda f: f
25+
else:
26+
from typing_extensions import deprecated
27+
1728
from cryptography import utils, x509
1829
from cryptography.hazmat.primitives.asymmetric import (
1930
dsa,
@@ -529,6 +540,10 @@ def _to_EC_KEY(self) -> Any:
529540
return _ffi.gc(key, _lib.EC_KEY_free)
530541

531542

543+
@deprecated(
544+
"get_elliptic_curves is deprecated. You should use the APIs in "
545+
"cryptography instead."
546+
)
532547
def get_elliptic_curves() -> set[_EllipticCurve]:
533548
"""
534549
Return a set of objects representing the elliptic curves supported in the
@@ -544,20 +559,10 @@ def get_elliptic_curves() -> set[_EllipticCurve]:
544559
return _EllipticCurve._get_elliptic_curves(_lib)
545560

546561

547-
_get_elliptic_curves_internal = get_elliptic_curves
548-
549-
utils.deprecated(
550-
get_elliptic_curves,
551-
__name__,
552-
(
553-
"get_elliptic_curves is deprecated. You should use the APIs in "
554-
"cryptography instead."
555-
),
556-
DeprecationWarning,
557-
name="get_elliptic_curves",
562+
@deprecated(
563+
"get_elliptic_curve is deprecated. You should use the APIs in "
564+
"cryptography instead."
558565
)
559-
560-
561566
def get_elliptic_curve(name: str) -> _EllipticCurve:
562567
"""
563568
Return a single curve object selected by name.
@@ -570,24 +575,12 @@ def get_elliptic_curve(name: str) -> _EllipticCurve:
570575
571576
If the named curve is not supported then :py:class:`ValueError` is raised.
572577
"""
573-
for curve in _get_elliptic_curves_internal():
578+
for curve in get_elliptic_curves():
574579
if curve.name == name:
575580
return curve
576581
raise ValueError("unknown curve name", name)
577582

578583

579-
utils.deprecated(
580-
get_elliptic_curve,
581-
__name__,
582-
(
583-
"get_elliptic_curve is deprecated. You should use the APIs in "
584-
"cryptography instead."
585-
),
586-
DeprecationWarning,
587-
name="get_elliptic_curve",
588-
)
589-
590-
591584
@functools.total_ordering
592585
class X509Name:
593586
"""
@@ -783,6 +776,10 @@ def get_components(self) -> list[tuple[bytes, bytes]]:
783776
return result
784777

785778

779+
@deprecated(
780+
"X509Extension support in pyOpenSSL is deprecated. You should use the "
781+
"APIs in cryptography."
782+
)
786783
class X509Extension:
787784
"""
788785
An X.509 v3 certificate extension.
@@ -953,19 +950,10 @@ def get_data(self) -> bytes:
953950
return _ffi.buffer(char_result, result_length)[:]
954951

955952

956-
_X509ExtensionInternal = X509Extension
957-
utils.deprecated(
958-
X509Extension,
959-
__name__,
960-
(
961-
"X509Extension support in pyOpenSSL is deprecated. You should use the "
962-
"APIs in cryptography."
963-
),
964-
DeprecationWarning,
965-
name="X509Extension",
953+
@deprecated(
954+
"CSR support in pyOpenSSL is deprecated. You should use the APIs "
955+
"in cryptography."
966956
)
967-
968-
969957
class X509Req:
970958
"""
971959
An X.509 certificate signing requests.
@@ -1091,9 +1079,7 @@ def get_subject(self) -> X509Name:
10911079

10921080
return name
10931081

1094-
def add_extensions(
1095-
self, extensions: Iterable[_X509ExtensionInternal]
1096-
) -> None:
1082+
def add_extensions(self, extensions: Iterable[X509Extension]) -> None:
10971083
"""
10981084
Add extensions to the certificate signing request.
10991085
@@ -1117,7 +1103,7 @@ def add_extensions(
11171103
stack = _ffi.gc(stack, _lib.sk_X509_EXTENSION_free)
11181104

11191105
for ext in extensions:
1120-
if not isinstance(ext, _X509ExtensionInternal):
1106+
if not isinstance(ext, X509Extension):
11211107
raise ValueError("One of the elements is not an X509Extension")
11221108

11231109
# TODO push can fail (here and elsewhere)
@@ -1126,7 +1112,7 @@ def add_extensions(
11261112
add_result = _lib.X509_REQ_add_extensions(self._req, stack)
11271113
_openssl_assert(add_result == 1)
11281114

1129-
def get_extensions(self) -> list[_X509ExtensionInternal]:
1115+
def get_extensions(self) -> list[X509Extension]:
11301116
"""
11311117
Get X.509 extensions in the certificate signing request.
11321118
@@ -1156,7 +1142,7 @@ def get_extensions(self) -> list[_X509ExtensionInternal]:
11561142
)
11571143

11581144
for i in range(_lib.sk_X509_EXTENSION_num(native_exts_obj)):
1159-
ext = _X509ExtensionInternal.__new__(_X509ExtensionInternal)
1145+
ext = X509Extension.__new__(X509Extension)
11601146
extension = _lib.X509_EXTENSION_dup(
11611147
_lib.sk_X509_EXTENSION_value(native_exts_obj, i)
11621148
)
@@ -1210,20 +1196,6 @@ def verify(self, pkey: PKey) -> bool:
12101196
return result
12111197

12121198

1213-
_X509ReqInternal = X509Req
1214-
1215-
utils.deprecated(
1216-
X509Req,
1217-
__name__,
1218-
(
1219-
"CSR support in pyOpenSSL is deprecated. You should use the APIs "
1220-
"in cryptography."
1221-
),
1222-
DeprecationWarning,
1223-
name="X509Req",
1224-
)
1225-
1226-
12271199
class X509:
12281200
"""
12291201
An X.509 certificate.
@@ -1655,9 +1627,7 @@ def get_extension_count(self) -> int:
16551627
"""
16561628
return _lib.X509_get_ext_count(self._x509)
16571629

1658-
def add_extensions(
1659-
self, extensions: Iterable[_X509ExtensionInternal]
1660-
) -> None:
1630+
def add_extensions(self, extensions: Iterable[X509Extension]) -> None:
16611631
"""
16621632
Add extensions to the certificate.
16631633
@@ -1676,13 +1646,13 @@ def add_extensions(
16761646
)
16771647

16781648
for ext in extensions:
1679-
if not isinstance(ext, _X509ExtensionInternal):
1649+
if not isinstance(ext, X509Extension):
16801650
raise ValueError("One of the elements is not an X509Extension")
16811651

16821652
add_result = _lib.X509_add_ext(self._x509, ext._extension, -1)
16831653
_openssl_assert(add_result == 1)
16841654

1685-
def get_extension(self, index: int) -> _X509ExtensionInternal:
1655+
def get_extension(self, index: int) -> X509Extension:
16861656
"""
16871657
Get a specific extension of the certificate by index.
16881658
@@ -1706,7 +1676,7 @@ def get_extension(self, index: int) -> _X509ExtensionInternal:
17061676
stacklevel=2,
17071677
)
17081678

1709-
ext = _X509ExtensionInternal.__new__(_X509ExtensionInternal)
1679+
ext = X509Extension.__new__(X509Extension)
17101680
ext._extension = _lib.X509_get_ext(self._x509, index)
17111681
if ext._extension == _ffi.NULL:
17121682
raise IndexError("extension index out of bounds")
@@ -2461,7 +2431,7 @@ def load_certificate_request(type: int, buffer: bytes) -> X509Req:
24612431

24622432
_openssl_assert(req != _ffi.NULL)
24632433

2464-
x509req = _X509ReqInternal.__new__(_X509ReqInternal)
2434+
x509req = X509Req.__new__(X509Req)
24652435
x509req._req = _ffi.gc(req, _lib.X509_REQ_free)
24662436
return x509req
24672437

tests/test_crypto.py

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
X509,
3737
Error,
3838
PKey,
39+
X509Extension,
3940
X509Name,
4041
X509Req,
4142
X509Store,
@@ -57,11 +58,6 @@
5758
load_publickey,
5859
)
5960

60-
with pytest.warns(DeprecationWarning):
61-
from OpenSSL.crypto import (
62-
X509Extension,
63-
)
64-
6561
from .util import (
6662
NON_ASCII,
6763
)

0 commit comments

Comments
 (0)