6
6
import struct
7
7
import subprocess
8
8
import sys
9
+ from collections .abc import Iterable , Sequence
9
10
from functools import partial
11
+ from pathlib import Path
10
12
11
13
12
14
__all__ = [
@@ -85,18 +87,6 @@ def add_excepthook(hook):
85
87
sys .excepthook = __call_excepthooks
86
88
87
89
88
- def exc_message (e ):
89
- """
90
- In python 3.x, when an exception is reraised it saves original
91
- exception in its args, therefore in order to find the actual
92
- message, we need to unpack arguments recursively.
93
- """
94
- msg = e .args [0 ]
95
- if isinstance (msg , Exception ):
96
- return exc_message (msg )
97
- return msg
98
-
99
-
100
90
def get_unbound_function (unbound ):
101
91
# Op.make_thunk isn't bound, so don't have a __func__ attr.
102
92
# But bound method, have a __func__ method that point to the
@@ -106,8 +96,9 @@ def get_unbound_function(unbound):
106
96
return unbound
107
97
108
98
109
- def maybe_add_to_os_environ_pathlist (var , newpath ):
110
- """Unfortunately, Conda offers to make itself the default Python
99
+ def maybe_add_to_os_environ_pathlist (var : str , newpath : Path | str ) -> None :
100
+ """
101
+ Unfortunately, Conda offers to make itself the default Python
111
102
and those who use it that way will probably not activate envs
112
103
correctly meaning e.g. mingw-w64 g++ may not be on their PATH.
113
104
@@ -118,18 +109,18 @@ def maybe_add_to_os_environ_pathlist(var, newpath):
118
109
The reason we check first is because Windows environment vars
119
110
are limited to 8191 characters and it is easy to hit that.
120
111
121
- `var` will typically be 'PATH'."""
122
-
123
- import os
112
+ `var` will typically be 'PATH'.
113
+ """
114
+ if not Path (newpath ).is_absolute ():
115
+ return
124
116
125
- if os .path .isabs (newpath ):
126
- try :
127
- oldpaths = os .environ [var ].split (os .pathsep )
128
- if newpath not in oldpaths :
129
- newpaths = os .pathsep .join ([newpath , * oldpaths ])
130
- os .environ [var ] = newpaths
131
- except Exception :
132
- pass
117
+ try :
118
+ oldpaths = os .environ [var ].split (os .pathsep )
119
+ if str (newpath ) not in oldpaths :
120
+ newpaths = os .pathsep .join ([str (newpath ), * oldpaths ])
121
+ os .environ [var ] = newpaths
122
+ except Exception :
123
+ pass
133
124
134
125
135
126
def subprocess_Popen (command , ** params ):
@@ -210,7 +201,7 @@ def output_subprocess_Popen(command, **params):
210
201
return (* out , p .returncode )
211
202
212
203
213
- def hash_from_code (msg ) :
204
+ def hash_from_code (msg : str | bytes ) -> str :
214
205
"""Return the SHA256 hash of a string or bytes."""
215
206
# hashlib.sha256() requires an object that supports buffer interface,
216
207
# but Python 3 (unicode) strings don't.
@@ -221,27 +212,7 @@ def hash_from_code(msg):
221
212
return "m" + hashlib .sha256 (msg ).hexdigest ()
222
213
223
214
224
- def memoize (f ):
225
- """
226
- Cache the return value for each tuple of arguments (which must be hashable).
227
-
228
- """
229
- cache = {}
230
-
231
- def rval (* args , ** kwargs ):
232
- kwtup = tuple (kwargs .items ())
233
- key = (args , kwtup )
234
- if key not in cache :
235
- val = f (* args , ** kwargs )
236
- cache [key ] = val
237
- else :
238
- val = cache [key ]
239
- return val
240
-
241
- return rval
242
-
243
-
244
- def uniq (seq ):
215
+ def uniq (seq : Sequence ) -> list :
245
216
"""
246
217
Do not use set, this must always return the same value at the same index.
247
218
If we just exchange other values, but keep the same pattern of duplication,
@@ -253,11 +224,12 @@ def uniq(seq):
253
224
return [x for i , x in enumerate (seq ) if seq .index (x ) == i ]
254
225
255
226
256
- def difference (seq1 , seq2 ):
227
+ def difference (seq1 : Iterable , seq2 : Iterable ):
257
228
r"""
258
229
Returns all elements in seq1 which are not in seq2: i.e ``seq1\seq2``.
259
230
260
231
"""
232
+ seq2 = list (seq2 )
261
233
try :
262
234
# try to use O(const * len(seq1)) algo
263
235
if len (seq2 ) < 4 : # I'm guessing this threshold -JB
@@ -285,7 +257,7 @@ def from_return_values(values):
285
257
return [values ]
286
258
287
259
288
- def flatten (a ):
260
+ def flatten (a ) -> list :
289
261
"""
290
262
Recursively flatten tuple, list and set in a list.
291
263
0 commit comments