1+ # -*- coding: utf-8 -*- 
2+ 
13""" 
24certifi.py 
35~~~~~~~~~~ 
46
57This module returns the installation location of cacert.pem or its contents. 
68""" 
79import  os 
8- import  types 
9- from  typing  import  Union 
10+ import  sys 
11+ 
12+ 
13+ if  sys .version_info  >=  (3 , 9 ):
1014
11- try :
12-     from  importlib .resources  import  path  as  get_path , read_text 
15+     from  importlib .resources  import  as_file , files 
1316
1417    _CACERT_CTX  =  None 
1518    _CACERT_PATH  =  None 
@@ -33,36 +36,59 @@ def where() -> str:
3336            # We also have to hold onto the actual context manager, because 
3437            # it will do the cleanup whenever it gets garbage collected, so 
3538            # we will also store that at the global level as well. 
36-             _CACERT_CTX  =  get_path ( "certifi" ,  "cacert.pem" )
39+             _CACERT_CTX  =  as_file ( files ( "certifi" ). joinpath ( "cacert.pem" ) )
3740            _CACERT_PATH  =  str (_CACERT_CTX .__enter__ ())
3841
3942        return  _CACERT_PATH 
4043
44+ else :
4145
42- except  ImportError :
43-     Package  =  Union [types .ModuleType , str ]
44-     Resource  =  Union [str , "os.PathLike" ]
45- 
46-     # This fallback will work for Python versions prior to 3.7 that lack the 
47-     # importlib.resources module but relies on the existing `where` function 
48-     # so won't address issues with environments like PyOxidizer that don't set 
49-     # __file__ on modules. 
50-     def  read_text (
51-         package : Package ,
52-         resource : Resource ,
53-         encoding : str  =  'utf-8' ,
54-         errors : str  =  'strict' 
55-     ) ->  str :
56-         with  open (where (), encoding = encoding ) as  data :
57-             return  data .read ()
58- 
59-     # If we don't have importlib.resources, then we will just do the old logic 
60-     # of assuming we're on the filesystem and munge the path directly. 
61-     def  where () ->  str :
62-         f  =  os .path .dirname (__file__ )
46+     try :
47+         from  importlib .resources  import  path  as  get_path 
48+ 
49+         _CACERT_CTX  =  None 
50+         _CACERT_PATH  =  None 
51+ 
52+         def  where () ->  str :
53+             # This is slightly terrible, but we want to delay extracting the 
54+             # file in cases where we're inside of a zipimport situation until 
55+             # someone actually calls where(), but we don't want to re-extract 
56+             # the file on every call of where(), so we'll do it once then store 
57+             # it in a global variable. 
58+             global  _CACERT_CTX 
59+             global  _CACERT_PATH 
60+             if  _CACERT_PATH  is  None :
61+                 # This is slightly janky, the importlib.resources API wants you 
62+                 # to manage the cleanup of this file, so it doesn't actually 
63+                 # return a path, it returns a context manager that will give 
64+                 # you the path when you enter it and will do any cleanup when 
65+                 # you leave it. In the common case of not needing a temporary 
66+                 # file, it will just return the file system location and the 
67+                 # __exit__() is a no-op. 
68+                 # 
69+                 # We also have to hold onto the actual context manager, because 
70+                 # it will do the cleanup whenever it gets garbage collected, so 
71+                 # we will also store that at the global level as well. 
72+                 _CACERT_CTX  =  get_path ("certifi" , "cacert.pem" )
73+                 _CACERT_PATH  =  str (_CACERT_CTX .__enter__ ())
74+ 
75+             return  _CACERT_PATH 
76+ 
77+     except  ImportError :
78+         # This fallback will work for Python versions prior to 3.7 that lack 
79+         # the importlib.resources module but relies on the existing `where` 
80+         # function so won't address issues with environments like PyOxidizer 
81+         # that don't set __file__ on modules. 
82+ 
83+         # If we don't have importlib.resources, then we will just do the old 
84+         # logic of assuming we're on the filesystem and munge the path 
85+         # directly. 
86+         def  where () ->  str :
87+             f  =  os .path .dirname (__file__ )
6388
64-         return  os .path .join (f , "cacert.pem" )
89+              return  os .path .join (f , "cacert.pem" )
6590
6691
6792def  contents () ->  str :
68-     return  read_text ("certifi" , "cacert.pem" , encoding = "ascii" )
93+     with  open (where (), "r" , encoding = "ascii" ) as  fp :
94+         return  fp .read ()
0 commit comments