Description
The recently landed Python 3.11 deprecation warning fix released in 2022.6.15.1 on 9 Sept 2022 causes certifi to throw a ValueError
on Python 3.10 and a TypeError
on Python 3.9 when using an importer (like PyOxidizer's OxidizedImporter
) that doesn't support the relatively-new "Traversable" / files()
importlib API. This is because the full adapter layer for the older importlib resources API doesn't exist until Python 3.11.
On 3.10, the error is intentionally raised in the stdlib's DegenerateFiles
class:
https://github.com/python/cpython/blob/3.10/Lib/importlib/_adapters.py#L53-L54
...
File "certifi.core", line 37, in where
File "contextlib", line 135, in __enter__
File "importlib._common", line 89, in _tempfile
File "importlib.abc", line 371, in read_bytes
File "importlib._adapters", line 54, in open
ValueError
because the "adapter" in 3.10 exists only to fail, it seems.
On 3.9, the error is because the stdlib's files()
function assumes that certifi.__file__
(as certifi.__spec__.origin
) is not None
:
https://github.com/python/cpython/blob/3.9/Lib/importlib/_common.py#L17-L18
…
File "certifi.core", line 36, in where
File "importlib.resources", line 147, in files
File "importlib._common", line 14, in from_package
File "importlib._common", line 18, in fallback_resources
File "pathlib", line 1082, in __new__
File "pathlib", line 707, in _from_parts
File "pathlib", line 691, in _parse_args
TypeError: expected str, bytes or os.PathLike object, not NoneType
Two separate possible solutions come to mind:
- Gate the usage of the Traversable importlib API on Python ≥3.11 instead of ≥3.9, thus letting 3.9 and 3.10 use the older, more established API more likely to be supported by third-party importers.
- Gate the usage of the same on a feature-test for support by the actual
certifi.__loader__
in addition to the Python version. I'm not sure how to actually do this at the moment, but I assume it's possible.
Option 1 certainly seems simpler to me.