Show More
@@ -46,18 +46,22 class IPythonArgParseConfigLoader(ArgParseConfigLoader): | |||||
46 | """Default command line options for IPython based applications.""" |
|
46 | """Default command line options for IPython based applications.""" | |
47 |
|
47 | |||
48 | def _add_other_arguments(self): |
|
48 | def _add_other_arguments(self): | |
49 |
self.parser.add_argument('-ipythondir', |
|
49 | self.parser.add_argument('-ipythondir', '--ipythondir', | |
|
50 | dest='Global.ipythondir',type=str, | |||
50 | help='Set to override default location of Global.ipythondir.', |
|
51 | help='Set to override default location of Global.ipythondir.', | |
51 | default=NoConfigDefault, |
|
52 | default=NoConfigDefault, | |
52 | metavar='Global.ipythondir') |
|
53 | metavar='Global.ipythondir') | |
53 |
self.parser.add_argument('-p','-profile', |
|
54 | self.parser.add_argument('-p','-profile', '--profile', | |
|
55 | dest='Global.profile',type=str, | |||
54 | help='The string name of the ipython profile to be used.', |
|
56 | help='The string name of the ipython profile to be used.', | |
55 | default=NoConfigDefault, |
|
57 | default=NoConfigDefault, | |
56 | metavar='Global.profile') |
|
58 | metavar='Global.profile') | |
57 |
self.parser.add_argument('-log_level', |
|
59 | self.parser.add_argument('-log_level', '--log-level', | |
|
60 | dest="Global.log_level",type=int, | |||
58 | help='Set the log level (0,10,20,30,40,50). Default is 30.', |
|
61 | help='Set the log level (0,10,20,30,40,50). Default is 30.', | |
59 | default=NoConfigDefault) |
|
62 | default=NoConfigDefault) | |
60 |
self.parser.add_argument('-config_file', |
|
63 | self.parser.add_argument('-config_file', '--config-file', | |
|
64 | dest='Global.config_file',type=str, | |||
61 | help='Set the config file name to override default.', |
|
65 | help='Set the config file name to override default.', | |
62 | default=NoConfigDefault, |
|
66 | default=NoConfigDefault, | |
63 | metavar='Global.config_file') |
|
67 | metavar='Global.config_file') |
@@ -46,11 +46,11 class DisplayTrap(Component): | |||||
46 | # Only turn off the trap when the outermost call to __exit__ is made. |
|
46 | # Only turn off the trap when the outermost call to __exit__ is made. | |
47 | self._nested_level = 0 |
|
47 | self._nested_level = 0 | |
48 |
|
48 | |||
49 | @auto_attr |
|
49 | # @auto_attr | |
50 | def shell(self): |
|
50 | # def shell(self): | |
51 | return Component.get_instances( |
|
51 | # return Component.get_instances( | |
52 | root=self.root, |
|
52 | # root=self.root, | |
53 | klass='IPython.core.iplib.InteractiveShell')[0] |
|
53 | # klass='IPython.core.iplib.InteractiveShell')[0] | |
54 |
|
54 | |||
55 | def __enter__(self): |
|
55 | def __enter__(self): | |
56 | if self._nested_level == 0: |
|
56 | if self._nested_level == 0: |
@@ -1602,10 +1602,10 class InteractiveShell(Component, Magic): | |||||
1602 | else: |
|
1602 | else: | |
1603 | magic_args = self.var_expand(magic_args,1) |
|
1603 | magic_args = self.var_expand(magic_args,1) | |
1604 | with nested(self.builtin_trap,): |
|
1604 | with nested(self.builtin_trap,): | |
1605 |
re |
|
1605 | return fn(magic_args) | |
1606 | # Unfortunately, the return statement is what will trigger |
|
1606 | # Unfortunately, the return statement is what will trigger | |
1607 | # the displayhook, but it is no longer set! |
|
1607 | # the displayhook, but it is no longer set! | |
1608 | return result |
|
1608 | # return result | |
1609 |
|
1609 | |||
1610 | def define_magic(self, magicname, func): |
|
1610 | def define_magic(self, magicname, func): | |
1611 | """Expose own function as magic function for ipython |
|
1611 | """Expose own function as magic function for ipython |
@@ -1268,7 +1268,6 Currently the magic system has the following functions:\n""" | |||||
1268 | If you want IPython to automatically do this on every exception, see |
|
1268 | If you want IPython to automatically do this on every exception, see | |
1269 | the %pdb magic for more details. |
|
1269 | the %pdb magic for more details. | |
1270 | """ |
|
1270 | """ | |
1271 |
|
||||
1272 | self.shell.debugger(force=True) |
|
1271 | self.shell.debugger(force=True) | |
1273 |
|
1272 | |||
1274 | @testdec.skip_doctest |
|
1273 | @testdec.skip_doctest |
@@ -1,27 +1,56 | |||||
|
1 | #!/usr/bin/env python | |||
1 | # encoding: utf-8 |
|
2 | # encoding: utf-8 | |
|
3 | """ | |||
|
4 | Foolscap related utilities. | |||
|
5 | """ | |||
2 |
|
6 | |||
3 | """Foolscap related utilities.""" |
|
7 | #----------------------------------------------------------------------------- | |
4 |
|
8 | # Copyright (C) 2008-2009 The IPython Development Team | ||
5 | __docformat__ = "restructuredtext en" |
|
|||
6 |
|
||||
7 | #------------------------------------------------------------------------------- |
|
|||
8 | # Copyright (C) 2008 The IPython Development Team |
|
|||
9 | # |
|
9 | # | |
10 | # Distributed under the terms of the BSD License. The full license is in |
|
10 | # Distributed under the terms of the BSD License. The full license is in | |
11 | # the file COPYING, distributed as part of this software. |
|
11 | # the file COPYING, distributed as part of this software. | |
12 |
#----------------------------------------------------------------------------- |
|
12 | #----------------------------------------------------------------------------- | |
13 |
|
13 | |||
14 |
#----------------------------------------------------------------------------- |
|
14 | #----------------------------------------------------------------------------- | |
15 | # Imports |
|
15 | # Imports | |
16 |
#----------------------------------------------------------------------------- |
|
16 | #----------------------------------------------------------------------------- | |
17 |
|
17 | |||
18 | import os |
|
18 | import os | |
|
19 | import tempfile | |||
|
20 | ||||
|
21 | from twisted.internet import reactor, defer | |||
|
22 | from twisted.python import log | |||
19 |
|
23 | |||
20 | from foolscap import Tub, UnauthenticatedTub |
|
24 | from foolscap import Tub, UnauthenticatedTub | |
21 |
|
25 | |||
|
26 | from IPython.config.loader import Config | |||
|
27 | ||||
|
28 | from IPython.kernel.configobjfactory import AdaptedConfiguredObjectFactory | |||
|
29 | ||||
|
30 | from IPython.kernel.error import SecurityError | |||
|
31 | ||||
|
32 | from IPython.utils.traitlets import Int, Str, Bool, Instance | |||
|
33 | from IPython.utils.importstring import import_item | |||
|
34 | ||||
|
35 | #----------------------------------------------------------------------------- | |||
|
36 | # Code | |||
|
37 | #----------------------------------------------------------------------------- | |||
|
38 | ||||
|
39 | ||||
|
40 | # We do this so if a user doesn't have OpenSSL installed, it will try to use | |||
|
41 | # an UnauthenticatedTub. But, they will still run into problems if they | |||
|
42 | # try to use encrypted furls. | |||
|
43 | try: | |||
|
44 | import OpenSSL | |||
|
45 | except: | |||
|
46 | Tub = UnauthenticatedTub | |||
|
47 | have_crypto = False | |||
|
48 | else: | |||
|
49 | have_crypto = True | |||
|
50 | ||||
|
51 | ||||
22 | def check_furl_file_security(furl_file, secure): |
|
52 | def check_furl_file_security(furl_file, secure): | |
23 | """Remove the old furl_file if changing security modes.""" |
|
53 | """Remove the old furl_file if changing security modes.""" | |
24 |
|
||||
25 | if os.path.isfile(furl_file): |
|
54 | if os.path.isfile(furl_file): | |
26 | f = open(furl_file, 'r') |
|
55 | f = open(furl_file, 'r') | |
27 | oldfurl = f.read().strip() |
|
56 | oldfurl = f.read().strip() | |
@@ -29,7 +58,9 def check_furl_file_security(furl_file, secure): | |||||
29 | if (oldfurl.startswith('pb://') and not secure) or (oldfurl.startswith('pbu://') and secure): |
|
58 | if (oldfurl.startswith('pb://') and not secure) or (oldfurl.startswith('pbu://') and secure): | |
30 | os.remove(furl_file) |
|
59 | os.remove(furl_file) | |
31 |
|
60 | |||
|
61 | ||||
32 | def is_secure(furl): |
|
62 | def is_secure(furl): | |
|
63 | """Is the given FURL secure or not.""" | |||
33 | if is_valid(furl): |
|
64 | if is_valid(furl): | |
34 | if furl.startswith("pb://"): |
|
65 | if furl.startswith("pb://"): | |
35 | return True |
|
66 | return True | |
@@ -38,14 +69,18 def is_secure(furl): | |||||
38 | else: |
|
69 | else: | |
39 | raise ValueError("invalid furl: %s" % furl) |
|
70 | raise ValueError("invalid furl: %s" % furl) | |
40 |
|
71 | |||
|
72 | ||||
41 | def is_valid(furl): |
|
73 | def is_valid(furl): | |
|
74 | """Is the str a valid furl or not.""" | |||
42 | if isinstance(furl, str): |
|
75 | if isinstance(furl, str): | |
43 | if furl.startswith("pb://") or furl.startswith("pbu://"): |
|
76 | if furl.startswith("pb://") or furl.startswith("pbu://"): | |
44 | return True |
|
77 | return True | |
45 | else: |
|
78 | else: | |
46 | return False |
|
79 | return False | |
47 |
|
80 | |||
|
81 | ||||
48 | def find_furl(furl_or_file): |
|
82 | def find_furl(furl_or_file): | |
|
83 | """Find, validate and return a FURL in a string or file.""" | |||
49 | if isinstance(furl_or_file, str): |
|
84 | if isinstance(furl_or_file, str): | |
50 | if is_valid(furl_or_file): |
|
85 | if is_valid(furl_or_file): | |
51 | return furl_or_file |
|
86 | return furl_or_file | |
@@ -55,15 +90,120 def find_furl(furl_or_file): | |||||
55 | return furl |
|
90 | return furl | |
56 | raise ValueError("not a furl or a file containing a furl: %s" % furl_or_file) |
|
91 | raise ValueError("not a furl or a file containing a furl: %s" % furl_or_file) | |
57 |
|
92 | |||
58 | # We do this so if a user doesn't have OpenSSL installed, it will try to use |
|
|||
59 | # an UnauthenticatedTub. But, they will still run into problems if they |
|
|||
60 | # try to use encrypted furls. |
|
|||
61 | try: |
|
|||
62 | import OpenSSL |
|
|||
63 | except: |
|
|||
64 | Tub = UnauthenticatedTub |
|
|||
65 | have_crypto = False |
|
|||
66 | else: |
|
|||
67 | have_crypto = True |
|
|||
68 |
|
93 | |||
|
94 | def get_temp_furlfile(filename): | |||
|
95 | """Return a temporary furl file.""" | |||
|
96 | return tempfile.mktemp(dir=os.path.dirname(filename), | |||
|
97 | prefix=os.path.basename(filename)) | |||
|
98 | ||||
|
99 | ||||
|
100 | def make_tub(ip, port, secure, cert_file): | |||
|
101 | """Create a listening tub given an ip, port, and cert_file location. | |||
|
102 | ||||
|
103 | Parameters | |||
|
104 | ---------- | |||
|
105 | ip : str | |||
|
106 | The ip address or hostname that the tub should listen on. | |||
|
107 | Empty means all interfaces. | |||
|
108 | port : int | |||
|
109 | The port that the tub should listen on. A value of 0 means | |||
|
110 | pick a random port | |||
|
111 | secure: bool | |||
|
112 | Will the connection be secure (in the Foolscap sense). | |||
|
113 | cert_file: str | |||
|
114 | A filename of a file to be used for theSSL certificate. | |||
|
115 | ||||
|
116 | Returns | |||
|
117 | ------- | |||
|
118 | A tub, listener tuple. | |||
|
119 | """ | |||
|
120 | if secure: | |||
|
121 | if have_crypto: | |||
|
122 | tub = Tub(certFile=cert_file) | |||
|
123 | else: | |||
|
124 | raise SecurityError("OpenSSL/pyOpenSSL is not available, so we " | |||
|
125 | "can't run in secure mode. Try running without " | |||
|
126 | "security using 'ipcontroller -xy'.") | |||
|
127 | else: | |||
|
128 | tub = UnauthenticatedTub() | |||
|
129 | ||||
|
130 | # Set the strport based on the ip and port and start listening | |||
|
131 | if ip == '': | |||
|
132 | strport = "tcp:%i" % port | |||
|
133 | else: | |||
|
134 | strport = "tcp:%i:interface=%s" % (port, ip) | |||
|
135 | listener = tub.listenOn(strport) | |||
|
136 | ||||
|
137 | return tub, listener | |||
|
138 | ||||
|
139 | ||||
|
140 | class FCServiceFactory(AdaptedConfiguredObjectFactory): | |||
|
141 | """This class creates a tub with various services running in it. | |||
|
142 | ||||
|
143 | The basic idea is that :meth:`create` returns a running :class:`Tub` | |||
|
144 | instance that has a number of Foolscap references registered in it. | |||
|
145 | This class is a subclass of :class:`IPython.core.component.Component` | |||
|
146 | so the IPython configuration and component system are used. | |||
|
147 | ||||
|
148 | Attributes | |||
|
149 | ---------- | |||
|
150 | Interfaces : Config | |||
|
151 | A Config instance whose values are sub-Config objects having two | |||
|
152 | keys: furl_file and interface_chain. | |||
|
153 | ||||
|
154 | The other attributes are the standard ones for Foolscap. | |||
|
155 | """ | |||
|
156 | ||||
|
157 | ip = Str('', config=True) | |||
|
158 | port = Int(0, config=True) | |||
|
159 | secure = Bool(True, config=True) | |||
|
160 | cert_file = Str('', config=True) | |||
|
161 | location = Str('', config=True) | |||
|
162 | Interfaces = Instance(klass=Config, kw={}, allow_none=False, config=True) | |||
|
163 | ||||
|
164 | def _ip_changed(self, name, old, new): | |||
|
165 | if new == 'localhost' or new == '127.0.0.1': | |||
|
166 | self.location = '127.0.0.1' | |||
|
167 | ||||
|
168 | def create(self): | |||
|
169 | """Create and return the Foolscap tub with everything running.""" | |||
|
170 | ||||
|
171 | self.tub, self.listener = make_tub( | |||
|
172 | self.ip, self.port, self.secure, self.cert_file) | |||
|
173 | if not self.secure: | |||
|
174 | log.msg("WARNING: running with no security: %s" % self.__class__.__name__) | |||
|
175 | reactor.callWhenRunning(self.set_location_and_register) | |||
|
176 | return self.tub | |||
|
177 | ||||
|
178 | def set_location_and_register(self): | |||
|
179 | """Set the location for the tub and return a deferred.""" | |||
|
180 | ||||
|
181 | if self.location == '': | |||
|
182 | d = self.tub.setLocationAutomatically() | |||
|
183 | else: | |||
|
184 | d = defer.maybeDeferred(self.tub.setLocation, | |||
|
185 | "%s:%i" % (self.location, self.listener.getPortnum())) | |||
|
186 | self.adapt_to_interfaces(d) | |||
|
187 | ||||
|
188 | def adapt_to_interfaces(self, d): | |||
|
189 | """Run through the interfaces, adapt and register.""" | |||
|
190 | ||||
|
191 | for ifname, ifconfig in self.Interfaces.iteritems(): | |||
|
192 | log.msg("Adapting %r to interface: %s" % (self.adaptee, ifname)) | |||
|
193 | log.msg("Saving furl for interface [%s] to file: %s" % (ifname, ifconfig.furl_file)) | |||
|
194 | check_furl_file_security(ifconfig.furl_file, self.secure) | |||
|
195 | adaptee = self.adaptee | |||
|
196 | for i in ifconfig.interface_chain: | |||
|
197 | adaptee = import_item(i)(adaptee) | |||
|
198 | d.addCallback(self.register, adaptee, furl_file=ifconfig.furl_file) | |||
|
199 | ||||
|
200 | def register(self, empty, ref, furl_file): | |||
|
201 | """Register the reference with the FURL file. | |||
|
202 | ||||
|
203 | The FURL file is created and then moved to make sure that when the | |||
|
204 | file appears, the buffer has been flushed and the file closed. | |||
|
205 | """ | |||
|
206 | temp_furl_file = get_temp_furlfile(furl_file) | |||
|
207 | self.tub.registerReference(ref, furlFile=temp_furl_file) | |||
|
208 | os.rename(temp_furl_file, furl_file) | |||
69 |
|
209 |
@@ -151,6 +151,26 class _SimpleTest: | |||||
151 | return self.__repr__() |
|
151 | return self.__repr__() | |
152 |
|
152 | |||
153 |
|
153 | |||
|
154 | def getmembers(object, predicate=None): | |||
|
155 | """A safe version of inspect.getmembers that handles missing attributes. | |||
|
156 | ||||
|
157 | This is useful when there are descriptor based attributes that for | |||
|
158 | some reason raise AttributeError even though they exist. This happens | |||
|
159 | in zope.inteface with the __provides__ attribute. | |||
|
160 | """ | |||
|
161 | results = [] | |||
|
162 | for key in dir(object): | |||
|
163 | try: | |||
|
164 | value = getattr(object, key) | |||
|
165 | except AttributeError: | |||
|
166 | pass | |||
|
167 | else: | |||
|
168 | if not predicate or predicate(value): | |||
|
169 | results.append((key, value)) | |||
|
170 | results.sort() | |||
|
171 | return results | |||
|
172 | ||||
|
173 | ||||
154 | #----------------------------------------------------------------------------- |
|
174 | #----------------------------------------------------------------------------- | |
155 | # Base TraitletType for all traitlets |
|
175 | # Base TraitletType for all traitlets | |
156 | #----------------------------------------------------------------------------- |
|
176 | #----------------------------------------------------------------------------- | |
@@ -316,6 +336,9 class MetaHasTraitlets(type): | |||||
316 | This instantiates all TraitletTypes in the class dict and sets their |
|
336 | This instantiates all TraitletTypes in the class dict and sets their | |
317 | :attr:`name` attribute. |
|
337 | :attr:`name` attribute. | |
318 | """ |
|
338 | """ | |
|
339 | # print "MetaHasTraitlets (mcls, name): ", mcls, name | |||
|
340 | # print "MetaHasTraitlets (bases): ", bases | |||
|
341 | # print "MetaHasTraitlets (classdict): ", classdict | |||
319 | for k,v in classdict.iteritems(): |
|
342 | for k,v in classdict.iteritems(): | |
320 | if isinstance(v, TraitletType): |
|
343 | if isinstance(v, TraitletType): | |
321 | v.name = k |
|
344 | v.name = k | |
@@ -354,9 +377,16 class HasTraitlets(object): | |||||
354 | # Here we tell all the TraitletType instances to set their default |
|
377 | # Here we tell all the TraitletType instances to set their default | |
355 | # values on the instance. |
|
378 | # values on the instance. | |
356 | for key in dir(cls): |
|
379 | for key in dir(cls): | |
357 | value = getattr(cls, key) |
|
380 | # Some descriptors raise AttributeError like zope.interface's | |
358 | if isinstance(value, TraitletType): |
|
381 | # __provides__ attributes even though they exist. This causes | |
359 | value.instance_init(inst) |
|
382 | # AttributeErrors even though they are listed in dir(cls). | |
|
383 | try: | |||
|
384 | value = getattr(cls, key) | |||
|
385 | except AttributeError: | |||
|
386 | pass | |||
|
387 | else: | |||
|
388 | if isinstance(value, TraitletType): | |||
|
389 | value.instance_init(inst) | |||
360 | return inst |
|
390 | return inst | |
361 |
|
391 | |||
362 | # def __init__(self): |
|
392 | # def __init__(self): | |
@@ -475,7 +505,7 class HasTraitlets(object): | |||||
475 | exists, but has any value. This is because get_metadata returns |
|
505 | exists, but has any value. This is because get_metadata returns | |
476 | None if a metadata key doesn't exist. |
|
506 | None if a metadata key doesn't exist. | |
477 | """ |
|
507 | """ | |
478 |
traitlets = dict([memb for memb in |
|
508 | traitlets = dict([memb for memb in getmembers(self.__class__) if \ | |
479 | isinstance(memb[1], TraitletType)]) |
|
509 | isinstance(memb[1], TraitletType)]) | |
480 |
|
510 | |||
481 | if len(metadata) == 0: |
|
511 | if len(metadata) == 0: |
General Comments 0
You need to be logged in to leave comments.
Login now