Changeset 790
- Timestamp:
- 08/10/07 17:02:11 (1 year ago)
- Files:
-
- pyrun/trunk/ChangeLog (modified) (3 diffs)
- pyrun/trunk/pyrun.py (modified) (7 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
pyrun/trunk/ChangeLog
r788 r790 2 2 ~~~~~~~~~ 3 3 4 0.1.1 4 0.1.1: 5 * bugfix: propagate source file name (or sensibly invented filename) to 6 the __file__ attribute of the code instance that becomes our __main__ 7 * -d works with -m and -c, should also work with -s but have not tried yet. 8 * -d option uses pdb.runeval rather than set_trace making for considerably 9 simpler target debugging. May consider introducing an "eager" -d variant 10 that behaves like 0.1 (set_trace *in* pyrun.py) later. 11 * Allow the target to run when -d is in effect, without requiring user to 12 manaully do ``opts.d = False`` 13 * By default suppress -D if -d is in effect. 5 14 * Added -c, its much like python -c 6 * The `run script` option changed from -S to -C 7 * By default, print a warning if any of the argv discovery path items dont 8 exist on the file system. -q suppreses the warnings 15 * The `run script` option changed from -S to -C exist on the file system. -q 16 suppreses the warnings 9 17 10 0.1d 18 0.1d: 11 19 * `-S` option to explicitly run a python script. uses compiler.compile to 12 20 load and compile the code from an arbitrary file. uses … … 23 31 * documentation tidy up 24 32 25 0.1c 33 0.1c: 26 34 * Use the parent directory of the top package directory for each explicitly 27 35 listed python file in the discovery path. This means you need to *always* … … 29 37 to allow the targeted modules imports to work correctly. 30 38 31 0.1b 39 0.1b: 32 40 33 41 * path discovery and python module execution pyrun/trunk/pyrun.py
r788 r790 444 444 445 445 446 def compile_and_run(source, mod_name='__main__', 447 init_globals=None, mod_fname=None, mod_loader=None, alter_sys=True): 448 """compile `filename` and run the code using runpy._run_module_code.""" 449 446 def get_module_code_and_filename(mod_name): 447 """Get the code object and filename for the python module `mod_name` 448 449 This is exactly like runpy.run_module but instead of running the code, 450 it returns (code, filename) 451 452 """ 450 453 global runpy 451 454 if not have_runpy: 452 455 runpy = __import__('runpy') 453 456 454 if mod_fname is None: 455 mod_fname = filename 456 code = compiler.compile(source, mod_fname or '<unknown-source>', 'exec') 457 return runpy._run_module_code(code, 458 mod_name=mod_name, 459 init_globals=init_globals, 460 mod_fname=mod_fname, 461 mod_loader=mod_loader, 462 alter_sys=alter_sys 463 ) 464 457 loader = runpy.get_loader(mod_name) 458 if loader is None: 459 raise ImportError("No module named " + mod_name) 460 code = loader.get_code(mod_name) 461 if code is None: 462 raise ImportError("No code object available for " + mod_name) 463 filename = runpy._get_filename(loader, mod_name) 464 return code, filename 465 466 467 def get_module_code(mod_name): 468 """Get the code object for the python module `mod_name`""" 469 470 return get_module_code_and_filename(mod_name)[0] 471 472 473 def get_module_filename(mod_name): 474 """Get the filename for the python module `mod_name`""" 475 476 return get_module_code_and_filename(mod_name)[1] 477 478 479 def dbg_run_code(code, run_globals, init_globals, 480 mod_name, mod_fname, mod_loader): 481 if init_globals is not None: 482 run_globals.update(init_globals) 483 run_globals.update(__name__ = mod_name, 484 __file__ = mod_fname, 485 __loader__ = mod_loader) 486 import pdb 487 pdb.runeval(code, run_globals) 488 return run_globals 489 490 491 def run_module_code(runner, code, init_globals=None, 492 mod_name=None, mod_fname=None, 493 mod_loader=None, alter_sys=False): 494 495 """Variant of runpy._run_module_code with hook for _run_code 496 497 `runner` must be None or be a suitable replacement for runpy._run_code 498 499 (For example see dbg_run_code above) 500 501 """ 502 503 if runner is None: 504 assert have_runpy 505 runner = runpy._run_code 506 507 # Set up the top level namespace dictionary 508 if alter_sys: 509 # Modify sys.argv[0] and sys.module[mod_name] 510 temp_module = imp.new_module(mod_name) 511 mod_globals = temp_module.__dict__ 512 saved_argv0 = sys.argv[0] 513 restore_module = mod_name in sys.modules 514 if restore_module: 515 saved_module = sys.modules[mod_name] 516 sys.argv[0] = mod_fname 517 sys.modules[mod_name] = temp_module 518 try: 519 runner(code, mod_globals, init_globals, 520 mod_name, mod_fname, mod_loader) 521 finally: 522 sys.argv[0] = saved_argv0 523 if restore_module: 524 sys.modules[mod_name] = saved_module 525 else: 526 del sys.modules[mod_name] 527 # Copy the globals of the temporary module, as they 528 # may be cleared when the temporary module goes away 529 return mod_globals.copy() 530 else: 531 # Leave the sys module alone 532 return runner(code, {}, init_globals, 533 mod_name, mod_fname, mod_loader) 534 535 536 def striplines(s): 537 return '\n'.join(map(''.__class__.strip, s.split('\n'))) 538 539 interactive_BANNER_BOILERPLATE = """\ 540 handy locals() are: 541 The function run() (runs the discovered module or -c/-C/-S options) 542 The variables target_argv, pthextend 543 544 Update target_argv *in place* before calling run() if you want to tweak 545 the sys.argv the module sees.""" 465 546 466 547 def runex(argv=None): … … 485 566 sourcefile = None 486 567 if opts.c and opts.C and not opts.q: 487 print ( 488 'Warning: -c and -C can not be used together. Ignoring "-C %s"' 489 ) % opts.C 568 print striplines((''' 569 Warning: -c and -C can not be used together. Ignoring "-C %s" 570 ''' % opts.C) 571 ) 490 572 491 573 if opts.C: … … 501 583 502 584 if not opts.q and doesnotexist: 503 print (''' 504 Warning: your discovery path arguments referenced the following files or 505 directories which do not exist on the file system:''') 585 print striplines('''\ 586 Warning: your discovery path arguments referenced the following 587 files or directories which do not exist on the file system: 588 ''') 506 589 print '\t' + '\n\t'.join(doesnotexist) 507 590 … … 595 678 sys.argv[:] = target_argv[:] 596 679 if runpy is not False: 680 runner = None 681 if opts.d: 682 runner = dbg_run_code 597 683 if not source: 598 return runpy.run_module( 599 modname, run_name='__main__', alter_sys=True 600 ) 684 code, filename = get_module_code_and_filename(modname) 601 685 else: 602 return compile_and_run(source, mod_fname=sourcefile) 603 604 if opts.d: 605 import pdb 606 pdb.set_trace() 686 code = compiler.compile(source, sourcefile, 'exec') 687 filename = sourcefile 688 689 return run_module_code(runner, code, 690 init_globals=None, 691 mod_name='__main__', 692 mod_fname=filename, 693 alter_sys=True 694 ) 607 695 if opts.i: 608 696 banner='' … … 617 705 if opts.p or opts.P: 618 706 banner += '\n\n' 619 banner += """\ 620 handy locals() are: 621 The function run() (runs the discovered module or -c/-C/-S options) 622 The variables target_argv, pthextend 623 624 Update target_argv *in place* before calling run() if you want to tweak 625 the sys.argv the module sees.""" 707 708 bannerl += interactive_BANNER_BOILERPLATE 626 709 627 710 import code … … 639 722 print os.pathsep.join(pthextend) 640 723 641 if not (opts.n or opts. d or opts.i) and (modname or source):724 if not (opts.n or opts.i) and (modname or source): 642 725 exitval = run() 643 726 if not isinstance(exitval, int): … … 652 735 msg = exc_string(einfo=einfo) 653 736 print msg 654 if opts.D :737 if opts.D and not opts.d: 655 738 import pdb 656 739 pdb.post_mortem(einfo[2])