##// END OF EJS Templates
Move pretty into lib, because it's heavily changed now.
Thomas Spura -
Show More
@@ -1,557 +1,557 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """Display formatters.
2 """Display formatters.
3
3
4
4
5 Authors:
5 Authors:
6
6
7 * Robert Kern
7 * Robert Kern
8 * Brian Granger
8 * Brian Granger
9 """
9 """
10 #-----------------------------------------------------------------------------
10 #-----------------------------------------------------------------------------
11 # Copyright (c) 2010, IPython Development Team.
11 # Copyright (c) 2010, IPython Development Team.
12 #
12 #
13 # Distributed under the terms of the Modified BSD License.
13 # Distributed under the terms of the Modified BSD License.
14 #
14 #
15 # The full license is in the file COPYING.txt, distributed with this software.
15 # The full license is in the file COPYING.txt, distributed with this software.
16 #-----------------------------------------------------------------------------
16 #-----------------------------------------------------------------------------
17
17
18 #-----------------------------------------------------------------------------
18 #-----------------------------------------------------------------------------
19 # Imports
19 # Imports
20 #-----------------------------------------------------------------------------
20 #-----------------------------------------------------------------------------
21
21
22 # Stdlib imports
22 # Stdlib imports
23 import abc
23 import abc
24 import sys
24 import sys
25 # We must use StringIO, as cStringIO doesn't handle unicode properly.
25 # We must use StringIO, as cStringIO doesn't handle unicode properly.
26 from StringIO import StringIO
26 from StringIO import StringIO
27
27
28 # Our own imports
28 # Our own imports
29 from IPython.config.configurable import Configurable
29 from IPython.config.configurable import Configurable
30 from IPython.external import pretty
30 from IPython.lib import pretty
31 from IPython.utils.traitlets import Bool, Dict, Int, Str, CStr
31 from IPython.utils.traitlets import Bool, Dict, Int, Str, CStr
32
32
33
33
34 #-----------------------------------------------------------------------------
34 #-----------------------------------------------------------------------------
35 # The main DisplayFormatter class
35 # The main DisplayFormatter class
36 #-----------------------------------------------------------------------------
36 #-----------------------------------------------------------------------------
37
37
38
38
39 class DisplayFormatter(Configurable):
39 class DisplayFormatter(Configurable):
40
40
41 # When set to true only the default plain text formatter will be used.
41 # When set to true only the default plain text formatter will be used.
42 plain_text_only = Bool(False, config=True)
42 plain_text_only = Bool(False, config=True)
43
43
44 # A dict of formatter whose keys are format types (MIME types) and whose
44 # A dict of formatter whose keys are format types (MIME types) and whose
45 # values are subclasses of BaseFormatter.
45 # values are subclasses of BaseFormatter.
46 formatters = Dict(config=True)
46 formatters = Dict(config=True)
47 def _formatters_default(self):
47 def _formatters_default(self):
48 """Activate the default formatters."""
48 """Activate the default formatters."""
49 formatter_classes = [
49 formatter_classes = [
50 PlainTextFormatter,
50 PlainTextFormatter,
51 HTMLFormatter,
51 HTMLFormatter,
52 SVGFormatter,
52 SVGFormatter,
53 PNGFormatter,
53 PNGFormatter,
54 LatexFormatter,
54 LatexFormatter,
55 JSONFormatter
55 JSONFormatter
56 ]
56 ]
57 d = {}
57 d = {}
58 for cls in formatter_classes:
58 for cls in formatter_classes:
59 f = cls(config=self.config)
59 f = cls(config=self.config)
60 d[f.format_type] = f
60 d[f.format_type] = f
61 return d
61 return d
62
62
63 def format(self, obj, include=None, exclude=None):
63 def format(self, obj, include=None, exclude=None):
64 """Return a format data dict for an object.
64 """Return a format data dict for an object.
65
65
66 By default all format types will be computed.
66 By default all format types will be computed.
67
67
68 The following MIME types are currently implemented:
68 The following MIME types are currently implemented:
69
69
70 * text/plain
70 * text/plain
71 * text/html
71 * text/html
72 * text/latex
72 * text/latex
73 * application/json
73 * application/json
74 * image/png
74 * image/png
75 * immage/svg+xml
75 * immage/svg+xml
76
76
77 Parameters
77 Parameters
78 ----------
78 ----------
79 obj : object
79 obj : object
80 The Python object whose format data will be computed.
80 The Python object whose format data will be computed.
81 include : list or tuple, optional
81 include : list or tuple, optional
82 A list of format type strings (MIME types) to include in the
82 A list of format type strings (MIME types) to include in the
83 format data dict. If this is set *only* the format types included
83 format data dict. If this is set *only* the format types included
84 in this list will be computed.
84 in this list will be computed.
85 exclude : list or tuple, optional
85 exclude : list or tuple, optional
86 A list of format type string (MIME types) to exclue in the format
86 A list of format type string (MIME types) to exclue in the format
87 data dict. If this is set all format types will be computed,
87 data dict. If this is set all format types will be computed,
88 except for those included in this argument.
88 except for those included in this argument.
89
89
90 Returns
90 Returns
91 -------
91 -------
92 format_dict : dict
92 format_dict : dict
93 A dictionary of key/value pairs, one or each format that was
93 A dictionary of key/value pairs, one or each format that was
94 generated for the object. The keys are the format types, which
94 generated for the object. The keys are the format types, which
95 will usually be MIME type strings and the values and JSON'able
95 will usually be MIME type strings and the values and JSON'able
96 data structure containing the raw data for the representation in
96 data structure containing the raw data for the representation in
97 that format.
97 that format.
98 """
98 """
99 format_dict = {}
99 format_dict = {}
100
100
101 # If plain text only is active
101 # If plain text only is active
102 if self.plain_text_only:
102 if self.plain_text_only:
103 formatter = self.formatters['text/plain']
103 formatter = self.formatters['text/plain']
104 try:
104 try:
105 data = formatter(obj)
105 data = formatter(obj)
106 except:
106 except:
107 # FIXME: log the exception
107 # FIXME: log the exception
108 raise
108 raise
109 if data is not None:
109 if data is not None:
110 format_dict['text/plain'] = data
110 format_dict['text/plain'] = data
111 return format_dict
111 return format_dict
112
112
113 for format_type, formatter in self.formatters.items():
113 for format_type, formatter in self.formatters.items():
114 if include is not None:
114 if include is not None:
115 if format_type not in include:
115 if format_type not in include:
116 continue
116 continue
117 if exclude is not None:
117 if exclude is not None:
118 if format_type in exclude:
118 if format_type in exclude:
119 continue
119 continue
120 try:
120 try:
121 data = formatter(obj)
121 data = formatter(obj)
122 except:
122 except:
123 # FIXME: log the exception
123 # FIXME: log the exception
124 raise
124 raise
125 if data is not None:
125 if data is not None:
126 format_dict[format_type] = data
126 format_dict[format_type] = data
127 return format_dict
127 return format_dict
128
128
129 @property
129 @property
130 def format_types(self):
130 def format_types(self):
131 """Return the format types (MIME types) of the active formatters."""
131 """Return the format types (MIME types) of the active formatters."""
132 return self.formatters.keys()
132 return self.formatters.keys()
133
133
134
134
135 #-----------------------------------------------------------------------------
135 #-----------------------------------------------------------------------------
136 # Formatters for specific format types (text, html, svg, etc.)
136 # Formatters for specific format types (text, html, svg, etc.)
137 #-----------------------------------------------------------------------------
137 #-----------------------------------------------------------------------------
138
138
139
139
140 class FormatterABC(object):
140 class FormatterABC(object):
141 """ Abstract base class for Formatters.
141 """ Abstract base class for Formatters.
142
142
143 A formatter is a callable class that is responsible for computing the
143 A formatter is a callable class that is responsible for computing the
144 raw format data for a particular format type (MIME type). For example,
144 raw format data for a particular format type (MIME type). For example,
145 an HTML formatter would have a format type of `text/html` and would return
145 an HTML formatter would have a format type of `text/html` and would return
146 the HTML representation of the object when called.
146 the HTML representation of the object when called.
147 """
147 """
148 __metaclass__ = abc.ABCMeta
148 __metaclass__ = abc.ABCMeta
149
149
150 # The format type of the data returned, usually a MIME type.
150 # The format type of the data returned, usually a MIME type.
151 format_type = 'text/plain'
151 format_type = 'text/plain'
152
152
153 # Is the formatter enabled...
153 # Is the formatter enabled...
154 enabled = True
154 enabled = True
155
155
156 @abc.abstractmethod
156 @abc.abstractmethod
157 def __call__(self, obj):
157 def __call__(self, obj):
158 """Return a JSON'able representation of the object.
158 """Return a JSON'able representation of the object.
159
159
160 If the object cannot be formatted by this formatter, then return None
160 If the object cannot be formatted by this formatter, then return None
161 """
161 """
162 try:
162 try:
163 return repr(obj)
163 return repr(obj)
164 except TypeError:
164 except TypeError:
165 return None
165 return None
166
166
167
167
168 class BaseFormatter(Configurable):
168 class BaseFormatter(Configurable):
169 """A base formatter class that is configurable.
169 """A base formatter class that is configurable.
170
170
171 This formatter should usually be used as the base class of all formatters.
171 This formatter should usually be used as the base class of all formatters.
172 It is a traited :class:`Configurable` class and includes an extensible
172 It is a traited :class:`Configurable` class and includes an extensible
173 API for users to determine how their objects are formatted. The following
173 API for users to determine how their objects are formatted. The following
174 logic is used to find a function to format an given object.
174 logic is used to find a function to format an given object.
175
175
176 1. The object is introspected to see if it has a method with the name
176 1. The object is introspected to see if it has a method with the name
177 :attr:`print_method`. If is does, that object is passed to that method
177 :attr:`print_method`. If is does, that object is passed to that method
178 for formatting.
178 for formatting.
179 2. If no print method is found, three internal dictionaries are consulted
179 2. If no print method is found, three internal dictionaries are consulted
180 to find print method: :attr:`singleton_printers`, :attr:`type_printers`
180 to find print method: :attr:`singleton_printers`, :attr:`type_printers`
181 and :attr:`deferred_printers`.
181 and :attr:`deferred_printers`.
182
182
183 Users should use these dictionaries to register functions that will be
183 Users should use these dictionaries to register functions that will be
184 used to compute the format data for their objects (if those objects don't
184 used to compute the format data for their objects (if those objects don't
185 have the special print methods). The easiest way of using these
185 have the special print methods). The easiest way of using these
186 dictionaries is through the :meth:`for_type` and :meth:`for_type_by_name`
186 dictionaries is through the :meth:`for_type` and :meth:`for_type_by_name`
187 methods.
187 methods.
188
188
189 If no function/callable is found to compute the format data, ``None`` is
189 If no function/callable is found to compute the format data, ``None`` is
190 returned and this format type is not used.
190 returned and this format type is not used.
191 """
191 """
192
192
193 format_type = Str('text/plain')
193 format_type = Str('text/plain')
194
194
195 enabled = Bool(True, config=True)
195 enabled = Bool(True, config=True)
196
196
197 print_method = Str('__repr__')
197 print_method = Str('__repr__')
198
198
199 # The singleton printers.
199 # The singleton printers.
200 # Maps the IDs of the builtin singleton objects to the format functions.
200 # Maps the IDs of the builtin singleton objects to the format functions.
201 singleton_printers = Dict(config=True)
201 singleton_printers = Dict(config=True)
202 def _singleton_printers_default(self):
202 def _singleton_printers_default(self):
203 return {}
203 return {}
204
204
205 # The type-specific printers.
205 # The type-specific printers.
206 # Map type objects to the format functions.
206 # Map type objects to the format functions.
207 type_printers = Dict(config=True)
207 type_printers = Dict(config=True)
208 def _type_printers_default(self):
208 def _type_printers_default(self):
209 return {}
209 return {}
210
210
211 # The deferred-import type-specific printers.
211 # The deferred-import type-specific printers.
212 # Map (modulename, classname) pairs to the format functions.
212 # Map (modulename, classname) pairs to the format functions.
213 deferred_printers = Dict(config=True)
213 deferred_printers = Dict(config=True)
214 def _deferred_printers_default(self):
214 def _deferred_printers_default(self):
215 return {}
215 return {}
216
216
217 def __call__(self, obj):
217 def __call__(self, obj):
218 """Compute the format for an object."""
218 """Compute the format for an object."""
219 if self.enabled:
219 if self.enabled:
220 obj_id = id(obj)
220 obj_id = id(obj)
221 try:
221 try:
222 obj_class = getattr(obj, '__class__', None) or type(obj)
222 obj_class = getattr(obj, '__class__', None) or type(obj)
223 if hasattr(obj_class, self.print_method):
223 if hasattr(obj_class, self.print_method):
224 printer = getattr(obj_class, self.print_method)
224 printer = getattr(obj_class, self.print_method)
225 return printer(obj)
225 return printer(obj)
226 try:
226 try:
227 printer = self.singleton_printers[obj_id]
227 printer = self.singleton_printers[obj_id]
228 except (TypeError, KeyError):
228 except (TypeError, KeyError):
229 pass
229 pass
230 else:
230 else:
231 return printer(obj)
231 return printer(obj)
232 for cls in pretty._get_mro(obj_class):
232 for cls in pretty._get_mro(obj_class):
233 if cls in self.type_printers:
233 if cls in self.type_printers:
234 return self.type_printers[cls](obj)
234 return self.type_printers[cls](obj)
235 else:
235 else:
236 printer = self._in_deferred_types(cls)
236 printer = self._in_deferred_types(cls)
237 if printer is not None:
237 if printer is not None:
238 return printer(obj)
238 return printer(obj)
239 return None
239 return None
240 except Exception:
240 except Exception:
241 pass
241 pass
242 else:
242 else:
243 return None
243 return None
244
244
245 def for_type(self, typ, func):
245 def for_type(self, typ, func):
246 """Add a format function for a given type.
246 """Add a format function for a given type.
247
247
248 Parameters
248 Parameters
249 -----------
249 -----------
250 typ : class
250 typ : class
251 The class of the object that will be formatted using `func`.
251 The class of the object that will be formatted using `func`.
252 func : callable
252 func : callable
253 The callable that will be called to compute the format data. The
253 The callable that will be called to compute the format data. The
254 call signature of this function is simple, it must take the
254 call signature of this function is simple, it must take the
255 object to be formatted and return the raw data for the given
255 object to be formatted and return the raw data for the given
256 format. Subclasses may use a different call signature for the
256 format. Subclasses may use a different call signature for the
257 `func` argument.
257 `func` argument.
258 """
258 """
259 oldfunc = self.type_printers.get(typ, None)
259 oldfunc = self.type_printers.get(typ, None)
260 if func is not None:
260 if func is not None:
261 # To support easy restoration of old printers, we need to ignore
261 # To support easy restoration of old printers, we need to ignore
262 # Nones.
262 # Nones.
263 self.type_printers[typ] = func
263 self.type_printers[typ] = func
264 return oldfunc
264 return oldfunc
265
265
266 def for_type_by_name(self, type_module, type_name, func):
266 def for_type_by_name(self, type_module, type_name, func):
267 """Add a format function for a type specified by the full dotted
267 """Add a format function for a type specified by the full dotted
268 module and name of the type, rather than the type of the object.
268 module and name of the type, rather than the type of the object.
269
269
270 Parameters
270 Parameters
271 ----------
271 ----------
272 type_module : str
272 type_module : str
273 The full dotted name of the module the type is defined in, like
273 The full dotted name of the module the type is defined in, like
274 ``numpy``.
274 ``numpy``.
275 type_name : str
275 type_name : str
276 The name of the type (the class name), like ``dtype``
276 The name of the type (the class name), like ``dtype``
277 func : callable
277 func : callable
278 The callable that will be called to compute the format data. The
278 The callable that will be called to compute the format data. The
279 call signature of this function is simple, it must take the
279 call signature of this function is simple, it must take the
280 object to be formatted and return the raw data for the given
280 object to be formatted and return the raw data for the given
281 format. Subclasses may use a different call signature for the
281 format. Subclasses may use a different call signature for the
282 `func` argument.
282 `func` argument.
283 """
283 """
284 key = (type_module, type_name)
284 key = (type_module, type_name)
285 oldfunc = self.deferred_printers.get(key, None)
285 oldfunc = self.deferred_printers.get(key, None)
286 if func is not None:
286 if func is not None:
287 # To support easy restoration of old printers, we need to ignore
287 # To support easy restoration of old printers, we need to ignore
288 # Nones.
288 # Nones.
289 self.deferred_printers[key] = func
289 self.deferred_printers[key] = func
290 return oldfunc
290 return oldfunc
291
291
292 def _in_deferred_types(self, cls):
292 def _in_deferred_types(self, cls):
293 """
293 """
294 Check if the given class is specified in the deferred type registry.
294 Check if the given class is specified in the deferred type registry.
295
295
296 Returns the printer from the registry if it exists, and None if the
296 Returns the printer from the registry if it exists, and None if the
297 class is not in the registry. Successful matches will be moved to the
297 class is not in the registry. Successful matches will be moved to the
298 regular type registry for future use.
298 regular type registry for future use.
299 """
299 """
300 mod = getattr(cls, '__module__', None)
300 mod = getattr(cls, '__module__', None)
301 name = getattr(cls, '__name__', None)
301 name = getattr(cls, '__name__', None)
302 key = (mod, name)
302 key = (mod, name)
303 printer = None
303 printer = None
304 if key in self.deferred_printers:
304 if key in self.deferred_printers:
305 # Move the printer over to the regular registry.
305 # Move the printer over to the regular registry.
306 printer = self.deferred_printers.pop(key)
306 printer = self.deferred_printers.pop(key)
307 self.type_printers[cls] = printer
307 self.type_printers[cls] = printer
308 return printer
308 return printer
309
309
310
310
311 class PlainTextFormatter(BaseFormatter):
311 class PlainTextFormatter(BaseFormatter):
312 """The default pretty-printer.
312 """The default pretty-printer.
313
313
314 This uses :mod:`IPython.external.pretty` to compute the format data of
314 This uses :mod:`IPython.external.pretty` to compute the format data of
315 the object. If the object cannot be pretty printed, :func:`repr` is used.
315 the object. If the object cannot be pretty printed, :func:`repr` is used.
316 See the documentation of :mod:`IPython.external.pretty` for details on
316 See the documentation of :mod:`IPython.external.pretty` for details on
317 how to write pretty printers. Here is a simple example::
317 how to write pretty printers. Here is a simple example::
318
318
319 def dtype_pprinter(obj, p, cycle):
319 def dtype_pprinter(obj, p, cycle):
320 if cycle:
320 if cycle:
321 return p.text('dtype(...)')
321 return p.text('dtype(...)')
322 if hasattr(obj, 'fields'):
322 if hasattr(obj, 'fields'):
323 if obj.fields is None:
323 if obj.fields is None:
324 p.text(repr(obj))
324 p.text(repr(obj))
325 else:
325 else:
326 p.begin_group(7, 'dtype([')
326 p.begin_group(7, 'dtype([')
327 for i, field in enumerate(obj.descr):
327 for i, field in enumerate(obj.descr):
328 if i > 0:
328 if i > 0:
329 p.text(',')
329 p.text(',')
330 p.breakable()
330 p.breakable()
331 p.pretty(field)
331 p.pretty(field)
332 p.end_group(7, '])')
332 p.end_group(7, '])')
333 """
333 """
334
334
335 # The format type of data returned.
335 # The format type of data returned.
336 format_type = Str('text/plain')
336 format_type = Str('text/plain')
337
337
338 # This subclass ignores this attribute as it always need to return
338 # This subclass ignores this attribute as it always need to return
339 # something.
339 # something.
340 enabled = Bool(True, config=False)
340 enabled = Bool(True, config=False)
341
341
342 # Look for a __pretty__ methods to use for pretty printing.
342 # Look for a __pretty__ methods to use for pretty printing.
343 print_method = Str('__pretty__')
343 print_method = Str('__pretty__')
344
344
345 # Whether to pretty-print or not.
345 # Whether to pretty-print or not.
346 pprint = Bool(True, config=True)
346 pprint = Bool(True, config=True)
347
347
348 # Whether to be verbose or not.
348 # Whether to be verbose or not.
349 verbose = Bool(False, config=True)
349 verbose = Bool(False, config=True)
350
350
351 # The maximum width.
351 # The maximum width.
352 max_width = Int(79, config=True)
352 max_width = Int(79, config=True)
353
353
354 # The newline character.
354 # The newline character.
355 newline = Str('\n', config=True)
355 newline = Str('\n', config=True)
356
356
357 # format-string for pprinting floats
357 # format-string for pprinting floats
358 float_format = Str('%r')
358 float_format = Str('%r')
359 # setter for float precision, either int or direct format-string
359 # setter for float precision, either int or direct format-string
360 float_precision = CStr('', config=True)
360 float_precision = CStr('', config=True)
361
361
362 def _float_precision_changed(self, name, old, new):
362 def _float_precision_changed(self, name, old, new):
363 """float_precision changed, set float_format accordingly.
363 """float_precision changed, set float_format accordingly.
364
364
365 float_precision can be set by int or str.
365 float_precision can be set by int or str.
366 This will set float_format, after interpreting input.
366 This will set float_format, after interpreting input.
367 If numpy has been imported, numpy print precision will also be set.
367 If numpy has been imported, numpy print precision will also be set.
368
368
369 integer `n` sets format to '%.nf', otherwise, format set directly.
369 integer `n` sets format to '%.nf', otherwise, format set directly.
370
370
371 An empty string returns to defaults (repr for float, 8 for numpy).
371 An empty string returns to defaults (repr for float, 8 for numpy).
372
372
373 This parameter can be set via the '%precision' magic.
373 This parameter can be set via the '%precision' magic.
374 """
374 """
375
375
376 if '%' in new:
376 if '%' in new:
377 # got explicit format string
377 # got explicit format string
378 fmt = new
378 fmt = new
379 try:
379 try:
380 fmt%3.14159
380 fmt%3.14159
381 except Exception:
381 except Exception:
382 raise ValueError("Precision must be int or format string, not %r"%new)
382 raise ValueError("Precision must be int or format string, not %r"%new)
383 elif new:
383 elif new:
384 # otherwise, should be an int
384 # otherwise, should be an int
385 try:
385 try:
386 i = int(new)
386 i = int(new)
387 assert i >= 0
387 assert i >= 0
388 except ValueError:
388 except ValueError:
389 raise ValueError("Precision must be int or format string, not %r"%new)
389 raise ValueError("Precision must be int or format string, not %r"%new)
390 except AssertionError:
390 except AssertionError:
391 raise ValueError("int precision must be non-negative, not %r"%i)
391 raise ValueError("int precision must be non-negative, not %r"%i)
392
392
393 fmt = '%%.%if'%i
393 fmt = '%%.%if'%i
394 if 'numpy' in sys.modules:
394 if 'numpy' in sys.modules:
395 # set numpy precision if it has been imported
395 # set numpy precision if it has been imported
396 import numpy
396 import numpy
397 numpy.set_printoptions(precision=i)
397 numpy.set_printoptions(precision=i)
398 else:
398 else:
399 # default back to repr
399 # default back to repr
400 fmt = '%r'
400 fmt = '%r'
401 if 'numpy' in sys.modules:
401 if 'numpy' in sys.modules:
402 import numpy
402 import numpy
403 # numpy default is 8
403 # numpy default is 8
404 numpy.set_printoptions(precision=8)
404 numpy.set_printoptions(precision=8)
405 self.float_format = fmt
405 self.float_format = fmt
406
406
407 # Use the default pretty printers from IPython.external.pretty.
407 # Use the default pretty printers from IPython.external.pretty.
408 def _singleton_printers_default(self):
408 def _singleton_printers_default(self):
409 return pretty._singleton_pprinters.copy()
409 return pretty._singleton_pprinters.copy()
410
410
411 def _type_printers_default(self):
411 def _type_printers_default(self):
412 d = pretty._type_pprinters.copy()
412 d = pretty._type_pprinters.copy()
413 d[float] = lambda obj,p,cycle: p.text(self.float_format%obj)
413 d[float] = lambda obj,p,cycle: p.text(self.float_format%obj)
414 return d
414 return d
415
415
416 def _deferred_printers_default(self):
416 def _deferred_printers_default(self):
417 return pretty._deferred_type_pprinters.copy()
417 return pretty._deferred_type_pprinters.copy()
418
418
419 #### FormatterABC interface ####
419 #### FormatterABC interface ####
420
420
421 def __call__(self, obj):
421 def __call__(self, obj):
422 """Compute the pretty representation of the object."""
422 """Compute the pretty representation of the object."""
423 if not self.pprint:
423 if not self.pprint:
424 try:
424 try:
425 return repr(obj)
425 return repr(obj)
426 except TypeError:
426 except TypeError:
427 return ''
427 return ''
428 else:
428 else:
429 # This uses use StringIO, as cStringIO doesn't handle unicode.
429 # This uses use StringIO, as cStringIO doesn't handle unicode.
430 stream = StringIO()
430 stream = StringIO()
431 printer = pretty.RepresentationPrinter(stream, self.verbose,
431 printer = pretty.RepresentationPrinter(stream, self.verbose,
432 self.max_width, self.newline,
432 self.max_width, self.newline,
433 singleton_pprinters=self.singleton_printers,
433 singleton_pprinters=self.singleton_printers,
434 type_pprinters=self.type_printers,
434 type_pprinters=self.type_printers,
435 deferred_pprinters=self.deferred_printers)
435 deferred_pprinters=self.deferred_printers)
436 printer.pretty(obj)
436 printer.pretty(obj)
437 printer.flush()
437 printer.flush()
438 return stream.getvalue()
438 return stream.getvalue()
439
439
440
440
441 class HTMLFormatter(BaseFormatter):
441 class HTMLFormatter(BaseFormatter):
442 """An HTML formatter.
442 """An HTML formatter.
443
443
444 To define the callables that compute the HTML representation of your
444 To define the callables that compute the HTML representation of your
445 objects, define a :meth:`__html__` method or use the :meth:`for_type`
445 objects, define a :meth:`__html__` method or use the :meth:`for_type`
446 or :meth:`for_type_by_name` methods to register functions that handle
446 or :meth:`for_type_by_name` methods to register functions that handle
447 this.
447 this.
448 """
448 """
449 format_type = Str('text/html')
449 format_type = Str('text/html')
450
450
451 print_method = Str('__html__')
451 print_method = Str('__html__')
452
452
453
453
454 class SVGFormatter(BaseFormatter):
454 class SVGFormatter(BaseFormatter):
455 """An SVG formatter.
455 """An SVG formatter.
456
456
457 To define the callables that compute the SVG representation of your
457 To define the callables that compute the SVG representation of your
458 objects, define a :meth:`__svg__` method or use the :meth:`for_type`
458 objects, define a :meth:`__svg__` method or use the :meth:`for_type`
459 or :meth:`for_type_by_name` methods to register functions that handle
459 or :meth:`for_type_by_name` methods to register functions that handle
460 this.
460 this.
461 """
461 """
462 format_type = Str('image/svg+xml')
462 format_type = Str('image/svg+xml')
463
463
464 print_method = Str('__svg__')
464 print_method = Str('__svg__')
465
465
466
466
467 class PNGFormatter(BaseFormatter):
467 class PNGFormatter(BaseFormatter):
468 """A PNG formatter.
468 """A PNG formatter.
469
469
470 To define the callables that compute the PNG representation of your
470 To define the callables that compute the PNG representation of your
471 objects, define a :meth:`__png__` method or use the :meth:`for_type`
471 objects, define a :meth:`__png__` method or use the :meth:`for_type`
472 or :meth:`for_type_by_name` methods to register functions that handle
472 or :meth:`for_type_by_name` methods to register functions that handle
473 this. The raw data should be the base64 encoded raw png data.
473 this. The raw data should be the base64 encoded raw png data.
474 """
474 """
475 format_type = Str('image/png')
475 format_type = Str('image/png')
476
476
477 print_method = Str('__png__')
477 print_method = Str('__png__')
478
478
479
479
480 class LatexFormatter(BaseFormatter):
480 class LatexFormatter(BaseFormatter):
481 """A LaTeX formatter.
481 """A LaTeX formatter.
482
482
483 To define the callables that compute the LaTeX representation of your
483 To define the callables that compute the LaTeX representation of your
484 objects, define a :meth:`__latex__` method or use the :meth:`for_type`
484 objects, define a :meth:`__latex__` method or use the :meth:`for_type`
485 or :meth:`for_type_by_name` methods to register functions that handle
485 or :meth:`for_type_by_name` methods to register functions that handle
486 this.
486 this.
487 """
487 """
488 format_type = Str('text/latex')
488 format_type = Str('text/latex')
489
489
490 print_method = Str('__latex__')
490 print_method = Str('__latex__')
491
491
492
492
493 class JSONFormatter(BaseFormatter):
493 class JSONFormatter(BaseFormatter):
494 """A JSON string formatter.
494 """A JSON string formatter.
495
495
496 To define the callables that compute the JSON string representation of
496 To define the callables that compute the JSON string representation of
497 your objects, define a :meth:`__json__` method or use the :meth:`for_type`
497 your objects, define a :meth:`__json__` method or use the :meth:`for_type`
498 or :meth:`for_type_by_name` methods to register functions that handle
498 or :meth:`for_type_by_name` methods to register functions that handle
499 this.
499 this.
500 """
500 """
501 format_type = Str('application/json')
501 format_type = Str('application/json')
502
502
503 print_method = Str('__json__')
503 print_method = Str('__json__')
504
504
505
505
506 FormatterABC.register(BaseFormatter)
506 FormatterABC.register(BaseFormatter)
507 FormatterABC.register(PlainTextFormatter)
507 FormatterABC.register(PlainTextFormatter)
508 FormatterABC.register(HTMLFormatter)
508 FormatterABC.register(HTMLFormatter)
509 FormatterABC.register(SVGFormatter)
509 FormatterABC.register(SVGFormatter)
510 FormatterABC.register(PNGFormatter)
510 FormatterABC.register(PNGFormatter)
511 FormatterABC.register(LatexFormatter)
511 FormatterABC.register(LatexFormatter)
512 FormatterABC.register(JSONFormatter)
512 FormatterABC.register(JSONFormatter)
513
513
514
514
515 def format_display_data(obj, include=None, exclude=None):
515 def format_display_data(obj, include=None, exclude=None):
516 """Return a format data dict for an object.
516 """Return a format data dict for an object.
517
517
518 By default all format types will be computed.
518 By default all format types will be computed.
519
519
520 The following MIME types are currently implemented:
520 The following MIME types are currently implemented:
521
521
522 * text/plain
522 * text/plain
523 * text/html
523 * text/html
524 * text/latex
524 * text/latex
525 * application/json
525 * application/json
526 * image/png
526 * image/png
527 * immage/svg+xml
527 * immage/svg+xml
528
528
529 Parameters
529 Parameters
530 ----------
530 ----------
531 obj : object
531 obj : object
532 The Python object whose format data will be computed.
532 The Python object whose format data will be computed.
533
533
534 Returns
534 Returns
535 -------
535 -------
536 format_dict : dict
536 format_dict : dict
537 A dictionary of key/value pairs, one or each format that was
537 A dictionary of key/value pairs, one or each format that was
538 generated for the object. The keys are the format types, which
538 generated for the object. The keys are the format types, which
539 will usually be MIME type strings and the values and JSON'able
539 will usually be MIME type strings and the values and JSON'able
540 data structure containing the raw data for the representation in
540 data structure containing the raw data for the representation in
541 that format.
541 that format.
542 include : list or tuple, optional
542 include : list or tuple, optional
543 A list of format type strings (MIME types) to include in the
543 A list of format type strings (MIME types) to include in the
544 format data dict. If this is set *only* the format types included
544 format data dict. If this is set *only* the format types included
545 in this list will be computed.
545 in this list will be computed.
546 exclude : list or tuple, optional
546 exclude : list or tuple, optional
547 A list of format type string (MIME types) to exclue in the format
547 A list of format type string (MIME types) to exclue in the format
548 data dict. If this is set all format types will be computed,
548 data dict. If this is set all format types will be computed,
549 except for those included in this argument.
549 except for those included in this argument.
550 """
550 """
551 from IPython.core.interactiveshell import InteractiveShell
551 from IPython.core.interactiveshell import InteractiveShell
552
552
553 InteractiveShell.instance().display_formatter.format(
553 InteractiveShell.instance().display_formatter.format(
554 obj,
554 obj,
555 include,
555 include,
556 exclude
556 exclude
557 )
557 )
1 NO CONTENT: file renamed from IPython/external/pretty/_pretty.py to IPython/lib/pretty.py
NO CONTENT: file renamed from IPython/external/pretty/_pretty.py to IPython/lib/pretty.py
@@ -1,381 +1,380 b''
1 # encoding: utf-8
1 # encoding: utf-8
2 """
2 """
3 This module defines the things that are used in setup.py for building IPython
3 This module defines the things that are used in setup.py for building IPython
4
4
5 This includes:
5 This includes:
6
6
7 * The basic arguments to setup
7 * The basic arguments to setup
8 * Functions for finding things like packages, package data, etc.
8 * Functions for finding things like packages, package data, etc.
9 * A function for checking dependencies.
9 * A function for checking dependencies.
10 """
10 """
11 from __future__ import print_function
11 from __future__ import print_function
12
12
13 #-------------------------------------------------------------------------------
13 #-------------------------------------------------------------------------------
14 # Copyright (C) 2008 The IPython Development Team
14 # Copyright (C) 2008 The IPython Development Team
15 #
15 #
16 # Distributed under the terms of the BSD License. The full license is in
16 # Distributed under the terms of the BSD License. The full license is in
17 # the file COPYING, distributed as part of this software.
17 # the file COPYING, distributed as part of this software.
18 #-------------------------------------------------------------------------------
18 #-------------------------------------------------------------------------------
19
19
20 #-------------------------------------------------------------------------------
20 #-------------------------------------------------------------------------------
21 # Imports
21 # Imports
22 #-------------------------------------------------------------------------------
22 #-------------------------------------------------------------------------------
23 import os
23 import os
24 import sys
24 import sys
25
25
26 from ConfigParser import ConfigParser
26 from ConfigParser import ConfigParser
27 from distutils.command.build_py import build_py
27 from distutils.command.build_py import build_py
28 from glob import glob
28 from glob import glob
29
29
30 from setupext import install_data_ext
30 from setupext import install_data_ext
31
31
32 #-------------------------------------------------------------------------------
32 #-------------------------------------------------------------------------------
33 # Useful globals and utility functions
33 # Useful globals and utility functions
34 #-------------------------------------------------------------------------------
34 #-------------------------------------------------------------------------------
35
35
36 # A few handy globals
36 # A few handy globals
37 isfile = os.path.isfile
37 isfile = os.path.isfile
38 pjoin = os.path.join
38 pjoin = os.path.join
39
39
40 def oscmd(s):
40 def oscmd(s):
41 print(">", s)
41 print(">", s)
42 os.system(s)
42 os.system(s)
43
43
44 # A little utility we'll need below, since glob() does NOT allow you to do
44 # A little utility we'll need below, since glob() does NOT allow you to do
45 # exclusion on multiple endings!
45 # exclusion on multiple endings!
46 def file_doesnt_endwith(test,endings):
46 def file_doesnt_endwith(test,endings):
47 """Return true if test is a file and its name does NOT end with any
47 """Return true if test is a file and its name does NOT end with any
48 of the strings listed in endings."""
48 of the strings listed in endings."""
49 if not isfile(test):
49 if not isfile(test):
50 return False
50 return False
51 for e in endings:
51 for e in endings:
52 if test.endswith(e):
52 if test.endswith(e):
53 return False
53 return False
54 return True
54 return True
55
55
56 #---------------------------------------------------------------------------
56 #---------------------------------------------------------------------------
57 # Basic project information
57 # Basic project information
58 #---------------------------------------------------------------------------
58 #---------------------------------------------------------------------------
59
59
60 # release.py contains version, authors, license, url, keywords, etc.
60 # release.py contains version, authors, license, url, keywords, etc.
61 execfile(pjoin('IPython','core','release.py'))
61 execfile(pjoin('IPython','core','release.py'))
62
62
63 # Create a dict with the basic information
63 # Create a dict with the basic information
64 # This dict is eventually passed to setup after additional keys are added.
64 # This dict is eventually passed to setup after additional keys are added.
65 setup_args = dict(
65 setup_args = dict(
66 name = name,
66 name = name,
67 version = version,
67 version = version,
68 description = description,
68 description = description,
69 long_description = long_description,
69 long_description = long_description,
70 author = author,
70 author = author,
71 author_email = author_email,
71 author_email = author_email,
72 url = url,
72 url = url,
73 download_url = download_url,
73 download_url = download_url,
74 license = license,
74 license = license,
75 platforms = platforms,
75 platforms = platforms,
76 keywords = keywords,
76 keywords = keywords,
77 cmdclass = {'install_data': install_data_ext},
77 cmdclass = {'install_data': install_data_ext},
78 )
78 )
79
79
80
80
81 #---------------------------------------------------------------------------
81 #---------------------------------------------------------------------------
82 # Find packages
82 # Find packages
83 #---------------------------------------------------------------------------
83 #---------------------------------------------------------------------------
84
84
85 def add_package(packages,pname,config=False,tests=False,scripts=False,
85 def add_package(packages,pname,config=False,tests=False,scripts=False,
86 others=None):
86 others=None):
87 """
87 """
88 Add a package to the list of packages, including certain subpackages.
88 Add a package to the list of packages, including certain subpackages.
89 """
89 """
90 packages.append('.'.join(['IPython',pname]))
90 packages.append('.'.join(['IPython',pname]))
91 if config:
91 if config:
92 packages.append('.'.join(['IPython',pname,'config']))
92 packages.append('.'.join(['IPython',pname,'config']))
93 if tests:
93 if tests:
94 packages.append('.'.join(['IPython',pname,'tests']))
94 packages.append('.'.join(['IPython',pname,'tests']))
95 if scripts:
95 if scripts:
96 packages.append('.'.join(['IPython',pname,'scripts']))
96 packages.append('.'.join(['IPython',pname,'scripts']))
97 if others is not None:
97 if others is not None:
98 for o in others:
98 for o in others:
99 packages.append('.'.join(['IPython',pname,o]))
99 packages.append('.'.join(['IPython',pname,o]))
100
100
101 def find_packages():
101 def find_packages():
102 """
102 """
103 Find all of IPython's packages.
103 Find all of IPython's packages.
104 """
104 """
105 packages = ['IPython']
105 packages = ['IPython']
106 add_package(packages, 'config', tests=True, others=['default','profile'])
106 add_package(packages, 'config', tests=True, others=['default','profile'])
107 add_package(packages, 'core', tests=True)
107 add_package(packages, 'core', tests=True)
108 add_package(packages, 'deathrow', tests=True)
108 add_package(packages, 'deathrow', tests=True)
109 add_package(packages, 'extensions')
109 add_package(packages, 'extensions')
110 add_package(packages, 'external')
110 add_package(packages, 'external')
111 add_package(packages, 'external.argparse')
111 add_package(packages, 'external.argparse')
112 add_package(packages, 'external.configobj')
112 add_package(packages, 'external.configobj')
113 add_package(packages, 'external.decorator')
113 add_package(packages, 'external.decorator')
114 add_package(packages, 'external.decorators')
114 add_package(packages, 'external.decorators')
115 add_package(packages, 'external.guid')
115 add_package(packages, 'external.guid')
116 add_package(packages, 'external.Itpl')
116 add_package(packages, 'external.Itpl')
117 add_package(packages, 'external.mglob')
117 add_package(packages, 'external.mglob')
118 add_package(packages, 'external.path')
118 add_package(packages, 'external.path')
119 add_package(packages, 'external.pretty')
120 add_package(packages, 'external.pyparsing')
119 add_package(packages, 'external.pyparsing')
121 add_package(packages, 'external.simplegeneric')
120 add_package(packages, 'external.simplegeneric')
122 add_package(packages, 'external.validate')
121 add_package(packages, 'external.validate')
123 add_package(packages, 'frontend')
122 add_package(packages, 'frontend')
124 add_package(packages, 'frontend.qt')
123 add_package(packages, 'frontend.qt')
125 add_package(packages, 'frontend.qt.console', tests=True)
124 add_package(packages, 'frontend.qt.console', tests=True)
126 add_package(packages, 'frontend.terminal', tests=True)
125 add_package(packages, 'frontend.terminal', tests=True)
127 add_package(packages, 'kernel', config=False, tests=True, scripts=True)
126 add_package(packages, 'kernel', config=False, tests=True, scripts=True)
128 add_package(packages, 'kernel.core', config=False, tests=True)
127 add_package(packages, 'kernel.core', config=False, tests=True)
129 add_package(packages, 'lib', tests=True)
128 add_package(packages, 'lib', tests=True)
130 add_package(packages, 'quarantine', tests=True)
129 add_package(packages, 'quarantine', tests=True)
131 add_package(packages, 'scripts')
130 add_package(packages, 'scripts')
132 add_package(packages, 'testing', tests=True)
131 add_package(packages, 'testing', tests=True)
133 add_package(packages, 'testing.plugin', tests=False)
132 add_package(packages, 'testing.plugin', tests=False)
134 add_package(packages, 'utils', tests=True)
133 add_package(packages, 'utils', tests=True)
135 add_package(packages, 'zmq')
134 add_package(packages, 'zmq')
136 add_package(packages, 'zmq.pylab')
135 add_package(packages, 'zmq.pylab')
137 return packages
136 return packages
138
137
139 #---------------------------------------------------------------------------
138 #---------------------------------------------------------------------------
140 # Find package data
139 # Find package data
141 #---------------------------------------------------------------------------
140 #---------------------------------------------------------------------------
142
141
143 def find_package_data():
142 def find_package_data():
144 """
143 """
145 Find IPython's package_data.
144 Find IPython's package_data.
146 """
145 """
147 # This is not enough for these things to appear in an sdist.
146 # This is not enough for these things to appear in an sdist.
148 # We need to muck with the MANIFEST to get this to work
147 # We need to muck with the MANIFEST to get this to work
149 package_data = {
148 package_data = {
150 'IPython.config.userconfig' : ['*'],
149 'IPython.config.userconfig' : ['*'],
151 'IPython.testing' : ['*.txt']
150 'IPython.testing' : ['*.txt']
152 }
151 }
153 return package_data
152 return package_data
154
153
155
154
156 #---------------------------------------------------------------------------
155 #---------------------------------------------------------------------------
157 # Find data files
156 # Find data files
158 #---------------------------------------------------------------------------
157 #---------------------------------------------------------------------------
159
158
160 def make_dir_struct(tag,base,out_base):
159 def make_dir_struct(tag,base,out_base):
161 """Make the directory structure of all files below a starting dir.
160 """Make the directory structure of all files below a starting dir.
162
161
163 This is just a convenience routine to help build a nested directory
162 This is just a convenience routine to help build a nested directory
164 hierarchy because distutils is too stupid to do this by itself.
163 hierarchy because distutils is too stupid to do this by itself.
165
164
166 XXX - this needs a proper docstring!
165 XXX - this needs a proper docstring!
167 """
166 """
168
167
169 # we'll use these a lot below
168 # we'll use these a lot below
170 lbase = len(base)
169 lbase = len(base)
171 pathsep = os.path.sep
170 pathsep = os.path.sep
172 lpathsep = len(pathsep)
171 lpathsep = len(pathsep)
173
172
174 out = []
173 out = []
175 for (dirpath,dirnames,filenames) in os.walk(base):
174 for (dirpath,dirnames,filenames) in os.walk(base):
176 # we need to strip out the dirpath from the base to map it to the
175 # we need to strip out the dirpath from the base to map it to the
177 # output (installation) path. This requires possibly stripping the
176 # output (installation) path. This requires possibly stripping the
178 # path separator, because otherwise pjoin will not work correctly
177 # path separator, because otherwise pjoin will not work correctly
179 # (pjoin('foo/','/bar') returns '/bar').
178 # (pjoin('foo/','/bar') returns '/bar').
180
179
181 dp_eff = dirpath[lbase:]
180 dp_eff = dirpath[lbase:]
182 if dp_eff.startswith(pathsep):
181 if dp_eff.startswith(pathsep):
183 dp_eff = dp_eff[lpathsep:]
182 dp_eff = dp_eff[lpathsep:]
184 # The output path must be anchored at the out_base marker
183 # The output path must be anchored at the out_base marker
185 out_path = pjoin(out_base,dp_eff)
184 out_path = pjoin(out_base,dp_eff)
186 # Now we can generate the final filenames. Since os.walk only produces
185 # Now we can generate the final filenames. Since os.walk only produces
187 # filenames, we must join back with the dirpath to get full valid file
186 # filenames, we must join back with the dirpath to get full valid file
188 # paths:
187 # paths:
189 pfiles = [pjoin(dirpath,f) for f in filenames]
188 pfiles = [pjoin(dirpath,f) for f in filenames]
190 # Finally, generate the entry we need, which is a pari of (output
189 # Finally, generate the entry we need, which is a pari of (output
191 # path, files) for use as a data_files parameter in install_data.
190 # path, files) for use as a data_files parameter in install_data.
192 out.append((out_path, pfiles))
191 out.append((out_path, pfiles))
193
192
194 return out
193 return out
195
194
196
195
197 def find_data_files():
196 def find_data_files():
198 """
197 """
199 Find IPython's data_files.
198 Find IPython's data_files.
200
199
201 Most of these are docs.
200 Most of these are docs.
202 """
201 """
203
202
204 docdirbase = pjoin('share', 'doc', 'ipython')
203 docdirbase = pjoin('share', 'doc', 'ipython')
205 manpagebase = pjoin('share', 'man', 'man1')
204 manpagebase = pjoin('share', 'man', 'man1')
206
205
207 # Simple file lists can be made by hand
206 # Simple file lists can be made by hand
208 manpages = filter(isfile, glob(pjoin('docs','man','*.1.gz')))
207 manpages = filter(isfile, glob(pjoin('docs','man','*.1.gz')))
209 igridhelpfiles = filter(isfile,
208 igridhelpfiles = filter(isfile,
210 glob(pjoin('IPython','extensions','igrid_help.*')))
209 glob(pjoin('IPython','extensions','igrid_help.*')))
211
210
212 # For nested structures, use the utility above
211 # For nested structures, use the utility above
213 example_files = make_dir_struct(
212 example_files = make_dir_struct(
214 'data',
213 'data',
215 pjoin('docs','examples'),
214 pjoin('docs','examples'),
216 pjoin(docdirbase,'examples')
215 pjoin(docdirbase,'examples')
217 )
216 )
218 manual_files = make_dir_struct(
217 manual_files = make_dir_struct(
219 'data',
218 'data',
220 pjoin('docs','dist'),
219 pjoin('docs','dist'),
221 pjoin(docdirbase,'manual')
220 pjoin(docdirbase,'manual')
222 )
221 )
223
222
224 # And assemble the entire output list
223 # And assemble the entire output list
225 data_files = [ (manpagebase, manpages),
224 data_files = [ (manpagebase, manpages),
226 (pjoin(docdirbase, 'extensions'), igridhelpfiles),
225 (pjoin(docdirbase, 'extensions'), igridhelpfiles),
227 ] + manual_files + example_files
226 ] + manual_files + example_files
228
227
229 return data_files
228 return data_files
230
229
231
230
232 def make_man_update_target(manpage):
231 def make_man_update_target(manpage):
233 """Return a target_update-compliant tuple for the given manpage.
232 """Return a target_update-compliant tuple for the given manpage.
234
233
235 Parameters
234 Parameters
236 ----------
235 ----------
237 manpage : string
236 manpage : string
238 Name of the manpage, must include the section number (trailing number).
237 Name of the manpage, must include the section number (trailing number).
239
238
240 Example
239 Example
241 -------
240 -------
242
241
243 >>> make_man_update_target('ipython.1') #doctest: +NORMALIZE_WHITESPACE
242 >>> make_man_update_target('ipython.1') #doctest: +NORMALIZE_WHITESPACE
244 ('docs/man/ipython.1.gz',
243 ('docs/man/ipython.1.gz',
245 ['docs/man/ipython.1'],
244 ['docs/man/ipython.1'],
246 'cd docs/man && gzip -9c ipython.1 > ipython.1.gz')
245 'cd docs/man && gzip -9c ipython.1 > ipython.1.gz')
247 """
246 """
248 man_dir = pjoin('docs', 'man')
247 man_dir = pjoin('docs', 'man')
249 manpage_gz = manpage + '.gz'
248 manpage_gz = manpage + '.gz'
250 manpath = pjoin(man_dir, manpage)
249 manpath = pjoin(man_dir, manpage)
251 manpath_gz = pjoin(man_dir, manpage_gz)
250 manpath_gz = pjoin(man_dir, manpage_gz)
252 gz_cmd = ( "cd %(man_dir)s && gzip -9c %(manpage)s > %(manpage_gz)s" %
251 gz_cmd = ( "cd %(man_dir)s && gzip -9c %(manpage)s > %(manpage_gz)s" %
253 locals() )
252 locals() )
254 return (manpath_gz, [manpath], gz_cmd)
253 return (manpath_gz, [manpath], gz_cmd)
255
254
256 #---------------------------------------------------------------------------
255 #---------------------------------------------------------------------------
257 # Find scripts
256 # Find scripts
258 #---------------------------------------------------------------------------
257 #---------------------------------------------------------------------------
259
258
260 def find_scripts():
259 def find_scripts():
261 """
260 """
262 Find IPython's scripts.
261 Find IPython's scripts.
263 """
262 """
264 kernel_scripts = pjoin('IPython','kernel','scripts')
263 kernel_scripts = pjoin('IPython','kernel','scripts')
265 main_scripts = pjoin('IPython','scripts')
264 main_scripts = pjoin('IPython','scripts')
266 scripts = [pjoin(kernel_scripts, 'ipengine'),
265 scripts = [pjoin(kernel_scripts, 'ipengine'),
267 pjoin(kernel_scripts, 'ipcontroller'),
266 pjoin(kernel_scripts, 'ipcontroller'),
268 pjoin(kernel_scripts, 'ipcluster'),
267 pjoin(kernel_scripts, 'ipcluster'),
269 pjoin(main_scripts, 'ipython'),
268 pjoin(main_scripts, 'ipython'),
270 pjoin(main_scripts, 'ipython-qtconsole'),
269 pjoin(main_scripts, 'ipython-qtconsole'),
271 pjoin(main_scripts, 'pycolor'),
270 pjoin(main_scripts, 'pycolor'),
272 pjoin(main_scripts, 'irunner'),
271 pjoin(main_scripts, 'irunner'),
273 pjoin(main_scripts, 'iptest')
272 pjoin(main_scripts, 'iptest')
274 ]
273 ]
275
274
276 # Script to be run by the windows binary installer after the default setup
275 # Script to be run by the windows binary installer after the default setup
277 # routine, to add shortcuts and similar windows-only things. Windows
276 # routine, to add shortcuts and similar windows-only things. Windows
278 # post-install scripts MUST reside in the scripts/ dir, otherwise distutils
277 # post-install scripts MUST reside in the scripts/ dir, otherwise distutils
279 # doesn't find them.
278 # doesn't find them.
280 if 'bdist_wininst' in sys.argv:
279 if 'bdist_wininst' in sys.argv:
281 if len(sys.argv) > 2 and \
280 if len(sys.argv) > 2 and \
282 ('sdist' in sys.argv or 'bdist_rpm' in sys.argv):
281 ('sdist' in sys.argv or 'bdist_rpm' in sys.argv):
283 print("ERROR: bdist_wininst must be run alone. Exiting.",
282 print("ERROR: bdist_wininst must be run alone. Exiting.",
284 file=sys.stderr)
283 file=sys.stderr)
285 sys.exit(1)
284 sys.exit(1)
286 scripts.append(pjoin('scripts','ipython_win_post_install.py'))
285 scripts.append(pjoin('scripts','ipython_win_post_install.py'))
287
286
288 return scripts
287 return scripts
289
288
290 #---------------------------------------------------------------------------
289 #---------------------------------------------------------------------------
291 # Verify all dependencies
290 # Verify all dependencies
292 #---------------------------------------------------------------------------
291 #---------------------------------------------------------------------------
293
292
294 def check_for_dependencies():
293 def check_for_dependencies():
295 """Check for IPython's dependencies.
294 """Check for IPython's dependencies.
296
295
297 This function should NOT be called if running under setuptools!
296 This function should NOT be called if running under setuptools!
298 """
297 """
299 from setupext.setupext import (
298 from setupext.setupext import (
300 print_line, print_raw, print_status,
299 print_line, print_raw, print_status,
301 check_for_zopeinterface, check_for_twisted,
300 check_for_zopeinterface, check_for_twisted,
302 check_for_foolscap, check_for_pyopenssl,
301 check_for_foolscap, check_for_pyopenssl,
303 check_for_sphinx, check_for_pygments,
302 check_for_sphinx, check_for_pygments,
304 check_for_nose, check_for_pexpect
303 check_for_nose, check_for_pexpect
305 )
304 )
306 print_line()
305 print_line()
307 print_raw("BUILDING IPYTHON")
306 print_raw("BUILDING IPYTHON")
308 print_status('python', sys.version)
307 print_status('python', sys.version)
309 print_status('platform', sys.platform)
308 print_status('platform', sys.platform)
310 if sys.platform == 'win32':
309 if sys.platform == 'win32':
311 print_status('Windows version', sys.getwindowsversion())
310 print_status('Windows version', sys.getwindowsversion())
312
311
313 print_raw("")
312 print_raw("")
314 print_raw("OPTIONAL DEPENDENCIES")
313 print_raw("OPTIONAL DEPENDENCIES")
315
314
316 check_for_zopeinterface()
315 check_for_zopeinterface()
317 check_for_twisted()
316 check_for_twisted()
318 check_for_foolscap()
317 check_for_foolscap()
319 check_for_pyopenssl()
318 check_for_pyopenssl()
320 check_for_sphinx()
319 check_for_sphinx()
321 check_for_pygments()
320 check_for_pygments()
322 check_for_nose()
321 check_for_nose()
323 check_for_pexpect()
322 check_for_pexpect()
324
323
325
324
326 def record_commit_info(pkg_dir, build_cmd=build_py):
325 def record_commit_info(pkg_dir, build_cmd=build_py):
327 """ Return extended build command class for recording commit
326 """ Return extended build command class for recording commit
328
327
329 The extended command tries to run git to find the current commit, getting
328 The extended command tries to run git to find the current commit, getting
330 the empty string if it fails. It then writes the commit hash into a file
329 the empty string if it fails. It then writes the commit hash into a file
331 in the `pkg_dir` path, named ``.git_commit_info.ini``.
330 in the `pkg_dir` path, named ``.git_commit_info.ini``.
332
331
333 In due course this information can be used by the package after it is
332 In due course this information can be used by the package after it is
334 installed, to tell you what commit it was installed from if known.
333 installed, to tell you what commit it was installed from if known.
335
334
336 To make use of this system, you need a package with a .git_commit_info.ini
335 To make use of this system, you need a package with a .git_commit_info.ini
337 file - e.g. ``myproject/.git_commit_info.ini`` - that might well look like
336 file - e.g. ``myproject/.git_commit_info.ini`` - that might well look like
338 this::
337 this::
339
338
340 # This is an ini file that may contain information about the code state
339 # This is an ini file that may contain information about the code state
341 [commit hash]
340 [commit hash]
342 # The line below may contain a valid hash if it has been substituted
341 # The line below may contain a valid hash if it has been substituted
343 # during 'git archive'
342 # during 'git archive'
344 archive_subst_hash=$Format:%h$
343 archive_subst_hash=$Format:%h$
345 # This line may be modified by the install process
344 # This line may be modified by the install process
346 install_hash=
345 install_hash=
347
346
348 The .git_commit_info file above is also designed to be used with git
347 The .git_commit_info file above is also designed to be used with git
349 substitution - so you probably also want a ``.gitattributes`` file in the
348 substitution - so you probably also want a ``.gitattributes`` file in the
350 root directory of your working tree that contains something like this::
349 root directory of your working tree that contains something like this::
351
350
352 myproject/.git_commit_info.ini export-subst
351 myproject/.git_commit_info.ini export-subst
353
352
354 That will cause the ``.git_commit_info.ini`` file to get filled in by ``git
353 That will cause the ``.git_commit_info.ini`` file to get filled in by ``git
355 archive`` - useful in case someone makes such an archive - for example with
354 archive`` - useful in case someone makes such an archive - for example with
356 via the github 'download source' button.
355 via the github 'download source' button.
357
356
358 Although all the above will work as is, you might consider having something
357 Although all the above will work as is, you might consider having something
359 like a ``get_info()`` function in your package to display the commit
358 like a ``get_info()`` function in your package to display the commit
360 information at the terminal. See the ``pkg_info.py`` module in the nipy
359 information at the terminal. See the ``pkg_info.py`` module in the nipy
361 package for an example.
360 package for an example.
362 """
361 """
363 class MyBuildPy(build_cmd):
362 class MyBuildPy(build_cmd):
364 ''' Subclass to write commit data into installation tree '''
363 ''' Subclass to write commit data into installation tree '''
365 def run(self):
364 def run(self):
366 build_py.run(self)
365 build_py.run(self)
367 import subprocess
366 import subprocess
368 proc = subprocess.Popen('git rev-parse --short HEAD',
367 proc = subprocess.Popen('git rev-parse --short HEAD',
369 stdout=subprocess.PIPE,
368 stdout=subprocess.PIPE,
370 stderr=subprocess.PIPE,
369 stderr=subprocess.PIPE,
371 shell=True)
370 shell=True)
372 repo_commit, _ = proc.communicate()
371 repo_commit, _ = proc.communicate()
373 # We write the installation commit even if it's empty
372 # We write the installation commit even if it's empty
374 cfg_parser = ConfigParser()
373 cfg_parser = ConfigParser()
375 cfg_parser.read(pjoin(pkg_dir, '.git_commit_info.ini'))
374 cfg_parser.read(pjoin(pkg_dir, '.git_commit_info.ini'))
376 cfg_parser.set('commit hash', 'install_hash', repo_commit)
375 cfg_parser.set('commit hash', 'install_hash', repo_commit)
377 out_pth = pjoin(self.build_lib, pkg_dir, '.git_commit_info.ini')
376 out_pth = pjoin(self.build_lib, pkg_dir, '.git_commit_info.ini')
378 out_file = open(out_pth, 'wt')
377 out_file = open(out_pth, 'wt')
379 cfg_parser.write(out_file)
378 cfg_parser.write(out_file)
380 out_file.close()
379 out_file.close()
381 return MyBuildPy
380 return MyBuildPy
1 NO CONTENT: file was removed
NO CONTENT: file was removed
General Comments 0
You need to be logged in to leave comments. Login now