Skip to content

Commit f5618b0

Browse files
authored
Merge pull request #222 from aiokitchen/fix-docbuild
Python 3.13 support
2 parents eac0bcd + 8d2598c commit f5618b0

File tree

10 files changed

+738
-669
lines changed

10 files changed

+738
-669
lines changed

.github/workflows/tests.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,11 +55,11 @@ jobs:
5555

5656
matrix:
5757
python:
58-
- '3.8'
5958
- '3.9'
6059
- '3.10'
6160
- '3.11'
6261
- '3.12'
62+
- '3.13'
6363
steps:
6464
- uses: actions/checkout@v2
6565
- name: Setup python${{ matrix.python }}

aiomisc/process_pool.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,9 @@ def _statistic_callback(
3939
self._statistic.sum_time += loop.time() - start_time
4040

4141
def submit(self, *args: Any, **kwargs: Any) -> Future:
42-
"""Submit blocking function to the pool"""
42+
"""
43+
Submit blocking function to the pool
44+
"""
4345
loop = asyncio.get_running_loop()
4446
start_time = loop.time()
4547
future = super().submit(*args, **kwargs)

aiomisc/service/tls.py

Lines changed: 57 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,19 @@
1717
log = logging.getLogger(__name__)
1818

1919

20+
DEFAULT_SSL_CIPHERS = (
21+
"ECDHE-RSA-AES256-GCM-SHA384",
22+
"ECDHE-ECDSA-AES256-GCM-SHA384",
23+
"ECDHE-RSA-CHACHA20-POLY1305",
24+
"ECDHE-ECDSA-CHACHA20-POLY1305",
25+
"ECDHE-RSA-AES128-GCM-SHA256",
26+
"ECDHE-ECDSA-AES128-GCM-SHA256",
27+
)
28+
29+
DEFAULT_SSL_MIN_VERSION = ssl.TLSVersion.TLSv1_3
30+
DEFAULT_SSL_MAX_VERSION = ssl.TLSVersion.TLSv1_3
31+
32+
2033
@dataclass(frozen=True)
2134
class SSLOptionsBase:
2235
cert: Optional[Path]
@@ -25,13 +38,19 @@ class SSLOptionsBase:
2538
verify: bool
2639
require_client_cert: bool
2740
purpose: ssl.Purpose
41+
minimum_version: ssl.TLSVersion = DEFAULT_SSL_MIN_VERSION
42+
maximum_version: ssl.TLSVersion = DEFAULT_SSL_MAX_VERSION
43+
ciphers: Tuple[str, ...] = DEFAULT_SSL_CIPHERS
2844

2945

3046
class SSLOptions(SSLOptionsBase):
3147
def __init__(
3248
self, cert: Optional[PathOrStr], key: Optional[PathOrStr],
3349
ca: Optional[PathOrStr], verify: bool, require_client_cert: bool,
3450
purpose: ssl.Purpose,
51+
minimum_version: ssl.TLSVersion = DEFAULT_SSL_MIN_VERSION,
52+
maximum_version: ssl.TLSVersion = DEFAULT_SSL_MAX_VERSION,
53+
ciphers: Tuple[str, ...] = DEFAULT_SSL_CIPHERS,
3554
) -> None:
3655
super().__init__(
3756
cert=Path(cert) if cert else None,
@@ -40,25 +59,48 @@ def __init__(
4059
verify=verify,
4160
require_client_cert=require_client_cert,
4261
purpose=purpose,
62+
minimum_version=minimum_version,
63+
maximum_version=maximum_version,
64+
ciphers=ciphers,
4365
)
4466

4567
def create_context(self) -> ssl.SSLContext:
4668
context = ssl.create_default_context(
47-
purpose=self.purpose, cafile=self.ca,
69+
purpose=self.purpose,
4870
)
4971

50-
if self.ca and not self.ca.exists():
51-
raise FileNotFoundError("CA file doesn't exists")
72+
# Disable compression to prevent CRIME attacks
73+
context.options |= ssl.OP_NO_COMPRESSION
74+
75+
context.maximum_version = self.maximum_version
76+
context.minimum_version = self.minimum_version
77+
context.set_ciphers(":".join(self.ciphers))
78+
79+
if not self.verify:
80+
context.check_hostname = False
81+
82+
if self.ca:
83+
log.debug("Loading CA from %s", self.ca)
84+
if not self.ca.exists():
85+
raise FileNotFoundError(
86+
"CA file doesn't exists", str(self.ca.resolve()),
87+
)
88+
context.load_verify_locations(cafile=str(self.ca))
5289

5390
if self.require_client_cert:
91+
log.debug("Set server-side cert verification")
5492
context.verify_mode = ssl.VerifyMode.CERT_REQUIRED
93+
# Post-handshake authentication is required
94+
context.post_handshake_auth = True
95+
else:
96+
# Disable server-side cert verification
97+
context.check_hostname = False
98+
context.verify_mode = ssl.VerifyMode.CERT_NONE
5599

100+
# Load server-side cert and key
56101
if self.key and self.cert:
57102
context.load_cert_chain(self.cert, self.key)
58103

59-
if not self.verify:
60-
context.check_hostname = False
61-
62104
return context
63105

64106

@@ -69,13 +111,20 @@ def __init__(
69111
self, *, address: Optional[str] = None, port: Optional[int] = None,
70112
cert: PathOrStr, key: PathOrStr, ca: Optional[PathOrStr] = None,
71113
require_client_cert: bool = False, verify: bool = True,
114+
minimum_version: ssl.TLSVersion = DEFAULT_SSL_MIN_VERSION,
115+
maximum_version: ssl.TLSVersion = DEFAULT_SSL_MAX_VERSION,
116+
ciphers: Tuple[str, ...] = DEFAULT_SSL_CIPHERS,
72117
options: OptionsType = (), sock: Optional[socket.socket] = None,
73118
**kwargs: Any,
74119
):
75120

76121
self.__ssl_options = SSLOptions(
77-
cert, key, ca, verify, require_client_cert,
78-
ssl.Purpose.CLIENT_AUTH,
122+
cert=cert, key=key, ca=ca, verify=verify,
123+
require_client_cert=require_client_cert,
124+
purpose=ssl.Purpose.CLIENT_AUTH,
125+
minimum_version=minimum_version,
126+
maximum_version=maximum_version,
127+
ciphers=ciphers,
79128
)
80129

81130
if not sock:

docs/source/index.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ aiomisc - miscellaneous utils for asyncio
55
:target: https://coveralls.io/github/aiokitchen/aiomisc
66
:alt: Coveralls
77

8-
.. image:: https://github.com/aiokitchen/aiomisc/workflows/tox/badge.svg
9-
:target: https://github.com/aiokitchen/aiomisc/actions?query=workflow%3Atox
8+
.. image:: https://github.com/aiokitchen/aiomisc/actions/workflows/tests.yml/badge.svg
9+
:target: https://github.com/aiokitchen/aiomisc/actions/workflows/tests.yml
1010
:alt: Actions
1111

1212
.. image:: https://img.shields.io/pypi/v/aiomisc.svg

docs/source/locale/ru/LC_MESSAGES/api/aiomisc.po

Lines changed: 42 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,14 @@ msgid ""
66
msgstr ""
77
"Project-Id-Version: aiomisc 16.1.16\n"
88
"Report-Msgid-Bugs-To: \n"
9-
"POT-Creation-Date: 2024-06-03 23:11+0200\n"
9+
"POT-Creation-Date: 2025-03-03 13:05+0100\n"
1010
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
1111
"Last-Translator: Ivan Sitkin <[email protected]>\n"
1212
"Language-Team: LANGUAGE <[email protected]>\n"
1313
"MIME-Version: 1.0\n"
1414
"Content-Type: text/plain; charset=utf-8\n"
1515
"Content-Transfer-Encoding: 8bit\n"
16-
"Generated-By: Babel 2.15.0\n"
16+
"Generated-By: Babel 2.17.0\n"
1717

1818
#: ../../source/api/aiomisc.rst:2
1919
msgid "``aiomisc`` module"
@@ -321,6 +321,7 @@ msgid ""
321321
msgstr ""
322322

323323
#: of typing.ParamSpec:15
324+
#, python-brace-format
324325
msgid ""
325326
"T = TypeVar('T')\n"
326327
"P = ParamSpec('P')\n"
@@ -585,6 +586,45 @@ msgstr ""
585586
msgid "``aiomisc.log`` module"
586587
msgstr "Модуль ``aiomisc.log``"
587588

589+
#: aiomisc.log.ThreadedHandler:1 of
590+
msgid "Bases: :py:class:`~logging.Handler`"
591+
msgstr ""
592+
593+
#: aiomisc.log.ThreadedHandler:1 of
594+
msgid ""
595+
"Initializes the instance - basically setting the formatter to None and "
596+
"the filter list to empty."
597+
msgstr ""
598+
599+
#: aiomisc.log.ThreadedHandler.close:1 of
600+
msgid "Tidy up any resources used by the handler."
601+
msgstr ""
602+
603+
#: aiomisc.log.ThreadedHandler.close:3 of
604+
msgid ""
605+
"This version removes the handler from an internal map of handlers, "
606+
"_handlers, which is used for handler lookup by name. Subclasses should "
607+
"ensure that this gets called from overridden close() methods."
608+
msgstr ""
609+
610+
#: aiomisc.log.ThreadedHandler.emit:1 of
611+
msgid "Do whatever it takes to actually log the specified logging record."
612+
msgstr ""
613+
614+
#: aiomisc.log.ThreadedHandler.emit:3 of
615+
msgid ""
616+
"This version is intended to be implemented by subclasses and so raises a "
617+
"NotImplementedError."
618+
msgstr ""
619+
620+
#: aiomisc.log.ThreadedHandler.flush:1 of
621+
msgid "Ensure all logging output has been flushed."
622+
msgstr ""
623+
624+
#: aiomisc.log.ThreadedHandler.flush:3 of
625+
msgid "This version does nothing and is intended to be implemented by subclasses."
626+
msgstr ""
627+
588628
#: ../../source/api/aiomisc.rst:93
589629
msgid "``aiomisc.periodic`` module"
590630
msgstr "Модуль ``aiomisc.periodic``"

0 commit comments

Comments
 (0)