Show More
@@ -0,0 +1,33 b'' | |||||
|
1 | """Simple example using doctests. | |||
|
2 | ||||
|
3 | This file just contains doctests both using plain python and IPython prompts. | |||
|
4 | All tests should be loaded by nose. | |||
|
5 | """ | |||
|
6 | ||||
|
7 | def pyfunc(): | |||
|
8 | """Some pure python tests... | |||
|
9 | ||||
|
10 | >>> pyfunc() | |||
|
11 | 'pyfunc' | |||
|
12 | ||||
|
13 | >>> import os | |||
|
14 | ||||
|
15 | >>> 2+3 | |||
|
16 | 5 | |||
|
17 | ||||
|
18 | >>> for i in range(3): | |||
|
19 | ... print i, | |||
|
20 | ... print i+1, | |||
|
21 | ... | |||
|
22 | 0 1 1 2 2 3 | |||
|
23 | """ | |||
|
24 | return 'pyfunc' | |||
|
25 | ||||
|
26 | ||||
|
27 | def ipyfunc2(): | |||
|
28 | """Some pure python tests... | |||
|
29 | ||||
|
30 | >>> 1+1 | |||
|
31 | 2 | |||
|
32 | """ | |||
|
33 | return 'pyfunc2' |
@@ -318,6 +318,9 b' def cd_completer(self, event):' | |||||
318 | return ents |
|
318 | return ents | |
319 | return [] |
|
319 | return [] | |
320 |
|
320 | |||
|
321 | if event.symbol.startswith('--'): | |||
|
322 | return ["--" + os.path.basename(d) for d in ip.user_ns['_dh']] | |||
|
323 | ||||
321 | if relpath.startswith('~'): |
|
324 | if relpath.startswith('~'): | |
322 | relpath = os.path.expanduser(relpath).replace('\\','/') |
|
325 | relpath = os.path.expanduser(relpath).replace('\\','/') | |
323 | found = [] |
|
326 | found = [] |
@@ -12,6 +12,8 b' from IPython.ipapi import TryNext' | |||||
12 | import IPython.macro |
|
12 | import IPython.macro | |
13 | import IPython.Shell |
|
13 | import IPython.Shell | |
14 |
|
14 | |||
|
15 | _leo_push_history = set() | |||
|
16 | ||||
15 | def init_ipython(ipy): |
|
17 | def init_ipython(ipy): | |
16 | """ This will be run by _ip.load('ipy_leo') |
|
18 | """ This will be run by _ip.load('ipy_leo') | |
17 |
|
19 | |||
@@ -25,17 +27,21 b' def init_ipython(ipy):' | |||||
25 | ip.expose_magic('mb',mb_f) |
|
27 | ip.expose_magic('mb',mb_f) | |
26 | ip.expose_magic('lee',lee_f) |
|
28 | ip.expose_magic('lee',lee_f) | |
27 | ip.expose_magic('leoref',leoref_f) |
|
29 | ip.expose_magic('leoref',leoref_f) | |
|
30 | ip.expose_magic('lleo',lleo_f) | |||
|
31 | # Note that no other push command should EVER have lower than 0 | |||
|
32 | expose_ileo_push(push_mark_req, -1) | |||
28 | expose_ileo_push(push_cl_node,100) |
|
33 | expose_ileo_push(push_cl_node,100) | |
29 | # this should be the LAST one that will be executed, and it will never raise TryNext |
|
34 | # this should be the LAST one that will be executed, and it will never raise TryNext | |
30 | expose_ileo_push(push_ipython_script, 1000) |
|
35 | expose_ileo_push(push_ipython_script, 1000) | |
31 | expose_ileo_push(push_plain_python, 100) |
|
36 | expose_ileo_push(push_plain_python, 100) | |
32 | expose_ileo_push(push_ev_node, 100) |
|
37 | expose_ileo_push(push_ev_node, 100) | |
|
38 | ip.set_hook('pre_prompt_hook', ileo_pre_prompt_hook) | |||
33 | global wb |
|
39 | global wb | |
34 | wb = LeoWorkbook() |
|
40 | wb = LeoWorkbook() | |
35 | ip.user_ns['wb'] = wb |
|
41 | ip.user_ns['wb'] = wb | |
36 |
|
42 | |||
37 | show_welcome() |
|
|||
38 |
|
43 | |||
|
44 | first_launch = True | |||
39 |
|
45 | |||
40 | def update_commander(new_leox): |
|
46 | def update_commander(new_leox): | |
41 | """ Set the Leo commander to use |
|
47 | """ Set the Leo commander to use | |
@@ -45,7 +51,12 b' def update_commander(new_leox):' | |||||
45 | ipython-launch to tell ILeo what document the commands apply to. |
|
51 | ipython-launch to tell ILeo what document the commands apply to. | |
46 |
|
52 | |||
47 | """ |
|
53 | """ | |
48 |
|
54 | |||
|
55 | global first_launch | |||
|
56 | if first_launch: | |||
|
57 | show_welcome() | |||
|
58 | first_launch = False | |||
|
59 | ||||
49 | global c,g |
|
60 | global c,g | |
50 | c,g = new_leox.c, new_leox.g |
|
61 | c,g = new_leox.c, new_leox.g | |
51 | print "Set Leo Commander:",c.frame.getTitle() |
|
62 | print "Set Leo Commander:",c.frame.getTitle() | |
@@ -70,9 +81,10 b' def format_for_leo(obj):' | |||||
70 | """ Convert obj to string representiation (for editing in Leo)""" |
|
81 | """ Convert obj to string representiation (for editing in Leo)""" | |
71 | return pprint.pformat(obj) |
|
82 | return pprint.pformat(obj) | |
72 |
|
83 | |||
73 | @format_for_leo.when_type(list) |
|
84 | # Just an example - note that this is a bad to actually do! | |
74 | def format_list(obj): |
|
85 | #@format_for_leo.when_type(list) | |
75 | return "\n".join(str(s) for s in obj) |
|
86 | #def format_list(obj): | |
|
87 | # return "\n".join(str(s) for s in obj) | |||
76 |
|
88 | |||
77 |
|
89 | |||
78 | attribute_re = re.compile('^[a-zA-Z_][a-zA-Z0-9_]*$') |
|
90 | attribute_re = re.compile('^[a-zA-Z_][a-zA-Z0-9_]*$') | |
@@ -175,6 +187,7 b' class LeoNode(object, UserDict.DictMixin):' | |||||
175 | def __get_h(self): return self.p.headString() |
|
187 | def __get_h(self): return self.p.headString() | |
176 | def __set_h(self,val): |
|
188 | def __set_h(self,val): | |
177 | c.setHeadString(self.p,val) |
|
189 | c.setHeadString(self.p,val) | |
|
190 | LeoNode.last_edited = self | |||
178 | c.redraw() |
|
191 | c.redraw() | |
179 |
|
192 | |||
180 | h = property( __get_h, __set_h, doc = "Node headline string") |
|
193 | h = property( __get_h, __set_h, doc = "Node headline string") | |
@@ -182,6 +195,7 b' class LeoNode(object, UserDict.DictMixin):' | |||||
182 | def __get_b(self): return self.p.bodyString() |
|
195 | def __get_b(self): return self.p.bodyString() | |
183 | def __set_b(self,val): |
|
196 | def __set_b(self,val): | |
184 | c.setBodyString(self.p, val) |
|
197 | c.setBodyString(self.p, val) | |
|
198 | LeoNode.last_edited = self | |||
185 | c.redraw() |
|
199 | c.redraw() | |
186 |
|
200 | |||
187 | b = property(__get_b, __set_b, doc = "Nody body string") |
|
201 | b = property(__get_b, __set_b, doc = "Nody body string") | |
@@ -251,6 +265,14 b' class LeoNode(object, UserDict.DictMixin):' | |||||
251 | p = c.createLastChildNode(self.p, head, '') |
|
265 | p = c.createLastChildNode(self.p, head, '') | |
252 | LeoNode(p).v = val |
|
266 | LeoNode(p).v = val | |
253 |
|
267 | |||
|
268 | def __delitem__(self, key): | |||
|
269 | """ Remove child | |||
|
270 | ||||
|
271 | Allows stuff like wb.foo.clear() to remove all children | |||
|
272 | """ | |||
|
273 | self[key].p.doDelete() | |||
|
274 | c.redraw() | |||
|
275 | ||||
254 | def ipush(self): |
|
276 | def ipush(self): | |
255 | """ Does push-to-ipython on the node """ |
|
277 | """ Does push-to-ipython on the node """ | |
256 | push_from_leo(self) |
|
278 | push_from_leo(self) | |
@@ -260,6 +282,12 b' class LeoNode(object, UserDict.DictMixin):' | |||||
260 | c.setCurrentPosition(self.p) |
|
282 | c.setCurrentPosition(self.p) | |
261 | c.redraw() |
|
283 | c.redraw() | |
262 |
|
284 | |||
|
285 | def append(self): | |||
|
286 | """ Add new node as the last child, return the new node """ | |||
|
287 | p = self.p.insertAsLastChild() | |||
|
288 | return LeoNode(p) | |||
|
289 | ||||
|
290 | ||||
263 | def script(self): |
|
291 | def script(self): | |
264 | """ Method to get the 'tangled' contents of the node |
|
292 | """ Method to get the 'tangled' contents of the node | |
265 |
|
293 | |||
@@ -319,6 +347,19 b' class LeoWorkbook:' | |||||
319 | if re.match(cmp, node.h, re.IGNORECASE): |
|
347 | if re.match(cmp, node.h, re.IGNORECASE): | |
320 | yield node |
|
348 | yield node | |
321 | return |
|
349 | return | |
|
350 | ||||
|
351 | def require(self, req): | |||
|
352 | """ Used to control node push dependencies | |||
|
353 | ||||
|
354 | Call this as first statement in nodes. If node has not been pushed, it will be pushed before proceeding | |||
|
355 | ||||
|
356 | E.g. wb.require('foo') will do wb.foo.ipush() if it hasn't been done already | |||
|
357 | """ | |||
|
358 | ||||
|
359 | if req not in _leo_push_history: | |||
|
360 | es('Require: ' + req) | |||
|
361 | getattr(self,req).ipush() | |||
|
362 | ||||
322 |
|
363 | |||
323 | @IPython.generics.complete_object.when_type(LeoWorkbook) |
|
364 | @IPython.generics.complete_object.when_type(LeoWorkbook) | |
324 | def workbook_complete(obj, prev): |
|
365 | def workbook_complete(obj, prev): | |
@@ -361,9 +402,13 b' def push_ipython_script(node):' | |||||
361 | hstart = len(ip.IP.input_hist) |
|
402 | hstart = len(ip.IP.input_hist) | |
362 | script = node.script() |
|
403 | script = node.script() | |
363 |
|
404 | |||
|
405 | # The current node _p needs to handle wb.require() and recursive ipushes | |||
|
406 | old_p = ip.user_ns.get('_p',None) | |||
364 | ip.user_ns['_p'] = node |
|
407 | ip.user_ns['_p'] = node | |
365 | ip.runlines(script) |
|
408 | ip.runlines(script) | |
366 |
ip.user_ns |
|
409 | ip.user_ns['_p'] = old_p | |
|
410 | if old_p is None: | |||
|
411 | del ip.user_ns['_p'] | |||
367 |
|
412 | |||
368 | has_output = False |
|
413 | has_output = False | |
369 | for idx in range(hstart,len(ip.IP.input_hist)): |
|
414 | for idx in range(hstart,len(ip.IP.input_hist)): | |
@@ -428,6 +473,14 b' def push_ev_node(node):' | |||||
428 | res = ip.ev(expr) |
|
473 | res = ip.ev(expr) | |
429 | node.v = res |
|
474 | node.v = res | |
430 |
|
475 | |||
|
476 | def push_mark_req(node): | |||
|
477 | """ This should be the first one that gets called. | |||
|
478 | ||||
|
479 | It will mark the node as 'pushed', for wb.require. | |||
|
480 | """ | |||
|
481 | _leo_push_history.add(node.h) | |||
|
482 | raise TryNext | |||
|
483 | ||||
431 |
|
484 | |||
432 | def push_position_from_leo(p): |
|
485 | def push_position_from_leo(p): | |
433 | try: |
|
486 | try: | |
@@ -521,13 +574,12 b' def lee_f(self,s):' | |||||
521 | finally: |
|
574 | finally: | |
522 | c.redraw() |
|
575 | c.redraw() | |
523 |
|
576 | |||
524 |
|
||||
525 |
|
||||
526 | def leoref_f(self,s): |
|
577 | def leoref_f(self,s): | |
527 | """ Quick reference for ILeo """ |
|
578 | """ Quick reference for ILeo """ | |
528 | import textwrap |
|
579 | import textwrap | |
529 | print textwrap.dedent("""\ |
|
580 | print textwrap.dedent("""\ | |
530 |
%le |
|
581 | %lee file/object - open file / object in leo | |
|
582 | %lleo Launch leo (use if you started ipython first!) | |||
531 | wb.foo.v - eval node foo (i.e. headstring is 'foo' or '@ipy foo') |
|
583 | wb.foo.v - eval node foo (i.e. headstring is 'foo' or '@ipy foo') | |
532 | wb.foo.v = 12 - assign to body of node foo |
|
584 | wb.foo.v = 12 - assign to body of node foo | |
533 | wb.foo.b - read or write the body of node foo |
|
585 | wb.foo.b - read or write the body of node foo | |
@@ -560,6 +612,16 b' def mb_completer(self,event):' | |||||
560 | cmds.sort() |
|
612 | cmds.sort() | |
561 | return cmds |
|
613 | return cmds | |
562 |
|
614 | |||
|
615 | def ileo_pre_prompt_hook(self): | |||
|
616 | # this will fail if leo is not running yet | |||
|
617 | try: | |||
|
618 | c.outerUpdate() | |||
|
619 | except NameError: | |||
|
620 | pass | |||
|
621 | raise TryNext | |||
|
622 | ||||
|
623 | ||||
|
624 | ||||
563 | def show_welcome(): |
|
625 | def show_welcome(): | |
564 | print "------------------" |
|
626 | print "------------------" | |
565 | print "Welcome to Leo-enabled IPython session!" |
|
627 | print "Welcome to Leo-enabled IPython session!" | |
@@ -574,5 +636,25 b' def run_leo_startup_node():' | |||||
574 | print "Running @ipy-startup nodes" |
|
636 | print "Running @ipy-startup nodes" | |
575 | for n in LeoNode(p): |
|
637 | for n in LeoNode(p): | |
576 | push_from_leo(n) |
|
638 | push_from_leo(n) | |
577 |
|
||||
578 |
|
639 | |||
|
640 | def lleo_f(selg, args): | |||
|
641 | """ Launch leo from within IPython | |||
|
642 | ||||
|
643 | This command will return immediately when Leo has been | |||
|
644 | launched, leaving a Leo session that is connected | |||
|
645 | with current IPython session (once you press alt+I in leo) | |||
|
646 | ||||
|
647 | Usage:: | |||
|
648 | lleo foo.leo | |||
|
649 | lleo | |||
|
650 | """ | |||
|
651 | ||||
|
652 | import shlex, sys | |||
|
653 | argv = ['leo'] + shlex.split(args) | |||
|
654 | sys.argv = argv | |||
|
655 | # if this var exists and is true, leo will "launch" (connect) | |||
|
656 | # ipython immediately when it's started | |||
|
657 | global _request_immediate_connect | |||
|
658 | _request_immediate_connect = True | |||
|
659 | import leo.core.runLeo | |||
|
660 | leo.core.runLeo.run() |
@@ -193,7 +193,7 b' which already exists. But you must first start the logging process with' | |||||
193 | try: |
|
193 | try: | |
194 | input_hist = self.shell.user_ns['_ih'] |
|
194 | input_hist = self.shell.user_ns['_ih'] | |
195 | except: |
|
195 | except: | |
196 | print 'userns:',self.shell.user_ns.keys() |
|
196 | #print 'userns:',self.shell.user_ns.keys() # dbg | |
197 | return |
|
197 | return | |
198 |
|
198 | |||
199 | out_cache = self.shell.outputcache |
|
199 | out_cache = self.shell.outputcache |
@@ -2693,6 +2693,8 b' Defaulting color scheme to \'NoColor\'"""' | |||||
2693 |
|
2693 | |||
2694 | cd -<n>: changes to the n-th directory in the directory history. |
|
2694 | cd -<n>: changes to the n-th directory in the directory history. | |
2695 |
|
2695 | |||
|
2696 | cd --foo: change to directory that matches 'foo' in history | |||
|
2697 | ||||
2696 | cd -b <bookmark_name>: jump to a bookmark set by %bookmark |
|
2698 | cd -b <bookmark_name>: jump to a bookmark set by %bookmark | |
2697 | (note: cd <bookmark_name> is enough if there is no |
|
2699 | (note: cd <bookmark_name> is enough if there is no | |
2698 | directory <bookmark_name>, but a bookmark with the name exists.) |
|
2700 | directory <bookmark_name>, but a bookmark with the name exists.) | |
@@ -2722,6 +2724,31 b' Defaulting color scheme to \'NoColor\'"""' | |||||
2722 | return |
|
2724 | return | |
2723 | else: |
|
2725 | else: | |
2724 | opts = {} |
|
2726 | opts = {} | |
|
2727 | elif parameter_s.startswith('--'): | |||
|
2728 | ps = None | |||
|
2729 | fallback = None | |||
|
2730 | pat = parameter_s[2:] | |||
|
2731 | dh = self.shell.user_ns['_dh'] | |||
|
2732 | # first search only by basename (last component) | |||
|
2733 | for ent in reversed(dh): | |||
|
2734 | if pat in os.path.basename(ent) and os.path.isdir(ent): | |||
|
2735 | ps = ent | |||
|
2736 | break | |||
|
2737 | ||||
|
2738 | if fallback is None and pat in ent and os.path.isdir(ent): | |||
|
2739 | fallback = ent | |||
|
2740 | ||||
|
2741 | # if we have no last part match, pick the first full path match | |||
|
2742 | if ps is None: | |||
|
2743 | ps = fallback | |||
|
2744 | ||||
|
2745 | if ps is None: | |||
|
2746 | print "No matching entry in directory history" | |||
|
2747 | return | |||
|
2748 | else: | |||
|
2749 | opts = {} | |||
|
2750 | ||||
|
2751 | ||||
2725 | else: |
|
2752 | else: | |
2726 | #turn all non-space-escaping backslashes to slashes, |
|
2753 | #turn all non-space-escaping backslashes to slashes, | |
2727 | # for c:\windows\directory\names\ |
|
2754 | # for c:\windows\directory\names\ |
@@ -22,10 +22,10 b" name = 'ipython'" | |||||
22 | # because bdist_rpm does not accept dashes (an RPM) convention, and |
|
22 | # because bdist_rpm does not accept dashes (an RPM) convention, and | |
23 | # bdist_deb does not accept underscores (a Debian convention). |
|
23 | # bdist_deb does not accept underscores (a Debian convention). | |
24 |
|
24 | |||
25 |
development = |
|
25 | development = False # change this to False to do a release | |
26 |
version_base = '0.9. |
|
26 | version_base = '0.9.beta' | |
27 | branch = 'ipython' |
|
27 | branch = 'ipython' | |
28 |
revision = '10 |
|
28 | revision = '1099' | |
29 |
|
29 | |||
30 | if development: |
|
30 | if development: | |
31 | if branch == 'ipython': |
|
31 | if branch == 'ipython': |
@@ -1009,7 +1009,7 b' class InteractiveShell(object,Magic):' | |||||
1009 | hello |
|
1009 | hello | |
1010 |
|
1010 | |||
1011 | In [10]: _ip.IP.complete('x.l') |
|
1011 | In [10]: _ip.IP.complete('x.l') | |
1012 |
Out[10]: ['x.ljust', 'x.lower', 'x.lstrip'] |
|
1012 | Out[10]: ['x.ljust', 'x.lower', 'x.lstrip'] | |
1013 | """ |
|
1013 | """ | |
1014 |
|
1014 | |||
1015 | complete = self.Completer.complete |
|
1015 | complete = self.Completer.complete |
@@ -128,8 +128,9 b' class IEngineCoreTestCase(object):' | |||||
128 | return d |
|
128 | return d | |
129 |
|
129 | |||
130 | @parametric |
|
130 | @parametric | |
131 | def testExecuteFailures(cls): |
|
131 | def testExecuteFailuresEngineService(cls): | |
132 |
return [(cls.runTestExecuteFailures, cmd, exc) |
|
132 | return [(cls.runTestExecuteFailures, cmd, exc) | |
|
133 | for cmd, exc in invalidCommands] | |||
133 |
|
134 | |||
134 | def runTestPushPull(self, o): |
|
135 | def runTestPushPull(self, o): | |
135 | d = self.engine.push(dict(a=o)) |
|
136 | d = self.engine.push(dict(a=o)) |
@@ -187,7 +187,7 b' class IMultiEngineTestCase(IMultiEngineBaseTestCase):' | |||||
187 | return d |
|
187 | return d | |
188 |
|
188 | |||
189 | @parametric |
|
189 | @parametric | |
190 | def testExecuteFailures(cls): |
|
190 | def testExecuteFailuresMultiEng(cls): | |
191 | return [(cls.runExecuteFailures,cmd,exc) for |
|
191 | return [(cls.runExecuteFailures,cmd,exc) for | |
192 | cmd,exc in invalidCommands] |
|
192 | cmd,exc in invalidCommands] | |
193 |
|
193 |
@@ -3,49 +3,70 b' PREFIX=~/usr/local' | |||||
3 | PREFIX=~/tmp/local |
|
3 | PREFIX=~/tmp/local | |
4 |
|
4 | |||
5 | NOSE0=nosetests -vs --with-doctest --doctest-tests --detailed-errors |
|
5 | NOSE0=nosetests -vs --with-doctest --doctest-tests --detailed-errors | |
6 |
NOSE=nosetests -vvs --with-ipdoctest --doctest-tests --doctest-extension=txt |
|
6 | NOSE=nosetests -vvs --with-ipdoctest --doctest-tests --doctest-extension=txt \ | |
7 |
|
7 | --detailed-errors | ||
8 | #--with-color |
|
|||
9 |
|
|
8 | ||
10 | SRC=ipdoctest.py setup.py ../decorators.py |
|
9 | SRC=ipdoctest.py setup.py ../decorators.py | |
11 |
|
10 | |||
|
11 | # Default target for clean 'make' | |||
|
12 | default: iplib | |||
|
13 | ||||
|
14 | # The actual plugin installation | |||
12 | plugin: IPython_doctest_plugin.egg-info |
|
15 | plugin: IPython_doctest_plugin.egg-info | |
13 |
|
16 | |||
|
17 | # Simple targets that test one thing | |||
|
18 | simple: plugin simple.py | |||
|
19 | $(NOSE) simple.py | |||
|
20 | ||||
14 | dtest: plugin dtexample.py |
|
21 | dtest: plugin dtexample.py | |
15 | $(NOSE) dtexample.py |
|
22 | $(NOSE) dtexample.py | |
16 |
|
23 | |||
17 | # Note: this test is double counting!!! |
|
24 | rtest: plugin test_refs.py | |
18 | rtest: plugin dtexample.py |
|
|||
19 | $(NOSE) test_refs.py |
|
25 | $(NOSE) test_refs.py | |
20 |
|
26 | |||
21 | std: plugin |
|
|||
22 | nosetests -vs --with-doctest --doctest-tests IPython.strdispatch |
|
|||
23 | $(NOSE) IPython.strdispatch |
|
|||
24 |
|
||||
25 | test: plugin dtexample.py |
|
27 | test: plugin dtexample.py | |
26 | $(NOSE) dtexample.py test*.py test*.txt |
|
28 | $(NOSE) dtexample.py test*.py test*.txt | |
27 |
|
29 | |||
28 | deb: plugin dtexample.py |
|
30 | deb: plugin dtexample.py | |
29 | $(NOSE) test_combo.txt |
|
31 | $(NOSE) test_combo.txt | |
30 |
|
32 | |||
31 | iptest: plugin |
|
33 | # IPython tests | |
32 | $(NOSE) IPython |
|
|||
33 |
|
||||
34 | deco: |
|
34 | deco: | |
35 | $(NOSE0) IPython.testing.decorators |
|
35 | $(NOSE0) IPython.testing.decorators | |
36 |
|
36 | |||
37 |
m |
|
37 | magic: plugin | |
38 |
$(NOSE) |
|
38 | $(NOSE) IPython.Magic | |
39 |
|
39 | |||
40 | ipipe: plugin |
|
40 | ipipe: plugin | |
41 |
$(NOSE) |
|
41 | $(NOSE) IPython.Extensions.ipipe | |
|
42 | ||||
|
43 | iplib: plugin | |||
|
44 | $(NOSE) IPython.iplib | |||
|
45 | ||||
|
46 | strd: plugin | |||
|
47 | $(NOSE) IPython.strdispatch | |||
|
48 | ||||
|
49 | engine: plugin | |||
|
50 | $(NOSE) IPython.kernel | |||
|
51 | ||||
|
52 | tf: plugin | |||
|
53 | $(NOSE) IPython.config.traitlets | |||
|
54 | ||||
|
55 | # All of ipython itself | |||
|
56 | ipython: plugin | |||
|
57 | $(NOSE) IPython | |||
|
58 | ||||
|
59 | ||||
|
60 | # Combined targets | |||
|
61 | sr: rtest strd | |||
42 |
|
62 | |||
43 | sr: rtest std |
|
63 | base: dtest rtest test strd deco | |
44 |
|
64 | |||
45 | base: dtest rtest test std deco |
|
65 | quick: base iplib ipipe | |
46 |
|
66 | |||
47 |
all: base ip |
|
67 | all: base ipython | |
48 |
|
68 | |||
|
69 | # Main plugin and cleanup | |||
49 | IPython_doctest_plugin.egg-info: $(SRC) |
|
70 | IPython_doctest_plugin.egg-info: $(SRC) | |
50 | python setup.py install --prefix=$(PREFIX) |
|
71 | python setup.py install --prefix=$(PREFIX) | |
51 | touch $@ |
|
72 | touch $@ |
@@ -58,6 +58,12 b' def ipfunc():' | |||||
58 | numbered history of _NN outputs, since those won't exist under the |
|
58 | numbered history of _NN outputs, since those won't exist under the | |
59 | doctest environment: |
|
59 | doctest environment: | |
60 |
|
60 | |||
|
61 | In [7]: 'hi' | |||
|
62 | Out[7]: 'hi' | |||
|
63 | ||||
|
64 | In [8]: print repr(_) | |||
|
65 | 'hi' | |||
|
66 | ||||
61 | In [7]: 3+4 |
|
67 | In [7]: 3+4 | |
62 | Out[7]: 7 |
|
68 | Out[7]: 7 | |
63 |
|
69 |
@@ -13,21 +13,6 b' Limitations:' | |||||
13 | '_34==True', for example). For IPython tests run via an external process the |
|
13 | '_34==True', for example). For IPython tests run via an external process the | |
14 | prompt numbers may be different, and IPython tests run as normal python code |
|
14 | prompt numbers may be different, and IPython tests run as normal python code | |
15 | won't even have these special _NN variables set at all. |
|
15 | won't even have these special _NN variables set at all. | |
16 |
|
||||
17 | - IPython functions that produce output as a side-effect of calling a system |
|
|||
18 | process (e.g. 'ls') can be doc-tested, but they must be handled in an |
|
|||
19 | external IPython process. Such doctests must be tagged with: |
|
|||
20 |
|
||||
21 | # ipdoctest: EXTERNAL |
|
|||
22 |
|
||||
23 | so that the testing machinery handles them differently. Since these are run |
|
|||
24 | via pexpect in an external process, they can't deal with exceptions or other |
|
|||
25 | fancy featurs of regular doctests. You must limit such tests to simple |
|
|||
26 | matching of the output. For this reason, I recommend you limit these kinds |
|
|||
27 | of doctests to features that truly require a separate process, and use the |
|
|||
28 | normal IPython ones (which have all the features of normal doctests) for |
|
|||
29 | everything else. See the examples at the bottom of this file for a |
|
|||
30 | comparison of what can be done with both types. |
|
|||
31 | """ |
|
16 | """ | |
32 |
|
17 | |||
33 |
|
18 | |||
@@ -63,9 +48,6 b' import nose.core' | |||||
63 | from nose.plugins import doctests, Plugin |
|
48 | from nose.plugins import doctests, Plugin | |
64 | from nose.util import anyp, getpackage, test_address, resolve_name, tolist |
|
49 | from nose.util import anyp, getpackage, test_address, resolve_name, tolist | |
65 |
|
50 | |||
66 | # Our own imports |
|
|||
67 | #from extdoctest import ExtensionDoctest, DocTestFinder |
|
|||
68 | #from dttools import DocTestFinder, DocTestCase |
|
|||
69 | #----------------------------------------------------------------------------- |
|
51 | #----------------------------------------------------------------------------- | |
70 | # Module globals and other constants |
|
52 | # Module globals and other constants | |
71 |
|
53 | |||
@@ -79,9 +61,9 b' log = logging.getLogger(__name__)' | |||||
79 | # gets the job done. |
|
61 | # gets the job done. | |
80 |
|
62 | |||
81 |
|
63 | |||
82 |
# |
|
64 | # Hack to modify the %run command so we can sync the user's namespace with the | |
83 |
# |
|
65 | # test globals. Once we move over to a clean magic system, this will be done | |
84 |
# |
|
66 | # with much less ugliness. | |
85 |
|
67 | |||
86 | def _run_ns_sync(self,arg_s,runner=None): |
|
68 | def _run_ns_sync(self,arg_s,runner=None): | |
87 | """Modified version of %run that syncs testing namespaces. |
|
69 | """Modified version of %run that syncs testing namespaces. | |
@@ -94,6 +76,35 b' def _run_ns_sync(self,arg_s,runner=None):' | |||||
94 | return out |
|
76 | return out | |
95 |
|
77 | |||
96 |
|
78 | |||
|
79 | class ipnsdict(dict): | |||
|
80 | """A special subclass of dict for use as an IPython namespace in doctests. | |||
|
81 | ||||
|
82 | This subclass adds a simple checkpointing capability so that when testing | |||
|
83 | machinery clears it (we use it as the test execution context), it doesn't | |||
|
84 | get completely destroyed. | |||
|
85 | """ | |||
|
86 | ||||
|
87 | def __init__(self,*a): | |||
|
88 | dict.__init__(self,*a) | |||
|
89 | self._savedict = {} | |||
|
90 | ||||
|
91 | def clear(self): | |||
|
92 | dict.clear(self) | |||
|
93 | self.update(self._savedict) | |||
|
94 | ||||
|
95 | def _checkpoint(self): | |||
|
96 | self._savedict.clear() | |||
|
97 | self._savedict.update(self) | |||
|
98 | ||||
|
99 | def update(self,other): | |||
|
100 | self._checkpoint() | |||
|
101 | dict.update(self,other) | |||
|
102 | # If '_' is in the namespace, python won't set it when executing code, | |||
|
103 | # and we have examples that test it. So we ensure that the namespace | |||
|
104 | # is always 'clean' of it before it's used for test code execution. | |||
|
105 | self.pop('_',None) | |||
|
106 | ||||
|
107 | ||||
97 | def start_ipython(): |
|
108 | def start_ipython(): | |
98 | """Start a global IPython shell, which we need for IPython-specific syntax. |
|
109 | """Start a global IPython shell, which we need for IPython-specific syntax. | |
99 | """ |
|
110 | """ | |
@@ -117,7 +128,10 b' def start_ipython():' | |||||
117 | _main = sys.modules.get('__main__') |
|
128 | _main = sys.modules.get('__main__') | |
118 |
|
129 | |||
119 | # Start IPython instance. We customize it to start with minimal frills. |
|
130 | # Start IPython instance. We customize it to start with minimal frills. | |
120 | IPython.Shell.IPShell(['--classic','--noterm_title']) |
|
131 | user_ns,global_ns = IPython.ipapi.make_user_namespaces(ipnsdict(),dict()) | |
|
132 | ||||
|
133 | IPython.Shell.IPShell(['--classic','--noterm_title'], | |||
|
134 | user_ns,global_ns) | |||
121 |
|
135 | |||
122 | # Deactivate the various python system hooks added by ipython for |
|
136 | # Deactivate the various python system hooks added by ipython for | |
123 | # interactive convenience so we don't confuse the doctest system |
|
137 | # interactive convenience so we don't confuse the doctest system | |
@@ -257,7 +271,7 b' class IPDoctestOutputChecker(doctest.OutputChecker):' | |||||
257 | output string for flags that tell us to ignore the output. |
|
271 | output string for flags that tell us to ignore the output. | |
258 | """ |
|
272 | """ | |
259 |
|
273 | |||
260 | random_re = re.compile(r'#\s*random') |
|
274 | random_re = re.compile(r'#\s*random\s+') | |
261 |
|
275 | |||
262 | def check_output(self, want, got, optionflags): |
|
276 | def check_output(self, want, got, optionflags): | |
263 | """Check output, accepting special markers embedded in the output. |
|
277 | """Check output, accepting special markers embedded in the output. | |
@@ -307,12 +321,20 b' class DocTestCase(doctests.DocTestCase):' | |||||
307 | self._dt_setUp = setUp |
|
321 | self._dt_setUp = setUp | |
308 | self._dt_tearDown = tearDown |
|
322 | self._dt_tearDown = tearDown | |
309 |
|
323 | |||
|
324 | # XXX - store this runner once in the object! | |||
|
325 | runner = IPDocTestRunner(optionflags=optionflags, | |||
|
326 | checker=checker, verbose=False) | |||
|
327 | self._dt_runner = runner | |||
|
328 | ||||
|
329 | ||||
310 | # Each doctest should remember what directory it was loaded from... |
|
330 | # Each doctest should remember what directory it was loaded from... | |
311 | self._ori_dir = os.getcwd() |
|
331 | self._ori_dir = os.getcwd() | |
312 |
|
332 | |||
313 | # Modified runTest from the default stdlib |
|
333 | # Modified runTest from the default stdlib | |
314 | def runTest(self): |
|
334 | def runTest(self): | |
315 | test = self._dt_test |
|
335 | test = self._dt_test | |
|
336 | runner = self._dt_runner | |||
|
337 | ||||
316 | old = sys.stdout |
|
338 | old = sys.stdout | |
317 | new = StringIO() |
|
339 | new = StringIO() | |
318 | optionflags = self._dt_optionflags |
|
340 | optionflags = self._dt_optionflags | |
@@ -322,9 +344,6 b' class DocTestCase(doctests.DocTestCase):' | |||||
322 | # so add the default reporting flags |
|
344 | # so add the default reporting flags | |
323 | optionflags |= _unittest_reportflags |
|
345 | optionflags |= _unittest_reportflags | |
324 |
|
346 | |||
325 | runner = IPDocTestRunner(optionflags=optionflags, |
|
|||
326 | checker=self._dt_checker, verbose=False) |
|
|||
327 |
|
||||
328 | try: |
|
347 | try: | |
329 | # Save our current directory and switch out to the one where the |
|
348 | # Save our current directory and switch out to the one where the | |
330 | # test was originally created, in case another doctest did a |
|
349 | # test was originally created, in case another doctest did a | |
@@ -333,8 +352,8 b' class DocTestCase(doctests.DocTestCase):' | |||||
333 | os.chdir(self._ori_dir) |
|
352 | os.chdir(self._ori_dir) | |
334 |
|
353 | |||
335 | runner.DIVIDER = "-"*70 |
|
354 | runner.DIVIDER = "-"*70 | |
336 | failures, tries = runner.run( |
|
355 | failures, tries = runner.run(test,out=new.write, | |
337 |
|
|
356 | clear_globs=False) | |
338 | finally: |
|
357 | finally: | |
339 | sys.stdout = old |
|
358 | sys.stdout = old | |
340 | os.chdir(curdir) |
|
359 | os.chdir(curdir) | |
@@ -342,6 +361,19 b' class DocTestCase(doctests.DocTestCase):' | |||||
342 | if failures: |
|
361 | if failures: | |
343 | raise self.failureException(self.format_failure(new.getvalue())) |
|
362 | raise self.failureException(self.format_failure(new.getvalue())) | |
344 |
|
363 | |||
|
364 | def setUp(self): | |||
|
365 | """Modified test setup that syncs with ipython namespace""" | |||
|
366 | ||||
|
367 | if isinstance(self._dt_test.examples[0],IPExample): | |||
|
368 | # for IPython examples *only*, we swap the globals with the ipython | |||
|
369 | # namespace, after updating it with the globals (which doctest | |||
|
370 | # fills with the necessary info from the module being tested). | |||
|
371 | _ip.IP.user_ns.update(self._dt_test.globs) | |||
|
372 | self._dt_test.globs = _ip.IP.user_ns | |||
|
373 | ||||
|
374 | doctests.DocTestCase.setUp(self) | |||
|
375 | ||||
|
376 | ||||
345 |
|
377 | |||
346 | # A simple subclassing of the original with a different class name, so we can |
|
378 | # A simple subclassing of the original with a different class name, so we can | |
347 | # distinguish and treat differently IPython examples from pure python ones. |
|
379 | # distinguish and treat differently IPython examples from pure python ones. | |
@@ -403,7 +435,7 b' class IPDocTestParser(doctest.DocTestParser):' | |||||
403 | # Mark a test as being fully random. In this case, we simply append the |
|
435 | # Mark a test as being fully random. In this case, we simply append the | |
404 | # random marker ('#random') to each individual example's output. This way |
|
436 | # random marker ('#random') to each individual example's output. This way | |
405 | # we don't need to modify any other code. |
|
437 | # we don't need to modify any other code. | |
406 | _RANDOM_TEST = re.compile(r'#\s*all-random') |
|
438 | _RANDOM_TEST = re.compile(r'#\s*all-random\s+') | |
407 |
|
439 | |||
408 | # Mark tests to be executed in an external process - currently unsupported. |
|
440 | # Mark tests to be executed in an external process - currently unsupported. | |
409 | _EXTERNAL_IP = re.compile(r'#\s*ipdoctest:\s*EXTERNAL') |
|
441 | _EXTERNAL_IP = re.compile(r'#\s*ipdoctest:\s*EXTERNAL') | |
@@ -438,6 +470,8 b' class IPDocTestParser(doctest.DocTestParser):' | |||||
438 | output = [] |
|
470 | output = [] | |
439 | charno, lineno = 0, 0 |
|
471 | charno, lineno = 0, 0 | |
440 |
|
472 | |||
|
473 | # We make 'all random' tests by adding the '# random' mark to every | |||
|
474 | # block of output in the test. | |||
441 | if self._RANDOM_TEST.search(string): |
|
475 | if self._RANDOM_TEST.search(string): | |
442 | random_marker = '\n# random' |
|
476 | random_marker = '\n# random' | |
443 | else: |
|
477 | else: | |
@@ -605,12 +639,6 b' class IPDocTestRunner(doctest.DocTestRunner,object):' | |||||
605 | # for all examples, most of which won't be calling %run anyway). |
|
639 | # for all examples, most of which won't be calling %run anyway). | |
606 | _run_ns_sync.test_globs = test.globs |
|
640 | _run_ns_sync.test_globs = test.globs | |
607 |
|
641 | |||
608 | # dbg |
|
|||
609 | ## print >> sys.stderr, "Test:",test |
|
|||
610 | ## for ex in test.examples: |
|
|||
611 | ## print >> sys.stderr, ex.source |
|
|||
612 | ## print >> sys.stderr, 'Want:\n',ex.want,'\n--' |
|
|||
613 |
|
||||
614 | return super(IPDocTestRunner,self).run(test, |
|
642 | return super(IPDocTestRunner,self).run(test, | |
615 | compileflags,out,clear_globs) |
|
643 | compileflags,out,clear_globs) | |
616 |
|
644 | |||
@@ -635,8 +663,10 b' class ExtensionDoctest(doctests.Doctest):' | |||||
635 | Plugin.configure(self, options, config) |
|
663 | Plugin.configure(self, options, config) | |
636 | self.doctest_tests = options.doctest_tests |
|
664 | self.doctest_tests = options.doctest_tests | |
637 | self.extension = tolist(options.doctestExtension) |
|
665 | self.extension = tolist(options.doctestExtension) | |
638 | self.finder = DocTestFinder() |
|
666 | ||
639 | self.parser = doctest.DocTestParser() |
|
667 | self.parser = doctest.DocTestParser() | |
|
668 | self.finder = DocTestFinder() | |||
|
669 | self.checker = IPDoctestOutputChecker() | |||
640 | self.globs = None |
|
670 | self.globs = None | |
641 | self.extraglobs = None |
|
671 | self.extraglobs = None | |
642 |
|
672 | |||
@@ -666,6 +696,9 b' class ExtensionDoctest(doctests.Doctest):' | |||||
666 | if not tests: |
|
696 | if not tests: | |
667 | return |
|
697 | return | |
668 |
|
698 | |||
|
699 | # always use whitespace and ellipsis options | |||
|
700 | optionflags = doctest.NORMALIZE_WHITESPACE | doctest.ELLIPSIS | |||
|
701 | ||||
669 | tests.sort() |
|
702 | tests.sort() | |
670 | module_file = module.__file__ |
|
703 | module_file = module.__file__ | |
671 | if module_file[-4:] in ('.pyc', '.pyo'): |
|
704 | if module_file[-4:] in ('.pyc', '.pyo'): | |
@@ -675,15 +708,11 b' class ExtensionDoctest(doctests.Doctest):' | |||||
675 | continue |
|
708 | continue | |
676 | if not test.filename: |
|
709 | if not test.filename: | |
677 | test.filename = module_file |
|
710 | test.filename = module_file | |
678 |
|
||||
679 | # xxx - checker and options may be ok instantiated once outside loop |
|
|||
680 | # always use whitespace and ellipsis options |
|
|||
681 | optionflags = doctest.NORMALIZE_WHITESPACE | doctest.ELLIPSIS |
|
|||
682 | checker = IPDoctestOutputChecker() |
|
|||
683 |
|
711 | |||
684 | yield DocTestCase(test, |
|
712 | yield DocTestCase(test, | |
685 | optionflags=optionflags, |
|
713 | optionflags=optionflags, | |
686 | checker=checker) |
|
714 | checker=self.checker) | |
|
715 | ||||
687 |
|
716 | |||
688 | def loadTestsFromFile(self, filename): |
|
717 | def loadTestsFromFile(self, filename): | |
689 | #print 'lTF',filename # dbg |
|
718 | #print 'lTF',filename # dbg | |
@@ -716,7 +745,7 b' class ExtensionDoctest(doctests.Doctest):' | |||||
716 | """ |
|
745 | """ | |
717 | #print 'Filename:',filename # dbg |
|
746 | #print 'Filename:',filename # dbg | |
718 |
|
747 | |||
719 | # temporarily hardcoded list, will move to driver later |
|
748 | # XXX - temporarily hardcoded list, will move to driver later | |
720 | exclude = ['IPython/external/', |
|
749 | exclude = ['IPython/external/', | |
721 | 'IPython/Extensions/ipy_', |
|
750 | 'IPython/Extensions/ipy_', | |
722 | 'IPython/platutils_win32', |
|
751 | 'IPython/platutils_win32', | |
@@ -747,7 +776,9 b' class IPythonDoctest(ExtensionDoctest):' | |||||
747 | Plugin.configure(self, options, config) |
|
776 | Plugin.configure(self, options, config) | |
748 | self.doctest_tests = options.doctest_tests |
|
777 | self.doctest_tests = options.doctest_tests | |
749 | self.extension = tolist(options.doctestExtension) |
|
778 | self.extension = tolist(options.doctestExtension) | |
|
779 | ||||
750 | self.parser = IPDocTestParser() |
|
780 | self.parser = IPDocTestParser() | |
751 | self.finder = DocTestFinder(parser=self.parser) |
|
781 | self.finder = DocTestFinder(parser=self.parser) | |
|
782 | self.checker = IPDoctestOutputChecker() | |||
752 | self.globs = None |
|
783 | self.globs = None | |
753 | self.extraglobs = None |
|
784 | self.extraglobs = None |
@@ -1,6 +1,7 b'' | |||||
1 | include README_Windows.txt |
|
1 | include README_Windows.txt | |
2 | include win32_manual_post_install.py |
|
2 | include win32_manual_post_install.py | |
3 | include ipython.py |
|
3 | include ipython.py | |
|
4 | include setupbase.py | |||
4 |
|
5 | |||
5 | graft scripts |
|
6 | graft scripts | |
6 |
|
7 | |||
@@ -13,14 +14,15 b' graft IPython/config' | |||||
13 | graft IPython/testing |
|
14 | graft IPython/testing | |
14 | graft IPython/tools |
|
15 | graft IPython/tools | |
15 |
|
16 | |||
|
17 | recursive-include IPython/Extensions igrid_help* | |||
|
18 | ||||
16 | graft docs |
|
19 | graft docs | |
17 | exclude docs/\#* |
|
20 | exclude docs/\#* | |
18 | exclude docs/man/*.1 |
|
21 | exclude docs/man/*.1 | |
19 |
|
22 | |||
20 | # There seems to be no way of excluding whole subdirectories, other than |
|
23 | # docs subdirs we want to skip | |
21 | # manually excluding all their subdirs. distutils really is horrible... |
|
24 | prune docs/attic | |
22 | exclude docs/attic/* |
|
25 | prune docs/build | |
23 | exclude docs/build/* |
|
|||
24 |
|
26 | |||
25 | global-exclude *~ |
|
27 | global-exclude *~ | |
26 | global-exclude *.flc |
|
28 | global-exclude *.flc |
@@ -21,10 +21,27 b' help:' | |||||
21 | @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" |
|
21 | @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" | |
22 | @echo " changes to make an overview over all changed/added/deprecated items" |
|
22 | @echo " changes to make an overview over all changed/added/deprecated items" | |
23 | @echo " linkcheck to check all external links for integrity" |
|
23 | @echo " linkcheck to check all external links for integrity" | |
|
24 | @echo | |||
|
25 | @echo "Compound utility targets:" | |||
|
26 | @echo "pdf latex and then runs the PDF generation" | |||
|
27 | @echo "all html and pdf" | |||
|
28 | @echo "dist all, and then puts the results in dist/" | |||
24 |
|
29 | |||
25 | clean: |
|
30 | clean: | |
26 | -rm -rf build/* |
|
31 | -rm -rf build/* | |
27 |
|
32 | |||
|
33 | pdf: latex | |||
|
34 | cd build/latex && make all-pdf | |||
|
35 | ||||
|
36 | all: html pdf | |||
|
37 | ||||
|
38 | dist: all | |||
|
39 | mkdir -p dist | |||
|
40 | -rm -rf dist/* | |||
|
41 | ln build/latex/IPython.pdf dist/ | |||
|
42 | cp -al build/html dist/ | |||
|
43 | @echo "Build finished. Final docs are in dist/" | |||
|
44 | ||||
28 | html: |
|
45 | html: | |
29 | mkdir -p build/html build/doctrees |
|
46 | mkdir -p build/html build/doctrees | |
30 | $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) build/html |
|
47 | $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) build/html |
@@ -53,6 +53,9 b' New features' | |||||
53 | the main usage of the script is for starting things on localhost. Eventually |
|
53 | the main usage of the script is for starting things on localhost. Eventually | |
54 | when ipcluster is able to start things on other hosts, we will put security |
|
54 | when ipcluster is able to start things on other hosts, we will put security | |
55 | back. |
|
55 | back. | |
|
56 | * 'cd --foo' searches directory history for string foo, and jumps to that dir. | |||
|
57 | Last part of dir name is checked first. If no matches for that are found, | |||
|
58 | look at the whole path. | |||
56 |
|
59 | |||
57 | Bug fixes |
|
60 | Bug fixes | |
58 | --------- |
|
61 | --------- | |
@@ -64,6 +67,8 b' Bug fixes' | |||||
64 | * A few subpackages has missing `__init__.py` files. |
|
67 | * A few subpackages has missing `__init__.py` files. | |
65 | * The documentation is only created is Sphinx is found. Previously, the `setup.py` |
|
68 | * The documentation is only created is Sphinx is found. Previously, the `setup.py` | |
66 | script would fail if it was missing. |
|
69 | script would fail if it was missing. | |
|
70 | * Greedy 'cd' completion has been disabled again (it was enabled in 0.8.4) | |||
|
71 | ||||
67 |
|
72 | |||
68 | Backwards incompatible changes |
|
73 | Backwards incompatible changes | |
69 | ------------------------------ |
|
74 | ------------------------------ |
@@ -44,7 +44,7 b" copyright = '2008, The IPython Development Team'" | |||||
44 | # The short X.Y version. |
|
44 | # The short X.Y version. | |
45 | version = '0.9' |
|
45 | version = '0.9' | |
46 | # The full version, including alpha/beta/rc tags. |
|
46 | # The full version, including alpha/beta/rc tags. | |
47 | release = '0.9' |
|
47 | release = '0.9.beta1' | |
48 |
|
48 | |||
49 | # There are two options for replacing |today|: either, you set today to some |
|
49 | # There are two options for replacing |today|: either, you set today to some | |
50 | # non-false value, then it is used: |
|
50 | # non-false value, then it is used: | |
@@ -135,13 +135,17 b" htmlhelp_basename = 'IPythondoc'" | |||||
135 | latex_paper_size = 'letter' |
|
135 | latex_paper_size = 'letter' | |
136 |
|
136 | |||
137 | # The font size ('10pt', '11pt' or '12pt'). |
|
137 | # The font size ('10pt', '11pt' or '12pt'). | |
138 |
latex_font_size = '1 |
|
138 | latex_font_size = '11pt' | |
139 |
|
139 | |||
140 | # Grouping the document tree into LaTeX files. List of tuples |
|
140 | # Grouping the document tree into LaTeX files. List of tuples | |
141 | # (source start file, target name, title, author, document class [howto/manual]). |
|
141 | # (source start file, target name, title, author, document class [howto/manual]). | |
142 | latex_documents = [ |
|
142 | ||
143 |
('index', 'IPython.tex', 'IPython Documentation', |
|
143 | latex_documents = [ ('index', 'IPython.tex', 'IPython Documentation', | |
144 | ] |
|
144 | ur"""Brian Granger and Fernando Pérez\\ | |
|
145 | With contributions from:\\ | |||
|
146 | Benjamin Ragan-Kelley and Ville Vainio.""", | |||
|
147 | 'manual'), | |||
|
148 | ] | |||
145 |
|
149 | |||
146 | # The name of an image file (relative to this directory) to place at the top of |
|
150 | # The name of an image file (relative to this directory) to place at the top of | |
147 | # the title page. |
|
151 | # the title page. |
@@ -75,17 +75,17 b" if len(sys.argv) >= 2 and sys.argv[1] in ('sdist','bdist_rpm'):" | |||||
75 | to_update = [ |
|
75 | to_update = [ | |
76 | # FIXME - Disabled for now: we need to redo an automatic way |
|
76 | # FIXME - Disabled for now: we need to redo an automatic way | |
77 | # of generating the magic info inside the rst. |
|
77 | # of generating the magic info inside the rst. | |
78 | #('doc/magic.tex', |
|
78 | #('docs/magic.tex', | |
79 | #['IPython/Magic.py'], |
|
79 | #['IPython/Magic.py'], | |
80 | #"cd doc && ./update_magic.sh" ), |
|
80 | #"cd doc && ./update_magic.sh" ), | |
81 |
|
81 | |||
82 | ('doc/ipython.1.gz', |
|
82 | ('docs/man/ipython.1.gz', | |
83 | ['doc/ipython.1'], |
|
83 | ['docs/man/ipython.1'], | |
84 | "cd doc && gzip -9c ipython.1 > ipython.1.gz"), |
|
84 | "cd docs/man && gzip -9c ipython.1 > ipython.1.gz"), | |
85 |
|
85 | |||
86 | ('doc/pycolor.1.gz', |
|
86 | ('docs/man/pycolor.1.gz', | |
87 | ['doc/pycolor.1'], |
|
87 | ['docs/man/pycolor.1'], | |
88 | "cd doc && gzip -9c pycolor.1 > pycolor.1.gz"), |
|
88 | "cd docs/man && gzip -9c pycolor.1 > pycolor.1.gz"), | |
89 | ] |
|
89 | ] | |
90 |
|
90 | |||
91 | # Only build the docs is sphinx is present |
|
91 | # Only build the docs is sphinx is present | |
@@ -101,12 +101,16 b" if len(sys.argv) >= 2 and sys.argv[1] in ('sdist','bdist_rpm'):" | |||||
101 | # The do_sphinx scripts builds html and pdf, so just one |
|
101 | # The do_sphinx scripts builds html and pdf, so just one | |
102 | # target is enough to cover all manual generation |
|
102 | # target is enough to cover all manual generation | |
103 | # to_update.append( |
|
103 | # to_update.append( | |
104 | # ('doc/manual/ipython.pdf', |
|
104 | # ('docs/manual/ipython.pdf', | |
105 | # ['IPython/Release.py','doc/source/ipython.rst'], |
|
105 | # ['IPython/Release.py','docs/source/ipython.rst'], | |
106 | # "cd docs && python do_sphinx.py") |
|
106 | # "cd docs && python do_sphinx.py") | |
107 | # ) |
|
107 | # ) | |
|
108 | ||||
108 | [ target_update(*t) for t in to_update ] |
|
109 | [ target_update(*t) for t in to_update ] | |
109 |
|
110 | |||
|
111 | # Build the docs | |||
|
112 | os.system('cd docs && make dist') | |||
|
113 | ||||
110 | #--------------------------------------------------------------------------- |
|
114 | #--------------------------------------------------------------------------- | |
111 | # Find all the packages, package data, scripts and data_files |
|
115 | # Find all the packages, package data, scripts and data_files | |
112 | #--------------------------------------------------------------------------- |
|
116 | #--------------------------------------------------------------------------- |
@@ -82,7 +82,8 b' setup_args = dict(' | |||||
82 | # Find packages |
|
82 | # Find packages | |
83 | #--------------------------------------------------------------------------- |
|
83 | #--------------------------------------------------------------------------- | |
84 |
|
84 | |||
85 |
def add_package(packages, |
|
85 | def add_package(packages,pname,config=False,tests=False,scripts=False, | |
|
86 | others=None): | |||
86 | """ |
|
87 | """ | |
87 | Add a package to the list of packages, including certain subpackages. |
|
88 | Add a package to the list of packages, including certain subpackages. | |
88 | """ |
|
89 | """ | |
@@ -140,37 +141,74 b' def find_package_data():' | |||||
140 | # Find data files |
|
141 | # Find data files | |
141 | #--------------------------------------------------------------------------- |
|
142 | #--------------------------------------------------------------------------- | |
142 |
|
143 | |||
|
144 | def make_dir_struct(tag,base,out_base): | |||
|
145 | """Make the directory structure of all files below a starting dir. | |||
|
146 | ||||
|
147 | This is just a convenience routine to help build a nested directory | |||
|
148 | hierarchy because distutils is too stupid to do this by itself. | |||
|
149 | ||||
|
150 | XXX - this needs a proper docstring! | |||
|
151 | """ | |||
|
152 | ||||
|
153 | # we'll use these a lot below | |||
|
154 | lbase = len(base) | |||
|
155 | pathsep = os.path.sep | |||
|
156 | lpathsep = len(pathsep) | |||
|
157 | ||||
|
158 | out = [] | |||
|
159 | for (dirpath,dirnames,filenames) in os.walk(base): | |||
|
160 | # we need to strip out the dirpath from the base to map it to the | |||
|
161 | # output (installation) path. This requires possibly stripping the | |||
|
162 | # path separator, because otherwise pjoin will not work correctly | |||
|
163 | # (pjoin('foo/','/bar') returns '/bar'). | |||
|
164 | ||||
|
165 | dp_eff = dirpath[lbase:] | |||
|
166 | if dp_eff.startswith(pathsep): | |||
|
167 | dp_eff = dp_eff[lpathsep:] | |||
|
168 | # The output path must be anchored at the out_base marker | |||
|
169 | out_path = pjoin(out_base,dp_eff) | |||
|
170 | # Now we can generate the final filenames. Since os.walk only produces | |||
|
171 | # filenames, we must join back with the dirpath to get full valid file | |||
|
172 | # paths: | |||
|
173 | pfiles = [pjoin(dirpath,f) for f in filenames] | |||
|
174 | # Finally, generate the entry we need, which is a triple of (tag,output | |||
|
175 | # path, files) for use as a data_files parameter in install_data. | |||
|
176 | out.append((tag,out_path,pfiles)) | |||
|
177 | ||||
|
178 | return out | |||
|
179 | ||||
|
180 | ||||
143 | def find_data_files(): |
|
181 | def find_data_files(): | |
144 | """ |
|
182 | """ | |
145 | Find IPython's data_files. |
|
183 | Find IPython's data_files. | |
|
184 | ||||
|
185 | Most of these are docs. | |||
146 | """ |
|
186 | """ | |
147 |
|
187 | |||
148 | # I can't find how to make distutils create a nested dir. structure, so |
|
|||
149 | # in the meantime do it manually. Butt ugly. |
|
|||
150 | # Note that http://www.redbrick.dcu.ie/~noel/distutils.html, ex. 2/3, contain |
|
|||
151 | # information on how to do this more cleanly once python 2.4 can be assumed. |
|
|||
152 | # Thanks to Noel for the tip. |
|
|||
153 | docdirbase = 'share/doc/ipython' |
|
188 | docdirbase = 'share/doc/ipython' | |
154 | manpagebase = 'share/man/man1' |
|
189 | manpagebase = 'share/man/man1' | |
155 |
|
190 | |||
156 | # We only need to exclude from this things NOT already excluded in the |
|
191 | # Simple file lists can be made by hand | |
157 | # MANIFEST.in file. |
|
192 | manpages = filter(isfile, glob('docs/man/*.1.gz')) | |
158 | exclude = ('.sh','.1.gz') |
|
|||
159 | # We need to figure out how we want to package all of our rst docs? |
|
|||
160 | # docfiles = filter(lambda f:file_doesnt_endwith(f,exclude),glob('docs/*')) |
|
|||
161 | examfiles = filter(isfile, glob('docs/examples/core/*.py')) |
|
|||
162 | examfiles.append(filter(isfile, glob('docs/examples/kernel/*.py'))) |
|
|||
163 | manpages = filter(isfile, glob('docs/man/*.1.gz')) |
|
|||
164 | igridhelpfiles = filter(isfile, glob('IPython/Extensions/igrid_help.*')) |
|
193 | igridhelpfiles = filter(isfile, glob('IPython/Extensions/igrid_help.*')) | |
|
194 | ||||
|
195 | # For nested structures, use the utility above | |||
|
196 | example_files = make_dir_struct('data','docs/examples', | |||
|
197 | pjoin(docdirbase,'examples')) | |||
|
198 | manual_files = make_dir_struct('data','docs/dist',pjoin(docdirbase,'manual')) | |||
|
199 | ||||
|
200 | # And assemble the entire output list | |||
|
201 | data_files = [ ('data',manpagebase, manpages), | |||
|
202 | ('data',pjoin(docdirbase,'extensions'),igridhelpfiles), | |||
|
203 | ] + manual_files + example_files | |||
|
204 | ||||
|
205 | ## import pprint # dbg | |||
|
206 | ## print '*'*80 | |||
|
207 | ## print 'data files' | |||
|
208 | ## pprint.pprint(data_files) | |||
|
209 | ## print '*'*80 | |||
165 |
|
210 | |||
166 | data_files = [#('data', docdirbase, docfiles), |
|
211 | return data_files | |
167 | ('data', pjoin(docdirbase, 'examples'),examfiles), |
|
|||
168 | ('data', manpagebase, manpages), |
|
|||
169 | ('data',pjoin(docdirbase, 'extensions'),igridhelpfiles), |
|
|||
170 | ] |
|
|||
171 | # import pprint |
|
|||
172 | # pprint.pprint(data_files) |
|
|||
173 | return [] |
|
|||
174 |
|
212 | |||
175 | #--------------------------------------------------------------------------- |
|
213 | #--------------------------------------------------------------------------- | |
176 | # Find scripts |
|
214 | # Find scripts | |
@@ -180,14 +218,14 b' def find_scripts():' | |||||
180 | """ |
|
218 | """ | |
181 | Find IPython's scripts. |
|
219 | Find IPython's scripts. | |
182 | """ |
|
220 | """ | |
183 | scripts = [] |
|
221 | scripts = ['IPython/kernel/scripts/ipengine', | |
184 |
|
|
222 | 'IPython/kernel/scripts/ipcontroller', | |
185 |
|
|
223 | 'IPython/kernel/scripts/ipcluster', | |
186 | scripts.append('IPython/kernel/scripts/ipcluster') |
|
224 | 'scripts/ipython', | |
187 | scripts.append('scripts/ipython') |
|
225 | 'scripts/ipythonx', | |
188 | scripts.append('scripts/ipythonx') |
|
226 | 'scripts/pycolor', | |
189 | scripts.append('scripts/pycolor') |
|
227 | 'scripts/irunner', | |
190 | scripts.append('scripts/irunner') |
|
228 | ] | |
191 |
|
229 | |||
192 | # Script to be run by the windows binary installer after the default setup |
|
230 | # Script to be run by the windows binary installer after the default setup | |
193 | # routine, to add shortcuts and similar windows-only things. Windows |
|
231 | # routine, to add shortcuts and similar windows-only things. Windows | |
@@ -202,7 +240,7 b' def find_scripts():' | |||||
202 | return scripts |
|
240 | return scripts | |
203 |
|
241 | |||
204 | #--------------------------------------------------------------------------- |
|
242 | #--------------------------------------------------------------------------- | |
205 | # Find scripts |
|
243 | # Verify all dependencies | |
206 | #--------------------------------------------------------------------------- |
|
244 | #--------------------------------------------------------------------------- | |
207 |
|
245 | |||
208 | def check_for_dependencies(): |
|
246 | def check_for_dependencies(): |
@@ -4,7 +4,7 b'' | |||||
4 |
|
4 | |||
5 | import os,sys,shutil |
|
5 | import os,sys,shutil | |
6 |
|
6 | |||
7 |
basever = '0. |
|
7 | basever = '0.9.0' | |
8 |
|
8 | |||
9 | def oscmd(c): |
|
9 | def oscmd(c): | |
10 | print ">",c |
|
10 | print ">",c | |
@@ -30,7 +30,7 b' ver = verinfo()' | |||||
30 | if ver['branch-nick'] == 'ipython': |
|
30 | if ver['branch-nick'] == 'ipython': | |
31 | tarname = 'ipython-%s.bzr.r%s.tgz' % (basever, ver['revno']) |
|
31 | tarname = 'ipython-%s.bzr.r%s.tgz' % (basever, ver['revno']) | |
32 | else: |
|
32 | else: | |
33 |
tarname = 'ipython-%s.bzr.r%s.%s.tgz' % (basever, ver['revno'], |
|
33 | tarname = 'ipython-%s.bzr.r%s.%s.tgz' % (basever, ver['revno'], | |
|
34 | ver['branch-nick']) | |||
34 |
|
35 | |||
35 | oscmd('bzr export ' + tarname) |
|
36 | oscmd('bzr export ' + tarname) | |
36 |
|
@@ -21,8 +21,8 b' cd $ipdir' | |||||
21 | ./setup.py sdist --formats=gztar |
|
21 | ./setup.py sdist --formats=gztar | |
22 |
|
22 | |||
23 | # Build rpms |
|
23 | # Build rpms | |
24 | python2.4 ./setup.py bdist_rpm --binary-only --release=py24 --python=/usr/bin/python2.4 |
|
24 | #python2.4 ./setup.py bdist_rpm --binary-only --release=py24 --python=/usr/bin/python2.4 | |
25 | python2.5 ./setup.py bdist_rpm --binary-only --release=py25 --python=/usr/bin/python2.5 |
|
25 | #python2.5 ./setup.py bdist_rpm --binary-only --release=py25 --python=/usr/bin/python2.5 | |
26 |
|
26 | |||
27 | # Build eggs |
|
27 | # Build eggs | |
28 | python2.4 ./setup_bdist_egg.py |
|
28 | python2.4 ./setup_bdist_egg.py |
General Comments 0
You need to be logged in to leave comments.
Login now