@@ -132,6 +132,7 @@ def create_winpython_start_menu_folder(current=True):
132
132
def create_shortcut (path , description , filename , arguments = "" , workdir = "" , iconpath = "" , iconindex = 0 , verbose = True ):
133
133
"""Create Windows shortcut (.lnk file)."""
134
134
import pythoncom
135
+ from win32com .shell import shel
135
136
ilink = pythoncom .CoCreateInstance (shell .CLSID_ShellLink , None , pythoncom .CLSCTX_INPROC_SERVER , shell .IID_IShellLink )
136
137
ilink .SetPath (path )
137
138
ilink .SetDescription (description )
@@ -243,25 +244,21 @@ def patch_shebang_line(fname, pad=b" ", to_movable=True, targetdir=""):
243
244
def patch_shebang_line_py (fname , to_movable = True , targetdir = "" ):
244
245
"""Changes shebang line in '.py' file to relative or absolue path"""
245
246
import fileinput
246
-
247
247
if to_movable :
248
248
exec_path = r'#!.\python.exe'
249
249
if 'pypy3' in sys .executable : # PyPy !
250
250
exec_path = r'#!.\pypy3.exe'
251
251
else :
252
252
exec_path = '#!' + sys .executable
253
253
for line in fileinput .input (fname , inplace = True ):
254
- if re .match (r'^#\!.*python\.exe$' , line ) is not None :
254
+ if re .match (r'^#\!.*python\.exe$' , line ) or re . match ( r'^#\!.*pypy3\.exe$' , line ) :
255
255
print (exec_path )
256
- elif re .match (r'^#\!.*pypy3\.exe$' , line ) is not None :# PyPy !
257
- print (exec_path )
258
256
else :
259
257
print (line , end = '' )
260
258
261
259
def guess_encoding (csv_file ):
262
260
"""guess the encoding of the given file"""
263
261
# UTF_8_BOM = "\xEF\xBB\xBF"
264
- # Python behavior on UTF-16 not great on write, so we drop it
265
262
with io .open (csv_file , "rb" ) as f :
266
263
data = f .read (5 )
267
264
if data .startswith (b"\xEF \xBB \xBF " ): # UTF-8 with a "BOM" (normally no BOM in utf-8)
@@ -273,7 +270,7 @@ def guess_encoding(csv_file):
273
270
return ["utf-8" ]
274
271
except :
275
272
return [locale .getdefaultlocale ()[1 ], "utf-8" ]
276
-
273
+
277
274
def replace_in_file (filepath : Path , replacements : list [tuple [str , str ]], filedest : Path = None , verbose = False ):
278
275
"""
279
276
Replaces strings in a file
@@ -285,7 +282,7 @@ def replace_in_file(filepath: Path, replacements: list[tuple[str, str]], filedes
285
282
the_encoding = guess_encoding (filepath )[0 ]
286
283
with open (filepath , "r" , encoding = the_encoding ) as f :
287
284
content = f .read ()
288
- new_content = content
285
+ new_content = content
289
286
for old_text , new_text in replacements :
290
287
new_content = new_content .replace (old_text , new_text )
291
288
outfile = filedest if filedest else filepath
@@ -305,15 +302,11 @@ def patch_sourcefile(fname, in_text, out_text, silent_mode=False):
305
302
def _create_temp_dir ():
306
303
"""Create a temporary directory and remove it at exit"""
307
304
tmpdir = tempfile .mkdtemp (prefix = 'wppm_' )
308
- atexit .register (
309
- lambda path : shutil .rmtree (path , onexc = onerror ),
310
- tmpdir ,
311
- )
305
+ atexit .register (lambda path : shutil .rmtree (path , onexc = onerror ), tmpdir )
312
306
return tmpdir
313
307
314
308
def extract_archive (fname , targetdir = None , verbose = False ):
315
- """Extract .zip, .exe (considered to be a zip archive) or .tar.gz archive
316
- to a temporary directory (if targetdir is None).
309
+ """Extract .zip, .exe or .tar.gz archive to a temporary directory.
317
310
Return the temporary directory path"""
318
311
targetdir = targetdir or create_temp_dir ()
319
312
Path (targetdir ).mkdir (parents = True , exist_ok = True )
@@ -336,24 +329,19 @@ def get_source_package_infos(fname):
336
329
def buildflit_wininst (root , python_exe = None , copy_to = None , verbose = False ):
337
330
"""Build Wheel from Python package located in *root* with flit."""
338
331
python_exe = python_exe or sys .executable
339
- assert Path (python_exe ).is_file ()
340
332
cmd = [python_exe , '-m' ,'flit' , 'build' ]
341
-
342
- # root = a tmp dir in windows\tmp,
343
333
if verbose :
344
334
subprocess .call (cmd , cwd = root )
345
335
else :
346
- p = subprocess .Popen (cmd , cwd = root , stdout = subprocess .PIPE , stderr = subprocess .PIPE )
347
- p .communicate ()
348
- p .stdout .close ()
349
- p .stderr .close ()
336
+ process = subprocess .Popen (cmd , cwd = root , stdout = subprocess .PIPE , stderr = subprocess .PIPE )
337
+ process .communicate ()
338
+ process .stdout .close ()
339
+ process .stderr .close ()
350
340
distdir = str (Path (root ) / 'dist' )
351
341
if not Path (distdir ).is_dir ():
352
342
raise RuntimeError (
353
- "Build failed: see package README file for further"
354
- " details regarding installation requirements.\n \n "
355
- "For more concrete debugging infos, please try to build "
356
- "the package from the command line:\n "
343
+ "Build failed: see package README file for further details regarding installation requirements.\n \n "
344
+ "For more concrete debugging infos, please try to build the package from the command line:\n "
357
345
"1. Open a WinPython command prompt\n "
358
346
"2. Change working directory to the appropriate folder\n "
359
347
"3. Type `python -m filt build`"
@@ -366,83 +354,56 @@ def buildflit_wininst(root, python_exe=None, copy_to=None, verbose=False):
366
354
raise RuntimeError (f"Build failed: not a pure Python package? { distdir } " )
367
355
368
356
src_fname = str (Path (distdir ) / distname )
369
- if copy_to is None :
370
- return src_fname
371
- else :
357
+ if copy_to :
372
358
dst_fname = str (Path (copy_to ) / distname )
373
359
shutil .move (src_fname , dst_fname )
374
360
if verbose :
375
361
print (f"Move: { src_fname } --> { dst_fname } " )
376
362
return dst_fname
363
+ return src_fname
377
364
378
365
def direct_pip_install (fname , python_exe = None , verbose = False , install_options = None ):
379
366
"""Direct install via python -m pip !"""
380
- copy_to = str (Path (fname ).parent )
381
-
382
- if python_exe is None :
383
- python_exe = sys .executable
384
- assert Path (python_exe ).is_file ()
367
+ python_exe = python_exe or sys .executable
385
368
myroot = str (Path (python_exe ).parent )
386
369
387
- cmd = [python_exe , "-m" , "pip" , "install" ]
388
- if install_options :
389
- cmd += install_options # typically ['--no-deps']
390
- print ("python -m pip install_options" , install_options )
391
- cmd += [fname ]
392
-
393
- if verbose :
394
- subprocess .call (cmd , cwd = myroot )
395
- else :
396
- p = subprocess .Popen (cmd , cwd = myroot , stdout = subprocess .PIPE , stderr = subprocess .PIPE )
397
- stdout , stderr = p .communicate ()
398
- the_log = f"{ stdout } " + f"\n { stderr } "
399
-
370
+ cmd = [python_exe , "-m" , "pip" , "install" ] + (install_options or []) + [fname ]
371
+ if not verbose :
372
+ process = subprocess .Popen (cmd , cwd = myroot , stdout = subprocess .PIPE , stderr = subprocess .PIPE )
373
+ stdout , stderr = process .communicate ()
374
+ the_log = f"{ stdout } \n { stderr } "
400
375
if " not find " in the_log or " not found " in the_log :
401
- print (f"Failed to Install: \n { fname } \n " )
402
- print (f"msg: { the_log } " )
376
+ print (f"Failed to Install: \n { fname } \n msg: { the_log } " )
403
377
raise RuntimeError
404
- p .stdout .close ()
405
- p .stderr .close ()
406
- src_fname = fname
407
- if copy_to is None :
408
- return src_fname
378
+ process .stdout .close ()
379
+ process .stderr .close ()
409
380
else :
410
- if verbose :
411
- print (f"Installed { src_fname } " )
412
- return src_fname
413
-
381
+ subprocess .call (cmd , cwd = myroot )
382
+ print (f"Installed { fname } via { ' ' .join (cmd )} " )
383
+ return fname
414
384
415
385
def do_script (this_script , python_exe = None , copy_to = None , verbose = False , install_options = None ):
416
386
"""Execute a script (get-pip typically)."""
417
387
python_exe = python_exe or sys .executable
418
388
myroot = os .path .dirname (python_exe )
419
-
420
389
# cmd = [python_exe, myroot + r'\Scripts\pip-script.py', 'install']
421
- cmd = [python_exe ]
422
- if install_options :
423
- cmd += install_options # typically ['--no-deps']
424
- print ('script install_options' , install_options )
425
- if this_script :
426
- cmd += [this_script ]
427
- # print('build_wheel', myroot, cmd)
390
+ cmd = [python_exe ] + (install_options or []) + ([this_script ] if this_script else [])
428
391
print ("Executing " , cmd )
429
-
430
- if verbose :
431
- subprocess .call (cmd , cwd = myroot )
392
+ if not verbose :
393
+ process = subprocess .Popen (cmd , cwd = myroot , stdout = subprocess .PIPE , stderr = subprocess .PIPE )
394
+ process .communicate ()
395
+ process .stdout .close ()
396
+ process .stderr .close ()
432
397
else :
433
- p = subprocess .Popen (cmd , cwd = myroot , stdout = subprocess .PIPE , stderr = subprocess .PIPE )
434
- p .communicate ()
435
- p .stdout .close ()
436
- p .stderr .close ()
437
- if verbose :
398
+ subprocess .call (cmd , cwd = myroot )
438
399
print ("Executed " , cmd )
439
400
return 'ok'
440
401
441
402
def columns_width (list_of_lists ):
442
403
"""Return the maximum string length of each column of a list of lists."""
443
404
if not isinstance (list_of_lists , list ):
444
405
return [0 ]
445
- return [max (len (str (item )) for item in sublist ) for sublist in zip (* list_of_lists )]
406
+ return [max (len (str (item )) for item in sublist ) for sublist in zip (* list_of_lists )]
446
407
447
408
def formatted_list (list_of_list , full = False , max_width = 70 ):
448
409
"""Format a list_of_list to fixed length columns."""
@@ -466,7 +427,6 @@ def get_package_metadata(database, name):
466
427
"url" : f"https://pypi.org/project/{ name } " ,
467
428
}
468
429
for key in my_metadata :
469
- # wheel replace '-' per '_' in key
470
430
for name2 in (name , normalize (name )):
471
431
try :
472
432
my_metadata [key ] = db .get (name2 , key )
0 commit comments