Show More
@@ -987,9 +987,9 b' class Image(DisplayObject):' | |||||
987 | """shortcut for returning metadata with shape information, if defined""" |
|
987 | """shortcut for returning metadata with shape information, if defined""" | |
988 | try: |
|
988 | try: | |
989 | b64_data = b2a_base64(self.data).decode('ascii') |
|
989 | b64_data = b2a_base64(self.data).decode('ascii') | |
990 | except TypeError: |
|
990 | except TypeError as e: | |
991 | raise FileNotFoundError( |
|
991 | raise FileNotFoundError( | |
992 | "No such file or directory: '%s'" % (self.data)) |
|
992 | "No such file or directory: '%s'" % (self.data)) from e | |
993 | md = {} |
|
993 | md = {} | |
994 | if self.metadata: |
|
994 | if self.metadata: | |
995 | md.update(self.metadata) |
|
995 | md.update(self.metadata) |
@@ -106,7 +106,7 b' def _detect_screen_size(screen_lines_def):' | |||||
106 | term_flags = termios.tcgetattr(sys.stdout) |
|
106 | term_flags = termios.tcgetattr(sys.stdout) | |
107 | except termios.error as err: |
|
107 | except termios.error as err: | |
108 | # can fail on Linux 2.6, pager_page will catch the TypeError |
|
108 | # can fail on Linux 2.6, pager_page will catch the TypeError | |
109 | raise TypeError('termios error: {0}'.format(err)) |
|
109 | raise TypeError('termios error: {0}'.format(err)) from err | |
110 |
|
110 | |||
111 | try: |
|
111 | try: | |
112 | scr = curses.initscr() |
|
112 | scr = curses.initscr() |
@@ -200,8 +200,8 b' def _reshow_nbagg_figure(fig):' | |||||
200 | """reshow an nbagg figure""" |
|
200 | """reshow an nbagg figure""" | |
201 | try: |
|
201 | try: | |
202 | reshow = fig.canvas.manager.reshow |
|
202 | reshow = fig.canvas.manager.reshow | |
203 | except AttributeError: |
|
203 | except AttributeError as e: | |
204 | raise NotImplementedError() |
|
204 | raise NotImplementedError() from e | |
205 | else: |
|
205 | else: | |
206 | reshow() |
|
206 | reshow() | |
207 |
|
207 |
@@ -51,7 +51,7 b' def _check_pil_jpeg_bytes():' | |||||
51 | img.save(buf, 'jpeg') |
|
51 | img.save(buf, 'jpeg') | |
52 | except Exception as e: |
|
52 | except Exception as e: | |
53 | ename = e.__class__.__name__ |
|
53 | ename = e.__class__.__name__ | |
54 | raise SkipTest("PIL can't write JPEG to BytesIO: %s: %s" % (ename, e)) |
|
54 | raise SkipTest("PIL can't write JPEG to BytesIO: %s: %s" % (ename, e)) from e | |
55 |
|
55 | |||
56 | @dec.skip_without("PIL.Image") |
|
56 | @dec.skip_without("PIL.Image") | |
57 | def test_figure_to_jpeg(): |
|
57 | def test_figure_to_jpeg(): |
@@ -241,8 +241,8 b' class TestMagicRunSimple(tt.TempFileMixin):' | |||||
241 | if sys.platform == 'win32': |
|
241 | if sys.platform == 'win32': | |
242 | try: |
|
242 | try: | |
243 | import win32api |
|
243 | import win32api | |
244 | except ImportError: |
|
244 | except ImportError as e: | |
245 | raise SkipTest("Test requires pywin32") |
|
245 | raise SkipTest("Test requires pywin32") from e | |
246 | src = ("class A(object):\n" |
|
246 | src = ("class A(object):\n" | |
247 | " def __del__(self):\n" |
|
247 | " def __del__(self):\n" | |
248 | " print('object A deleted')\n" |
|
248 | " print('object A deleted')\n" |
@@ -126,13 +126,13 b' class StoreMagics(Magics):' | |||||
126 | if 'd' in opts: |
|
126 | if 'd' in opts: | |
127 | try: |
|
127 | try: | |
128 | todel = args[0] |
|
128 | todel = args[0] | |
129 | except IndexError: |
|
129 | except IndexError as e: | |
130 | raise UsageError('You must provide the variable to forget') |
|
130 | raise UsageError('You must provide the variable to forget') from e | |
131 | else: |
|
131 | else: | |
132 | try: |
|
132 | try: | |
133 | del db['autorestore/' + todel] |
|
133 | del db['autorestore/' + todel] | |
134 | except: |
|
134 | except BaseException as e: | |
135 | raise UsageError("Can't delete variable '%s'" % todel) |
|
135 | raise UsageError("Can't delete variable '%s'" % todel) from e | |
136 | # reset |
|
136 | # reset | |
137 | elif 'z' in opts: |
|
137 | elif 'z' in opts: | |
138 | for k in db.keys('autorestore/*'): |
|
138 | for k in db.keys('autorestore/*'): | |
@@ -203,8 +203,8 b' class StoreMagics(Magics):' | |||||
203 | name = arg |
|
203 | name = arg | |
204 | try: |
|
204 | try: | |
205 | cmd = ip.alias_manager.retrieve_alias(name) |
|
205 | cmd = ip.alias_manager.retrieve_alias(name) | |
206 | except ValueError: |
|
206 | except ValueError as e: | |
207 | raise UsageError("Unknown variable '%s'" % name) |
|
207 | raise UsageError("Unknown variable '%s'" % name) from e | |
208 |
|
208 | |||
209 | staliases = db.get('stored_aliases',{}) |
|
209 | staliases = db.get('stored_aliases',{}) | |
210 | staliases[name] = cmd |
|
210 | staliases[name] = cmd |
@@ -16,9 +16,9 b' def win32_clipboard_get():' | |||||
16 | """ |
|
16 | """ | |
17 | try: |
|
17 | try: | |
18 | import win32clipboard |
|
18 | import win32clipboard | |
19 | except ImportError: |
|
19 | except ImportError as e: | |
20 | raise TryNext("Getting text from the clipboard requires the pywin32 " |
|
20 | raise TryNext("Getting text from the clipboard requires the pywin32 " | |
21 | "extensions: http://sourceforge.net/projects/pywin32/") |
|
21 | "extensions: http://sourceforge.net/projects/pywin32/") from e | |
22 | win32clipboard.OpenClipboard() |
|
22 | win32clipboard.OpenClipboard() | |
23 | try: |
|
23 | try: | |
24 | text = win32clipboard.GetClipboardData(win32clipboard.CF_UNICODETEXT) |
|
24 | text = win32clipboard.GetClipboardData(win32clipboard.CF_UNICODETEXT) | |
@@ -26,8 +26,8 b' def win32_clipboard_get():' | |||||
26 | try: |
|
26 | try: | |
27 | text = win32clipboard.GetClipboardData(win32clipboard.CF_TEXT) |
|
27 | text = win32clipboard.GetClipboardData(win32clipboard.CF_TEXT) | |
28 | text = py3compat.cast_unicode(text, py3compat.DEFAULT_ENCODING) |
|
28 | text = py3compat.cast_unicode(text, py3compat.DEFAULT_ENCODING) | |
29 | except (TypeError, win32clipboard.error): |
|
29 | except (TypeError, win32clipboard.error) as e: | |
30 | raise ClipboardEmpty |
|
30 | raise ClipboardEmpty from e | |
31 | finally: |
|
31 | finally: | |
32 | win32clipboard.CloseClipboard() |
|
32 | win32clipboard.CloseClipboard() | |
33 | return text |
|
33 | return text | |
@@ -52,15 +52,15 b' def tkinter_clipboard_get():' | |||||
52 | """ |
|
52 | """ | |
53 | try: |
|
53 | try: | |
54 | from tkinter import Tk, TclError |
|
54 | from tkinter import Tk, TclError | |
55 | except ImportError: |
|
55 | except ImportError as e: | |
56 | raise TryNext("Getting text from the clipboard on this platform requires tkinter.") |
|
56 | raise TryNext("Getting text from the clipboard on this platform requires tkinter.") from e | |
57 |
|
57 | |||
58 | root = Tk() |
|
58 | root = Tk() | |
59 | root.withdraw() |
|
59 | root.withdraw() | |
60 | try: |
|
60 | try: | |
61 | text = root.clipboard_get() |
|
61 | text = root.clipboard_get() | |
62 | except TclError: |
|
62 | except TclError as e: | |
63 | raise ClipboardEmpty |
|
63 | raise ClipboardEmpty from e | |
64 | finally: |
|
64 | finally: | |
65 | root.destroy() |
|
65 | root.destroy() | |
66 | text = py3compat.cast_unicode(text, py3compat.DEFAULT_ENCODING) |
|
66 | text = py3compat.cast_unicode(text, py3compat.DEFAULT_ENCODING) |
@@ -97,21 +97,21 b' def get_parent(globals, level):' | |||||
97 | for x in range(level, 1, -1): |
|
97 | for x in range(level, 1, -1): | |
98 | try: |
|
98 | try: | |
99 | dot = name.rindex('.', 0, dot) |
|
99 | dot = name.rindex('.', 0, dot) | |
100 | except ValueError: |
|
100 | except ValueError as e: | |
101 | raise ValueError("attempted relative import beyond top-level " |
|
101 | raise ValueError("attempted relative import beyond top-level " | |
102 | "package") |
|
102 | "package") from e | |
103 | name = name[:dot] |
|
103 | name = name[:dot] | |
104 |
|
104 | |||
105 | try: |
|
105 | try: | |
106 | parent = sys.modules[name] |
|
106 | parent = sys.modules[name] | |
107 | except: |
|
107 | except BaseException as e: | |
108 | if orig_level < 1: |
|
108 | if orig_level < 1: | |
109 | warn("Parent module '%.200s' not found while handling absolute " |
|
109 | warn("Parent module '%.200s' not found while handling absolute " | |
110 | "import" % name) |
|
110 | "import" % name) | |
111 | parent = None |
|
111 | parent = None | |
112 | else: |
|
112 | else: | |
113 | raise SystemError("Parent module '%.200s' not loaded, cannot " |
|
113 | raise SystemError("Parent module '%.200s' not loaded, cannot " | |
114 | "perform relative import" % name) |
|
114 | "perform relative import" % name) from e | |
115 |
|
115 | |||
116 | # We expect, but can't guarantee, if parent != None, that: |
|
116 | # We expect, but can't guarantee, if parent != None, that: | |
117 | # - parent.__name__ == name |
|
117 | # - parent.__name__ == name | |
@@ -292,9 +292,9 b' def deep_reload_hook(m):' | |||||
292 | else: |
|
292 | else: | |
293 | try: |
|
293 | try: | |
294 | parent = sys.modules[name[:dot]] |
|
294 | parent = sys.modules[name[:dot]] | |
295 | except KeyError: |
|
295 | except KeyError as e: | |
296 | modules_reloading.clear() |
|
296 | modules_reloading.clear() | |
297 | raise ImportError("reload(): parent %.200s not in sys.modules" % name[:dot]) |
|
297 | raise ImportError("reload(): parent %.200s not in sys.modules" % name[:dot]) from e | |
298 | subname = name[dot+1:] |
|
298 | subname = name[dot+1:] | |
299 | path = getattr(parent, "__path__", None) |
|
299 | path = getattr(parent, "__path__", None) | |
300 |
|
300 |
@@ -182,9 +182,9 b' class Audio(DisplayObject):' | |||||
182 |
|
182 | |||
183 | try: |
|
183 | try: | |
184 | max_abs_value = float(max([abs(x) for x in data])) |
|
184 | max_abs_value = float(max([abs(x) for x in data])) | |
185 | except TypeError: |
|
185 | except TypeError as e: | |
186 | raise TypeError('Only lists of mono audio are ' |
|
186 | raise TypeError('Only lists of mono audio are ' | |
187 | 'supported if numpy is not installed') |
|
187 | 'supported if numpy is not installed') from e | |
188 |
|
188 | |||
189 | normalization_factor = Audio._get_normalization_factor(max_abs_value, normalize) |
|
189 | normalization_factor = Audio._get_normalization_factor(max_abs_value, normalize) | |
190 | scaled = array.array('h', [int(x / normalization_factor * 32767) for x in data]) |
|
190 | scaled = array.array('h', [int(x / normalization_factor * 32767) for x in data]) |
@@ -281,9 +281,9 b' class InputHookManager(object):' | |||||
281 |
|
281 | |||
282 | try: |
|
282 | try: | |
283 | gui_hook = self.guihooks[gui] |
|
283 | gui_hook = self.guihooks[gui] | |
284 | except KeyError: |
|
284 | except KeyError as e: | |
285 | e = "Invalid GUI request {!r}, valid ones are: {}" |
|
285 | e = "Invalid GUI request {!r}, valid ones are: {}" | |
286 | raise ValueError(e.format(gui, ', '.join(self.guihooks))) |
|
286 | raise ValueError(e.format(gui, ', '.join(self.guihooks))) from e | |
287 | self._current_gui = gui |
|
287 | self._current_gui = gui | |
288 |
|
288 | |||
289 | app = gui_hook.enable(app) |
|
289 | app = gui_hook.enable(app) |
@@ -61,10 +61,10 b" if sys.platform == 'darwin':" | |||||
61 | doc='glutCheckLoop( ) -> None', |
|
61 | doc='glutCheckLoop( ) -> None', | |
62 | argNames=(), |
|
62 | argNames=(), | |
63 | ) |
|
63 | ) | |
64 | except AttributeError: |
|
64 | except AttributeError as e: | |
65 | raise RuntimeError( |
|
65 | raise RuntimeError( | |
66 | '''Your glut implementation does not allow interactive sessions. ''' |
|
66 | '''Your glut implementation does not allow interactive sessions. ''' | |
67 | '''Consider installing freeglut.''') |
|
67 | '''Consider installing freeglut.''') from e | |
68 | glutMainLoopEvent = glutCheckLoop |
|
68 | glutMainLoopEvent = glutCheckLoop | |
69 | elif glut.HAVE_FREEGLUT: |
|
69 | elif glut.HAVE_FREEGLUT: | |
70 | glutMainLoopEvent = glut.glutMainLoopEvent |
|
70 | glutMainLoopEvent = glut.glutMainLoopEvent |
@@ -95,8 +95,8 b" def latex_to_png(s, encode=False, backend=None, wrap=False, color='Black'," | |||||
95 | try: |
|
95 | try: | |
96 | color = "RGB {}".format(" ".join([str(int(x, 16)) for x in |
|
96 | color = "RGB {}".format(" ".join([str(int(x, 16)) for x in | |
97 | textwrap.wrap(color[1:], 2)])) |
|
97 | textwrap.wrap(color[1:], 2)])) | |
98 | except ValueError: |
|
98 | except ValueError as e: | |
99 | raise ValueError('Invalid color specification {}.'.format(color)) |
|
99 | raise ValueError('Invalid color specification {}.'.format(color)) from e | |
100 | else: |
|
100 | else: | |
101 | raise ValueError('Invalid color specification {}.'.format(color)) |
|
101 | raise ValueError('Invalid color specification {}.'.format(color)) | |
102 | else: |
|
102 | else: |
@@ -113,7 +113,7 b" def locate_profile(profile='default'):" | |||||
113 | from IPython.core.profiledir import ProfileDir, ProfileDirError |
|
113 | from IPython.core.profiledir import ProfileDir, ProfileDirError | |
114 | try: |
|
114 | try: | |
115 | pd = ProfileDir.find_profile_dir_by_name(get_ipython_dir(), profile) |
|
115 | pd = ProfileDir.find_profile_dir_by_name(get_ipython_dir(), profile) | |
116 | except ProfileDirError: |
|
116 | except ProfileDirError as e: | |
117 | # IOError makes more sense when people are expecting a path |
|
117 | # IOError makes more sense when people are expecting a path | |
118 | raise IOError("Couldn't find profile %r" % profile) |
|
118 | raise IOError("Couldn't find profile %r" % profile) from e | |
119 | return pd.location |
|
119 | return pd.location |
@@ -107,10 +107,10 b' def float_doctest(sphinx_shell, args, input_lines, found, submitted):' | |||||
107 | try: |
|
107 | try: | |
108 | rtol = float(args[2]) |
|
108 | rtol = float(args[2]) | |
109 | atol = float(args[3]) |
|
109 | atol = float(args[3]) | |
110 | except IndexError: |
|
110 | except IndexError as e: | |
111 | e = ("Both `rtol` and `atol` must be specified " |
|
111 | e = ("Both `rtol` and `atol` must be specified " | |
112 | "if either are specified: {0}".format(args)) |
|
112 | "if either are specified: {0}".format(args)) | |
113 | raise IndexError(e) |
|
113 | raise IndexError(e) from e | |
114 |
|
114 | |||
115 | try: |
|
115 | try: | |
116 | submitted = str_to_array(submitted) |
|
116 | submitted = str_to_array(submitted) |
@@ -181,8 +181,8 b' class TerminalMagics(Magics):' | |||||
181 | else: |
|
181 | else: | |
182 | error('Could not get text from the clipboard.') |
|
182 | error('Could not get text from the clipboard.') | |
183 | return |
|
183 | return | |
184 | except ClipboardEmpty: |
|
184 | except ClipboardEmpty as e: | |
185 | raise UsageError("The clipboard appears to be empty") |
|
185 | raise UsageError("The clipboard appears to be empty") from e | |
186 |
|
186 | |||
187 | # By default, echo back to terminal unless quiet mode is requested |
|
187 | # By default, echo back to terminal unless quiet mode is requested | |
188 | if 'q' not in opts: |
|
188 | if 'q' not in opts: |
@@ -44,10 +44,10 b" if sys.platform == 'darwin':" | |||||
44 | doc='glutCheckLoop( ) -> None', |
|
44 | doc='glutCheckLoop( ) -> None', | |
45 | argNames=(), |
|
45 | argNames=(), | |
46 | ) |
|
46 | ) | |
47 | except AttributeError: |
|
47 | except AttributeError as e: | |
48 | raise RuntimeError( |
|
48 | raise RuntimeError( | |
49 | '''Your glut implementation does not allow interactive sessions. ''' |
|
49 | '''Your glut implementation does not allow interactive sessions. ''' | |
50 | '''Consider installing freeglut.''') |
|
50 | '''Consider installing freeglut.''') from e | |
51 | glutMainLoopEvent = glutCheckLoop |
|
51 | glutMainLoopEvent = glutCheckLoop | |
52 | elif glut.HAVE_FREEGLUT: |
|
52 | elif glut.HAVE_FREEGLUT: | |
53 | glutMainLoopEvent = glut.glutMainLoopEvent |
|
53 | glutMainLoopEvent = glut.glutMainLoopEvent |
@@ -443,8 +443,8 b' def fake_input(inputs):' | |||||
443 | def mock_input(prompt=''): |
|
443 | def mock_input(prompt=''): | |
444 | try: |
|
444 | try: | |
445 | return next(it) |
|
445 | return next(it) | |
446 | except StopIteration: |
|
446 | except StopIteration as e: | |
447 | raise EOFError('No more inputs given') |
|
447 | raise EOFError('No more inputs given') from e | |
448 |
|
448 | |||
449 | return patch('builtins.input', mock_input) |
|
449 | return patch('builtins.input', mock_input) | |
450 |
|
450 |
@@ -75,8 +75,8 b' def _find_cmd(cmd):' | |||||
75 | """Find the full path to a .bat or .exe using the win32api module.""" |
|
75 | """Find the full path to a .bat or .exe using the win32api module.""" | |
76 | try: |
|
76 | try: | |
77 | from win32api import SearchPath |
|
77 | from win32api import SearchPath | |
78 | except ImportError: |
|
78 | except ImportError as e: | |
79 | raise ImportError('you need to have pywin32 installed for this to work') |
|
79 | raise ImportError('you need to have pywin32 installed for this to work') from e | |
80 | else: |
|
80 | else: | |
81 | PATH = os.environ['PATH'] |
|
81 | PATH = os.environ['PATH'] | |
82 | extensions = ['.exe', '.com', '.bat', '.py'] |
|
82 | extensions = ['.exe', '.com', '.bat', '.py'] |
@@ -176,9 +176,9 b' class ColorSchemeTable(dict):' | |||||
176 | scheme_test = scheme.lower() |
|
176 | scheme_test = scheme.lower() | |
177 | try: |
|
177 | try: | |
178 | scheme_idx = valid_schemes.index(scheme_test) |
|
178 | scheme_idx = valid_schemes.index(scheme_test) | |
179 | except ValueError: |
|
179 | except ValueError as e: | |
180 | raise ValueError('Unrecognized color scheme: ' + scheme + \ |
|
180 | raise ValueError('Unrecognized color scheme: ' + scheme + \ | |
181 | '\nValid schemes: '+str(scheme_names).replace("'', ",'')) |
|
181 | '\nValid schemes: '+str(scheme_names).replace("'', ",'')) from e | |
182 | else: |
|
182 | else: | |
183 | active = scheme_names[scheme_idx] |
|
183 | active = scheme_names[scheme_idx] | |
184 | self.active_scheme_name = active |
|
184 | self.active_scheme_name = active |
@@ -31,8 +31,8 b' def import_item(name):' | |||||
31 | module = __import__(package, fromlist=[obj]) |
|
31 | module = __import__(package, fromlist=[obj]) | |
32 | try: |
|
32 | try: | |
33 | pak = getattr(module, obj) |
|
33 | pak = getattr(module, obj) | |
34 | except AttributeError: |
|
34 | except AttributeError as e: | |
35 | raise ImportError('No module named %s' % obj) |
|
35 | raise ImportError('No module named %s' % obj) from e | |
36 | return pak |
|
36 | return pak | |
37 | else: |
|
37 | else: | |
38 | # called with un-dotted string |
|
38 | # called with un-dotted string |
@@ -120,7 +120,7 b' class Struct(dict):' | |||||
120 | try: |
|
120 | try: | |
121 | self.__setitem__(key, value) |
|
121 | self.__setitem__(key, value) | |
122 | except KeyError as e: |
|
122 | except KeyError as e: | |
123 | raise AttributeError(e) |
|
123 | raise AttributeError(e) from e | |
124 |
|
124 | |||
125 | def __getattr__(self, key): |
|
125 | def __getattr__(self, key): | |
126 | """Get an attr by calling :meth:`dict.__getitem__`. |
|
126 | """Get an attr by calling :meth:`dict.__getitem__`. | |
@@ -145,8 +145,8 b' class Struct(dict):' | |||||
145 | """ |
|
145 | """ | |
146 | try: |
|
146 | try: | |
147 | result = self[key] |
|
147 | result = self[key] | |
148 | except KeyError: |
|
148 | except KeyError as e: | |
149 | raise AttributeError(key) |
|
149 | raise AttributeError(key) from e | |
150 | else: |
|
150 | else: | |
151 | return result |
|
151 | return result | |
152 |
|
152 |
@@ -39,8 +39,8 b" if sys.platform == 'win32':" | |||||
39 | """ |
|
39 | """ | |
40 | try: |
|
40 | try: | |
41 | import ctypes |
|
41 | import ctypes | |
42 | except ImportError: |
|
42 | except ImportError as e: | |
43 | raise ImportError('you need to have ctypes installed for this to work') |
|
43 | raise ImportError('you need to have ctypes installed for this to work') from e | |
44 | _GetLongPathName = ctypes.windll.kernel32.GetLongPathNameW |
|
44 | _GetLongPathName = ctypes.windll.kernel32.GetLongPathNameW | |
45 | _GetLongPathName.argtypes = [ctypes.c_wchar_p, ctypes.c_wchar_p, |
|
45 | _GetLongPathName.argtypes = [ctypes.c_wchar_p, ctypes.c_wchar_p, | |
46 | ctypes.c_uint ] |
|
46 | ctypes.c_uint ] |
@@ -90,5 +90,5 b' class ShimModule(types.ModuleType):' | |||||
90 | name = "%s.%s" % (self._mirror, key) |
|
90 | name = "%s.%s" % (self._mirror, key) | |
91 | try: |
|
91 | try: | |
92 | return import_item(name) |
|
92 | return import_item(name) | |
93 | except ImportError: |
|
93 | except ImportError as e: | |
94 | raise AttributeError(key) |
|
94 | raise AttributeError(key) from e |
@@ -40,7 +40,7 b' def make_link_node(rawtext, app, type, slug, options):' | |||||
40 | if not base.endswith('/'): |
|
40 | if not base.endswith('/'): | |
41 | base += '/' |
|
41 | base += '/' | |
42 | except AttributeError as err: |
|
42 | except AttributeError as err: | |
43 | raise ValueError('github_project_url configuration value is not set (%s)' % str(err)) |
|
43 | raise ValueError('github_project_url configuration value is not set (%s)' % str(err)) from err | |
44 |
|
44 | |||
45 | ref = base + type + '/' + slug + '/' |
|
45 | ref = base + type + '/' + slug + '/' | |
46 | set_classes(options) |
|
46 | set_classes(options) | |
@@ -137,7 +137,7 b' def ghcommit_role(name, rawtext, text, lineno, inliner, options={}, content=[]):' | |||||
137 | if not base.endswith('/'): |
|
137 | if not base.endswith('/'): | |
138 | base += '/' |
|
138 | base += '/' | |
139 | except AttributeError as err: |
|
139 | except AttributeError as err: | |
140 | raise ValueError('github_project_url configuration value is not set (%s)' % str(err)) |
|
140 | raise ValueError('github_project_url configuration value is not set (%s)' % str(err)) from err | |
141 |
|
141 | |||
142 | ref = base + text |
|
142 | ref = base + text | |
143 | node = nodes.reference(rawtext, text[:6], refuri=ref, **options) |
|
143 | node = nodes.reference(rawtext, text[:6], refuri=ref, **options) |
@@ -30,8 +30,8 b' class Obj(dict):' | |||||
30 | def __getattr__(self, name): |
|
30 | def __getattr__(self, name): | |
31 | try: |
|
31 | try: | |
32 | return self[name] |
|
32 | return self[name] | |
33 | except KeyError: |
|
33 | except KeyError as e: | |
34 | raise AttributeError(name) |
|
34 | raise AttributeError(name) from e | |
35 |
|
35 | |||
36 | def __setattr__(self, name, val): |
|
36 | def __setattr__(self, name, val): | |
37 | self[name] = val |
|
37 | self[name] = val |
General Comments 0
You need to be logged in to leave comments.
Login now