X Tutup
Skip to content

Commit 1f3eaf7

Browse files
committed
factor out option parsing to a common module for different front ends to use
1 parent b312472 commit 1f3eaf7

File tree

3 files changed

+111
-55
lines changed

3 files changed

+111
-55
lines changed

bpython/args.py

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
"""
2+
Module to handle command line argument parsing, for all front-ends.
3+
"""
4+
5+
import os
6+
import sys
7+
import code
8+
from optparse import OptionParser, OptionGroup
9+
from itertools import takewhile
10+
11+
from bpython import __version__
12+
from bpython.config import loadini, Struct, migrate_rc
13+
14+
def parse(args, extras=None):
15+
"""Receive an argument list - if None, use sys.argv - parse all args and
16+
take appropriate action. Also receive optional extra options: this should
17+
be a tuple of (title, description, options)
18+
title: The title for the option group
19+
description: A full description of the option group
20+
options: A list of optparse.Option objects to be added to the
21+
group
22+
23+
e.g.:
24+
25+
parse(['-i', '-m', 'foo.py'],
26+
('Front end-specific options',
27+
'A full description of what these options are for',
28+
[optparse.Option('-f', action='store_true', dest='f', help='Explode'),
29+
optparse.Option('-l', action='store_true', dest='l', help='Love')]))
30+
31+
32+
Return a tuple of (config, options, exec_args) wherein "config" is the
33+
config object either parsed from a default/specified config file or default
34+
config options, "options" is the parsed options from
35+
OptionParser.parse_args, and "exec_args" are the args (if any) to be parsed
36+
to the executed file (if any).
37+
"""
38+
if args is None:
39+
args = sys.argv[1:]
40+
41+
parser = OptionParser(usage='Usage: %prog [options] [file [args]]\n'
42+
'NOTE: If bpython sees an argument it does '
43+
'not know, execution falls back to the '
44+
'regular Python interpreter.')
45+
parser.add_option('--config', '-c', default='~/.bpython/config',
46+
help='use CONFIG instead of default config file')
47+
parser.add_option('--interactive', '-i', action='store_true',
48+
help='Drop to bpython shell after running file '
49+
'instead of exiting')
50+
parser.add_option('--quiet', '-q', action='store_true',
51+
help="Don't flush the output to stdout.")
52+
parser.add_option('--version', '-V', action='store_true',
53+
help='print version and exit')
54+
55+
if extras is not None:
56+
extras_group = OptionGroup(parser, extras[0], extras[1])
57+
for option in extras[2]:
58+
extras_group.option_list.append(option)
59+
parser.add_option_group(extras_group)
60+
61+
all_args = set(parser._short_opt.keys() + parser._long_opt.keys())
62+
if args and not all_args.intersection(args):
63+
# Just let Python handle this
64+
os.execv(sys.executable, [sys.executable] + args)
65+
else:
66+
# Split args in bpython args and args for the executed file
67+
real_args = list(takewhile(lambda arg: arg in all_args, args))
68+
exec_args = args[len(real_args):]
69+
70+
options, args = parser.parse_args(real_args)
71+
72+
if options.version:
73+
print 'bpython version', __version__,
74+
print 'on top of Python', sys.version.split()[0]
75+
print '(C) 2008-2009 Bob Farrell et al. See AUTHORS for detail.'
76+
raise SystemExit
77+
78+
if not (sys.stdin.isatty() and sys.stdout.isatty()):
79+
interpreter = code.InteractiveInterpreter()
80+
interpreter.runsource(sys.stdin.read())
81+
raise SystemExit
82+
83+
path = os.path.expanduser('~/.bpythonrc')
84+
# migrating old configuration file
85+
if os.path.isfile(path):
86+
migrate_rc(path)
87+
config = Struct()
88+
89+
loadini(config, options.config)
90+
91+
return config, options, exec_args
92+
93+
def exec_code(interpreter, args):
94+
"""
95+
Helper to execute code in a given interpreter. args should be a [faked]
96+
sys.argv
97+
"""
98+
with open(args[0], 'r') as sourcefile:
99+
code_obj = compile(sourcefile.read(), args[0], 'exec')
100+
old_argv, sys.argv = sys.argv, args
101+
interpreter.runcode(code_obj)
102+
sys.argv = old_argv

bpython/cli.py

Lines changed: 4 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -57,14 +57,14 @@
5757
from bpython import importcompletion
5858

5959
# This for config
60-
from bpython.config import Struct, loadini, migrate_rc
60+
from bpython.config import Struct, migrate_rc
6161

6262
# This for keys
6363
from bpython.keys import key_dispatch
6464

65-
from bpython import __version__
6665
from bpython.pager import page
6766
from bpython.repl import Interpreter, Repl
67+
import bpython.args
6868

6969

7070
def log(x):
@@ -1549,11 +1549,7 @@ def main_curses(scr, args, config, interactive=True, locals_=None):
15491549
sys.stderr = repl
15501550

15511551
if args:
1552-
with open(args[0], 'r') as sourcefile:
1553-
code_obj = compile(sourcefile.read(), args[0], 'exec')
1554-
old_argv, sys.argv = sys.argv, args
1555-
interpreter.runcode(code_obj)
1556-
sys.argv = old_argv
1552+
bpython.args.exec_code(interpreter, args)
15571553
if not interactive:
15581554
curses.raw(False)
15591555
return repl.getstdout()
@@ -1578,53 +1574,9 @@ def main_curses(scr, args, config, interactive=True, locals_=None):
15781574
def main(args=None, locals_=None):
15791575
global stdscr
15801576

1581-
if args is None:
1582-
args = sys.argv[1:]
1583-
1584-
parser = OptionParser(usage='Usage: %prog [options] [file [args]]\n'
1585-
'NOTE: If bpython sees an argument it does '
1586-
'not know, execution falls back to the '
1587-
'regular Python interpreter.')
1588-
parser.add_option('--config', '-c', default='~/.bpython/config',
1589-
help='use CONFIG instead of default config file')
1590-
parser.add_option('--interactive', '-i', action='store_true',
1591-
help='Drop to bpython shell after running file '
1592-
'instead of exiting')
1593-
parser.add_option('--quiet', '-q', action='store_true',
1594-
help="Don't flush the output to stdout.")
1595-
parser.add_option('--version', '-V', action='store_true',
1596-
help='print version and exit')
1597-
1598-
all_args = set(parser._short_opt.keys() + parser._long_opt.keys())
1599-
if args and not all_args.intersection(args):
1600-
# Just let Python handle this
1601-
os.execv(sys.executable, [sys.executable] + args)
1602-
else:
1603-
# Split args in bpython args and args for the executed file
1604-
real_args = list(takewhile(lambda arg: arg in all_args, args))
1605-
exec_args = args[len(real_args):]
1606-
1607-
options, args = parser.parse_args(real_args)
1608-
1609-
if options.version:
1610-
print 'bpython version', __version__,
1611-
print 'on top of Python', sys.version.split()[0]
1612-
print '(C) 2008-2009 Bob Farrell et al. See AUTHORS for detail.'
1613-
return
1614-
1615-
if not (sys.stdin.isatty() and sys.stdout.isatty()):
1616-
interpreter = code.InteractiveInterpreter()
1617-
interpreter.runsource(sys.stdin.read())
1618-
return
1619-
16201577
setlocale(LC_ALL, '')
16211578

1622-
path = os.path.expanduser('~/.bpythonrc')
1623-
# migrating old configuration file
1624-
if os.path.isfile(path):
1625-
migrate_rc(path)
1626-
config = Struct()
1627-
loadini(config, options.config)
1579+
config, options, exec_args = bpython.args.parse(args)
16281580

16291581
# Save stdin, stdout and stderr for later restoration
16301582
orig_stdin = sys.stdin

bpython/gtk_.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
from bpython import importcompletion, repl
4040
from bpython.config import Struct, loadini
4141
from bpython.formatter import theme_map
42+
import bpython.args
4243

4344

4445
_COLORS = dict(b='blue', c='cyan', g='green', m='magenta', r='red',
@@ -616,12 +617,13 @@ def init_import_completion():
616617

617618

618619
def main(args=None):
619-
if args is None:
620-
args = sys.argv[1:]
621620

622621
setlocale(LC_ALL, '')
623622
config = Struct()
624-
loadini(config, '~/.bpython/config')
623+
624+
config, options, exec_args = bpython.args.parse(args)
625+
626+
loadini(config, '~/.bpython/config', options.config)
625627

626628
interpreter = repl.Interpreter(None, getpreferredencoding())
627629
repl_widget = ReplWidget(interpreter, config)

0 commit comments

Comments
 (0)
X Tutup