bpo-5680: IDLE: Customize running a module (GH-13763)
The initialize options are 1) add command line options, which are appended to sys.argv as if passed on a real command line, and 2) skip the shell restart. The customization dialog is accessed by a new entry on the Run menu.
This commit is contained in:
parent
7fb3190bcf
commit
201bc2d18b
|
@ -207,9 +207,13 @@ Strip trailing whitespace
|
|||
Run menu (Editor window only)
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
.. _python-shell:
|
||||
|
||||
Python Shell
|
||||
Open or wake up the Python Shell window.
|
||||
|
||||
.. _check-module:
|
||||
|
||||
Check Module
|
||||
Check the syntax of the module currently open in the Editor window. If the
|
||||
module has not been saved IDLE will either prompt the user to save or
|
||||
|
@ -217,8 +221,10 @@ Check Module
|
|||
there is a syntax error, the approximate location is indicated in the
|
||||
Editor window.
|
||||
|
||||
.. _run-module:
|
||||
|
||||
Run Module
|
||||
Do Check Module (above). If no error, restart the shell to clean the
|
||||
Do :ref:`Check Module <check-module>`. If no error, restart the shell to clean the
|
||||
environment, then execute the module. Output is displayed in the Shell
|
||||
window. Note that output requires use of ``print`` or ``write``.
|
||||
When execution is complete, the Shell retains focus and displays a prompt.
|
||||
|
@ -226,6 +232,14 @@ Run Module
|
|||
This is similar to executing a file with ``python -i file`` at a command
|
||||
line.
|
||||
|
||||
.. _run-custom:
|
||||
|
||||
Run... Customized
|
||||
Same as :ref:`Run Module <run-module>`, but run the module with customized
|
||||
settings. *Command Line Arguments* extend :data:`sys.argv` as if passed
|
||||
on a command line. The module can be run in the Shell without restarting.
|
||||
|
||||
|
||||
Shell menu (Shell window only)
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
|
|
|
@ -63,6 +63,7 @@ force-open-calltip= <Control-Key-backslash>
|
|||
format-paragraph= <Alt-Key-q>
|
||||
flash-paren= <Control-Key-0>
|
||||
run-module= <Key-F5>
|
||||
run-custom= <Shift-Key-F5>
|
||||
check-module= <Alt-Key-x>
|
||||
zoom-height= <Alt-Key-2>
|
||||
|
||||
|
@ -122,6 +123,7 @@ force-open-calltip= <Control-Key-backslash>
|
|||
format-paragraph= <Alt-Key-q>
|
||||
flash-paren= <Control-Key-0>
|
||||
run-module= <Key-F5>
|
||||
run-custom= <Shift-Key-F5>
|
||||
check-module= <Alt-Key-x>
|
||||
zoom-height= <Alt-Key-2>
|
||||
|
||||
|
@ -181,6 +183,7 @@ force-open-calltip= <Control-Key-backslash>
|
|||
format-paragraph= <Alt-Key-q>
|
||||
flash-paren= <Control-Key-0>
|
||||
run-module= <Key-F5>
|
||||
run-custom= <Shift-Key-F5>
|
||||
check-module= <Alt-Key-x>
|
||||
zoom-height= <Alt-Key-2>
|
||||
|
||||
|
@ -240,6 +243,7 @@ force-open-calltip= <Control-Key-backslash>
|
|||
format-paragraph= <Option-Key-q>
|
||||
flash-paren= <Control-Key-0>
|
||||
run-module= <Key-F5>
|
||||
run-custom= <Shift-Key-F5>
|
||||
check-module= <Option-Key-x>
|
||||
zoom-height= <Option-Key-0>
|
||||
|
||||
|
@ -300,5 +304,6 @@ force-open-calltip= <Control-Key-backslash>
|
|||
format-paragraph= <Option-Key-q>
|
||||
flash-paren= <Control-Key-0>
|
||||
run-module= <Key-F5>
|
||||
run-custom= <Shift-Key-F5>
|
||||
check-module= <Option-Key-x>
|
||||
zoom-height= <Option-Key-0>
|
||||
|
|
|
@ -591,7 +591,9 @@ class IdleConf:
|
|||
former_extension_events = { # Those with user-configurable keys.
|
||||
'<<force-open-completions>>', '<<expand-word>>',
|
||||
'<<force-open-calltip>>', '<<flash-paren>>', '<<format-paragraph>>',
|
||||
'<<run-module>>', '<<check-module>>', '<<zoom-height>>'}
|
||||
'<<run-module>>', '<<check-module>>', '<<zoom-height>>',
|
||||
'<<run-custom>>',
|
||||
}
|
||||
|
||||
def GetCoreKeys(self, keySetName=None):
|
||||
"""Return dict of core virtual-key keybindings for keySetName.
|
||||
|
@ -658,6 +660,7 @@ class IdleConf:
|
|||
'<<flash-paren>>': ['<Control-Key-0>'],
|
||||
'<<format-paragraph>>': ['<Alt-Key-q>'],
|
||||
'<<run-module>>': ['<Key-F5>'],
|
||||
'<<run-custom>>': ['<Shift-Key-F5>'],
|
||||
'<<check-module>>': ['<Alt-Key-x>'],
|
||||
'<<zoom-height>>': ['<Alt-Key-2>'],
|
||||
}
|
||||
|
|
|
@ -304,6 +304,7 @@ class EditorWindow(object):
|
|||
scriptbinding = ScriptBinding(self)
|
||||
text.bind("<<check-module>>", scriptbinding.check_module_event)
|
||||
text.bind("<<run-module>>", scriptbinding.run_module_event)
|
||||
text.bind("<<run-custom>>", scriptbinding.run_custom_event)
|
||||
text.bind("<<do-rstrip>>", self.Rstrip(self).do_rstrip)
|
||||
ctip = self.Calltip(self)
|
||||
text.bind("<<try-open-calltip>>", ctip.try_open_calltip_event)
|
||||
|
|
|
@ -248,17 +248,21 @@ including lines within multiline strings.</dd>
|
|||
</div>
|
||||
<div class="section" id="run-menu-editor-window-only">
|
||||
<span id="index-2"></span><h3>Run menu (Editor window only)<a class="headerlink" href="#run-menu-editor-window-only" title="Permalink to this headline">¶</a></h3>
|
||||
<dl class="docutils">
|
||||
<dl class="docutils" id="python-shell">
|
||||
<dt>Python Shell</dt>
|
||||
<dd>Open or wake up the Python Shell window.</dd>
|
||||
</dl>
|
||||
<dl class="docutils" id="check-module">
|
||||
<dt>Check Module</dt>
|
||||
<dd>Check the syntax of the module currently open in the Editor window. If the
|
||||
module has not been saved IDLE will either prompt the user to save or
|
||||
autosave, as selected in the General tab of the Idle Settings dialog. If
|
||||
there is a syntax error, the approximate location is indicated in the
|
||||
Editor window.</dd>
|
||||
</dl>
|
||||
<dl class="docutils" id="run-module">
|
||||
<dt>Run Module</dt>
|
||||
<dd>Do Check Module (above). If no error, restart the shell to clean the
|
||||
<dd>Do <a class="reference internal" href="#check-module"><span class="std std-ref">Check Module</span></a>. If no error, restart the shell to clean the
|
||||
environment, then execute the module. Output is displayed in the Shell
|
||||
window. Note that output requires use of <code class="docutils literal notranslate"><span class="pre">print</span></code> or <code class="docutils literal notranslate"><span class="pre">write</span></code>.
|
||||
When execution is complete, the Shell retains focus and displays a prompt.
|
||||
|
@ -266,6 +270,12 @@ At this point, one may interactively explore the result of execution.
|
|||
This is similar to executing a file with <code class="docutils literal notranslate"><span class="pre">python</span> <span class="pre">-i</span> <span class="pre">file</span></code> at a command
|
||||
line.</dd>
|
||||
</dl>
|
||||
<dl class="docutils" id="run-custom">
|
||||
<dt>Run… Customized</dt>
|
||||
<dd>Same as <a class="reference internal" href="#run-module"><span class="std std-ref">Run Module</span></a>, but run the module with customized
|
||||
settings. <em>Command Line Arguments</em> extend <a class="reference internal" href="sys.html#sys.argv" title="sys.argv"><code class="xref py py-data docutils literal notranslate"><span class="pre">sys.argv</span></code></a> as if passed
|
||||
on a command line. The module can be run in the Shell without restarting.</dd>
|
||||
</dl>
|
||||
</div>
|
||||
<div class="section" id="shell-menu-shell-window-only">
|
||||
<h3>Shell menu (Shell window only)<a class="headerlink" href="#shell-menu-shell-window-only" title="Permalink to this headline">¶</a></h3>
|
||||
|
|
|
@ -108,6 +108,15 @@ _color_delegator_spec = {
|
|||
"The default color scheme is in idlelib/config-highlight.def"
|
||||
}
|
||||
|
||||
CustomRun_spec = {
|
||||
'file': 'query',
|
||||
'kwds': {'title': 'Custom Run Args',
|
||||
'_htest': True},
|
||||
'msg': "Enter with <Return> or [Ok]. Print valid entry to Shell\n"
|
||||
"Arguments are parsed into a list\n"
|
||||
"Close dialog with valid entry, <Escape>, [Cancel], [X]"
|
||||
}
|
||||
|
||||
ConfigDialog_spec = {
|
||||
'file': 'configdialog',
|
||||
'kwds': {'title': 'ConfigDialogTest',
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
"""Test query, coverage 91%).
|
||||
"""Test query, coverage 93%).
|
||||
|
||||
Non-gui tests for Query, SectionName, ModuleName, and HelpSource use
|
||||
dummy versions that extract the non-gui methods and add other needed
|
||||
|
@ -30,11 +30,9 @@ class QueryTest(unittest.TestCase):
|
|||
ok = query.Query.ok
|
||||
cancel = query.Query.cancel
|
||||
# Add attributes and initialization needed for tests.
|
||||
entry = Var()
|
||||
entry_error = {}
|
||||
def __init__(self, dummy_entry):
|
||||
self.entry.set(dummy_entry)
|
||||
self.entry_error['text'] = ''
|
||||
self.entry = Var(value=dummy_entry)
|
||||
self.entry_error = {'text': ''}
|
||||
self.result = None
|
||||
self.destroyed = False
|
||||
def showerror(self, message):
|
||||
|
@ -80,11 +78,9 @@ class SectionNameTest(unittest.TestCase):
|
|||
class Dummy_SectionName:
|
||||
entry_ok = query.SectionName.entry_ok # Function being tested.
|
||||
used_names = ['used']
|
||||
entry = Var()
|
||||
entry_error = {}
|
||||
def __init__(self, dummy_entry):
|
||||
self.entry.set(dummy_entry)
|
||||
self.entry_error['text'] = ''
|
||||
self.entry = Var(value=dummy_entry)
|
||||
self.entry_error = {'text': ''}
|
||||
def showerror(self, message):
|
||||
self.entry_error['text'] = message
|
||||
|
||||
|
@ -115,11 +111,9 @@ class ModuleNameTest(unittest.TestCase):
|
|||
class Dummy_ModuleName:
|
||||
entry_ok = query.ModuleName.entry_ok # Function being tested.
|
||||
text0 = ''
|
||||
entry = Var()
|
||||
entry_error = {}
|
||||
def __init__(self, dummy_entry):
|
||||
self.entry.set(dummy_entry)
|
||||
self.entry_error['text'] = ''
|
||||
self.entry = Var(value=dummy_entry)
|
||||
self.entry_error = {'text': ''}
|
||||
def showerror(self, message):
|
||||
self.entry_error['text'] = message
|
||||
|
||||
|
@ -144,9 +138,7 @@ class ModuleNameTest(unittest.TestCase):
|
|||
self.assertEqual(dialog.entry_error['text'], '')
|
||||
|
||||
|
||||
# 3 HelpSource test classes each test one function.
|
||||
|
||||
orig_platform = query.platform
|
||||
# 3 HelpSource test classes each test one method.
|
||||
|
||||
class HelpsourceBrowsefileTest(unittest.TestCase):
|
||||
"Test browse_file method of ModuleName subclass of Query."
|
||||
|
@ -178,17 +170,16 @@ class HelpsourcePathokTest(unittest.TestCase):
|
|||
|
||||
class Dummy_HelpSource:
|
||||
path_ok = query.HelpSource.path_ok
|
||||
path = Var()
|
||||
path_error = {}
|
||||
def __init__(self, dummy_path):
|
||||
self.path.set(dummy_path)
|
||||
self.path_error['text'] = ''
|
||||
self.path = Var(value=dummy_path)
|
||||
self.path_error = {'text': ''}
|
||||
def showerror(self, message, widget=None):
|
||||
self.path_error['text'] = message
|
||||
|
||||
orig_platform = query.platform # Set in test_path_ok_file.
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
query.platform = orig_platform
|
||||
query.platform = cls.orig_platform
|
||||
|
||||
def test_path_ok_blank(self):
|
||||
dialog = self.Dummy_HelpSource(' ')
|
||||
|
@ -242,6 +233,56 @@ class HelpsourceEntryokTest(unittest.TestCase):
|
|||
self.assertEqual(dialog.entry_ok(), result)
|
||||
|
||||
|
||||
# 2 CustomRun test classes each test one method.
|
||||
|
||||
class CustomRunCLIargsokTest(unittest.TestCase):
|
||||
"Test cli_ok method of the CustomRun subclass of Query."
|
||||
|
||||
class Dummy_CustomRun:
|
||||
cli_args_ok = query.CustomRun.cli_args_ok
|
||||
def __init__(self, dummy_entry):
|
||||
self.entry = Var(value=dummy_entry)
|
||||
self.entry_error = {'text': ''}
|
||||
def showerror(self, message):
|
||||
self.entry_error['text'] = message
|
||||
|
||||
def test_blank_args(self):
|
||||
dialog = self.Dummy_CustomRun(' ')
|
||||
self.assertEqual(dialog.cli_args_ok(), [])
|
||||
|
||||
def test_invalid_args(self):
|
||||
dialog = self.Dummy_CustomRun("'no-closing-quote")
|
||||
self.assertEqual(dialog.cli_args_ok(), None)
|
||||
self.assertIn('No closing', dialog.entry_error['text'])
|
||||
|
||||
def test_good_args(self):
|
||||
args = ['-n', '10', '--verbose', '-p', '/path', '--name']
|
||||
dialog = self.Dummy_CustomRun(' '.join(args) + ' "my name"')
|
||||
self.assertEqual(dialog.cli_args_ok(), args + ["my name"])
|
||||
self.assertEqual(dialog.entry_error['text'], '')
|
||||
|
||||
|
||||
class CustomRunEntryokTest(unittest.TestCase):
|
||||
"Test entry_ok method of the CustomRun subclass of Query."
|
||||
|
||||
class Dummy_CustomRun:
|
||||
entry_ok = query.CustomRun.entry_ok
|
||||
entry_error = {}
|
||||
restartvar = Var()
|
||||
def cli_args_ok(self):
|
||||
return self.cli_args
|
||||
|
||||
def test_entry_ok_customrun(self):
|
||||
dialog = self.Dummy_CustomRun()
|
||||
for restart in {True, False}:
|
||||
dialog.restartvar.set(restart)
|
||||
for cli_args, result in ((None, None),
|
||||
(['my arg'], (['my arg'], restart))):
|
||||
with self.subTest(restart=restart, cli_args=cli_args):
|
||||
dialog.cli_args = cli_args
|
||||
self.assertEqual(dialog.entry_ok(), result)
|
||||
|
||||
|
||||
# GUI TESTS
|
||||
|
||||
class QueryGuiTest(unittest.TestCase):
|
||||
|
@ -302,9 +343,7 @@ class SectionnameGuiTest(unittest.TestCase):
|
|||
dialog.entry.insert(0, 'okay')
|
||||
dialog.button_ok.invoke()
|
||||
self.assertEqual(dialog.result, 'okay')
|
||||
del dialog
|
||||
root.destroy()
|
||||
del root
|
||||
|
||||
|
||||
class ModulenameGuiTest(unittest.TestCase):
|
||||
|
@ -321,9 +360,7 @@ class ModulenameGuiTest(unittest.TestCase):
|
|||
self.assertEqual(dialog.entry.get(), 'idlelib')
|
||||
dialog.button_ok.invoke()
|
||||
self.assertTrue(dialog.result.endswith('__init__.py'))
|
||||
del dialog
|
||||
root.destroy()
|
||||
del root
|
||||
|
||||
|
||||
class HelpsourceGuiTest(unittest.TestCase):
|
||||
|
@ -343,9 +380,23 @@ class HelpsourceGuiTest(unittest.TestCase):
|
|||
dialog.button_ok.invoke()
|
||||
prefix = "file://" if sys.platform == 'darwin' else ''
|
||||
Equal(dialog.result, ('__test__', prefix + __file__))
|
||||
del dialog
|
||||
root.destroy()
|
||||
del root
|
||||
|
||||
|
||||
class CustomRunGuiTest(unittest.TestCase):
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
requires('gui')
|
||||
|
||||
def test_click_args(self):
|
||||
root = Tk()
|
||||
root.withdraw()
|
||||
dialog = query.CustomRun(root, 'Title', _utest=True)
|
||||
dialog.entry.insert(0, 'okay')
|
||||
dialog.button_ok.invoke()
|
||||
self.assertEqual(dialog.result, (['okay'], True))
|
||||
root.destroy()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
|
|
@ -76,6 +76,7 @@ menudefs = [
|
|||
('Python Shell', '<<open-python-shell>>'),
|
||||
('C_heck Module', '<<check-module>>'),
|
||||
('R_un Module', '<<run-module>>'),
|
||||
('Run... _Customized', '<<run-custom>>'),
|
||||
]),
|
||||
|
||||
('shell', [
|
||||
|
|
|
@ -21,10 +21,11 @@ Subclass HelpSource gets menu item and path for additions to Help menu.
|
|||
|
||||
import importlib
|
||||
import os
|
||||
import shlex
|
||||
from sys import executable, platform # Platform is set for one test.
|
||||
|
||||
from tkinter import Toplevel, StringVar, W, E, S
|
||||
from tkinter.ttk import Frame, Button, Entry, Label
|
||||
from tkinter import Toplevel, StringVar, BooleanVar, W, E, S
|
||||
from tkinter.ttk import Frame, Button, Entry, Label, Checkbutton
|
||||
from tkinter import filedialog
|
||||
from tkinter.font import Font
|
||||
|
||||
|
@ -83,7 +84,7 @@ class Query(Toplevel):
|
|||
self.deiconify() # Unhide now that geometry set.
|
||||
self.wait_window()
|
||||
|
||||
def create_widgets(self): # Call from override, if any.
|
||||
def create_widgets(self, ok_text='OK'): # Call from override, if any.
|
||||
# Bind to self widgets needed for entry_ok or unittest.
|
||||
self.frame = frame = Frame(self, padding=10)
|
||||
frame.grid(column=0, row=0, sticky='news')
|
||||
|
@ -99,7 +100,7 @@ class Query(Toplevel):
|
|||
self.entry_error = Label(frame, text=' ', foreground='red',
|
||||
font=self.error_font)
|
||||
self.button_ok = Button(
|
||||
frame, text='OK', default='active', command=self.ok)
|
||||
frame, text=ok_text, default='active', command=self.ok)
|
||||
self.button_cancel = Button(
|
||||
frame, text='Cancel', command=self.cancel)
|
||||
|
||||
|
@ -302,10 +303,56 @@ class HelpSource(Query):
|
|||
path = self.path_ok()
|
||||
return None if name is None or path is None else (name, path)
|
||||
|
||||
class CustomRun(Query):
|
||||
"""Get settings for custom run of module.
|
||||
|
||||
1. Command line arguments to extend sys.argv.
|
||||
2. Whether to restart Shell or not.
|
||||
"""
|
||||
# Used in runscript.run_custom_event
|
||||
|
||||
def __init__(self, parent, title, *, cli_args='',
|
||||
_htest=False, _utest=False):
|
||||
# TODO Use cli_args to pre-populate entry.
|
||||
message = 'Command Line Arguments for sys.argv:'
|
||||
super().__init__(
|
||||
parent, title, message, text0=cli_args,
|
||||
_htest=_htest, _utest=_utest)
|
||||
|
||||
def create_widgets(self):
|
||||
super().create_widgets(ok_text='Run')
|
||||
frame = self.frame
|
||||
self.restartvar = BooleanVar(self, value=True)
|
||||
restart = Checkbutton(frame, variable=self.restartvar, onvalue=True,
|
||||
offvalue=False, text='Restart shell')
|
||||
self.args_error = Label(frame, text=' ', foreground='red',
|
||||
font=self.error_font)
|
||||
|
||||
restart.grid(column=0, row=4, columnspan=3, padx=5, sticky='w')
|
||||
self.args_error.grid(column=0, row=12, columnspan=3, padx=5,
|
||||
sticky='we')
|
||||
|
||||
def cli_args_ok(self):
|
||||
"Validity check and parsing for command line arguments."
|
||||
cli_string = self.entry.get().strip()
|
||||
try:
|
||||
cli_args = shlex.split(cli_string, posix=True)
|
||||
except ValueError as err:
|
||||
self.showerror(str(err))
|
||||
return None
|
||||
return cli_args
|
||||
|
||||
def entry_ok(self):
|
||||
"Return apparently valid (cli_args, restart) or None"
|
||||
self.entry_error['text'] = ''
|
||||
cli_args = self.cli_args_ok()
|
||||
restart = self.restartvar.get()
|
||||
return None if cli_args is None else (cli_args, restart)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
from unittest import main
|
||||
main('idlelib.idle_test.test_query', verbosity=2, exit=False)
|
||||
|
||||
from idlelib.idle_test.htest import run
|
||||
run(Query, HelpSource)
|
||||
run(Query, HelpSource, CustomRun)
|
||||
|
|
|
@ -18,6 +18,7 @@ import tkinter.messagebox as tkMessageBox
|
|||
from idlelib.config import idleConf
|
||||
from idlelib import macosx
|
||||
from idlelib import pyshell
|
||||
from idlelib.query import CustomRun
|
||||
|
||||
indent_message = """Error: Inconsistent indentation detected!
|
||||
|
||||
|
@ -108,20 +109,24 @@ class ScriptBinding:
|
|||
# tries to run a module using the keyboard shortcut
|
||||
# (the menu item works fine).
|
||||
self.editwin.text_frame.after(200,
|
||||
lambda: self.editwin.text_frame.event_generate('<<run-module-event-2>>'))
|
||||
lambda: self.editwin.text_frame.event_generate(
|
||||
'<<run-module-event-2>>'))
|
||||
return 'break'
|
||||
else:
|
||||
return self._run_module_event(event)
|
||||
|
||||
def _run_module_event(self, event):
|
||||
def run_custom_event(self, event):
|
||||
return self._run_module_event(event, customize=True)
|
||||
|
||||
def _run_module_event(self, event, *, customize=False):
|
||||
"""Run the module after setting up the environment.
|
||||
|
||||
First check the syntax. If OK, make sure the shell is active and
|
||||
then transfer the arguments, set the run environment's working
|
||||
directory to the directory of the module being executed and also
|
||||
add that directory to its sys.path if not already included.
|
||||
First check the syntax. Next get customization. If OK, make
|
||||
sure the shell is active and then transfer the arguments, set
|
||||
the run environment's working directory to the directory of the
|
||||
module being executed and also add that directory to its
|
||||
sys.path if not already included.
|
||||
"""
|
||||
|
||||
filename = self.getfilename()
|
||||
if not filename:
|
||||
return 'break'
|
||||
|
@ -130,23 +135,34 @@ class ScriptBinding:
|
|||
return 'break'
|
||||
if not self.tabnanny(filename):
|
||||
return 'break'
|
||||
if customize:
|
||||
title = f"Customize {self.editwin.short_title()} Run"
|
||||
run_args = CustomRun(self.shell.text, title).result
|
||||
if not run_args: # User cancelled.
|
||||
return 'break'
|
||||
cli_args, restart = run_args if customize else ([], True)
|
||||
interp = self.shell.interp
|
||||
if pyshell.use_subprocess:
|
||||
interp.restart_subprocess(with_cwd=False, filename=
|
||||
self.editwin._filename_to_unicode(filename))
|
||||
if pyshell.use_subprocess and restart:
|
||||
interp.restart_subprocess(
|
||||
with_cwd=False, filename=
|
||||
self.editwin._filename_to_unicode(filename))
|
||||
dirname = os.path.dirname(filename)
|
||||
# XXX Too often this discards arguments the user just set...
|
||||
interp.runcommand("""if 1:
|
||||
argv = [filename]
|
||||
if cli_args:
|
||||
argv += cli_args
|
||||
interp.runcommand(f"""if 1:
|
||||
__file__ = {filename!r}
|
||||
import sys as _sys
|
||||
from os.path import basename as _basename
|
||||
argv = {argv!r}
|
||||
if (not _sys.argv or
|
||||
_basename(_sys.argv[0]) != _basename(__file__)):
|
||||
_sys.argv = [__file__]
|
||||
_basename(_sys.argv[0]) != _basename(__file__) or
|
||||
len(argv) > 1):
|
||||
_sys.argv = argv
|
||||
import os as _os
|
||||
_os.chdir({dirname!r})
|
||||
del _sys, _basename, _os
|
||||
\n""".format(filename=filename, dirname=dirname))
|
||||
\n""")
|
||||
interp.prepend_syspath(filename)
|
||||
# XXX KBK 03Jul04 When run w/o subprocess, runtime warnings still
|
||||
# go to __stderr__. With subprocess, they go to the shell.
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
Add 'Run... Customized' to the Run menu to run a module with customized
|
||||
settings. Any 'command line arguments' entered are added to sys.argv.
|
||||
One can suppress the normal Shell main module restart.
|
Loading…
Reference in New Issue