Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 766931a

Browse filesBrowse files
committed
merge
2 parents eff7f27 + 61cd40a commit 766931a
Copy full SHA for 766931a

9 files changed

+99-127Lines changed: 99 additions & 127 deletions

File tree

Expand file treeCollapse file tree
Open diff view settings
Filter options
Expand file treeCollapse file tree
Open diff view settings
Collapse file

‎CHANGELOG‎

Copy file name to clipboardExpand all lines: CHANGELOG
+16-1Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,21 @@
11
Changelog
22
=========
33

4+
v0.9.8
5+
------
6+
* Config files are now located according to the XDG Base Directory
7+
Specification. The support for the old bpythonrc files has been
8+
dropped and ~/.bpython.ini as config file location is no longer supported.
9+
See issue #91.
10+
11+
v0.9.7.1
12+
--------
13+
14+
A bugfix release. The fixed bugs are:
15+
16+
* #128: bpython-gtk is broken
17+
* #134: crash when using pastebin and no active internet connection
18+
419
v0.9.7
520
------
621

@@ -15,7 +30,7 @@ integrates with a Twisted reactor and through that with things like the GTK
1530
event loop.
1631

1732
At the same time we have done a lot of work on the GTK frontend. The GTK
18-
frontend is now 'usable'. Please give that a spin as well by running python-gtk
33+
frontend is now 'usable'. Please give that a spin as well by running bpython-gtk
1934
on you system.
2035

2136
We also welcome a new contributor in the name of Michele Orrù who we hope will
Collapse file

‎README‎

Copy file name to clipboardExpand all lines: README
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ http://bitbucket.org/bobf/bpython/issues/
4747
For any other ways of communicating with bpython
4848
users and devs you can find us at the communication
4949
page on the projects homepage:
50-
http://www.noiseforfree.com/bpython/community.html
50+
http://bpython-interpreter.org/community
5151

5252
Hope to see you there!
5353

Collapse file

‎bpython/__init__.py‎

Copy file name to clipboardExpand all lines: bpython/__init__.py
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
# THE SOFTWARE.
2222

2323

24-
__version__ = '0.9.7'
24+
__version__ = '0.9.7.1'
2525

2626

2727
def embed(locals_=None, args=['-i', '-q'], banner=None):
Collapse file

‎bpython/args.py‎

Copy file name to clipboardExpand all lines: bpython/args.py
+2-7Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
from optparse import OptionParser, OptionGroup
1010

1111
from bpython import __version__
12-
from bpython.config import loadini, Struct, migrate_rc
12+
from bpython.config import default_config_path, loadini, Struct
1313

1414

1515
class OptionParserFailed(ValueError):
@@ -58,7 +58,7 @@ def parse(args, extras=None, ignore_stdin=False):
5858
# That's probably fixable though, for example by having that
5959
# option swallow all remaining arguments in a callback.
6060
parser.disable_interspersed_args()
61-
parser.add_option('--config', '-c', default='~/.bpython/config',
61+
parser.add_option('--config', '-c', default=default_config_path(),
6262
help='use CONFIG instead of default config file')
6363
parser.add_option('--interactive', '-i', action='store_true',
6464
help='Drop to bpython shell after running file '
@@ -92,12 +92,7 @@ def parse(args, extras=None, ignore_stdin=False):
9292
interpreter.runsource(sys.stdin.read())
9393
raise SystemExit
9494

95-
path = os.path.expanduser('~/.bpythonrc')
96-
# migrating old configuration file
97-
if os.path.isfile(path):
98-
migrate_rc(path)
9995
config = Struct()
100-
10196
loadini(config, options.config)
10297

10398
return config, options, args
Collapse file

‎bpython/config.py‎

Copy file name to clipboard
+60-108Lines changed: 60 additions & 108 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,23 @@
1+
from __future__ import with_statement
12
import os
23
import sys
34
from ConfigParser import ConfigParser
45
from itertools import chain
56
from bpython.keys import key_dispatch
6-
import errno
77

88

99
class Struct(object):
1010
"""Simple class for instantiating objects we can add arbitrary attributes
1111
to and use for various arbitrary things."""
1212

13+
def get_config_home():
14+
"""Returns the base directory for bpython's configuration files."""
15+
xdg_config_home = os.environ.get('XDG_CONFIG_HOME', '~/.config')
16+
return os.path.join(xdg_config_home, 'bpython')
17+
18+
def default_config_path():
19+
"""Returns bpython's default configuration file path."""
20+
return os.path.join(get_config_home(), 'config')
1321

1422
def fill_config_with_default_values(config, default_values):
1523
for section in default_values.iterkeys():
@@ -25,11 +33,11 @@ def loadini(struct, configfile):
2533
"""Loads .ini configuration file and stores its values in struct"""
2634

2735
config_path = os.path.expanduser(configfile)
28-
if not os.path.isfile(config_path) and configfile == '~/.bpython/config':
29-
# FIXME: I decided ~/.bpython.ini was a crappy place for a config file,
30-
# so this is just a fallback if the default is passed - remove this
31-
# eventually please.
32-
config_path = os.path.expanduser('~/.bpython.ini')
36+
if not os.path.isfile(config_path) and configfile == default_config_path():
37+
# We decided that '~/.bpython/config' still was a crappy
38+
# place, use XDG Base Directory Specification instead. Fall
39+
# back to old config, though.
40+
config_path = os.path.expanduser('~/.bpython/config')
3341

3442
config = ConfigParser()
3543
fill_config_with_default_values(config, {
@@ -69,7 +77,13 @@ def loadini(struct, configfile):
6977
'gtk': {
7078
'font': 'monospace 10',
7179
'color_scheme': 'default'}})
72-
config.read(config_path)
80+
if not config.read(config_path):
81+
# No config file. If the user has it in the old place then complain
82+
if os.path.isfile(os.path.expanduser('~/.bpython.ini')):
83+
sys.stderr.write("Error: It seems that you have a config file at "
84+
"~/.bpython.ini. Please move your config file to "
85+
"%s\n" % default_config_path())
86+
sys.exit(1)
7387

7488
struct.dedent_after = config.getint('general', 'dedent_after')
7589
struct.tab_length = config.getint('general', 'tab_length')
@@ -126,7 +140,7 @@ def loadini(struct, configfile):
126140
'prompt': 'c',
127141
'prompt_more': 'g',
128142
}
129-
143+
130144
default_gtk_colors = {
131145
'keyword': 'b',
132146
'name': 'k',
@@ -145,123 +159,61 @@ def loadini(struct, configfile):
145159
'prompt_more': 'g',
146160
}
147161

148-
# TODO consolidate
149162
if color_scheme_name == 'default':
150163
struct.color_scheme = default_colors
151164
else:
152-
path = os.path.expanduser('~/.bpython/%s.theme' % (color_scheme_name,))
153-
load_theme(struct, path, config_path, default_colors)
165+
struct.color_scheme = dict()
166+
167+
theme_filename = color_scheme_name + '.theme'
168+
path = os.path.expanduser(os.path.join(get_config_home(),
169+
theme_filename))
170+
old_path = os.path.expanduser(os.path.join('~/.bpython',
171+
theme_filename))
172+
173+
for path in [path, old_path]:
174+
try:
175+
load_theme(struct, path, struct.color_scheme, default_colors)
176+
except EnvironmentError:
177+
continue
178+
else:
179+
break
180+
else:
181+
sys.stderr.write("Could not load theme '%s'.\n" %
182+
(color_scheme_name, ))
183+
sys.exit(1)
154184

155185
if color_gtk_scheme_name == 'default':
156186
struct.color_gtk_scheme = default_gtk_colors
157187
else:
158-
path = os.path.expanduser('~/.bpython/%s.theme' % (color_gtk_scheme_name,))
159-
load_gtk_theme(struct, path, config_path, default_gtk_colors)
160-
188+
struct.color_gtk_scheme = dict()
189+
# Note: This is a new config option, hence we don't have a
190+
# fallback directory.
191+
path = os.path.expanduser(os.path.join(get_config_home(),
192+
color_gtk_scheme_name + '.theme'))
193+
194+
try:
195+
load_theme(struct, path, struct.color_gtk_scheme, default_colors)
196+
except EnvironmentError:
197+
sys.stderr.write("Could not load gtk theme '%s'.\n" %
198+
(color_gtk_scheme_name, ))
199+
sys.exit(1)
161200

162201
# checks for valid key configuration this part still sucks
163202
for key in (struct.pastebin_key, struct.save_key):
164203
key_dispatch[key]
165204

166-
# TODO consolidate
167-
def load_theme(struct, path, inipath, default_colors):
205+
def load_theme(struct, path, colors, default_colors):
168206
theme = ConfigParser()
169-
try:
170-
f = open(path, 'r')
171-
except (IOError, OSError), e:
172-
sys.stdout.write("Error loading theme file specified in '%s':\n%s\n" %
173-
(inipath, e))
174-
sys.exit(1)
175-
theme.readfp(f)
176-
struct.color_scheme = {}
207+
with open(path, 'r') as f:
208+
theme.readfp(f)
177209
for k, v in chain(theme.items('syntax'), theme.items('interface')):
178210
if theme.has_option('syntax', k):
179-
struct.color_scheme[k] = theme.get('syntax', k)
211+
colors[k] = theme.get('syntax', k)
180212
else:
181-
struct.color_scheme[k] = theme.get('interface', k)
213+
colors[k] = theme.get('interface', k)
182214

183215
# Check against default theme to see if all values are defined
184216
for k, v in default_colors.iteritems():
185-
if k not in struct.color_scheme:
186-
struct.color_scheme[k] = v
187-
f.close()
188-
189-
190-
def load_gtk_theme(struct, path, inipath, default_colors):
191-
theme = ConfigParser()
192-
try:
193-
f = open(path, 'r')
194-
except (IOError, OSError), e:
195-
sys.stdout.write("Error loading theme file specified in '%s':\n%s\n" %
196-
(inipath, e))
197-
sys.exit(1)
198-
theme.readfp(f)
199-
struct.color_gtk_scheme = {}
200-
for k, v in chain(theme.items('syntax'), theme.items('interface')):
201-
if theme.has_option('syntax', k):
202-
struct.color_gtk_scheme[k] = theme.get('syntax', k)
203-
else:
204-
struct.color_gtk_scheme[k] = theme.get('interface', k)
205-
206-
# Check against default theme to see if all values are defined
207-
for k, v in default_colors.iteritems():
208-
if k not in struct.color_gtk_scheme:
209-
struct.color_gtk_scheme[k] = v
210-
f.close()
211-
212-
213-
214-
def migrate_rc(path):
215-
"""Use the shlex module to convert the old configuration file to the new
216-
format.
217-
The old configuration file is renamed but not removed by now."""
218-
import shlex
219-
f = open(path)
220-
parser = shlex.shlex(f)
221-
222-
bools = {
223-
'true': True,
224-
'yes': True,
225-
'on': True,
226-
'false': False,
227-
'no': False,
228-
'off': False}
229-
230-
config = ConfigParser()
231-
config.add_section('general')
232-
233-
while True:
234-
k = parser.get_token()
235-
v = None
236-
237-
if not k:
238-
break
239-
240-
k = k.lower()
241-
242-
if parser.get_token() == '=':
243-
v = parser.get_token() or None
244-
245-
if v is not None:
246-
try:
247-
v = int(v)
248-
except ValueError:
249-
if v.lower() in bools:
250-
v = bools[v.lower()]
251-
config.set('general', k, v)
252-
f.close()
253-
try:
254-
os.makedirs(os.path.expanduser('~/.bpython'))
255-
except OSError, e:
256-
if e.errno != errno.EEXIST:
257-
raise
258-
f = open(os.path.expanduser('~/.bpython/config'), 'w')
259-
config.write(f)
217+
if k not in colors:
218+
colors[k] = v
260219
f.close()
261-
os.rename(path, os.path.expanduser('~/.bpythonrc.bak'))
262-
print ("The configuration file for bpython has been changed. A new "
263-
"config file has been created as ~/.bpython/config")
264-
print ("The existing .bpythonrc file has been renamed to .bpythonrc.bak "
265-
"and it can be removed.")
266-
print "Press enter to continue."
267-
raw_input()
Collapse file

‎bpython/repl.py‎

Copy file name to clipboardExpand all lines: bpython/repl.py
+3-3Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@
3535
from glob import glob
3636
from itertools import takewhile
3737
from locale import getpreferredencoding
38-
from socket import error as socketerror
38+
from socket import error as SocketError
3939
from string import Template
4040
from urllib import quote as urlquote
4141
from xmlrpclib import ServerProxy, Error as XMLRPCError
@@ -714,8 +714,8 @@ def pastebin(self, s=None):
714714
self.interact.notify('Posting data to pastebin...')
715715
try:
716716
paste_id = pasteservice.pastes.newPaste('pycon', s)
717-
except (XMLRPCError, socketerror), e:
718-
self.interact.notify('Upload failed: %s' % e)
717+
except (SocketError, XMLRPCError), e:
718+
self.interact.notify('Upload failed: %s' % (str(e), ) )
719719
return
720720

721721
paste_url_template = Template(self.config.pastebin_show_url)
Collapse file

‎bpython/test/test_config.py‎

Copy file name to clipboardExpand all lines: bpython/test/test_config.py
+6-4Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,24 +8,26 @@
88
class TestConfig(unittest.TestCase):
99
def test_load_theme(self):
1010
struct = config.Struct()
11-
config.load_theme(struct, TEST_THEME_PATH, "test.ini", dict())
11+
struct.color_scheme = dict()
12+
config.load_theme(struct, TEST_THEME_PATH, struct.color_scheme, dict())
1213
expected = {"keyword": "y"}
1314
self.assertEquals(struct.color_scheme, expected)
1415

1516
defaults = {"name": "c"}
1617
expected.update(defaults)
17-
config.load_theme(struct, TEST_THEME_PATH, "test.ini", defaults)
18+
config.load_theme(struct, TEST_THEME_PATH, struct.color_scheme, defaults)
1819
self.assertEquals(struct.color_scheme, expected)
1920

2021
def test_load_gtk_scheme(self):
2122
struct = config.Struct()
22-
config.load_gtk_theme(struct, TEST_THEME_PATH, "test.ini", dict())
23+
struct.color_gtk_scheme = dict()
24+
config.load_theme(struct, TEST_THEME_PATH, struct.color_gtk_scheme, dict())
2325
expected = {"keyword": "y"}
2426
self.assertEquals(struct.color_gtk_scheme, expected)
2527

2628
defaults = {"name": "c"}
2729
expected.update(defaults)
28-
config.load_gtk_theme(struct, TEST_THEME_PATH, "test.ini", defaults)
30+
config.load_theme(struct, TEST_THEME_PATH, struct.color_gtk_scheme, defaults)
2931
self.assertEquals(struct.color_gtk_scheme, expected)
3032

3133

Collapse file

‎bpython/urwid.py‎

Copy file name to clipboardExpand all lines: bpython/urwid.py
+9-1Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -304,6 +304,14 @@ def mouse_event(self, *args):
304304
finally:
305305
self._bpy_may_move_cursor = False
306306

307+
class BPythonListBox(urwid.ListBox):
308+
"""Like `urwid.ListBox`, except that it does not eat up and
309+
down keys.
310+
"""
311+
def keypress(self, size, key):
312+
if key not in ["up", "down"]:
313+
return urwid.ListBox.keypress(self, size, key)
314+
return key
307315

308316
class Tooltip(urwid.BoxWidget):
309317

@@ -408,7 +416,7 @@ class URWIDRepl(repl.Repl):
408416
def __init__(self, event_loop, palette, interpreter, config):
409417
repl.Repl.__init__(self, interpreter, config)
410418

411-
self.listbox = urwid.ListBox(urwid.SimpleListWalker([]))
419+
self.listbox = BPythonListBox(urwid.SimpleListWalker([]))
412420

413421
# String is straight from bpython.cli
414422
self.statusbar = Statusbar(config,
Collapse file

‎doc/bpython.1‎

Copy file name to clipboardExpand all lines: doc/bpython.1
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ http://docs.bpython-interpreter.org/configuration.html#keyboard
8989
.SH FILES
9090
~/.bpython/config
9191
.RS
92-
Your bpython config. See sample-config (in /usr/share/docs/bpython/examples on Debian) for various options you can use, or read
92+
Your bpython config. See sample-config (in /usr/share/doc/bpython/examples on Debian) for various options you can use, or read
9393
.BR bpython-config (5)
9494
.
9595
.RE

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.