Show More
@@ -454,7 +454,7 b' range_re = re.compile(r"""' | |||||
454 | ((?P<sep>[\-:]) |
|
454 | ((?P<sep>[\-:]) | |
455 | ((?P<endsess>~?\d+)/)? |
|
455 | ((?P<endsess>~?\d+)/)? | |
456 | (?P<end>\d+))? |
|
456 | (?P<end>\d+))? | |
457 | """, re.VERBOSE) |
|
457 | $""", re.VERBOSE) | |
458 |
|
458 | |||
459 | def extract_hist_ranges(ranges_str): |
|
459 | def extract_hist_ranges(ranges_str): | |
460 | """Turn a string of history ranges into 3-tuples of (session, start, stop). |
|
460 | """Turn a string of history ranges into 3-tuples of (session, start, stop). |
@@ -50,6 +50,7 b' from IPython.core.formatters import DisplayFormatter' | |||||
50 | from IPython.core.history import HistoryManager |
|
50 | from IPython.core.history import HistoryManager | |
51 | from IPython.core.inputsplitter import IPythonInputSplitter |
|
51 | from IPython.core.inputsplitter import IPythonInputSplitter | |
52 | from IPython.core.logger import Logger |
|
52 | from IPython.core.logger import Logger | |
|
53 | from IPython.core.macro import Macro | |||
53 | from IPython.core.magic import Magic |
|
54 | from IPython.core.magic import Magic | |
54 | from IPython.core.payload import PayloadManager |
|
55 | from IPython.core.payload import PayloadManager | |
55 | from IPython.core.plugin import PluginManager |
|
56 | from IPython.core.plugin import PluginManager | |
@@ -2528,6 +2529,48 b' class InteractiveShell(Configurable, Magic):' | |||||
2528 | def show_usage(self): |
|
2529 | def show_usage(self): | |
2529 | """Show a usage message""" |
|
2530 | """Show a usage message""" | |
2530 | page.page(IPython.core.usage.interactive_usage) |
|
2531 | page.page(IPython.core.usage.interactive_usage) | |
|
2532 | ||||
|
2533 | def find_user_code(self, target, raw=True): | |||
|
2534 | """Get a code string from history, file, or a string or macro. | |||
|
2535 | ||||
|
2536 | This is mainly used by magic functions. | |||
|
2537 | ||||
|
2538 | Parameters | |||
|
2539 | ---------- | |||
|
2540 | target : str | |||
|
2541 | A string specifying code to retrieve. This will be tried respectively | |||
|
2542 | as: ranges of input history (see %history for syntax), a filename, or | |||
|
2543 | an expression evaluating to a string or Macro in the user namespace. | |||
|
2544 | raw : bool | |||
|
2545 | If true (default), retrieve raw history. Has no effect on the other | |||
|
2546 | retrieval mechanisms. | |||
|
2547 | ||||
|
2548 | Returns | |||
|
2549 | ------- | |||
|
2550 | A string of code. | |||
|
2551 | ||||
|
2552 | ValueError is raised if nothing is found, and TypeError if it evaluates | |||
|
2553 | to an object of another type. In each case, .args[0] is a printable | |||
|
2554 | message. | |||
|
2555 | """ | |||
|
2556 | code = self.extract_input_lines(target, raw=raw) # Grab history | |||
|
2557 | if code: | |||
|
2558 | return code | |||
|
2559 | if os.path.isfile(target): # Read file | |||
|
2560 | return open(target, "r").read() | |||
|
2561 | ||||
|
2562 | try: # User namespace | |||
|
2563 | codeobj = eval(target, self.user_ns) | |||
|
2564 | except Exception: | |||
|
2565 | raise ValueError(("'%s' was not found in history, as a file, nor in" | |||
|
2566 | " the user namespace.") % target) | |||
|
2567 | if isinstance(codeobj, basestring): | |||
|
2568 | return codeobj | |||
|
2569 | elif isinstance(codeobj, Macro): | |||
|
2570 | return codeobj.value | |||
|
2571 | ||||
|
2572 | raise TypeError("%s is neither a string nor a macro." % target, | |||
|
2573 | codeobj) | |||
2531 |
|
2574 | |||
2532 | #------------------------------------------------------------------------- |
|
2575 | #------------------------------------------------------------------------- | |
2533 | # Things related to IPython exiting |
|
2576 | # Things related to IPython exiting |
@@ -7,8 +7,13 b'' | |||||
7 | # the file COPYING, distributed as part of this software. |
|
7 | # the file COPYING, distributed as part of this software. | |
8 | #***************************************************************************** |
|
8 | #***************************************************************************** | |
9 |
|
9 | |||
|
10 | import re | |||
|
11 | import sys | |||
|
12 | ||||
10 | import IPython.utils.io |
|
13 | import IPython.utils.io | |
11 |
|
14 | |||
|
15 | coding_declaration = re.compile(r"#\s*coding[:=]\s*([-\w.]+)") | |||
|
16 | ||||
12 | class Macro(object): |
|
17 | class Macro(object): | |
13 | """Simple class to store the value of macros as strings. |
|
18 | """Simple class to store the value of macros as strings. | |
14 |
|
19 | |||
@@ -20,9 +25,24 b' class Macro(object):' | |||||
20 |
|
25 | |||
21 | def __init__(self,code): |
|
26 | def __init__(self,code): | |
22 | """store the macro value, as a single string which can be executed""" |
|
27 | """store the macro value, as a single string which can be executed""" | |
23 | self.value = code.rstrip()+'\n' |
|
28 | lines = [] | |
24 |
|
29 | enc = None | ||
|
30 | for line in code.splitlines(): | |||
|
31 | coding_match = coding_declaration.match(line) | |||
|
32 | if coding_match: | |||
|
33 | enc = coding_match.group(1) | |||
|
34 | else: | |||
|
35 | lines.append(line) | |||
|
36 | code = "\n".join(lines) | |||
|
37 | if isinstance(code, bytes): | |||
|
38 | code = code.decode(enc or sys.getdefaultencoding()) | |||
|
39 | self.value = code + '\n' | |||
|
40 | ||||
25 | def __str__(self): |
|
41 | def __str__(self): | |
|
42 | enc = sys.stdin.encoding or sys.getdefaultencoding() | |||
|
43 | return self.value.encode(enc, "replace") | |||
|
44 | ||||
|
45 | def __unicode__(self): | |||
26 | return self.value |
|
46 | return self.value | |
27 |
|
47 | |||
28 | def __repr__(self): |
|
48 | def __repr__(self): | |
@@ -31,3 +51,10 b' class Macro(object):' | |||||
31 | def __getstate__(self): |
|
51 | def __getstate__(self): | |
32 | """ needed for safe pickling via %store """ |
|
52 | """ needed for safe pickling via %store """ | |
33 | return {'value': self.value} |
|
53 | return {'value': self.value} | |
|
54 | ||||
|
55 | def __add__(self, other): | |||
|
56 | if isinstance(other, Macro): | |||
|
57 | return Macro(self.value + other.value) | |||
|
58 | elif isinstance(other, basestring): | |||
|
59 | return Macro(self.value + other) | |||
|
60 | raise TypeError |
@@ -1960,7 +1960,8 b' Currently the magic system has the following functions:\\n"""' | |||||
1960 |
|
1960 | |||
1961 | @testdec.skip_doctest |
|
1961 | @testdec.skip_doctest | |
1962 | def magic_macro(self,parameter_s = ''): |
|
1962 | def magic_macro(self,parameter_s = ''): | |
1963 |
"""Define a |
|
1963 | """Define a macro for future re-execution. It accepts ranges of history, | |
|
1964 | filenames or string objects. | |||
1964 |
|
1965 | |||
1965 | Usage:\\ |
|
1966 | Usage:\\ | |
1966 | %macro [options] name n1-n2 n3-n4 ... n5 .. n6 ... |
|
1967 | %macro [options] name n1-n2 n3-n4 ... n5 .. n6 ... | |
@@ -2012,12 +2013,8 b' Currently the magic system has the following functions:\\n"""' | |||||
2012 | You can view a macro's contents by explicitly printing it with: |
|
2013 | You can view a macro's contents by explicitly printing it with: | |
2013 |
|
2014 | |||
2014 | 'print macro_name'. |
|
2015 | 'print macro_name'. | |
2015 |
|
2016 | |||
2016 | For one-off cases which DON'T contain magic function calls in them you |
|
2017 | """ | |
2017 | can obtain similar results by explicitly executing slices from your |
|
|||
2018 | input history with: |
|
|||
2019 |
|
||||
2020 | In [60]: exec In[44:48]+In[49]""" |
|
|||
2021 |
|
2018 | |||
2022 | opts,args = self.parse_options(parameter_s,'r',mode='list') |
|
2019 | opts,args = self.parse_options(parameter_s,'r',mode='list') | |
2023 | if not args: # List existing macros |
|
2020 | if not args: # List existing macros | |
@@ -2026,18 +2023,22 b' Currently the magic system has the following functions:\\n"""' | |||||
2026 | if len(args) == 1: |
|
2023 | if len(args) == 1: | |
2027 | raise UsageError( |
|
2024 | raise UsageError( | |
2028 | "%macro insufficient args; usage '%macro name n1-n2 n3-4...") |
|
2025 | "%macro insufficient args; usage '%macro name n1-n2 n3-4...") | |
2029 |
name, |
|
2026 | name, codefrom = args[0], " ".join(args[1:]) | |
2030 |
|
2027 | |||
2031 | #print 'rng',ranges # dbg |
|
2028 | #print 'rng',ranges # dbg | |
2032 | lines = self.extract_input_lines(ranges,'r' in opts) |
|
2029 | try: | |
|
2030 | lines = self.shell.find_user_code(codefrom, 'r' in opts) | |||
|
2031 | except (ValueError, TypeError) as e: | |||
|
2032 | print e.args[0] | |||
|
2033 | return | |||
2033 | macro = Macro(lines) |
|
2034 | macro = Macro(lines) | |
2034 | self.shell.define_macro(name, macro) |
|
2035 | self.shell.define_macro(name, macro) | |
2035 | print 'Macro `%s` created. To execute, type its name (without quotes).' % name |
|
2036 | print 'Macro `%s` created. To execute, type its name (without quotes).' % name | |
2036 | print 'Macro contents:' |
|
2037 | print '=== Macro contents: ===' | |
2037 | print macro, |
|
2038 | print macro, | |
2038 |
|
2039 | |||
2039 | def magic_save(self,parameter_s = ''): |
|
2040 | def magic_save(self,parameter_s = ''): | |
2040 | """Save a set of lines to a given filename. |
|
2041 | """Save a set of lines or a macro to a given filename. | |
2041 |
|
2042 | |||
2042 | Usage:\\ |
|
2043 | Usage:\\ | |
2043 | %save [options] filename n1-n2 n3-n4 ... n5 .. n6 ... |
|
2044 | %save [options] filename n1-n2 n3-n4 ... n5 .. n6 ... | |
@@ -2056,7 +2057,7 b' Currently the magic system has the following functions:\\n"""' | |||||
2056 | it asks for confirmation before overwriting existing files.""" |
|
2057 | it asks for confirmation before overwriting existing files.""" | |
2057 |
|
2058 | |||
2058 | opts,args = self.parse_options(parameter_s,'r',mode='list') |
|
2059 | opts,args = self.parse_options(parameter_s,'r',mode='list') | |
2059 |
fname, |
|
2060 | fname, codefrom = args[0], " ".join(args[1:]) | |
2060 | if not fname.endswith('.py'): |
|
2061 | if not fname.endswith('.py'): | |
2061 | fname += '.py' |
|
2062 | fname += '.py' | |
2062 | if os.path.isfile(fname): |
|
2063 | if os.path.isfile(fname): | |
@@ -2064,12 +2065,29 b' Currently the magic system has the following functions:\\n"""' | |||||
2064 | if ans.lower() not in ['y','yes']: |
|
2065 | if ans.lower() not in ['y','yes']: | |
2065 | print 'Operation cancelled.' |
|
2066 | print 'Operation cancelled.' | |
2066 | return |
|
2067 | return | |
2067 | cmds = self.extract_input_lines(ranges, 'r' in opts) |
|
2068 | try: | |
|
2069 | cmds = self.shell.find_user_code(codefrom, 'r' in opts) | |||
|
2070 | except (TypeError, ValueError) as e: | |||
|
2071 | print e.args[0] | |||
|
2072 | return | |||
|
2073 | if isinstance(cmds, unicode): | |||
|
2074 | cmds = cmds.encode("utf-8") | |||
2068 | with open(fname,'w') as f: |
|
2075 | with open(fname,'w') as f: | |
2069 | f.write("# coding: utf-8\n") |
|
2076 | f.write("# coding: utf-8\n") | |
2070 |
f.write(cmds |
|
2077 | f.write(cmds) | |
2071 | print 'The following commands were written to file `%s`:' % fname |
|
2078 | print 'The following commands were written to file `%s`:' % fname | |
2072 | print cmds |
|
2079 | print cmds | |
|
2080 | ||||
|
2081 | def magic_pastebin(self, parameter_s = ''): | |||
|
2082 | """Upload code to the 'Lodge it' paste bin, returning the URL.""" | |||
|
2083 | try: | |||
|
2084 | code = self.shell.find_user_code(parameter_s) | |||
|
2085 | except (ValueError, TypeError) as e: | |||
|
2086 | print e.args[0] | |||
|
2087 | return | |||
|
2088 | pbserver = ServerProxy('http://paste.pocoo.org/xmlrpc/') | |||
|
2089 | id = pbserver.pastes.newPaste("python", code) | |||
|
2090 | return "http://paste.pocoo.org/show/" + id | |||
2073 |
|
2091 | |||
2074 | def _edit_macro(self,mname,macro): |
|
2092 | def _edit_macro(self,mname,macro): | |
2075 | """open an editor with the macro data in a file""" |
|
2093 | """open an editor with the macro data in a file""" |
General Comments 0
You need to be logged in to leave comments.
Login now