Skip to content

Commit f7df71f

Browse files
cipherboyDanielNoordcdce8p
authored
Add missing ssl enums to astroid/brain (#1381)
Signed-off-by: Alexander Scheel <[email protected]> Co-authored-by: Daniël van Noord <[email protected]> Co-authored-by: Marc Mueller <[email protected]>
1 parent 20adb54 commit f7df71f

File tree

4 files changed

+136
-10
lines changed

4 files changed

+136
-10
lines changed

ChangeLog

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,10 @@ Release date: TBA
2222

2323
Closes PyCQA/pylint#3518
2424

25+
* Adds missing enums from ``ssl`` module.
26+
27+
Closes PyCQA/pylint#3691
28+
2529
* Remove dependency on ``pkg_resources`` from ``setuptools``.
2630

2731
Closes #1103

astroid/brain/brain_ssl.py

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,54 @@
66

77
from astroid import parse
88
from astroid.brain.helpers import register_module_extender
9+
from astroid.const import PY38_PLUS, PY310_PLUS
910
from astroid.manager import AstroidManager
1011

1112

13+
def _verifyflags_enum() -> str:
14+
enum = """
15+
class VerifyFlags(_IntFlag):
16+
VERIFY_DEFAULT = 0
17+
VERIFY_CRL_CHECK_LEAF = 1
18+
VERIFY_CRL_CHECK_CHAIN = 2
19+
VERIFY_X509_STRICT = 3
20+
VERIFY_X509_TRUSTED_FIRST = 4"""
21+
if PY310_PLUS:
22+
enum += """
23+
VERIFY_ALLOW_PROXY_CERTS = 5
24+
VERIFY_X509_PARTIAL_CHAIN = 6
25+
"""
26+
return enum
27+
28+
29+
def _options_enum() -> str:
30+
enum = """
31+
class Options(_IntFlag):
32+
OP_ALL = 1
33+
OP_NO_SSLv2 = 2
34+
OP_NO_SSLv3 = 3
35+
OP_NO_TLSv1 = 4
36+
OP_NO_TLSv1_1 = 5
37+
OP_NO_TLSv1_2 = 6
38+
OP_NO_TLSv1_3 = 7
39+
OP_CIPHER_SERVER_PREFERENCE = 8
40+
OP_SINGLE_DH_USE = 9
41+
OP_SINGLE_ECDH_USE = 10
42+
OP_NO_COMPRESSION = 11
43+
OP_NO_TICKET = 12
44+
OP_NO_RENEGOTIATION = 13"""
45+
if PY38_PLUS:
46+
enum += """
47+
OP_ENABLE_MIDDLEBOX_COMPAT = 14"""
48+
return enum
49+
50+
1251
def ssl_transform():
1352
return parse(
1453
"""
54+
# Import necessary for conversion of objects defined in C into enums
55+
from enum import IntEnum as _IntEnum, IntFlag as _IntFlag
56+
1557
from _ssl import OPENSSL_VERSION_NUMBER, OPENSSL_VERSION_INFO, OPENSSL_VERSION
1658
from _ssl import _SSLContext, MemoryBIO
1759
from _ssl import (
@@ -64,7 +106,54 @@ def ssl_transform():
64106
from _ssl import _OPENSSL_API_VERSION
65107
from _ssl import PROTOCOL_SSLv23, PROTOCOL_TLSv1, PROTOCOL_TLSv1_1, PROTOCOL_TLSv1_2
66108
from _ssl import PROTOCOL_TLS, PROTOCOL_TLS_CLIENT, PROTOCOL_TLS_SERVER
109+
110+
class AlertDescription(_IntEnum):
111+
ALERT_DESCRIPTION_ACCESS_DENIED = 0
112+
ALERT_DESCRIPTION_BAD_CERTIFICATE = 1
113+
ALERT_DESCRIPTION_BAD_CERTIFICATE_HASH_VALUE = 2
114+
ALERT_DESCRIPTION_BAD_CERTIFICATE_STATUS_RESPONSE = 3
115+
ALERT_DESCRIPTION_BAD_RECORD_MAC = 4
116+
ALERT_DESCRIPTION_CERTIFICATE_EXPIRED = 5
117+
ALERT_DESCRIPTION_CERTIFICATE_REVOKED = 6
118+
ALERT_DESCRIPTION_CERTIFICATE_UNKNOWN = 7
119+
ALERT_DESCRIPTION_CERTIFICATE_UNOBTAINABLE = 8
120+
ALERT_DESCRIPTION_CLOSE_NOTIFY = 9
121+
ALERT_DESCRIPTION_DECODE_ERROR = 10
122+
ALERT_DESCRIPTION_DECOMPRESSION_FAILURE = 11
123+
ALERT_DESCRIPTION_DECRYPT_ERROR = 12
124+
ALERT_DESCRIPTION_HANDSHAKE_FAILURE = 13
125+
ALERT_DESCRIPTION_ILLEGAL_PARAMETER = 14
126+
ALERT_DESCRIPTION_INSUFFICIENT_SECURITY = 15
127+
ALERT_DESCRIPTION_INTERNAL_ERROR = 16
128+
ALERT_DESCRIPTION_NO_RENEGOTIATION = 17
129+
ALERT_DESCRIPTION_PROTOCOL_VERSION = 18
130+
ALERT_DESCRIPTION_RECORD_OVERFLOW = 19
131+
ALERT_DESCRIPTION_UNEXPECTED_MESSAGE = 20
132+
ALERT_DESCRIPTION_UNKNOWN_CA = 21
133+
ALERT_DESCRIPTION_UNKNOWN_PSK_IDENTITY = 22
134+
ALERT_DESCRIPTION_UNRECOGNIZED_NAME = 23
135+
ALERT_DESCRIPTION_UNSUPPORTED_CERTIFICATE = 24
136+
ALERT_DESCRIPTION_UNSUPPORTED_EXTENSION = 25
137+
ALERT_DESCRIPTION_USER_CANCELLED = 26
138+
139+
class SSLErrorNumber(_IntEnum):
140+
SSL_ERROR_EOF = 0
141+
SSL_ERROR_INVALID_ERROR_CODE = 1
142+
SSL_ERROR_SSL = 2
143+
SSL_ERROR_SYSCALL = 3
144+
SSL_ERROR_WANT_CONNECT = 4
145+
SSL_ERROR_WANT_READ = 5
146+
SSL_ERROR_WANT_WRITE = 6
147+
SSL_ERROR_WANT_X509_LOOKUP = 7
148+
SSL_ERROR_ZERO_RETURN = 8
149+
150+
class VerifyMode(_IntEnum):
151+
CERT_NONE = 0
152+
CERT_OPTIONAL = 1
153+
CERT_REQUIRED = 2
67154
"""
155+
+ _verifyflags_enum()
156+
+ _options_enum()
68157
)
69158

70159

tests/test_brain_ssl.py

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html
2+
# For details: https://github.com/PyCQA/astroid/blob/main/LICENSE
3+
# Copyright (c) https://github.com/PyCQA/astroid/blob/main/CONTRIBUTORS.txt
4+
5+
"""Tests for the ssl brain."""
6+
7+
from astroid import bases, nodes, parse
8+
9+
10+
def test_ssl_brain() -> None:
11+
"""Test ssl brain transform."""
12+
module = parse(
13+
"""
14+
import ssl
15+
ssl.PROTOCOL_TLSv1
16+
ssl.VerifyMode
17+
ssl.TLSVersion
18+
ssl.VerifyMode.CERT_REQUIRED
19+
"""
20+
)
21+
inferred_protocol = next(module.body[1].value.infer())
22+
assert isinstance(inferred_protocol, nodes.Const)
23+
24+
inferred_verifymode = next(module.body[2].value.infer())
25+
assert isinstance(inferred_verifymode, nodes.ClassDef)
26+
assert inferred_verifymode.name == "VerifyMode"
27+
assert len(inferred_verifymode.bases) == 1
28+
29+
# Check that VerifyMode correctly inherits from enum.IntEnum
30+
int_enum = next(inferred_verifymode.bases[0].infer())
31+
assert isinstance(int_enum, nodes.ClassDef)
32+
assert int_enum.name == "IntEnum"
33+
assert int_enum.parent.name == "enum"
34+
35+
# TLSVersion is inferred from the main module, not from the brain
36+
inferred_tlsversion = next(module.body[3].value.infer())
37+
assert isinstance(inferred_tlsversion, nodes.ClassDef)
38+
assert inferred_tlsversion.name == "TLSVersion"
39+
40+
# TLSVersion is inferred from the main module, not from the brain
41+
inferred_cert_required = next(module.body[4].value.infer())
42+
assert isinstance(inferred_cert_required, bases.Instance)
43+
assert inferred_cert_required._proxied.name == "CERT_REQUIRED"

tests/unittest_regrtest.py

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -304,16 +304,6 @@ def foo(self): #@
304304
inferred = next(node.infer())
305305
self.assertEqual(inferred.decoratornames(), {".Parent.foo.getter"})
306306

307-
def test_ssl_protocol(self) -> None:
308-
node = extract_node(
309-
"""
310-
import ssl
311-
ssl.PROTOCOL_TLSv1
312-
"""
313-
)
314-
inferred = next(node.infer())
315-
self.assertIsInstance(inferred, nodes.Const)
316-
317307
def test_recursive_property_method(self) -> None:
318308
node = extract_node(
319309
"""

0 commit comments

Comments
 (0)