1- # -*- coding: utf-8 -*-
2-
31"""
42certifi.py
53~~~~~~~~~~
64
75This module returns the installation location of cacert.pem or its contents.
86"""
9- import os
7+ import sys
108
11- try :
12- from importlib .resources import path as get_path , read_text
9+
10+ if sys .version_info >= (3 , 11 ):
11+
12+ from importlib .resources import as_file , files
1313
1414 _CACERT_CTX = None
1515 _CACERT_PATH = None
1616
17- def where ():
17+ def where () -> str :
1818 # This is slightly terrible, but we want to delay extracting the file
1919 # in cases where we're inside of a zipimport situation until someone
2020 # actually calls where(), but we don't want to re-extract the file
@@ -33,28 +33,76 @@ def where():
3333 # We also have to hold onto the actual context manager, because
3434 # it will do the cleanup whenever it gets garbage collected, so
3535 # we will also store that at the global level as well.
36+ _CACERT_CTX = as_file (files ("certifi" ).joinpath ("cacert.pem" ))
37+ _CACERT_PATH = str (_CACERT_CTX .__enter__ ())
38+
39+ return _CACERT_PATH
40+
41+ def contents () -> str :
42+ return files ("certifi" ).joinpath ("cacert.pem" ).read_text (encoding = "ascii" )
43+
44+ elif sys .version_info >= (3 , 7 ):
45+
46+ from importlib .resources import path as get_path , read_text
47+
48+ _CACERT_CTX = None
49+ _CACERT_PATH = None
50+
51+ def where () -> str :
52+ # This is slightly terrible, but we want to delay extracting the
53+ # file in cases where we're inside of a zipimport situation until
54+ # someone actually calls where(), but we don't want to re-extract
55+ # the file on every call of where(), so we'll do it once then store
56+ # it in a global variable.
57+ global _CACERT_CTX
58+ global _CACERT_PATH
59+ if _CACERT_PATH is None :
60+ # This is slightly janky, the importlib.resources API wants you
61+ # to manage the cleanup of this file, so it doesn't actually
62+ # return a path, it returns a context manager that will give
63+ # you the path when you enter it and will do any cleanup when
64+ # you leave it. In the common case of not needing a temporary
65+ # file, it will just return the file system location and the
66+ # __exit__() is a no-op.
67+ #
68+ # We also have to hold onto the actual context manager, because
69+ # it will do the cleanup whenever it gets garbage collected, so
70+ # we will also store that at the global level as well.
3671 _CACERT_CTX = get_path ("certifi" , "cacert.pem" )
3772 _CACERT_PATH = str (_CACERT_CTX .__enter__ ())
3873
3974 return _CACERT_PATH
4075
76+ def contents () -> str :
77+ return read_text ("certifi" , "cacert.pem" , encoding = "ascii" )
78+
79+ else :
80+ import os
81+ import types
82+ from typing import Union
83+
84+ Package = Union [types .ModuleType , str ]
85+ Resource = Union [str , "os.PathLike" ]
4186
42- except ImportError :
4387 # This fallback will work for Python versions prior to 3.7 that lack the
4488 # importlib.resources module but relies on the existing `where` function
4589 # so won't address issues with environments like PyOxidizer that don't set
4690 # __file__ on modules.
47- def read_text (_module , _path , encoding = "ascii" ):
48- with open (where (), "r" , encoding = encoding ) as data :
91+ def read_text (
92+ package : Package ,
93+ resource : Resource ,
94+ encoding : str = 'utf-8' ,
95+ errors : str = 'strict'
96+ ) -> str :
97+ with open (where (), encoding = encoding ) as data :
4998 return data .read ()
5099
51100 # If we don't have importlib.resources, then we will just do the old logic
52101 # of assuming we're on the filesystem and munge the path directly.
53- def where ():
102+ def where () -> str :
54103 f = os .path .dirname (__file__ )
55104
56105 return os .path .join (f , "cacert.pem" )
57106
58-
59- def contents ():
60- return read_text ("certifi" , "cacert.pem" , encoding = "ascii" )
107+ def contents () -> str :
108+ return read_text ("certifi" , "cacert.pem" , encoding = "ascii" )
0 commit comments