##// END OF EJS Templates
Really use shutil to copy local file on Windows.
Thomas Kluyver -
Show More
@@ -1,154 +1,154 b''
1 1 # encoding: utf-8
2 2 """A class for managing IPython extensions.
3 3
4 4 Authors:
5 5
6 6 * Brian Granger
7 7 """
8 8
9 9 #-----------------------------------------------------------------------------
10 10 # Copyright (C) 2010-2011 The IPython Development Team
11 11 #
12 12 # Distributed under the terms of the BSD License. The full license is in
13 13 # the file COPYING, distributed as part of this software.
14 14 #-----------------------------------------------------------------------------
15 15
16 16 #-----------------------------------------------------------------------------
17 17 # Imports
18 18 #-----------------------------------------------------------------------------
19 19
20 20 import os
21 21 from shutil import copyfile
22 22 import sys
23 23 from urllib import urlretrieve
24 24 from urlparse import urlparse
25 25
26 26 from IPython.config.configurable import Configurable
27 27 from IPython.utils.traitlets import Instance
28 28
29 29 #-----------------------------------------------------------------------------
30 30 # Main class
31 31 #-----------------------------------------------------------------------------
32 32
33 33 class ExtensionManager(Configurable):
34 34 """A class to manage IPython extensions.
35 35
36 36 An IPython extension is an importable Python module that has
37 37 a function with the signature::
38 38
39 39 def load_ipython_extension(ipython):
40 40 # Do things with ipython
41 41
42 42 This function is called after your extension is imported and the
43 43 currently active :class:`InteractiveShell` instance is passed as
44 44 the only argument. You can do anything you want with IPython at
45 45 that point, including defining new magic and aliases, adding new
46 46 components, etc.
47 47
48 48 The :func:`load_ipython_extension` will be called again is you
49 49 load or reload the extension again. It is up to the extension
50 50 author to add code to manage that.
51 51
52 52 You can put your extension modules anywhere you want, as long as
53 53 they can be imported by Python's standard import mechanism. However,
54 54 to make it easy to write extensions, you can also put your extensions
55 55 in ``os.path.join(self.ipython_dir, 'extensions')``. This directory
56 56 is added to ``sys.path`` automatically.
57 57 """
58 58
59 59 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC')
60 60
61 61 def __init__(self, shell=None, config=None):
62 62 super(ExtensionManager, self).__init__(shell=shell, config=config)
63 63 self.shell.on_trait_change(
64 64 self._on_ipython_dir_changed, 'ipython_dir'
65 65 )
66 66
67 67 def __del__(self):
68 68 self.shell.on_trait_change(
69 69 self._on_ipython_dir_changed, 'ipython_dir', remove=True
70 70 )
71 71
72 72 @property
73 73 def ipython_extension_dir(self):
74 74 return os.path.join(self.shell.ipython_dir, u'extensions')
75 75
76 76 def _on_ipython_dir_changed(self):
77 77 if not os.path.isdir(self.ipython_extension_dir):
78 78 os.makedirs(self.ipython_extension_dir, mode = 0777)
79 79
80 80 def load_extension(self, module_str):
81 81 """Load an IPython extension by its module name.
82 82
83 83 If :func:`load_ipython_extension` returns anything, this function
84 84 will return that object.
85 85 """
86 86 from IPython.utils.syspathcontext import prepended_to_syspath
87 87
88 88 if module_str not in sys.modules:
89 89 with prepended_to_syspath(self.ipython_extension_dir):
90 90 __import__(module_str)
91 91 mod = sys.modules[module_str]
92 92 return self._call_load_ipython_extension(mod)
93 93
94 94 def unload_extension(self, module_str):
95 95 """Unload an IPython extension by its module name.
96 96
97 97 This function looks up the extension's name in ``sys.modules`` and
98 98 simply calls ``mod.unload_ipython_extension(self)``.
99 99 """
100 100 if module_str in sys.modules:
101 101 mod = sys.modules[module_str]
102 102 self._call_unload_ipython_extension(mod)
103 103
104 104 def reload_extension(self, module_str):
105 105 """Reload an IPython extension by calling reload.
106 106
107 107 If the module has not been loaded before,
108 108 :meth:`InteractiveShell.load_extension` is called. Otherwise
109 109 :func:`reload` is called and then the :func:`load_ipython_extension`
110 110 function of the module, if it exists is called.
111 111 """
112 112 from IPython.utils.syspathcontext import prepended_to_syspath
113 113
114 114 with prepended_to_syspath(self.ipython_extension_dir):
115 115 if module_str in sys.modules:
116 116 mod = sys.modules[module_str]
117 117 reload(mod)
118 118 self._call_load_ipython_extension(mod)
119 119 else:
120 120 self.load_extension(module_str)
121 121
122 122 def _call_load_ipython_extension(self, mod):
123 123 if hasattr(mod, 'load_ipython_extension'):
124 124 return mod.load_ipython_extension(self.shell)
125 125
126 126 def _call_unload_ipython_extension(self, mod):
127 127 if hasattr(mod, 'unload_ipython_extension'):
128 128 return mod.unload_ipython_extension(self.shell)
129 129
130 130 def install_extension(self, url, filename=None):
131 131 """Download and install an IPython extension.
132 132
133 133 If filename is given, the file will be so named (inside the extension
134 134 directory). Otherwise, the name from the URL will be used. The file must
135 135 have a .py or .zip extension; otherwise, a ValueError will be raised.
136 136 """
137 137 # Ensure the extension directory exists
138 138 if not os.path.isdir(self.ipython_extension_dir):
139 139 os.makedirs(self.ipython_extension_dir, mode = 0777)
140 140
141 141 if os.path.isfile(url):
142 142 src_filename = os.path.basename(url)
143 143 copy = copyfile
144 144 else:
145 145 src_filename = urlparse(url).path.split('/')[-1]
146 146 copy = urlretrieve
147 147
148 148 if filename is None:
149 149 filename = src_filename
150 150 if os.path.splitext(filename)[1] not in ('.py', '.zip'):
151 151 raise ValueError("The file must have a .py or .zip extension", filename)
152 152
153 153 filename = os.path.join(self.ipython_extension_dir, filename)
154 return urlretrieve(url, filename)
154 return copy(url, filename)
General Comments 0
You need to be logged in to leave comments. Login now