@@ -59,39 +59,32 @@ def onerror(function, path, excinfo):
5959def getFileProperties (fname ):
6060 """Read all properties of the given file return them as a dictionary."""
6161 import win32api
62- propNames = (
62+ prop_names = (
6363 'Comments' , 'InternalName' , 'ProductName' , 'CompanyName' , 'LegalCopyright' ,
6464 'ProductVersion' , 'FileDescription' , 'LegalTrademarks' , 'PrivateBuild' ,
6565 'FileVersion' , 'OriginalFilename' , 'SpecialBuild'
66- )
66+ )
6767 props = {'FixedFileInfo' : None , 'StringFileInfo' : None , 'FileVersion' : None }
6868
6969 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+ )
7878 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+ }
8983 except :
9084 pass
9185
9286 return props
9387
94-
9588def get_special_folder_path (path_name ):
9689 """Return special folder path."""
9790 from win32com .shell import shell , shellcon
@@ -104,21 +97,16 @@ def get_special_folder_path(path_name):
10497 if maybe == path_name :
10598 csidl = getattr (shellcon , maybe )
10699 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" )
111101
112102def 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 :
118106 try :
119107 folder = get_special_folder_path ("CSIDL_COMMON_PROGRAMS" )
120108 except OSError :
121- folder = get_special_folder_path ( "CSIDL_PROGRAMS" )
109+ pass
122110 return str (Path (folder ) / 'WinPython' )
123111
124112def remove_winpython_start_menu_folder (current = True ):
@@ -141,7 +129,6 @@ def create_winpython_start_menu_folder(current=True):
141129 Path (path ).mkdir (parents = True , exist_ok = True )
142130 return path
143131
144-
145132def create_shortcut (path , description , filename , arguments = "" , workdir = "" , iconpath = "" , iconindex = 0 , verbose = True ):
146133 """Create Windows shortcut (.lnk file)."""
147134 import pythoncom
@@ -178,7 +165,7 @@ def is_python_distribution(path):
178165 return has_exec and has_site
179166
180167def decode_fs_string (string ):
181- """Convert string from file system charset to unicode"""
168+ """Convert string from file system charset to unicode. """
182169 charset = sys .getfilesystemencoding () or locale .getpreferredencoding ()
183170 return string .decode (charset )
184171
@@ -197,11 +184,11 @@ def get_nodejs_version(path):
197184 return exec_shell_cmd ("node -v" , path ).splitlines ()[0 ]
198185
199186def get_npmjs_version (path ):
200- """Return version of the Nodejs installed in *path*"""
187+ """Return version of the Nodejs installed in *path*. """
201188 return exec_shell_cmd ("npm -v" , path ).splitlines ()[0 ]
202189
203190def get_pandoc_version (path ):
204- """Return version of the Pandoc executable in *path*"""
191+ """Return version of the Pandoc executable in *path*. """
205192 return exec_shell_cmd ("pandoc -v" , path ).splitlines ()[0 ].split (" " )[- 1 ]
206193
207194def python_query (cmd , path ):
@@ -215,40 +202,20 @@ def python_execmodule(cmd, path):
215202 exec_shell_cmd (f'{ the_exe } -m { cmd } ' , path )
216203
217204def 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*."""
221206 is_64 = python_query ("import sys; print(sys.maxsize > 2**32)" , path )
222207 arch = {"True" : 64 , "False" : 32 }.get (is_64 , None )
223208 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
226209 return ver , arch
227210
228-
229211def 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
240215
241216def 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".." )) + "\\ "
252219 executable = sys .executable
253220
254221 shebang_line = re .compile (rb"""(#!.*pythonw?\.exe)"?""" ) # Python3+
@@ -258,8 +225,6 @@ def patch_shebang_line(fname, pad=b" ", to_movable=True, targetdir=""):
258225
259226 with open (fname , "rb" ) as fh :
260227 initial_content = fh .read ()
261- fh .close
262- fh = None
263228 content = shebang_line .split (initial_content , maxsplit = 1 )
264229 if len (content ) != 3 :
265230 return
@@ -271,18 +236,13 @@ def patch_shebang_line(fname, pad=b" ", to_movable=True, targetdir=""):
271236 try :
272237 with open (fname , "wb" ) as fo :
273238 fo .write (final_content )
274- fo .close
275- fo = None
276239 print ("patched" , fname )
277240 except Exception :
278241 print ("failed to patch" , fname )
279242
280-
281243def patch_shebang_line_py (fname , to_movable = True , targetdir = "" ):
282244 """Changes shebang line in '.py' file to relative or absolue path"""
283245 import fileinput
284- import re
285- import sys
286246
287247 if to_movable :
288248 exec_path = r'#!.\python.exe'
@@ -298,7 +258,6 @@ def patch_shebang_line_py(fname, to_movable=True, targetdir=""):
298258 else :
299259 print (line , end = '' )
300260
301-
302261def guess_encoding (csv_file ):
303262 """guess the encoding of the given file"""
304263 # UTF_8_BOM = "\xEF\xBB\xBF"
@@ -328,7 +287,7 @@ def replace_in_file(filepath: Path, replacements: list[tuple[str, str]], filedes
328287 content = f .read ()
329288 new_content = content
330289 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 )
332291 outfile = filedest if filedest else filepath
333292 if new_content != content or str (outfile ) != str (filepath ):
334293 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
337296 print (f"patched from { Path (filepath ).name } into { outfile } !" )
338297
339298def 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. """
341300 if not silent_mode :
342301 print (f"patching { fname } from { in_text } to { out_text } " )
343302 if Path (fname ).is_file () and not in_text == out_text :
@@ -367,36 +326,24 @@ def extract_archive(fname, targetdir=None, verbose=False):
367326 obj .extractall (path = targetdir )
368327 return targetdir
369328
370-
371329def get_source_package_infos (fname ):
372330 """Return a tuple (name, version) of the Python source package."""
373331 if fname .endswith ('.whl' ):
374332 return Path (fname ).name .split ("-" )[:2 ]
375333 match = re .match (SOURCE_PATTERN , Path (fname ).name )
376334 return match .groups ()[:2 ] if match else None
377335
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
387339 assert Path (python_exe ).is_file ()
388340 cmd = [python_exe , '-m' ,'flit' , 'build' ]
389341
390342 # root = a tmp dir in windows\tmp,
391343 if verbose :
392344 subprocess .call (cmd , cwd = root )
393345 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 )
400347 p .communicate ()
401348 p .stdout .close ()
402349 p .stderr .close ()
@@ -428,7 +375,6 @@ def buildflit_wininst(
428375 print (f"Move: { src_fname } --> { dst_fname } " )
429376 return dst_fname
430377
431-
432378def direct_pip_install (fname , python_exe = None , verbose = False , install_options = None ):
433379 """Direct install via python -m pip !"""
434380 copy_to = str (Path (fname ).parent )
@@ -447,12 +393,7 @@ def direct_pip_install(fname, python_exe=None, verbose=False, install_options=No
447393 if verbose :
448394 subprocess .call (cmd , cwd = myroot )
449395 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 )
456397 stdout , stderr = p .communicate ()
457398 the_log = f"{ stdout } " + f"\n { stderr } "
458399
@@ -489,12 +430,7 @@ def do_script(this_script, python_exe=None, copy_to=None, verbose=False, install
489430 if verbose :
490431 subprocess .call (cmd , cwd = myroot )
491432 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 )
498434 p .communicate ()
499435 p .stdout .close ()
500436 p .stderr .close ()
0 commit comments