##// END OF EJS Templates
Convert str_to_unicode to str function call.
Srinivas Reddy Thatiparthy -
Show More
@@ -1,220 +1,219
1 1 """Logger class for IPython's logging facilities.
2 2 """
3 3
4 4 #*****************************************************************************
5 5 # Copyright (C) 2001 Janko Hauser <jhauser@zscout.de> and
6 6 # Copyright (C) 2001-2006 Fernando Perez <fperez@colorado.edu>
7 7 #
8 8 # Distributed under the terms of the BSD License. The full license is in
9 9 # the file COPYING, distributed as part of this software.
10 10 #*****************************************************************************
11 11
12 12 #****************************************************************************
13 13 # Modules and globals
14 14
15 15 # Python standard modules
16 16 import glob
17 17 import io
18 18 import os
19 19 import time
20 20
21 from IPython.utils.py3compat import str_to_unicode
22 21
23 22 #****************************************************************************
24 23 # FIXME: This class isn't a mixin anymore, but it still needs attributes from
25 24 # ipython and does input cache management. Finish cleanup later...
26 25
27 26 class Logger(object):
28 27 """A Logfile class with different policies for file creation"""
29 28
30 29 def __init__(self, home_dir, logfname='Logger.log', loghead=u'',
31 30 logmode='over'):
32 31
33 32 # this is the full ipython instance, we need some attributes from it
34 33 # which won't exist until later. What a mess, clean up later...
35 34 self.home_dir = home_dir
36 35
37 36 self.logfname = logfname
38 37 self.loghead = loghead
39 38 self.logmode = logmode
40 39 self.logfile = None
41 40
42 41 # Whether to log raw or processed input
43 42 self.log_raw_input = False
44 43
45 44 # whether to also log output
46 45 self.log_output = False
47 46
48 47 # whether to put timestamps before each log entry
49 48 self.timestamp = False
50 49
51 50 # activity control flags
52 51 self.log_active = False
53 52
54 53 # logmode is a validated property
55 54 def _set_mode(self,mode):
56 55 if mode not in ['append','backup','global','over','rotate']:
57 56 raise ValueError('invalid log mode %s given' % mode)
58 57 self._logmode = mode
59 58
60 59 def _get_mode(self):
61 60 return self._logmode
62 61
63 62 logmode = property(_get_mode,_set_mode)
64 63
65 64 def logstart(self, logfname=None, loghead=None, logmode=None,
66 65 log_output=False, timestamp=False, log_raw_input=False):
67 66 """Generate a new log-file with a default header.
68 67
69 68 Raises RuntimeError if the log has already been started"""
70 69
71 70 if self.logfile is not None:
72 71 raise RuntimeError('Log file is already active: %s' %
73 72 self.logfname)
74 73
75 74 # The parameters can override constructor defaults
76 75 if logfname is not None: self.logfname = logfname
77 76 if loghead is not None: self.loghead = loghead
78 77 if logmode is not None: self.logmode = logmode
79 78
80 79 # Parameters not part of the constructor
81 80 self.timestamp = timestamp
82 81 self.log_output = log_output
83 82 self.log_raw_input = log_raw_input
84 83
85 84 # init depending on the log mode requested
86 85 isfile = os.path.isfile
87 86 logmode = self.logmode
88 87
89 88 if logmode == 'append':
90 89 self.logfile = io.open(self.logfname, 'a', encoding='utf-8')
91 90
92 91 elif logmode == 'backup':
93 92 if isfile(self.logfname):
94 93 backup_logname = self.logfname+'~'
95 94 # Manually remove any old backup, since os.rename may fail
96 95 # under Windows.
97 96 if isfile(backup_logname):
98 97 os.remove(backup_logname)
99 98 os.rename(self.logfname,backup_logname)
100 99 self.logfile = io.open(self.logfname, 'w', encoding='utf-8')
101 100
102 101 elif logmode == 'global':
103 102 self.logfname = os.path.join(self.home_dir,self.logfname)
104 103 self.logfile = io.open(self.logfname, 'a', encoding='utf-8')
105 104
106 105 elif logmode == 'over':
107 106 if isfile(self.logfname):
108 107 os.remove(self.logfname)
109 108 self.logfile = io.open(self.logfname,'w', encoding='utf-8')
110 109
111 110 elif logmode == 'rotate':
112 111 if isfile(self.logfname):
113 112 if isfile(self.logfname+'.001~'):
114 113 old = glob.glob(self.logfname+'.*~')
115 114 old.sort()
116 115 old.reverse()
117 116 for f in old:
118 117 root, ext = os.path.splitext(f)
119 118 num = int(ext[1:-1])+1
120 119 os.rename(f, root+'.'+repr(num).zfill(3)+'~')
121 120 os.rename(self.logfname, self.logfname+'.001~')
122 121 self.logfile = io.open(self.logfname, 'w', encoding='utf-8')
123 122
124 123 if logmode != 'append':
125 124 self.logfile.write(self.loghead)
126 125
127 126 self.logfile.flush()
128 127 self.log_active = True
129 128
130 129 def switch_log(self,val):
131 130 """Switch logging on/off. val should be ONLY a boolean."""
132 131
133 132 if val not in [False,True,0,1]:
134 133 raise ValueError('Call switch_log ONLY with a boolean argument, '
135 134 'not with: %s' % val)
136 135
137 136 label = {0:'OFF',1:'ON',False:'OFF',True:'ON'}
138 137
139 138 if self.logfile is None:
140 139 print("""
141 140 Logging hasn't been started yet (use logstart for that).
142 141
143 142 %logon/%logoff are for temporarily starting and stopping logging for a logfile
144 143 which already exists. But you must first start the logging process with
145 144 %logstart (optionally giving a logfile name).""")
146 145
147 146 else:
148 147 if self.log_active == val:
149 148 print('Logging is already',label[val])
150 149 else:
151 150 print('Switching logging',label[val])
152 151 self.log_active = not self.log_active
153 152 self.log_active_out = self.log_active
154 153
155 154 def logstate(self):
156 155 """Print a status message about the logger."""
157 156 if self.logfile is None:
158 157 print('Logging has not been activated.')
159 158 else:
160 159 state = self.log_active and 'active' or 'temporarily suspended'
161 160 print('Filename :', self.logfname)
162 161 print('Mode :', self.logmode)
163 162 print('Output logging :', self.log_output)
164 163 print('Raw input log :', self.log_raw_input)
165 164 print('Timestamping :', self.timestamp)
166 165 print('State :', state)
167 166
168 167 def log(self, line_mod, line_ori):
169 168 """Write the sources to a log.
170 169
171 170 Inputs:
172 171
173 172 - line_mod: possibly modified input, such as the transformations made
174 173 by input prefilters or input handlers of various kinds. This should
175 174 always be valid Python.
176 175
177 176 - line_ori: unmodified input line from the user. This is not
178 177 necessarily valid Python.
179 178 """
180 179
181 180 # Write the log line, but decide which one according to the
182 181 # log_raw_input flag, set when the log is started.
183 182 if self.log_raw_input:
184 183 self.log_write(line_ori)
185 184 else:
186 185 self.log_write(line_mod)
187 186
188 187 def log_write(self, data, kind='input'):
189 188 """Write data to the log file, if active"""
190 189
191 190 #print 'data: %r' % data # dbg
192 191 if self.log_active and data:
193 192 write = self.logfile.write
194 193 if kind=='input':
195 194 if self.timestamp:
196 write(str_to_unicode(time.strftime('# %a, %d %b %Y %H:%M:%S\n',
195 write(str(time.strftime('# %a, %d %b %Y %H:%M:%S\n',
197 196 time.localtime())))
198 197 write(data)
199 198 elif kind=='output' and self.log_output:
200 199 odata = u'\n'.join([u'#[Out]# %s' % s
201 200 for s in data.splitlines()])
202 201 write(u'%s\n' % odata)
203 202 self.logfile.flush()
204 203
205 204 def logstop(self):
206 205 """Fully stop logging and close log file.
207 206
208 207 In order to start logging again, a new logstart() call needs to be
209 208 made, possibly (though not necessarily) with a new filename, mode and
210 209 other options."""
211 210
212 211 if self.logfile is not None:
213 212 self.logfile.close()
214 213 self.logfile = None
215 214 else:
216 215 print("Logging hadn't been started.")
217 216 self.log_active = False
218 217
219 218 # For backwards compatibility, in case anyone was using this.
220 219 close_log = logstop
@@ -1,184 +1,183
1 1 """Implementation of magic functions for IPython's own logging.
2 2 """
3 3 #-----------------------------------------------------------------------------
4 4 # Copyright (c) 2012 The IPython Development Team.
5 5 #
6 6 # Distributed under the terms of the Modified BSD License.
7 7 #
8 8 # The full license is in the file COPYING.txt, distributed with this software.
9 9 #-----------------------------------------------------------------------------
10 10
11 11 #-----------------------------------------------------------------------------
12 12 # Imports
13 13 #-----------------------------------------------------------------------------
14 14
15 15 # Stdlib
16 16 import os
17 17 import sys
18 18
19 19 # Our own packages
20 20 from IPython.core.magic import Magics, magics_class, line_magic
21 21 from warnings import warn
22 from IPython.utils.py3compat import str_to_unicode
23 22
24 23 #-----------------------------------------------------------------------------
25 24 # Magic implementation classes
26 25 #-----------------------------------------------------------------------------
27 26
28 27 @magics_class
29 28 class LoggingMagics(Magics):
30 29 """Magics related to all logging machinery."""
31 30
32 31 @line_magic
33 32 def logstart(self, parameter_s=''):
34 33 """Start logging anywhere in a session.
35 34
36 35 %logstart [-o|-r|-t] [log_name [log_mode]]
37 36
38 37 If no name is given, it defaults to a file named 'ipython_log.py' in your
39 38 current directory, in 'rotate' mode (see below).
40 39
41 40 '%logstart name' saves to file 'name' in 'backup' mode. It saves your
42 41 history up to that point and then continues logging.
43 42
44 43 %logstart takes a second optional parameter: logging mode. This can be one
45 44 of (note that the modes are given unquoted):
46 45
47 46 append
48 47 Keep logging at the end of any existing file.
49 48
50 49 backup
51 50 Rename any existing file to name~ and start name.
52 51
53 52 global
54 53 Append to a single logfile in your home directory.
55 54
56 55 over
57 56 Overwrite any existing log.
58 57
59 58 rotate
60 59 Create rotating logs: name.1~, name.2~, etc.
61 60
62 61 Options:
63 62
64 63 -o
65 64 log also IPython's output. In this mode, all commands which
66 65 generate an Out[NN] prompt are recorded to the logfile, right after
67 66 their corresponding input line. The output lines are always
68 67 prepended with a '#[Out]# ' marker, so that the log remains valid
69 68 Python code.
70 69
71 70 Since this marker is always the same, filtering only the output from
72 71 a log is very easy, using for example a simple awk call::
73 72
74 73 awk -F'#\\[Out\\]# ' '{if($2) {print $2}}' ipython_log.py
75 74
76 75 -r
77 76 log 'raw' input. Normally, IPython's logs contain the processed
78 77 input, so that user lines are logged in their final form, converted
79 78 into valid Python. For example, %Exit is logged as
80 79 _ip.magic("Exit"). If the -r flag is given, all input is logged
81 80 exactly as typed, with no transformations applied.
82 81
83 82 -t
84 83 put timestamps before each input line logged (these are put in
85 84 comments).
86 85 """
87 86
88 87 opts,par = self.parse_options(parameter_s,'ort')
89 88 log_output = 'o' in opts
90 89 log_raw_input = 'r' in opts
91 90 timestamp = 't' in opts
92 91
93 92 logger = self.shell.logger
94 93
95 94 # if no args are given, the defaults set in the logger constructor by
96 95 # ipython remain valid
97 96 if par:
98 97 try:
99 98 logfname,logmode = par.split()
100 99 except:
101 100 logfname = par
102 101 logmode = 'backup'
103 102 else:
104 103 logfname = logger.logfname
105 104 logmode = logger.logmode
106 105 # put logfname into rc struct as if it had been called on the command
107 106 # line, so it ends up saved in the log header Save it in case we need
108 107 # to restore it...
109 108 old_logfile = self.shell.logfile
110 109 if logfname:
111 110 logfname = os.path.expanduser(logfname)
112 111 self.shell.logfile = logfname
113 112
114 113 loghead = u'# IPython log file\n\n'
115 114 try:
116 115 logger.logstart(logfname, loghead, logmode, log_output, timestamp,
117 116 log_raw_input)
118 117 except:
119 118 self.shell.logfile = old_logfile
120 119 warn("Couldn't start log: %s" % sys.exc_info()[1])
121 120 else:
122 121 # log input history up to this point, optionally interleaving
123 122 # output if requested
124 123
125 124 if timestamp:
126 125 # disable timestamping for the previous history, since we've
127 126 # lost those already (no time machine here).
128 127 logger.timestamp = False
129 128
130 129 if log_raw_input:
131 130 input_hist = self.shell.history_manager.input_hist_raw
132 131 else:
133 132 input_hist = self.shell.history_manager.input_hist_parsed
134 133
135 134 if log_output:
136 135 log_write = logger.log_write
137 136 output_hist = self.shell.history_manager.output_hist
138 137 for n in range(1,len(input_hist)-1):
139 138 log_write(input_hist[n].rstrip() + u'\n')
140 139 if n in output_hist:
141 log_write(str_to_unicode(repr(output_hist[n])),'output')
140 log_write(str(repr(output_hist[n])),'output')
142 141 else:
143 142 logger.log_write(u'\n'.join(input_hist[1:]))
144 143 logger.log_write(u'\n')
145 144 if timestamp:
146 145 # re-enable timestamping
147 146 logger.timestamp = True
148 147
149 148 print ('Activating auto-logging. '
150 149 'Current session state plus future input saved.')
151 150 logger.logstate()
152 151
153 152 @line_magic
154 153 def logstop(self, parameter_s=''):
155 154 """Fully stop logging and close log file.
156 155
157 156 In order to start logging again, a new %logstart call needs to be made,
158 157 possibly (though not necessarily) with a new filename, mode and other
159 158 options."""
160 159 self.shell.logger.logstop()
161 160
162 161 @line_magic
163 162 def logoff(self, parameter_s=''):
164 163 """Temporarily stop logging.
165 164
166 165 You must have previously started logging."""
167 166 self.shell.logger.switch_log(0)
168 167
169 168 @line_magic
170 169 def logon(self, parameter_s=''):
171 170 """Restart logging.
172 171
173 172 This function is for restarting logging which you've temporarily
174 173 stopped with %logoff. For starting logging for the first time, you
175 174 must use the %logstart function, which allows you to specify an
176 175 optional log filename."""
177 176
178 177 self.shell.logger.switch_log(1)
179 178
180 179 @line_magic
181 180 def logstate(self, parameter_s=''):
182 181 """Print the status of the logging system."""
183 182
184 183 self.shell.logger.logstate()
@@ -1,164 +1,164
1 1 # coding: utf-8
2 2 """Tests for profile-related functions.
3 3
4 4 Currently only the startup-dir functionality is tested, but more tests should
5 5 be added for:
6 6
7 7 * ipython profile create
8 8 * ipython profile list
9 9 * ipython profile create --parallel
10 10 * security dir permissions
11 11
12 12 Authors
13 13 -------
14 14
15 15 * MinRK
16 16
17 17 """
18 18
19 19 #-----------------------------------------------------------------------------
20 20 # Imports
21 21 #-----------------------------------------------------------------------------
22 22
23 23 import os
24 24 import shutil
25 25 import sys
26 26 import tempfile
27 27
28 28 from unittest import TestCase
29 29
30 30 import nose.tools as nt
31 31
32 32 from IPython.core.profileapp import list_profiles_in, list_bundled_profiles
33 33 from IPython.core.profiledir import ProfileDir
34 34
35 35 from IPython.testing import decorators as dec
36 36 from IPython.testing import tools as tt
37 37 from IPython.utils import py3compat
38 38 from IPython.utils.process import getoutput
39 39 from IPython.utils.tempdir import TemporaryDirectory
40 40
41 41 #-----------------------------------------------------------------------------
42 42 # Globals
43 43 #-----------------------------------------------------------------------------
44 44 TMP_TEST_DIR = tempfile.mkdtemp()
45 45 HOME_TEST_DIR = os.path.join(TMP_TEST_DIR, "home_test_dir")
46 46 IP_TEST_DIR = os.path.join(HOME_TEST_DIR,'.ipython')
47 47
48 48 #
49 49 # Setup/teardown functions/decorators
50 50 #
51 51
52 52 def setup():
53 53 """Setup test environment for the module:
54 54
55 55 - Adds dummy home dir tree
56 56 """
57 57 # Do not mask exceptions here. In particular, catching WindowsError is a
58 58 # problem because that exception is only defined on Windows...
59 59 os.makedirs(IP_TEST_DIR)
60 60
61 61
62 62 def teardown():
63 63 """Teardown test environment for the module:
64 64
65 65 - Remove dummy home dir tree
66 66 """
67 67 # Note: we remove the parent test dir, which is the root of all test
68 68 # subdirs we may have created. Use shutil instead of os.removedirs, so
69 69 # that non-empty directories are all recursively removed.
70 70 shutil.rmtree(TMP_TEST_DIR)
71 71
72 72
73 73 #-----------------------------------------------------------------------------
74 74 # Test functions
75 75 #-----------------------------------------------------------------------------
76 76 def win32_without_pywin32():
77 77 if sys.platform == 'win32':
78 78 try:
79 79 import pywin32
80 80 except ImportError:
81 81 return True
82 82 return False
83 83
84 84
85 85 class ProfileStartupTest(TestCase):
86 86 def setUp(self):
87 87 # create profile dir
88 88 self.pd = ProfileDir.create_profile_dir_by_name(IP_TEST_DIR, 'test')
89 89 self.options = ['--ipython-dir', IP_TEST_DIR, '--profile', 'test']
90 90 self.fname = os.path.join(TMP_TEST_DIR, 'test.py')
91 91
92 92 def tearDown(self):
93 93 # We must remove this profile right away so its presence doesn't
94 94 # confuse other tests.
95 95 shutil.rmtree(self.pd.location)
96 96
97 97 def init(self, startup_file, startup, test):
98 98 # write startup python file
99 99 with open(os.path.join(self.pd.startup_dir, startup_file), 'w') as f:
100 100 f.write(startup)
101 101 # write simple test file, to check that the startup file was run
102 102 with open(self.fname, 'w') as f:
103 103 f.write(py3compat.doctest_refactor_print(test))
104 104
105 105 def validate(self, output):
106 106 tt.ipexec_validate(self.fname, output, '', options=self.options)
107 107
108 108 @dec.skipif(win32_without_pywin32(), "Test requires pywin32 on Windows")
109 109 def test_startup_py(self):
110 110 self.init('00-start.py', 'zzz=123\n',
111 111 py3compat.doctest_refactor_print('print zzz\n'))
112 112 self.validate('123')
113 113
114 114 @dec.skipif(win32_without_pywin32(), "Test requires pywin32 on Windows")
115 115 def test_startup_ipy(self):
116 116 self.init('00-start.ipy', '%xmode plain\n', '')
117 117 self.validate('Exception reporting mode: Plain')
118 118
119 119
120 120 def test_list_profiles_in():
121 121 # No need to remove these directories and files, as they will get nuked in
122 122 # the module-level teardown.
123 123 td = tempfile.mkdtemp(dir=TMP_TEST_DIR)
124 td = py3compat.str_to_unicode(td)
124 td = str(td)
125 125 for name in ('profile_foo', 'profile_hello', 'not_a_profile'):
126 126 os.mkdir(os.path.join(td, name))
127 127 if dec.unicode_paths:
128 128 os.mkdir(os.path.join(td, u'profile_ΓΌnicode'))
129 129
130 130 with open(os.path.join(td, 'profile_file'), 'w') as f:
131 131 f.write("I am not a profile directory")
132 132 profiles = list_profiles_in(td)
133 133
134 134 # unicode normalization can turn u'ΓΌnicode' into u'u\0308nicode',
135 135 # so only check for *nicode, and that creating a ProfileDir from the
136 136 # name remains valid
137 137 found_unicode = False
138 138 for p in list(profiles):
139 139 if p.endswith('nicode'):
140 140 pd = ProfileDir.find_profile_dir_by_name(td, p)
141 141 profiles.remove(p)
142 142 found_unicode = True
143 143 break
144 144 if dec.unicode_paths:
145 145 nt.assert_true(found_unicode)
146 146 nt.assert_equal(set(profiles), {'foo', 'hello'})
147 147
148 148
149 149 def test_list_bundled_profiles():
150 150 # This variable will need to be updated when a new profile gets bundled
151 151 bundled = sorted(list_bundled_profiles())
152 152 nt.assert_equal(bundled, [])
153 153
154 154
155 155 def test_profile_create_ipython_dir():
156 156 """ipython profile create respects --ipython-dir"""
157 157 with TemporaryDirectory() as td:
158 158 getoutput([sys.executable, '-m', 'IPython', 'profile', 'create',
159 159 'foo', '--ipython-dir=%s' % td])
160 160 profile_dir = os.path.join(td, 'profile_foo')
161 161 assert os.path.exists(profile_dir)
162 162 ipython_config = os.path.join(profile_dir, 'ipython_config.py')
163 163 assert os.path.exists(ipython_config)
164 164
@@ -1,206 +1,206
1 1 """Extra magics for terminal use."""
2 2
3 3 # Copyright (c) IPython Development Team.
4 4 # Distributed under the terms of the Modified BSD License.
5 5
6 6
7 7 from logging import error
8 8 import os
9 9 import sys
10 10
11 11 from IPython.core.error import TryNext, UsageError
12 12 from IPython.core.inputsplitter import IPythonInputSplitter
13 13 from IPython.core.magic import Magics, magics_class, line_magic
14 14 from IPython.lib.clipboard import ClipboardEmpty
15 15 from IPython.utils.text import SList, strip_email_quotes
16 16 from IPython.utils import py3compat
17 17
18 18 def get_pasted_lines(sentinel, l_input=py3compat.input, quiet=False):
19 19 """ Yield pasted lines until the user enters the given sentinel value.
20 20 """
21 21 if not quiet:
22 22 print("Pasting code; enter '%s' alone on the line to stop or use Ctrl-D." \
23 23 % sentinel)
24 24 prompt = ":"
25 25 else:
26 26 prompt = ""
27 27 while True:
28 28 try:
29 l = py3compat.str_to_unicode(l_input(prompt))
29 l = str(l_input(prompt))
30 30 if l == sentinel:
31 31 return
32 32 else:
33 33 yield l
34 34 except EOFError:
35 35 print('<EOF>')
36 36 return
37 37
38 38
39 39 @magics_class
40 40 class TerminalMagics(Magics):
41 41 def __init__(self, shell):
42 42 super(TerminalMagics, self).__init__(shell)
43 43 self.input_splitter = IPythonInputSplitter()
44 44
45 45 def store_or_execute(self, block, name):
46 46 """ Execute a block, or store it in a variable, per the user's request.
47 47 """
48 48 if name:
49 49 # If storing it for further editing
50 50 self.shell.user_ns[name] = SList(block.splitlines())
51 51 print("Block assigned to '%s'" % name)
52 52 else:
53 53 b = self.preclean_input(block)
54 54 self.shell.user_ns['pasted_block'] = b
55 55 self.shell.using_paste_magics = True
56 56 try:
57 57 self.shell.run_cell(b)
58 58 finally:
59 59 self.shell.using_paste_magics = False
60 60
61 61 def preclean_input(self, block):
62 62 lines = block.splitlines()
63 63 while lines and not lines[0].strip():
64 64 lines = lines[1:]
65 65 return strip_email_quotes('\n'.join(lines))
66 66
67 67 def rerun_pasted(self, name='pasted_block'):
68 68 """ Rerun a previously pasted command.
69 69 """
70 70 b = self.shell.user_ns.get(name)
71 71
72 72 # Sanity checks
73 73 if b is None:
74 74 raise UsageError('No previous pasted block available')
75 75 if not isinstance(b, str):
76 76 raise UsageError(
77 77 "Variable 'pasted_block' is not a string, can't execute")
78 78
79 79 print("Re-executing '%s...' (%d chars)"% (b.split('\n',1)[0], len(b)))
80 80 self.shell.run_cell(b)
81 81
82 82 @line_magic
83 83 def autoindent(self, parameter_s = ''):
84 84 """Toggle autoindent on/off (if available)."""
85 85
86 86 self.shell.set_autoindent()
87 87 print("Automatic indentation is:",['OFF','ON'][self.shell.autoindent])
88 88
89 89 @line_magic
90 90 def cpaste(self, parameter_s=''):
91 91 """Paste & execute a pre-formatted code block from clipboard.
92 92
93 93 You must terminate the block with '--' (two minus-signs) or Ctrl-D
94 94 alone on the line. You can also provide your own sentinel with '%paste
95 95 -s %%' ('%%' is the new sentinel for this operation).
96 96
97 97 The block is dedented prior to execution to enable execution of method
98 98 definitions. '>' and '+' characters at the beginning of a line are
99 99 ignored, to allow pasting directly from e-mails, diff files and
100 100 doctests (the '...' continuation prompt is also stripped). The
101 101 executed block is also assigned to variable named 'pasted_block' for
102 102 later editing with '%edit pasted_block'.
103 103
104 104 You can also pass a variable name as an argument, e.g. '%cpaste foo'.
105 105 This assigns the pasted block to variable 'foo' as string, without
106 106 dedenting or executing it (preceding >>> and + is still stripped)
107 107
108 108 '%cpaste -r' re-executes the block previously entered by cpaste.
109 109 '%cpaste -q' suppresses any additional output messages.
110 110
111 111 Do not be alarmed by garbled output on Windows (it's a readline bug).
112 112 Just press enter and type -- (and press enter again) and the block
113 113 will be what was just pasted.
114 114
115 115 IPython statements (magics, shell escapes) are not supported (yet).
116 116
117 117 See also
118 118 --------
119 119 paste: automatically pull code from clipboard.
120 120
121 121 Examples
122 122 --------
123 123 ::
124 124
125 125 In [8]: %cpaste
126 126 Pasting code; enter '--' alone on the line to stop.
127 127 :>>> a = ["world!", "Hello"]
128 128 :>>> print " ".join(sorted(a))
129 129 :--
130 130 Hello world!
131 131 """
132 132 opts, name = self.parse_options(parameter_s, 'rqs:', mode='string')
133 133 if 'r' in opts:
134 134 self.rerun_pasted()
135 135 return
136 136
137 137 quiet = ('q' in opts)
138 138
139 139 sentinel = opts.get('s', u'--')
140 140 block = '\n'.join(get_pasted_lines(sentinel, quiet=quiet))
141 141 self.store_or_execute(block, name)
142 142
143 143 @line_magic
144 144 def paste(self, parameter_s=''):
145 145 """Paste & execute a pre-formatted code block from clipboard.
146 146
147 147 The text is pulled directly from the clipboard without user
148 148 intervention and printed back on the screen before execution (unless
149 149 the -q flag is given to force quiet mode).
150 150
151 151 The block is dedented prior to execution to enable execution of method
152 152 definitions. '>' and '+' characters at the beginning of a line are
153 153 ignored, to allow pasting directly from e-mails, diff files and
154 154 doctests (the '...' continuation prompt is also stripped). The
155 155 executed block is also assigned to variable named 'pasted_block' for
156 156 later editing with '%edit pasted_block'.
157 157
158 158 You can also pass a variable name as an argument, e.g. '%paste foo'.
159 159 This assigns the pasted block to variable 'foo' as string, without
160 160 executing it (preceding >>> and + is still stripped).
161 161
162 162 Options:
163 163
164 164 -r: re-executes the block previously entered by cpaste.
165 165
166 166 -q: quiet mode: do not echo the pasted text back to the terminal.
167 167
168 168 IPython statements (magics, shell escapes) are not supported (yet).
169 169
170 170 See also
171 171 --------
172 172 cpaste: manually paste code into terminal until you mark its end.
173 173 """
174 174 opts, name = self.parse_options(parameter_s, 'rq', mode='string')
175 175 if 'r' in opts:
176 176 self.rerun_pasted()
177 177 return
178 178 try:
179 179 block = self.shell.hooks.clipboard_get()
180 180 except TryNext as clipboard_exc:
181 181 message = getattr(clipboard_exc, 'args')
182 182 if message:
183 183 error(message[0])
184 184 else:
185 185 error('Could not get text from the clipboard.')
186 186 return
187 187 except ClipboardEmpty:
188 188 raise UsageError("The clipboard appears to be empty")
189 189
190 190 # By default, echo back to terminal unless quiet mode is requested
191 191 if 'q' not in opts:
192 192 write = self.shell.write
193 193 write(self.shell.pycolorize(block))
194 194 if not block.endswith('\n'):
195 195 write('\n')
196 196 write("## -- End pasted text --\n")
197 197
198 198 self.store_or_execute(block, name)
199 199
200 200 # Class-level: add a '%cls' magic only on Windows
201 201 if sys.platform == 'win32':
202 202 @line_magic
203 203 def cls(self, s):
204 204 """Clear screen.
205 205 """
206 206 os.system("cls")
General Comments 0
You need to be logged in to leave comments. Login now