##// END OF EJS Templates
remove simplegeneric from external...
MinRK -
Show More
@@ -1,707 +1,707 b''
1 1 # -*- coding: utf-8 -*-
2 2 """
3 3 ======
4 4 Rmagic
5 5 ======
6 6
7 7 Magic command interface for interactive work with R via rpy2
8 8
9 9 .. note::
10 10
11 11 The ``rpy2`` package needs to be installed separately. It
12 12 can be obtained using ``easy_install`` or ``pip``.
13 13
14 14 You will also need a working copy of R.
15 15
16 16 Usage
17 17 =====
18 18
19 19 To enable the magics below, execute ``%load_ext rmagic``.
20 20
21 21 ``%R``
22 22
23 23 {R_DOC}
24 24
25 25 ``%Rpush``
26 26
27 27 {RPUSH_DOC}
28 28
29 29 ``%Rpull``
30 30
31 31 {RPULL_DOC}
32 32
33 33 ``%Rget``
34 34
35 35 {RGET_DOC}
36 36
37 37 """
38 38 from __future__ import print_function
39 39
40 40 #-----------------------------------------------------------------------------
41 41 # Copyright (C) 2012 The IPython Development Team
42 42 #
43 43 # Distributed under the terms of the BSD License. The full license is in
44 44 # the file COPYING, distributed as part of this software.
45 45 #-----------------------------------------------------------------------------
46 46
47 47 import sys
48 48 import tempfile
49 49 from glob import glob
50 50 from shutil import rmtree
51 51 import warnings
52 52
53 53 # numpy and rpy2 imports
54 54
55 55 import numpy as np
56 56
57 57 import rpy2.rinterface as ri
58 58 import rpy2.robjects as ro
59 59 try:
60 60 from rpy2.robjects import pandas2ri
61 61 pandas2ri.activate()
62 62 except ImportError:
63 63 pandas2ri = None
64 64 from rpy2.robjects import numpy2ri
65 65 numpy2ri.activate()
66 66
67 67 # IPython imports
68 68
69 69 from IPython.core.displaypub import publish_display_data
70 70 from IPython.core.magic import (Magics, magics_class, line_magic,
71 71 line_cell_magic, needs_local_scope)
72 72 from IPython.testing.skipdoctest import skip_doctest
73 73 from IPython.core.magic_arguments import (
74 74 argument, magic_arguments, parse_argstring
75 75 )
76 from IPython.external.simplegeneric import generic
76 from simplegeneric import generic
77 77 from IPython.utils.py3compat import (str_to_unicode, unicode_to_str, PY3,
78 78 unicode_type)
79 79 from IPython.utils.text import dedent
80 80
81 81 class RInterpreterError(ri.RRuntimeError):
82 82 """An error when running R code in a %%R magic cell."""
83 83 def __init__(self, line, err, stdout):
84 84 self.line = line
85 85 self.err = err.rstrip()
86 86 self.stdout = stdout.rstrip()
87 87
88 88 def __unicode__(self):
89 89 s = 'Failed to parse and evaluate line %r.\nR error message: %r' % \
90 90 (self.line, self.err)
91 91 if self.stdout and (self.stdout != self.err):
92 92 s += '\nR stdout:\n' + self.stdout
93 93 return s
94 94
95 95 if PY3:
96 96 __str__ = __unicode__
97 97 else:
98 98 def __str__(self):
99 99 return unicode_to_str(unicode(self), 'utf-8')
100 100
101 101 def Rconverter(Robj, dataframe=False):
102 102 """
103 103 Convert an object in R's namespace to one suitable
104 104 for ipython's namespace.
105 105
106 106 For a data.frame, it tries to return a structured array.
107 107 It first checks for colnames, then names.
108 108 If all are NULL, it returns np.asarray(Robj), else
109 109 it tries to construct a recarray
110 110
111 111 Parameters
112 112 ----------
113 113
114 114 Robj: an R object returned from rpy2
115 115 """
116 116 is_data_frame = ro.r('is.data.frame')
117 117 colnames = ro.r('colnames')
118 118 rownames = ro.r('rownames') # with pandas, these could be used for the index
119 119 names = ro.r('names')
120 120
121 121 if dataframe:
122 122 as_data_frame = ro.r('as.data.frame')
123 123 cols = colnames(Robj)
124 124 _names = names(Robj)
125 125 if cols != ri.NULL:
126 126 Robj = as_data_frame(Robj)
127 127 names = tuple(np.array(cols))
128 128 elif _names != ri.NULL:
129 129 names = tuple(np.array(_names))
130 130 else: # failed to find names
131 131 return np.asarray(Robj)
132 132 Robj = np.rec.fromarrays(Robj, names = names)
133 133 return np.asarray(Robj)
134 134
135 135 @generic
136 136 def pyconverter(pyobj):
137 137 """Convert Python objects to R objects. Add types using the decorator:
138 138
139 139 @pyconverter.when_type
140 140 """
141 141 return pyobj
142 142
143 143 # The default conversion for lists seems to make them a nested list. That has
144 144 # some advantages, but is rarely convenient, so for interactive use, we convert
145 145 # lists to a numpy array, which becomes an R vector.
146 146 @pyconverter.when_type(list)
147 147 def pyconverter_list(pyobj):
148 148 return np.asarray(pyobj)
149 149
150 150 if pandas2ri is None:
151 151 # pandas2ri was new in rpy2 2.3.3, so for now we'll fallback to pandas'
152 152 # conversion function.
153 153 try:
154 154 from pandas import DataFrame
155 155 from pandas.rpy.common import convert_to_r_dataframe
156 156 @pyconverter.when_type(DataFrame)
157 157 def pyconverter_dataframe(pyobj):
158 158 return convert_to_r_dataframe(pyobj, strings_as_factors=True)
159 159 except ImportError:
160 160 pass
161 161
162 162 @magics_class
163 163 class RMagics(Magics):
164 164 """A set of magics useful for interactive work with R via rpy2.
165 165 """
166 166
167 167 def __init__(self, shell, Rconverter=Rconverter,
168 168 pyconverter=pyconverter,
169 169 cache_display_data=False):
170 170 """
171 171 Parameters
172 172 ----------
173 173
174 174 shell : IPython shell
175 175
176 176 Rconverter : callable
177 177 To be called on values taken from R before putting them in the
178 178 IPython namespace.
179 179
180 180 pyconverter : callable
181 181 To be called on values in ipython namespace before
182 182 assigning to variables in rpy2.
183 183
184 184 cache_display_data : bool
185 185 If True, the published results of the final call to R are
186 186 cached in the variable 'display_cache'.
187 187
188 188 """
189 189 super(RMagics, self).__init__(shell)
190 190 self.cache_display_data = cache_display_data
191 191
192 192 self.r = ro.R()
193 193
194 194 self.Rstdout_cache = []
195 195 self.pyconverter = pyconverter
196 196 self.Rconverter = Rconverter
197 197
198 198 def eval(self, line):
199 199 '''
200 200 Parse and evaluate a line of R code with rpy2.
201 201 Returns the output to R's stdout() connection,
202 202 the value generated by evaluating the code, and a
203 203 boolean indicating whether the return value would be
204 204 visible if the line of code were evaluated in an R REPL.
205 205
206 206 R Code evaluation and visibility determination are
207 207 done via an R call of the form withVisible({<code>})
208 208
209 209 '''
210 210 old_writeconsole = ri.get_writeconsole()
211 211 ri.set_writeconsole(self.write_console)
212 212 try:
213 213 res = ro.r("withVisible({%s\n})" % line)
214 214 value = res[0] #value (R object)
215 215 visible = ro.conversion.ri2py(res[1])[0] #visible (boolean)
216 216 except (ri.RRuntimeError, ValueError) as exception:
217 217 warning_or_other_msg = self.flush() # otherwise next return seems to have copy of error
218 218 raise RInterpreterError(line, str_to_unicode(str(exception)), warning_or_other_msg)
219 219 text_output = self.flush()
220 220 ri.set_writeconsole(old_writeconsole)
221 221 return text_output, value, visible
222 222
223 223 def write_console(self, output):
224 224 '''
225 225 A hook to capture R's stdout in a cache.
226 226 '''
227 227 self.Rstdout_cache.append(output)
228 228
229 229 def flush(self):
230 230 '''
231 231 Flush R's stdout cache to a string, returning the string.
232 232 '''
233 233 value = ''.join([str_to_unicode(s, 'utf-8') for s in self.Rstdout_cache])
234 234 self.Rstdout_cache = []
235 235 return value
236 236
237 237 @skip_doctest
238 238 @needs_local_scope
239 239 @line_magic
240 240 def Rpush(self, line, local_ns=None):
241 241 '''
242 242 A line-level magic for R that pushes
243 243 variables from python to rpy2. The line should be made up
244 244 of whitespace separated variable names in the IPython
245 245 namespace::
246 246
247 247 In [7]: import numpy as np
248 248
249 249 In [8]: X = np.array([4.5,6.3,7.9])
250 250
251 251 In [9]: X.mean()
252 252 Out[9]: 6.2333333333333343
253 253
254 254 In [10]: %Rpush X
255 255
256 256 In [11]: %R mean(X)
257 257 Out[11]: array([ 6.23333333])
258 258
259 259 '''
260 260 if local_ns is None:
261 261 local_ns = {}
262 262
263 263 inputs = line.split(' ')
264 264 for input in inputs:
265 265 try:
266 266 val = local_ns[input]
267 267 except KeyError:
268 268 try:
269 269 val = self.shell.user_ns[input]
270 270 except KeyError:
271 271 # reraise the KeyError as a NameError so that it looks like
272 272 # the standard python behavior when you use an unnamed
273 273 # variable
274 274 raise NameError("name '%s' is not defined" % input)
275 275
276 276 self.r.assign(input, self.pyconverter(val))
277 277
278 278 @skip_doctest
279 279 @magic_arguments()
280 280 @argument(
281 281 '-d', '--as_dataframe', action='store_true',
282 282 default=False,
283 283 help='Convert objects to data.frames before returning to ipython.'
284 284 )
285 285 @argument(
286 286 'outputs',
287 287 nargs='*',
288 288 )
289 289 @line_magic
290 290 def Rpull(self, line):
291 291 '''
292 292 A line-level magic for R that pulls
293 293 variables from python to rpy2::
294 294
295 295 In [18]: _ = %R x = c(3,4,6.7); y = c(4,6,7); z = c('a',3,4)
296 296
297 297 In [19]: %Rpull x y z
298 298
299 299 In [20]: x
300 300 Out[20]: array([ 3. , 4. , 6.7])
301 301
302 302 In [21]: y
303 303 Out[21]: array([ 4., 6., 7.])
304 304
305 305 In [22]: z
306 306 Out[22]:
307 307 array(['a', '3', '4'],
308 308 dtype='|S1')
309 309
310 310
311 311 If --as_dataframe, then each object is returned as a structured array
312 312 after first passed through "as.data.frame" in R before
313 313 being calling self.Rconverter.
314 314 This is useful when a structured array is desired as output, or
315 315 when the object in R has mixed data types.
316 316 See the %%R docstring for more examples.
317 317
318 318 Notes
319 319 -----
320 320
321 321 Beware that R names can have '.' so this is not fool proof.
322 322 To avoid this, don't name your R objects with '.'s...
323 323
324 324 '''
325 325 args = parse_argstring(self.Rpull, line)
326 326 outputs = args.outputs
327 327 for output in outputs:
328 328 self.shell.push({output:self.Rconverter(self.r(output),dataframe=args.as_dataframe)})
329 329
330 330 @skip_doctest
331 331 @magic_arguments()
332 332 @argument(
333 333 '-d', '--as_dataframe', action='store_true',
334 334 default=False,
335 335 help='Convert objects to data.frames before returning to ipython.'
336 336 )
337 337 @argument(
338 338 'output',
339 339 nargs=1,
340 340 type=str,
341 341 )
342 342 @line_magic
343 343 def Rget(self, line):
344 344 '''
345 345 Return an object from rpy2, possibly as a structured array (if possible).
346 346 Similar to Rpull except only one argument is accepted and the value is
347 347 returned rather than pushed to self.shell.user_ns::
348 348
349 349 In [3]: dtype=[('x', '<i4'), ('y', '<f8'), ('z', '|S1')]
350 350
351 351 In [4]: datapy = np.array([(1, 2.9, 'a'), (2, 3.5, 'b'), (3, 2.1, 'c'), (4, 5, 'e')], dtype=dtype)
352 352
353 353 In [5]: %R -i datapy
354 354
355 355 In [6]: %Rget datapy
356 356 Out[6]:
357 357 array([['1', '2', '3', '4'],
358 358 ['2', '3', '2', '5'],
359 359 ['a', 'b', 'c', 'e']],
360 360 dtype='|S1')
361 361
362 362 In [7]: %Rget -d datapy
363 363 Out[7]:
364 364 array([(1, 2.9, 'a'), (2, 3.5, 'b'), (3, 2.1, 'c'), (4, 5.0, 'e')],
365 365 dtype=[('x', '<i4'), ('y', '<f8'), ('z', '|S1')])
366 366
367 367 '''
368 368 args = parse_argstring(self.Rget, line)
369 369 output = args.output
370 370 return self.Rconverter(self.r(output[0]),dataframe=args.as_dataframe)
371 371
372 372
373 373 @skip_doctest
374 374 @magic_arguments()
375 375 @argument(
376 376 '-i', '--input', action='append',
377 377 help='Names of input variable from shell.user_ns to be assigned to R variables of the same names after calling self.pyconverter. Multiple names can be passed separated only by commas with no whitespace.'
378 378 )
379 379 @argument(
380 380 '-o', '--output', action='append',
381 381 help='Names of variables to be pushed from rpy2 to shell.user_ns after executing cell body and applying self.Rconverter. Multiple names can be passed separated only by commas with no whitespace.'
382 382 )
383 383 @argument(
384 384 '-w', '--width', type=int,
385 385 help='Width of png plotting device sent as an argument to *png* in R.'
386 386 )
387 387 @argument(
388 388 '-h', '--height', type=int,
389 389 help='Height of png plotting device sent as an argument to *png* in R.'
390 390 )
391 391
392 392 @argument(
393 393 '-d', '--dataframe', action='append',
394 394 help='Convert these objects to data.frames and return as structured arrays.'
395 395 )
396 396 @argument(
397 397 '-u', '--units', type=unicode_type, choices=["px", "in", "cm", "mm"],
398 398 help='Units of png plotting device sent as an argument to *png* in R. One of ["px", "in", "cm", "mm"].'
399 399 )
400 400 @argument(
401 401 '-r', '--res', type=int,
402 402 help='Resolution of png plotting device sent as an argument to *png* in R. Defaults to 72 if *units* is one of ["in", "cm", "mm"].'
403 403 )
404 404 @argument(
405 405 '-p', '--pointsize', type=int,
406 406 help='Pointsize of png plotting device sent as an argument to *png* in R.'
407 407 )
408 408 @argument(
409 409 '-b', '--bg',
410 410 help='Background of png plotting device sent as an argument to *png* in R.'
411 411 )
412 412 @argument(
413 413 '-n', '--noreturn',
414 414 help='Force the magic to not return anything.',
415 415 action='store_true',
416 416 default=False
417 417 )
418 418 @argument(
419 419 'code',
420 420 nargs='*',
421 421 )
422 422 @needs_local_scope
423 423 @line_cell_magic
424 424 def R(self, line, cell=None, local_ns=None):
425 425 '''
426 426 Execute code in R, and pull some of the results back into the Python namespace.
427 427
428 428 In line mode, this will evaluate an expression and convert the returned value to a Python object.
429 429 The return value is determined by rpy2's behaviour of returning the result of evaluating the
430 430 final line.
431 431
432 432 Multiple R lines can be executed by joining them with semicolons::
433 433
434 434 In [9]: %R X=c(1,4,5,7); sd(X); mean(X)
435 435 Out[9]: array([ 4.25])
436 436
437 437 In cell mode, this will run a block of R code. The resulting value
438 438 is printed if it would printed be when evaluating the same code
439 439 within a standard R REPL.
440 440
441 441 Nothing is returned to python by default in cell mode::
442 442
443 443 In [10]: %%R
444 444 ....: Y = c(2,4,3,9)
445 445 ....: summary(lm(Y~X))
446 446
447 447 Call:
448 448 lm(formula = Y ~ X)
449 449
450 450 Residuals:
451 451 1 2 3 4
452 452 0.88 -0.24 -2.28 1.64
453 453
454 454 Coefficients:
455 455 Estimate Std. Error t value Pr(>|t|)
456 456 (Intercept) 0.0800 2.3000 0.035 0.975
457 457 X 1.0400 0.4822 2.157 0.164
458 458
459 459 Residual standard error: 2.088 on 2 degrees of freedom
460 460 Multiple R-squared: 0.6993,Adjusted R-squared: 0.549
461 461 F-statistic: 4.651 on 1 and 2 DF, p-value: 0.1638
462 462
463 463 In the notebook, plots are published as the output of the cell::
464 464
465 465 %R plot(X, Y)
466 466
467 467 will create a scatter plot of X bs Y.
468 468
469 469 If cell is not None and line has some R code, it is prepended to
470 470 the R code in cell.
471 471
472 472 Objects can be passed back and forth between rpy2 and python via the -i -o flags in line::
473 473
474 474 In [14]: Z = np.array([1,4,5,10])
475 475
476 476 In [15]: %R -i Z mean(Z)
477 477 Out[15]: array([ 5.])
478 478
479 479
480 480 In [16]: %R -o W W=Z*mean(Z)
481 481 Out[16]: array([ 5., 20., 25., 50.])
482 482
483 483 In [17]: W
484 484 Out[17]: array([ 5., 20., 25., 50.])
485 485
486 486 The return value is determined by these rules:
487 487
488 488 * If the cell is not None, the magic returns None.
489 489
490 490 * If the cell evaluates as False, the resulting value is returned
491 491 unless the final line prints something to the console, in
492 492 which case None is returned.
493 493
494 494 * If the final line results in a NULL value when evaluated
495 495 by rpy2, then None is returned.
496 496
497 497 * No attempt is made to convert the final value to a structured array.
498 498 Use the --dataframe flag or %Rget to push / return a structured array.
499 499
500 500 * If the -n flag is present, there is no return value.
501 501
502 502 * A trailing ';' will also result in no return value as the last
503 503 value in the line is an empty string.
504 504
505 505 The --dataframe argument will attempt to return structured arrays.
506 506 This is useful for dataframes with
507 507 mixed data types. Note also that for a data.frame,
508 508 if it is returned as an ndarray, it is transposed::
509 509
510 510 In [18]: dtype=[('x', '<i4'), ('y', '<f8'), ('z', '|S1')]
511 511
512 512 In [19]: datapy = np.array([(1, 2.9, 'a'), (2, 3.5, 'b'), (3, 2.1, 'c'), (4, 5, 'e')], dtype=dtype)
513 513
514 514 In [20]: %%R -o datar
515 515 datar = datapy
516 516 ....:
517 517
518 518 In [21]: datar
519 519 Out[21]:
520 520 array([['1', '2', '3', '4'],
521 521 ['2', '3', '2', '5'],
522 522 ['a', 'b', 'c', 'e']],
523 523 dtype='|S1')
524 524
525 525 In [22]: %%R -d datar
526 526 datar = datapy
527 527 ....:
528 528
529 529 In [23]: datar
530 530 Out[23]:
531 531 array([(1, 2.9, 'a'), (2, 3.5, 'b'), (3, 2.1, 'c'), (4, 5.0, 'e')],
532 532 dtype=[('x', '<i4'), ('y', '<f8'), ('z', '|S1')])
533 533
534 534 The --dataframe argument first tries colnames, then names.
535 535 If both are NULL, it returns an ndarray (i.e. unstructured)::
536 536
537 537 In [1]: %R mydata=c(4,6,8.3); NULL
538 538
539 539 In [2]: %R -d mydata
540 540
541 541 In [3]: mydata
542 542 Out[3]: array([ 4. , 6. , 8.3])
543 543
544 544 In [4]: %R names(mydata) = c('a','b','c'); NULL
545 545
546 546 In [5]: %R -d mydata
547 547
548 548 In [6]: mydata
549 549 Out[6]:
550 550 array((4.0, 6.0, 8.3),
551 551 dtype=[('a', '<f8'), ('b', '<f8'), ('c', '<f8')])
552 552
553 553 In [7]: %R -o mydata
554 554
555 555 In [8]: mydata
556 556 Out[8]: array([ 4. , 6. , 8.3])
557 557
558 558 '''
559 559
560 560 args = parse_argstring(self.R, line)
561 561
562 562 # arguments 'code' in line are prepended to
563 563 # the cell lines
564 564
565 565 if cell is None:
566 566 code = ''
567 567 return_output = True
568 568 line_mode = True
569 569 else:
570 570 code = cell
571 571 return_output = False
572 572 line_mode = False
573 573
574 574 code = ' '.join(args.code) + code
575 575
576 576 # if there is no local namespace then default to an empty dict
577 577 if local_ns is None:
578 578 local_ns = {}
579 579
580 580 if args.input:
581 581 for input in ','.join(args.input).split(','):
582 582 try:
583 583 val = local_ns[input]
584 584 except KeyError:
585 585 try:
586 586 val = self.shell.user_ns[input]
587 587 except KeyError:
588 588 raise NameError("name '%s' is not defined" % input)
589 589 self.r.assign(input, self.pyconverter(val))
590 590
591 591 if getattr(args, 'units') is not None:
592 592 if args.units != "px" and getattr(args, 'res') is None:
593 593 args.res = 72
594 594 args.units = '"%s"' % args.units
595 595
596 596 png_argdict = dict([(n, getattr(args, n)) for n in ['units', 'res', 'height', 'width', 'bg', 'pointsize']])
597 597 png_args = ','.join(['%s=%s' % (o,v) for o, v in png_argdict.items() if v is not None])
598 598 # execute the R code in a temporary directory
599 599
600 600 tmpd = tempfile.mkdtemp()
601 601 self.r('png("%s/Rplots%%03d.png",%s)' % (tmpd.replace('\\', '/'), png_args))
602 602
603 603 text_output = ''
604 604 try:
605 605 if line_mode:
606 606 for line in code.split(';'):
607 607 text_result, result, visible = self.eval(line)
608 608 text_output += text_result
609 609 if text_result:
610 610 # the last line printed something to the console so we won't return it
611 611 return_output = False
612 612 else:
613 613 text_result, result, visible = self.eval(code)
614 614 text_output += text_result
615 615 if visible:
616 616 old_writeconsole = ri.get_writeconsole()
617 617 ri.set_writeconsole(self.write_console)
618 618 ro.r.show(result)
619 619 text_output += self.flush()
620 620 ri.set_writeconsole(old_writeconsole)
621 621
622 622 except RInterpreterError as e:
623 623 print(e.stdout)
624 624 if not e.stdout.endswith(e.err):
625 625 print(e.err)
626 626 rmtree(tmpd)
627 627 return
628 628 finally:
629 629 self.r('dev.off()')
630 630
631 631 # read out all the saved .png files
632 632
633 633 images = [open(imgfile, 'rb').read() for imgfile in glob("%s/Rplots*png" % tmpd)]
634 634
635 635 # now publish the images
636 636 # mimicking IPython/zmq/pylab/backend_inline.py
637 637 fmt = 'png'
638 638 mimetypes = { 'png' : 'image/png', 'svg' : 'image/svg+xml' }
639 639 mime = mimetypes[fmt]
640 640
641 641 # publish the printed R objects, if any
642 642
643 643 display_data = []
644 644 if text_output:
645 645 display_data.append(('RMagic.R', {'text/plain':text_output}))
646 646
647 647 # flush text streams before sending figures, helps a little with output
648 648 for image in images:
649 649 # synchronization in the console (though it's a bandaid, not a real sln)
650 650 sys.stdout.flush(); sys.stderr.flush()
651 651 display_data.append(('RMagic.R', {mime: image}))
652 652
653 653 # kill the temporary directory
654 654 rmtree(tmpd)
655 655
656 656 # try to turn every output into a numpy array
657 657 # this means that output are assumed to be castable
658 658 # as numpy arrays
659 659
660 660 if args.output:
661 661 for output in ','.join(args.output).split(','):
662 662 self.shell.push({output:self.Rconverter(self.r(output), dataframe=False)})
663 663
664 664 if args.dataframe:
665 665 for output in ','.join(args.dataframe).split(','):
666 666 self.shell.push({output:self.Rconverter(self.r(output), dataframe=True)})
667 667
668 668 for tag, disp_d in display_data:
669 669 publish_display_data(data=disp_d, source=tag)
670 670
671 671 # this will keep a reference to the display_data
672 672 # which might be useful to other objects who happen to use
673 673 # this method
674 674
675 675 if self.cache_display_data:
676 676 self.display_cache = display_data
677 677
678 678 # if in line mode and return_output, return the result as an ndarray
679 679 if return_output and not args.noreturn:
680 680 if result != ri.NULL:
681 681 return self.Rconverter(result, dataframe=False)
682 682
683 683 __doc__ = __doc__.format(
684 684 R_DOC = dedent(RMagics.R.__doc__),
685 685 RPUSH_DOC = dedent(RMagics.Rpush.__doc__),
686 686 RPULL_DOC = dedent(RMagics.Rpull.__doc__),
687 687 RGET_DOC = dedent(RMagics.Rget.__doc__)
688 688 )
689 689
690 690
691 691 def load_ipython_extension(ip):
692 692 """Load the extension in IPython."""
693 693 warnings.warn("The rmagic extension in IPython is deprecated in favour of "
694 694 "rpy2.ipython. If available, that will be loaded instead.\n"
695 695 "http://rpy.sourceforge.net/")
696 696 try:
697 697 import rpy2.ipython
698 698 except ImportError:
699 699 pass # Fall back to our own implementation for now
700 700 else:
701 701 return rpy2.ipython.load_ipython_extension(ip)
702 702
703 703 ip.register_magics(RMagics)
704 704 # Initialising rpy2 interferes with readline. Since, at this point, we've
705 705 # probably just loaded rpy2, we reset the delimiters. See issue gh-2759.
706 706 if ip.has_readline:
707 707 ip.readline.set_completer_delims(ip.readline_delims)
@@ -1,49 +1,34 b''
1 1 # encoding: utf-8
2 2 """Generic functions for extending IPython.
3 3
4 See http://cheeseshop.python.org/pypi/simplegeneric.
4 See http://pypi.python.org/pypi/simplegeneric.
5 5 """
6 6
7 #-----------------------------------------------------------------------------
8 # Copyright (C) 2008-2011 The IPython Development Team
9 #
10 # Distributed under the terms of the BSD License. The full license is in
11 # the file COPYING, distributed as part of this software.
12 #-----------------------------------------------------------------------------
13
14 #-----------------------------------------------------------------------------
15 # Imports
16 #-----------------------------------------------------------------------------
17
18 7 from IPython.core.error import TryNext
19 from IPython.external.simplegeneric import generic
20
21 #-----------------------------------------------------------------------------
22 # Imports
23 #-----------------------------------------------------------------------------
8 from simplegeneric import generic
24 9
25 10
26 11 @generic
27 12 def inspect_object(obj):
28 13 """Called when you do obj?"""
29 14 raise TryNext
30 15
31 16
32 17 @generic
33 18 def complete_object(obj, prev_completions):
34 19 """Custom completer dispatching for python objects.
35 20
36 21 Parameters
37 22 ----------
38 23 obj : object
39 24 The object to complete.
40 25 prev_completions : list
41 26 List of attributes discovered so far.
42 27
43 28 This should return the list of attributes in obj. If you only wish to
44 29 add to the attributes already discovered normally, return
45 30 own_attrs + prev_completions.
46 31 """
47 32 raise TryNext
48 33
49 34
@@ -1,349 +1,350 b''
1 1 #!/usr/bin/env python
2 2 # -*- coding: utf-8 -*-
3 3 """Setup script for IPython.
4 4
5 5 Under Posix environments it works like a typical setup.py script.
6 6 Under Windows, the command sdist is not supported, since IPython
7 7 requires utilities which are not available under Windows."""
8 8
9 9 #-----------------------------------------------------------------------------
10 10 # Copyright (c) 2008-2011, IPython Development Team.
11 11 # Copyright (c) 2001-2007, Fernando Perez <fernando.perez@colorado.edu>
12 12 # Copyright (c) 2001, Janko Hauser <jhauser@zscout.de>
13 13 # Copyright (c) 2001, Nathaniel Gray <n8gray@caltech.edu>
14 14 #
15 15 # Distributed under the terms of the Modified BSD License.
16 16 #
17 17 # The full license is in the file COPYING.rst, distributed with this software.
18 18 #-----------------------------------------------------------------------------
19 19
20 20 #-----------------------------------------------------------------------------
21 21 # Minimal Python version sanity check
22 22 #-----------------------------------------------------------------------------
23 23 from __future__ import print_function
24 24
25 25 import sys
26 26
27 27 # This check is also made in IPython/__init__, don't forget to update both when
28 28 # changing Python version requirements.
29 29 v = sys.version_info
30 30 if v[:2] < (2,7) or (v[0] >= 3 and v[:2] < (3,3)):
31 31 error = "ERROR: IPython requires Python version 2.7 or 3.3 or above."
32 32 print(error, file=sys.stderr)
33 33 sys.exit(1)
34 34
35 35 PY3 = (sys.version_info[0] >= 3)
36 36
37 37 # At least we're on the python version we need, move on.
38 38
39 39 #-------------------------------------------------------------------------------
40 40 # Imports
41 41 #-------------------------------------------------------------------------------
42 42
43 43 # Stdlib imports
44 44 import os
45 45 import shutil
46 46
47 47 from glob import glob
48 48
49 49 # BEFORE importing distutils, remove MANIFEST. distutils doesn't properly
50 50 # update it when the contents of directories change.
51 51 if os.path.exists('MANIFEST'): os.remove('MANIFEST')
52 52
53 53 from distutils.core import setup
54 54
55 55 # Our own imports
56 56 from setupbase import target_update
57 57
58 58 from setupbase import (
59 59 setup_args,
60 60 find_packages,
61 61 find_package_data,
62 62 check_package_data_first,
63 63 find_entry_points,
64 64 build_scripts_entrypt,
65 65 find_data_files,
66 66 check_for_dependencies,
67 67 git_prebuild,
68 68 check_submodule_status,
69 69 update_submodules,
70 70 require_submodules,
71 71 UpdateSubmodules,
72 72 get_bdist_wheel,
73 73 CompileCSS,
74 74 JavascriptVersion,
75 75 css_js_prerelease,
76 76 install_symlinked,
77 77 install_lib_symlink,
78 78 install_scripts_for_symlink,
79 79 unsymlink,
80 80 )
81 81 from setupext import setupext
82 82
83 83 isfile = os.path.isfile
84 84 pjoin = os.path.join
85 85
86 86 #-------------------------------------------------------------------------------
87 87 # Handle OS specific things
88 88 #-------------------------------------------------------------------------------
89 89
90 90 if os.name in ('nt','dos'):
91 91 os_name = 'windows'
92 92 else:
93 93 os_name = os.name
94 94
95 95 # Under Windows, 'sdist' has not been supported. Now that the docs build with
96 96 # Sphinx it might work, but let's not turn it on until someone confirms that it
97 97 # actually works.
98 98 if os_name == 'windows' and 'sdist' in sys.argv:
99 99 print('The sdist command is not available under Windows. Exiting.')
100 100 sys.exit(1)
101 101
102 102 #-------------------------------------------------------------------------------
103 103 # Make sure we aren't trying to run without submodules
104 104 #-------------------------------------------------------------------------------
105 105 here = os.path.abspath(os.path.dirname(__file__))
106 106
107 107 def require_clean_submodules():
108 108 """Check on git submodules before distutils can do anything
109 109
110 110 Since distutils cannot be trusted to update the tree
111 111 after everything has been set in motion,
112 112 this is not a distutils command.
113 113 """
114 114 # PACKAGERS: Add a return here to skip checks for git submodules
115 115
116 116 # don't do anything if nothing is actually supposed to happen
117 117 for do_nothing in ('-h', '--help', '--help-commands', 'clean', 'submodule'):
118 118 if do_nothing in sys.argv:
119 119 return
120 120
121 121 status = check_submodule_status(here)
122 122
123 123 if status == "missing":
124 124 print("checking out submodules for the first time")
125 125 update_submodules(here)
126 126 elif status == "unclean":
127 127 print('\n'.join([
128 128 "Cannot build / install IPython with unclean submodules",
129 129 "Please update submodules with",
130 130 " python setup.py submodule",
131 131 "or",
132 132 " git submodule update",
133 133 "or commit any submodule changes you have made."
134 134 ]))
135 135 sys.exit(1)
136 136
137 137 require_clean_submodules()
138 138
139 139 #-------------------------------------------------------------------------------
140 140 # Things related to the IPython documentation
141 141 #-------------------------------------------------------------------------------
142 142
143 143 # update the manuals when building a source dist
144 144 if len(sys.argv) >= 2 and sys.argv[1] in ('sdist','bdist_rpm'):
145 145
146 146 # List of things to be updated. Each entry is a triplet of args for
147 147 # target_update()
148 148 to_update = [
149 149 # FIXME - Disabled for now: we need to redo an automatic way
150 150 # of generating the magic info inside the rst.
151 151 #('docs/magic.tex',
152 152 #['IPython/Magic.py'],
153 153 #"cd doc && ./update_magic.sh" ),
154 154
155 155 ('docs/man/ipcluster.1.gz',
156 156 ['docs/man/ipcluster.1'],
157 157 'cd docs/man && gzip -9c ipcluster.1 > ipcluster.1.gz'),
158 158
159 159 ('docs/man/ipcontroller.1.gz',
160 160 ['docs/man/ipcontroller.1'],
161 161 'cd docs/man && gzip -9c ipcontroller.1 > ipcontroller.1.gz'),
162 162
163 163 ('docs/man/ipengine.1.gz',
164 164 ['docs/man/ipengine.1'],
165 165 'cd docs/man && gzip -9c ipengine.1 > ipengine.1.gz'),
166 166
167 167 ('docs/man/ipython.1.gz',
168 168 ['docs/man/ipython.1'],
169 169 'cd docs/man && gzip -9c ipython.1 > ipython.1.gz'),
170 170
171 171 ]
172 172
173 173
174 174 [ target_update(*t) for t in to_update ]
175 175
176 176 #---------------------------------------------------------------------------
177 177 # Find all the packages, package data, and data_files
178 178 #---------------------------------------------------------------------------
179 179
180 180 packages = find_packages()
181 181 package_data = find_package_data()
182 182
183 183 data_files = find_data_files()
184 184
185 185 setup_args['packages'] = packages
186 186 setup_args['package_data'] = package_data
187 187 setup_args['data_files'] = data_files
188 188
189 189 #---------------------------------------------------------------------------
190 190 # custom distutils commands
191 191 #---------------------------------------------------------------------------
192 192 # imports here, so they are after setuptools import if there was one
193 193 from distutils.command.sdist import sdist
194 194 from distutils.command.upload import upload
195 195
196 196 class UploadWindowsInstallers(upload):
197 197
198 198 description = "Upload Windows installers to PyPI (only used from tools/release_windows.py)"
199 199 user_options = upload.user_options + [
200 200 ('files=', 'f', 'exe file (or glob) to upload')
201 201 ]
202 202 def initialize_options(self):
203 203 upload.initialize_options(self)
204 204 meta = self.distribution.metadata
205 205 base = '{name}-{version}'.format(
206 206 name=meta.get_name(),
207 207 version=meta.get_version()
208 208 )
209 209 self.files = os.path.join('dist', '%s.*.exe' % base)
210 210
211 211 def run(self):
212 212 for dist_file in glob(self.files):
213 213 self.upload_file('bdist_wininst', 'any', dist_file)
214 214
215 215 setup_args['cmdclass'] = {
216 216 'build_py': css_js_prerelease(
217 217 check_package_data_first(git_prebuild('IPython'))),
218 218 'sdist' : css_js_prerelease(git_prebuild('IPython', sdist)),
219 219 'upload_wininst' : UploadWindowsInstallers,
220 220 'submodule' : UpdateSubmodules,
221 221 'css' : CompileCSS,
222 222 'symlink': install_symlinked,
223 223 'install_lib_symlink': install_lib_symlink,
224 224 'install_scripts_sym': install_scripts_for_symlink,
225 225 'unsymlink': unsymlink,
226 226 'jsversion' : JavascriptVersion,
227 227 }
228 228
229 229 #---------------------------------------------------------------------------
230 230 # Handle scripts, dependencies, and setuptools specific things
231 231 #---------------------------------------------------------------------------
232 232
233 233 # For some commands, use setuptools. Note that we do NOT list install here!
234 234 # If you want a setuptools-enhanced install, just run 'setupegg.py install'
235 235 needs_setuptools = set(('develop', 'release', 'bdist_egg', 'bdist_rpm',
236 236 'bdist', 'bdist_dumb', 'bdist_wininst', 'bdist_wheel',
237 237 'egg_info', 'easy_install', 'upload', 'install_egg_info',
238 238 ))
239 239
240 240 if len(needs_setuptools.intersection(sys.argv)) > 0:
241 241 import setuptools
242 242
243 243 # This dict is used for passing extra arguments that are setuptools
244 244 # specific to setup
245 245 setuptools_extra_args = {}
246 246
247 247 # setuptools requirements
248 248
249 249 pyzmq = 'pyzmq>=13'
250 250
251 251 extras_require = dict(
252 252 parallel = [pyzmq],
253 253 qtconsole = [pyzmq, 'pygments'],
254 254 doc = ['Sphinx>=1.1', 'numpydoc'],
255 255 test = ['nose>=0.10.1', 'requests'],
256 256 terminal = [],
257 257 nbformat = ['jsonschema>=2.0'],
258 258 notebook = ['tornado>=4.0', pyzmq, 'jinja2', 'pygments', 'mistune>=0.5'],
259 259 nbconvert = ['pygments', 'jinja2', 'mistune>=0.3.1']
260 260 )
261 261
262 262 if not sys.platform.startswith('win'):
263 263 extras_require['notebook'].append('terminado>=0.3.3')
264 264
265 265 if sys.version_info < (3, 3):
266 266 extras_require['test'].append('mock')
267 267
268 268 extras_require['notebook'].extend(extras_require['nbformat'])
269 269 extras_require['nbconvert'].extend(extras_require['nbformat'])
270 270
271 271 install_requires = [
272 272 'decorator',
273 273 'path.py', # required by pickleshare, remove when pickleshare is added here
274 'simplegeneric>0.8',
274 275 ]
275 276
276 277 # add platform-specific dependencies
277 278 if sys.platform == 'darwin':
278 279 install_requires.append('appnope')
279 280 if 'bdist_wheel' in sys.argv[1:] or not setupext.check_for_readline():
280 281 install_requires.append('gnureadline')
281 282
282 283 if sys.platform.startswith('win'):
283 284 extras_require['terminal'].append('pyreadline>=2.0')
284 285 else:
285 286 install_requires.append('pexpect')
286 287
287 288 everything = set()
288 289 for deps in extras_require.values():
289 290 everything.update(deps)
290 291 extras_require['all'] = everything
291 292
292 293 if 'setuptools' in sys.modules:
293 294 # setup.py develop should check for submodules
294 295 from setuptools.command.develop import develop
295 296 setup_args['cmdclass']['develop'] = require_submodules(develop)
296 297 setup_args['cmdclass']['bdist_wheel'] = css_js_prerelease(get_bdist_wheel())
297 298
298 299 setuptools_extra_args['zip_safe'] = False
299 300 setuptools_extra_args['entry_points'] = {
300 301 'console_scripts': find_entry_points(),
301 302 'pygments.lexers': [
302 303 'ipythonconsole = IPython.lib.lexers:IPythonConsoleLexer',
303 304 'ipython = IPython.lib.lexers:IPythonLexer',
304 305 'ipython3 = IPython.lib.lexers:IPython3Lexer',
305 306 ],
306 307 }
307 308 setup_args['extras_require'] = extras_require
308 309 requires = setup_args['install_requires'] = install_requires
309 310
310 311 # Script to be run by the windows binary installer after the default setup
311 312 # routine, to add shortcuts and similar windows-only things. Windows
312 313 # post-install scripts MUST reside in the scripts/ dir, otherwise distutils
313 314 # doesn't find them.
314 315 if 'bdist_wininst' in sys.argv:
315 316 if len(sys.argv) > 2 and \
316 317 ('sdist' in sys.argv or 'bdist_rpm' in sys.argv):
317 318 print("ERROR: bdist_wininst must be run alone. Exiting.", file=sys.stderr)
318 319 sys.exit(1)
319 320 setup_args['data_files'].append(
320 321 ['Scripts', ('scripts/ipython.ico', 'scripts/ipython_nb.ico')])
321 322 setup_args['scripts'] = [pjoin('scripts','ipython_win_post_install.py')]
322 323 setup_args['options'] = {"bdist_wininst":
323 324 {"install_script":
324 325 "ipython_win_post_install.py"}}
325 326
326 327 else:
327 328 # If we are installing without setuptools, call this function which will
328 329 # check for dependencies an inform the user what is needed. This is
329 330 # just to make life easy for users.
330 331 for install_cmd in ('install', 'symlink'):
331 332 if install_cmd in sys.argv:
332 333 check_for_dependencies()
333 334 break
334 335 # scripts has to be a non-empty list, or install_scripts isn't called
335 336 setup_args['scripts'] = [e.split('=')[0].strip() for e in find_entry_points()]
336 337
337 338 setup_args['cmdclass']['build_scripts'] = build_scripts_entrypt
338 339
339 340 #---------------------------------------------------------------------------
340 341 # Do the actual setup now
341 342 #---------------------------------------------------------------------------
342 343
343 344 setup_args.update(setuptools_extra_args)
344 345
345 346 def main():
346 347 setup(**setup_args)
347 348
348 349 if __name__ == '__main__':
349 350 main()
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
General Comments 0
You need to be logged in to leave comments. Login now