@@ -59,39 +59,32 @@ def onerror(function, path, excinfo):
59
59
def getFileProperties (fname ):
60
60
"""Read all properties of the given file return them as a dictionary."""
61
61
import win32api
62
- propNames = (
62
+ prop_names = (
63
63
'Comments' , 'InternalName' , 'ProductName' , 'CompanyName' , 'LegalCopyright' ,
64
64
'ProductVersion' , 'FileDescription' , 'LegalTrademarks' , 'PrivateBuild' ,
65
65
'FileVersion' , 'OriginalFilename' , 'SpecialBuild'
66
- )
66
+ )
67
67
props = {'FixedFileInfo' : None , 'StringFileInfo' : None , 'FileVersion' : None }
68
68
69
69
try :
70
- fixedInfo = win32api .GetFileVersionInfo (fname , '\\ ' )
71
- props ['FixedFileInfo' ] = fixedInfo
72
- props ['FileVersion' ] = "%d.%d.%d.%d" % ( fixedInfo [ 'FileVersionMS' ] / 65536 ,
73
- fixedInfo ['FileVersionMS' ] % 65536 , fixedInfo [ 'FileVersionLS' ] / 65536 ,
74
- fixedInfo [ 'FileVersionLS ' ] % 65536 )
75
-
76
- # \VarFileInfo\Translation returns list of available (language, codepage)
77
- # pairs that can be used to retreive string info. We are using only the first pair.
70
+ fixed_info = win32api .GetFileVersionInfo (fname , '\\ ' )
71
+ props ['FixedFileInfo' ] = fixed_info
72
+ props ['FileVersion' ] = "{}.{}.{}.{}" . format (
73
+ fixed_info ['FileVersionMS' ] / / 65536 ,
74
+ fixed_info [ 'FileVersionMS ' ] % 65536 ,
75
+ fixed_info [ 'FileVersionLS' ] // 65536 ,
76
+ fixed_info [ 'FileVersionLS' ] % 65536
77
+ )
78
78
lang , codepage = win32api .GetFileVersionInfo (fname , '\\ VarFileInfo\\ Translation' )[0 ]
79
-
80
- # any other must be of the form \StringfileInfo\%04X%04X\parm_name, middle
81
- # two are language/codepage pair returned from above
82
- strInfo = {}
83
- for propName in propNames :
84
- strInfoPath = u'\\ StringFileInfo\\ %04X%04X\\ %s' % (lang , codepage , propName )
85
- ## print str_info
86
- strInfo [propName ] = win32api .GetFileVersionInfo (fname , strInfoPath )
87
-
88
- props ['StringFileInfo' ] = strInfo
79
+ props ['StringFileInfo' ] = {
80
+ prop_name : win32api .GetFileVersionInfo (fname , f'\\ StringFileInfo\\ { lang :04X} { codepage :04X} \\ { prop_name } ' )
81
+ for prop_name in prop_names
82
+ }
89
83
except :
90
84
pass
91
85
92
86
return props
93
87
94
-
95
88
def get_special_folder_path (path_name ):
96
89
"""Return special folder path."""
97
90
from win32com .shell import shell , shellcon
@@ -104,21 +97,16 @@ def get_special_folder_path(path_name):
104
97
if maybe == path_name :
105
98
csidl = getattr (shellcon , maybe )
106
99
return shell .SHGetSpecialFolderPath (0 , csidl , False )
107
- raise ValueError (
108
- f"{ path_name } is an unknown path ID"
109
- )
110
-
100
+ raise ValueError (f"{ path_name } is an unknown path ID" )
111
101
112
102
def get_winpython_start_menu_folder (current = True ):
113
- """Return WinPython Start menu shortcuts folder"""
114
- if current :
115
- # non-admin install - always goes in this user's start menu.
116
- folder = get_special_folder_path ("CSIDL_PROGRAMS" )
117
- else :
103
+ """Return WinPython Start menu shortcuts folder."""
104
+ folder = get_special_folder_path ("CSIDL_PROGRAMS" )
105
+ if not current :
118
106
try :
119
107
folder = get_special_folder_path ("CSIDL_COMMON_PROGRAMS" )
120
108
except OSError :
121
- folder = get_special_folder_path ( "CSIDL_PROGRAMS" )
109
+ pass
122
110
return str (Path (folder ) / 'WinPython' )
123
111
124
112
def remove_winpython_start_menu_folder (current = True ):
@@ -141,7 +129,6 @@ def create_winpython_start_menu_folder(current=True):
141
129
Path (path ).mkdir (parents = True , exist_ok = True )
142
130
return path
143
131
144
-
145
132
def create_shortcut (path , description , filename , arguments = "" , workdir = "" , iconpath = "" , iconindex = 0 , verbose = True ):
146
133
"""Create Windows shortcut (.lnk file)."""
147
134
import pythoncom
@@ -178,7 +165,7 @@ def is_python_distribution(path):
178
165
return has_exec and has_site
179
166
180
167
def decode_fs_string (string ):
181
- """Convert string from file system charset to unicode"""
168
+ """Convert string from file system charset to unicode. """
182
169
charset = sys .getfilesystemencoding () or locale .getpreferredencoding ()
183
170
return string .decode (charset )
184
171
@@ -197,11 +184,11 @@ def get_nodejs_version(path):
197
184
return exec_shell_cmd ("node -v" , path ).splitlines ()[0 ]
198
185
199
186
def get_npmjs_version (path ):
200
- """Return version of the Nodejs installed in *path*"""
187
+ """Return version of the Nodejs installed in *path*. """
201
188
return exec_shell_cmd ("npm -v" , path ).splitlines ()[0 ]
202
189
203
190
def get_pandoc_version (path ):
204
- """Return version of the Pandoc executable in *path*"""
191
+ """Return version of the Pandoc executable in *path*. """
205
192
return exec_shell_cmd ("pandoc -v" , path ).splitlines ()[0 ].split (" " )[- 1 ]
206
193
207
194
def python_query (cmd , path ):
@@ -215,40 +202,20 @@ def python_execmodule(cmd, path):
215
202
exec_shell_cmd (f'{ the_exe } -m { cmd } ' , path )
216
203
217
204
def get_python_infos (path ):
218
- """Return (version, architecture) for the Python distribution located in
219
- *path*. The version number is limited to MAJOR.MINOR, the architecture is
220
- an integer: 32 or 64"""
205
+ """Return (version, architecture) for the Python distribution located in *path*."""
221
206
is_64 = python_query ("import sys; print(sys.maxsize > 2**32)" , path )
222
207
arch = {"True" : 64 , "False" : 32 }.get (is_64 , None )
223
208
ver = python_query ("import sys;print(f'{sys.version_info.major}.{sys.version_info.minor}')" , path )
224
- if re .match (r"([0-9]*)\.([0-9]*)" , ver ) is None :
225
- ver = None
226
209
return ver , arch
227
210
228
-
229
211
def get_python_long_version (path ):
230
- """Return long version (X.Y.Z) for the Python distribution located in
231
- *path*"""
232
- ver = python_query (
233
- "import sys; print(f'{sys.version_info.major}.{sys.version_info.minor}.{sys.version_info.micro}')" ,
234
- path ,
235
- )
236
- if re .match (r"([0-9]*)\.([0-9]*)\.([0-9]*)" , ver ) is None :
237
- ver = None
238
- return ver
239
-
212
+ """Return long version (X.Y.Z) for the Python distribution located in *path*."""
213
+ ver = python_query ("import sys; print(f'{sys.version_info.major}.{sys.version_info.minor}.{sys.version_info.micro}')" , path )
214
+ return ver if re .match (r"([0-9]*)\.([0-9]*)\.([0-9]*)" , ver ) else None
240
215
241
216
def patch_shebang_line (fname , pad = b" " , to_movable = True , targetdir = "" ):
242
- """Remove absolute path to python.exe in shebang lines in binary files, or re-add it"""
243
-
244
- import re
245
- import sys
246
- import os
247
-
248
- target_dir = targetdir # movable option
249
- if to_movable == False :
250
- target_dir = os .path .abspath (os .path .dirname (fname ))
251
- target_dir = os .path .abspath (os .path .join (target_dir , r".." )) + "\\ "
217
+ """Remove absolute path to python.exe in shebang lines in binary files, or re-add it."""
218
+ target_dir = targetdir if to_movable else os .path .abspath (os .path .join (os .path .dirname (fname ), r".." )) + "\\ "
252
219
executable = sys .executable
253
220
254
221
shebang_line = re .compile (rb"""(#!.*pythonw?\.exe)"?""" ) # Python3+
@@ -258,8 +225,6 @@ def patch_shebang_line(fname, pad=b" ", to_movable=True, targetdir=""):
258
225
259
226
with open (fname , "rb" ) as fh :
260
227
initial_content = fh .read ()
261
- fh .close
262
- fh = None
263
228
content = shebang_line .split (initial_content , maxsplit = 1 )
264
229
if len (content ) != 3 :
265
230
return
@@ -271,18 +236,13 @@ def patch_shebang_line(fname, pad=b" ", to_movable=True, targetdir=""):
271
236
try :
272
237
with open (fname , "wb" ) as fo :
273
238
fo .write (final_content )
274
- fo .close
275
- fo = None
276
239
print ("patched" , fname )
277
240
except Exception :
278
241
print ("failed to patch" , fname )
279
242
280
-
281
243
def patch_shebang_line_py (fname , to_movable = True , targetdir = "" ):
282
244
"""Changes shebang line in '.py' file to relative or absolue path"""
283
245
import fileinput
284
- import re
285
- import sys
286
246
287
247
if to_movable :
288
248
exec_path = r'#!.\python.exe'
@@ -298,7 +258,6 @@ def patch_shebang_line_py(fname, to_movable=True, targetdir=""):
298
258
else :
299
259
print (line , end = '' )
300
260
301
-
302
261
def guess_encoding (csv_file ):
303
262
"""guess the encoding of the given file"""
304
263
# UTF_8_BOM = "\xEF\xBB\xBF"
@@ -328,7 +287,7 @@ def replace_in_file(filepath: Path, replacements: list[tuple[str, str]], filedes
328
287
content = f .read ()
329
288
new_content = content
330
289
for old_text , new_text in replacements :
331
- new_content = new_content .replace (old_text , new_text )
290
+ new_content = new_content .replace (old_text , new_text )
332
291
outfile = filedest if filedest else filepath
333
292
if new_content != content or str (outfile ) != str (filepath ):
334
293
with open (outfile , "w" , encoding = the_encoding ) as f :
@@ -337,7 +296,7 @@ def replace_in_file(filepath: Path, replacements: list[tuple[str, str]], filedes
337
296
print (f"patched from { Path (filepath ).name } into { outfile } !" )
338
297
339
298
def patch_sourcefile (fname , in_text , out_text , silent_mode = False ):
340
- """Replace a string in a source file"""
299
+ """Replace a string in a source file. """
341
300
if not silent_mode :
342
301
print (f"patching { fname } from { in_text } to { out_text } " )
343
302
if Path (fname ).is_file () and not in_text == out_text :
@@ -367,36 +326,24 @@ def extract_archive(fname, targetdir=None, verbose=False):
367
326
obj .extractall (path = targetdir )
368
327
return targetdir
369
328
370
-
371
329
def get_source_package_infos (fname ):
372
330
"""Return a tuple (name, version) of the Python source package."""
373
331
if fname .endswith ('.whl' ):
374
332
return Path (fname ).name .split ("-" )[:2 ]
375
333
match = re .match (SOURCE_PATTERN , Path (fname ).name )
376
334
return match .groups ()[:2 ] if match else None
377
335
378
- def buildflit_wininst (
379
- root ,
380
- python_exe = None ,
381
- copy_to = None ,
382
- verbose = False ,
383
- ):
384
- """Build Wheel from Python package located in *root*with flit"""
385
- if python_exe is None :
386
- python_exe = sys .executable
336
+ def buildflit_wininst (root , python_exe = None , copy_to = None , verbose = False ):
337
+ """Build Wheel from Python package located in *root* with flit."""
338
+ python_exe = python_exe or sys .executable
387
339
assert Path (python_exe ).is_file ()
388
340
cmd = [python_exe , '-m' ,'flit' , 'build' ]
389
341
390
342
# root = a tmp dir in windows\tmp,
391
343
if verbose :
392
344
subprocess .call (cmd , cwd = root )
393
345
else :
394
- p = subprocess .Popen (
395
- cmd ,
396
- cwd = root ,
397
- stdout = subprocess .PIPE ,
398
- stderr = subprocess .PIPE ,
399
- )
346
+ p = subprocess .Popen (cmd , cwd = root , stdout = subprocess .PIPE , stderr = subprocess .PIPE )
400
347
p .communicate ()
401
348
p .stdout .close ()
402
349
p .stderr .close ()
@@ -428,7 +375,6 @@ def buildflit_wininst(
428
375
print (f"Move: { src_fname } --> { dst_fname } " )
429
376
return dst_fname
430
377
431
-
432
378
def direct_pip_install (fname , python_exe = None , verbose = False , install_options = None ):
433
379
"""Direct install via python -m pip !"""
434
380
copy_to = str (Path (fname ).parent )
@@ -447,12 +393,7 @@ def direct_pip_install(fname, python_exe=None, verbose=False, install_options=No
447
393
if verbose :
448
394
subprocess .call (cmd , cwd = myroot )
449
395
else :
450
- p = subprocess .Popen (
451
- cmd ,
452
- cwd = myroot ,
453
- stdout = subprocess .PIPE ,
454
- stderr = subprocess .PIPE ,
455
- )
396
+ p = subprocess .Popen (cmd , cwd = myroot , stdout = subprocess .PIPE , stderr = subprocess .PIPE )
456
397
stdout , stderr = p .communicate ()
457
398
the_log = f"{ stdout } " + f"\n { stderr } "
458
399
@@ -489,12 +430,7 @@ def do_script(this_script, python_exe=None, copy_to=None, verbose=False, install
489
430
if verbose :
490
431
subprocess .call (cmd , cwd = myroot )
491
432
else :
492
- p = subprocess .Popen (
493
- cmd ,
494
- cwd = myroot ,
495
- stdout = subprocess .PIPE ,
496
- stderr = subprocess .PIPE ,
497
- )
433
+ p = subprocess .Popen (cmd , cwd = myroot , stdout = subprocess .PIPE , stderr = subprocess .PIPE )
498
434
p .communicate ()
499
435
p .stdout .close ()
500
436
p .stderr .close ()
0 commit comments