sethmlarson / truststore

Verify certificates using OS trust stores
https://truststore.readthedocs.io
MIT License
151 stars 18 forks source link

RecursionError: maximum recursion depth exceeded on Python 3.10.4 #94

Closed pradyunsg closed 1 year ago

pradyunsg commented 1 year ago

Behaviour

I'm hitting a RecursionError: maximum recursion depth exceeded while running https://github.com/pradyunsg/did with a patch to add truststore.inject_ssl() for use with httpx (i.e. not the requests/urllib3 stack). Patch below...

diff --git a/src/did.py b/src/did.py
index 31ebad3..a6eaf2b 100644
--- a/src/did.py
+++ b/src/did.py
@@ -6,6 +6,10 @@
 OSS update blog posts.
 """

+import truststore
+
+truststore.inject_into_ssl()
+
 __version__ = "0.1.0"

 import asyncio

I'm not quite sure why the recursion error is happening, but filing an issue eagerly to flag this to y'all. :)

Environment

❯ pip freeze
aiorwlock==1.3.0
anyio==3.6.2
attrs==22.2.0
certifi==2022.12.7
cffi==1.15.1
click==8.1.3
cryptography==40.0.1
fasteners==0.17.3
gidgethub==5.2.1
h11==0.14.0
httpcore==0.16.3
httpx==0.23.3
httpx-cache==0.7.0
idna==3.4
markdown-it-py==2.2.0
mdurl==0.1.2
msgpack==1.0.5
-e git+https://github.com/pradyunsg/did.git@60816da46caf348e8262698e21043bcd7e6d0118#egg=pradyunsg_did
pycparser==2.21
Pygments==2.14.0
PyJWT==2.6.0
rfc3986==1.5.0
rich==13.3.2
sniffio==1.3.0
truststore==0.6.0
uritemplate==4.1.1

Output

This is a traceback printed with rich.traceback with_locals=True, trimmed. You should see this if you run did this quarter or did this month after installing that repository.

[manual note: trimmed for brevity]
│ /Users/pgedam/Developer/github/did/src/did.py:481 in this                                        │
│                                                                                                  │
│   478 │   """stats for current [period header time]"""                                           │
│   479 │   period_ref, since, until = get_this_period(today=date.today(), period=period)          │
│   480 │   print(f"# Status update for {period_ref} ({since} to {until}*)")                       │
│ ❱ 481 │   main(since=since, until=until)                                                         │
│   482                                                                                            │
│   483                                                                                            │
│   484 @did.command("yesterday")                                                                  │
│                                                                                                  │
│ ╭──────────────── locals ─────────────────╮                                                      │
│ │     period = 'quarter'                  │                                                      │
│ │ period_ref = 'Q1 2023'                  │                                                      │
│ │      since = datetime.date(2023, 1, 1)  │                                                      │
│ │      until = datetime.date(2023, 3, 30) │                                                      │
│ ╰─────────────────────────────────────────╯                                                      │
│                                                                                                  │
│ /Users/pgedam/Developer/github/did/src/did.py:435 in main                                        │
│                                                                                                  │
│   432 def main(*, since: date, until: date) -> None:                                             │
│   433 │   print()                                                                                │
│   434 │   try:                                                                                   │
│ ❱ 435 │   │   asyncio.run(github(since, until))                                                  │
│   436 │   except gidgethub.BadRequest:                                                           │
│   437 │   │   rich.print(rich.traceback.Traceback(suppress=[asyncio]), file=sys.stderr)          │
│   438 │   │   gh_token_issue("Maybe the token expired? https://github.com/settings/tokens/")     │
│                                                                                                  │
│ ╭────────────── locals ──────────────╮                                                           │
│ │ since = datetime.date(2023, 1, 1)  │                                                           │
│ │ until = datetime.date(2023, 3, 30) │                                                           │
│ ╰────────────────────────────────────╯                                                           │
│                                                                                                  │
│ /Users/pgedam/.asdf/installs/python/3.10.4/lib/python3.10/asyncio/runners.py:44 in run           │
│                                                                                                  │
│ /Users/pgedam/.asdf/installs/python/3.10.4/lib/python3.10/asyncio/base_events.py:646 in          │
│ run_until_complete                                                                               │
│                                                                                                  │
│ /Users/pgedam/Developer/github/did/src/did.py:305 in github                                      │
│                                                                                                  │
│   302 │   #     "SponsorshipEvent",                                                              │
│   303 │   # }                                                                                    │
│   304 │                                                                                          │
│ ❱ 305 │   async with httpx_cache.AsyncClient(cache=CACHE) as client:                             │
│   306 │   │   gh = gidgethub.httpx.GitHubAPI(                                                    │
│   307 │   │   │   client,                                                                        │
│   308 │   │   │   "pradyunsg",                                                                   │
│                                                                                                  │
│ ╭─────────────────────────────────────────── locals ───────────────────────────────────────────╮ │
│ │  searches = {                                                                                │ │
│ │             │   'Issues created': 'author:pradyunsg type:issue                               │ │
│ │             created:2023-01-01..2023-03-30',                                                 │ │
│ │             │   'Assigned issues closed': 'assignee:pradyunsg type:issue                     │ │
│ │             closed:2023-01-01..2023-03-30',                                                  │ │
│ │             │   'PRs created': 'author:pradyunsg type:pr created:2023-01-01..2023-03-30',    │ │
│ │             │   'PRs reviewed': 'reviewed-by:pradyunsg type:pr                               │ │
│ │             reviewed:2023-01-01..2023-03-30',                                                │ │
│ │             │   'Assigned PRs closed': 'assignee:pradyunsg type:pr                           │ │
│ │             closed:2023-01-01..2023-03-30'                                                   │ │
│ │             }                                                                                │ │
│ │     since = datetime.date(2023, 1, 1)                                                        │ │
│ │ time_term = '2023-01-01..2023-03-30'                                                         │ │
│ │     until = datetime.date(2023, 3, 30)                                                       │ │
│ ╰──────────────────────────────────────────────────────────────────────────────────────────────╯ │
│                                                                                                  │
│ /Users/pgedam/Developer/github/did/.venv/lib/python3.10/site-packages/httpx_cache/client.py:167  │
│ in __init__                                                                                      │
│                                                                                                  │
│ /Users/pgedam/Developer/github/did/.venv/lib/python3.10/site-packages/httpx/_client.py:1400 in   │
│ __init__                                                                                         │
│                                                                                                  │
│ /Users/pgedam/Developer/github/did/.venv/lib/python3.10/site-packages/httpx_cache/client.py:200  │
│ in _init_transport                                                                               │
│                                                                                                  │
│ /Users/pgedam/Developer/github/did/.venv/lib/python3.10/site-packages/httpx/_client.py:1448 in   │
│ _init_transport                                                                                  │
│                                                                                                  │
│ /Users/pgedam/Developer/github/did/.venv/lib/python3.10/site-packages/httpx/_transports/default. │
│ py:261 in __init__                                                                               │
│                                                                                                  │
│ /Users/pgedam/Developer/github/did/.venv/lib/python3.10/site-packages/httpx/_config.py:51 in     │
│ create_ssl_context                                                                               │
│                                                                                                  │
│ /Users/pgedam/Developer/github/did/.venv/lib/python3.10/site-packages/httpx/_config.py:75 in     │
│ __init__                                                                                         │
│                                                                                                  │
│ /Users/pgedam/Developer/github/did/.venv/lib/python3.10/site-packages/httpx/_config.py:87 in     │
│ load_ssl_context                                                                                 │
│                                                                                                  │
│ /Users/pgedam/Developer/github/did/.venv/lib/python3.10/site-packages/httpx/_config.py:124 in    │
│ load_ssl_context_verify                                                                          │
│                                                                                                  │
│ /Users/pgedam/Developer/github/did/.venv/lib/python3.10/site-packages/httpx/_config.py:160 in    │
│ _create_default_ssl_context                                                                      │
│                                                                                                  │
│ /Users/pgedam/Developer/github/did/.venv/lib/python3.10/site-packages/httpx/_compat.py:30 in     │
│ set_minimum_tls_version_1_2                                                                      │
│                                                                                                  │
│ /Users/pgedam/Developer/github/did/.venv/lib/python3.10/site-packages/truststore/_api.py:226 in  │
│ minimum_version                                                                                  │
│                                                                                                  │
│   223 │                                                                                          │
│   224 │   @minimum_version.setter                                                                │
│   225 │   def minimum_version(self, value: ssl.TLSVersion) -> None:                              │
│ ❱ 226 │   │   self._ctx.minimum_version = value                                                  │
│   227 │                                                                                          │
│   228 │   @property                                                                              │
│   229 │   def options(self) -> ssl.Options:                                                      │
│                                                                                                  │
│ ╭────────────────────────── locals ──────────────────────────╮                                   │
│ │  self = <truststore._api.SSLContext object at 0x105e2f8c0> │                                   │
│ │ value = <TLSVersion.TLSv1_2: 771>                          │                                   │
│ ╰────────────────────────────────────────────────────────────╯                                   │
│                                                                                                  │
│ /Users/pgedam/.asdf/installs/python/3.10.4/lib/python3.10/ssl.py:603 in minimum_version          │
│                                                                                                  │
│    600 │   │   def minimum_version(self, value):                                                 │
│    601 │   │   │   if value == TLSVersion.SSLv3:                                                 │
│    602 │   │   │   │   self.options &= ~Options.OP_NO_SSLv3                                      │
│ ❱  603 │   │   │   super(SSLContext, SSLContext).minimum_version.__set__(self, value)            │
│    604 │   │                                                                                     │
│    605 │   │   @property                                                                         │
│    606 │   │   def maximum_version(self):                                                        │
│                                                                                                  │
[manual note: this stack entry is repeated a _lot_ of times, trimmed for brevity]
│ ╭──────────────────── locals ────────────────────╮                                               │
│ │  self = <ssl.SSLContext object at 0x105edc7c0> │                                               │
│ │ value = <TLSVersion.TLSv1_2: 771>              │                                               │
│ ╰────────────────────────────────────────────────╯                                               │
│                                                                                                  │
│ /Users/pgedam/.asdf/installs/python/3.10.4/lib/python3.10/ssl.py:603 in minimum_version          │
│                                                                                                  │
│    600 │   │   def minimum_version(self, value):                                                 │
│    601 │   │   │   if value == TLSVersion.SSLv3:                                                 │
│    602 │   │   │   │   self.options &= ~Options.OP_NO_SSLv3                                      │
│ ❱  603 │   │   │   super(SSLContext, SSLContext).minimum_version.__set__(self, value)            │
│    604 │   │                                                                                     │
│    605 │   │   @property                                                                         │
│    606 │   │   def maximum_version(self):                                                        │
│                                                                                                  │
│ ╭──────────────────── locals ────────────────────╮                                               │
│ │  self = <ssl.SSLContext object at 0x105edc7c0> │                                               │
│ │ value = <TLSVersion.TLSv1_2: 771>              │                                               │
│ ╰────────────────────────────────────────────────╯                                               │
│                                                                                                  │
│ /Users/pgedam/.asdf/installs/python/3.10.4/lib/python3.10/ssl.py:603 in minimum_version          │
│                                                                                                  │
│    600 │   │   def minimum_version(self, value):                                                 │
│    601 │   │   │   if value == TLSVersion.SSLv3:                                                 │
│    602 │   │   │   │   self.options &= ~Options.OP_NO_SSLv3                                      │
│ ❱  603 │   │   │   super(SSLContext, SSLContext).minimum_version.__set__(self, value)            │
│    604 │   │                                                                                     │
│    605 │   │   @property                                                                         │
│    606 │   │   def maximum_version(self):                                                        │
│                                                                                                  │
│ ╭──────────────────── locals ────────────────────╮                                               │
│ │  self = <ssl.SSLContext object at 0x105edc7c0> │                                               │
│ │ value = <TLSVersion.TLSv1_2: 771>              │                                               │
│ ╰────────────────────────────────────────────────╯                                               │
╰──────────────────────────────────────────────────────────────────────────────────────────────────╯
RecursionError: maximum recursion depth exceeded
sethmlarson commented 1 year ago

Thanks for reporting this, I was able to quickly reproduce! I'll get a fix out shortly :)

sethmlarson commented 1 year ago

@pradyunsg Release v0.6.1 with the fix, thanks for reporting!