Show More
@@ -17,7 +17,6 b' Authors:' | |||||
17 | #----------------------------------------------------------------------------- |
|
17 | #----------------------------------------------------------------------------- | |
18 |
|
18 | |||
19 | # stdlib imports |
|
19 | # stdlib imports | |
20 | import glob |
|
|||
21 | import os |
|
20 | import os | |
22 | import signal |
|
21 | import signal | |
23 | import sys |
|
22 | import sys | |
@@ -31,7 +30,7 b' from zmq.utils import jsonapi as json' | |||||
31 | from IPython.config.application import boolean_flag |
|
30 | from IPython.config.application import boolean_flag | |
32 | from IPython.core.application import BaseIPythonApplication |
|
31 | from IPython.core.application import BaseIPythonApplication | |
33 | from IPython.core.profiledir import ProfileDir |
|
32 | from IPython.core.profiledir import ProfileDir | |
34 | from IPython.lib.kernel import tunnel_to_kernel |
|
33 | from IPython.lib.kernel import tunnel_to_kernel, find_connection_file | |
35 | from IPython.frontend.qt.console.frontend_widget import FrontendWidget |
|
34 | from IPython.frontend.qt.console.frontend_widget import FrontendWidget | |
36 | from IPython.frontend.qt.console.ipython_widget import IPythonWidget |
|
35 | from IPython.frontend.qt.console.ipython_widget import IPythonWidget | |
37 | from IPython.frontend.qt.console.rich_ipython_widget import RichIPythonWidget |
|
36 | from IPython.frontend.qt.console.rich_ipython_widget import RichIPythonWidget | |
@@ -363,26 +362,12 b' class IPythonQtConsoleApp(BaseIPythonApplication):' | |||||
363 | fileglob, and the matching file in the current profile's security dir |
|
362 | fileglob, and the matching file in the current profile's security dir | |
364 | with the latest access time will be used. |
|
363 | with the latest access time will be used. | |
365 | """ |
|
364 | """ | |
366 | sec = self.profile_dir.security_dir |
|
|||
367 | if self.existing: |
|
365 | if self.existing: | |
368 | try: |
|
366 | try: | |
369 | # first, try explicit name |
|
367 | cf = find_connection_file(self.existing) | |
370 | cf = filefind(self.existing, ['.', sec]) |
|
368 | except Exception: | |
371 | except IOError: |
|
369 | self.log.critical("Could not find existing kernel connection file %s", self.existing) | |
372 | # not found by full name |
|
370 | self.exit(1) | |
373 | if '*' in self.existing: |
|
|||
374 | # given as a glob already |
|
|||
375 | pat = self.existing |
|
|||
376 | else: |
|
|||
377 | # accept any substring match |
|
|||
378 | pat = '*%s*' % self.existing |
|
|||
379 | matches = glob.glob( os.path.join(sec, pat) ) |
|
|||
380 | if not matches: |
|
|||
381 | self.log.critical("Could not find existing kernel connection file %s", self.existing) |
|
|||
382 | self.exit(1) |
|
|||
383 | else: |
|
|||
384 | # get most recent match: |
|
|||
385 | cf = sorted(matches, key=lambda f: os.stat(f).st_atime)[-1] |
|
|||
386 | self.log.info("Connecting to existing kernel: %s" % cf) |
|
371 | self.log.info("Connecting to existing kernel: %s" % cf) | |
387 | self.connection_file = cf |
|
372 | self.connection_file = cf | |
388 | # should load_connection_file only be used for existing? |
|
373 | # should load_connection_file only be used for existing? |
@@ -17,7 +17,9 b' Authors:' | |||||
17 | # Imports |
|
17 | # Imports | |
18 | #----------------------------------------------------------------------------- |
|
18 | #----------------------------------------------------------------------------- | |
19 |
|
19 | |||
|
20 | import glob | |||
20 | import json |
|
21 | import json | |
|
22 | import os | |||
21 | import sys |
|
23 | import sys | |
22 | from getpass import getpass |
|
24 | from getpass import getpass | |
23 | from subprocess import Popen, PIPE |
|
25 | from subprocess import Popen, PIPE | |
@@ -26,7 +28,8 b' from subprocess import Popen, PIPE' | |||||
26 | from IPython.external.ssh import tunnel |
|
28 | from IPython.external.ssh import tunnel | |
27 |
|
29 | |||
28 | # IPython imports |
|
30 | # IPython imports | |
29 |
from IPython. |
|
31 | from IPython.core.profiledir import ProfileDir | |
|
32 | from IPython.utils.path import filefind, get_ipython_dir | |||
30 | from IPython.utils.py3compat import str_to_bytes |
|
33 | from IPython.utils.py3compat import str_to_bytes | |
31 |
|
34 | |||
32 |
|
35 | |||
@@ -49,22 +52,108 b' def get_connection_file(app=None):' | |||||
49 |
|
52 | |||
50 | app = KernelApp.instance() |
|
53 | app = KernelApp.instance() | |
51 | return filefind(app.connection_file, ['.', app.profile_dir.security_dir]) |
|
54 | return filefind(app.connection_file, ['.', app.profile_dir.security_dir]) | |
52 |
|
55 | |||
53 | def get_connection_info(unpack=False): |
|
56 | def find_connection_file(filename, profile=None): | |
|
57 | """find a connection file, and return its absolute path. | |||
|
58 | ||||
|
59 | The current working directory and the profile's security | |||
|
60 | directory will be searched for the file if it is not given by | |||
|
61 | absolute path. | |||
|
62 | ||||
|
63 | If profile is unspecified, then the current running application's | |||
|
64 | profile will be used, or 'default', if not run from IPython. | |||
|
65 | ||||
|
66 | If the argument does not match an existing file, it will be interpreted as a | |||
|
67 | fileglob, and the matching file in the profile's security dir with | |||
|
68 | the latest access time will be used. | |||
|
69 | ||||
|
70 | Parameters | |||
|
71 | ---------- | |||
|
72 | filename : str | |||
|
73 | The connection file or fileglob to search for. | |||
|
74 | profile : str [optional] | |||
|
75 | The name of the profile to use when searching for the connection file, | |||
|
76 | if different from the current IPython session or 'default'. | |||
|
77 | ||||
|
78 | Returns | |||
|
79 | ------- | |||
|
80 | str : The absolute path of the connection file. | |||
|
81 | """ | |||
|
82 | from IPython.core.application import BaseIPythonApplication as IPApp | |||
|
83 | try: | |||
|
84 | # quick check for absolute path, before going through logic | |||
|
85 | return filefind(filename) | |||
|
86 | except IOError: | |||
|
87 | pass | |||
|
88 | ||||
|
89 | if profile is None: | |||
|
90 | # profile unspecified, check if running from an IPython app | |||
|
91 | if IPApp.initialized(): | |||
|
92 | app = IPApp.instance() | |||
|
93 | profile_dir = app.profile_dir | |||
|
94 | else: | |||
|
95 | # not running in IPython, use default profile | |||
|
96 | profile_dir = ProfileDir.find_profile_dir_by_name(get_ipython_dir(), 'default') | |||
|
97 | else: | |||
|
98 | # find profiledir by profile name: | |||
|
99 | profile_dir = ProfileDir.find_profile_dir_by_name(get_ipython_dir(), profile) | |||
|
100 | security_dir = profile_dir.security_dir | |||
|
101 | ||||
|
102 | try: | |||
|
103 | # first, try explicit name | |||
|
104 | return filefind(filename, ['.', security_dir]) | |||
|
105 | except IOError: | |||
|
106 | pass | |||
|
107 | ||||
|
108 | # not found by full name | |||
|
109 | ||||
|
110 | if '*' in filename: | |||
|
111 | # given as a glob already | |||
|
112 | pat = filename | |||
|
113 | else: | |||
|
114 | # accept any substring match | |||
|
115 | pat = '*%s*' % filename | |||
|
116 | matches = glob.glob( os.path.join(security_dir, pat) ) | |||
|
117 | if not matches: | |||
|
118 | raise IOError("Could not find %r in %r" % (filename, security_dir)) | |||
|
119 | elif len(matches) == 1: | |||
|
120 | return matches[0] | |||
|
121 | else: | |||
|
122 | # get most recent match, by access time: | |||
|
123 | return sorted(matches, key=lambda f: os.stat(f).st_atime)[-1] | |||
|
124 | ||||
|
125 | def get_connection_info(connection_file=None, unpack=False, profile=None): | |||
54 | """Return the connection information for the current Kernel. |
|
126 | """Return the connection information for the current Kernel. | |
55 |
|
127 | |||
56 | Parameters |
|
128 | Parameters | |
57 | ---------- |
|
129 | ---------- | |
|
130 | connection_file : str [optional] | |||
|
131 | The connection file to be used. Can be given by absolute path, or | |||
|
132 | IPython will search in the security directory of a given profile. | |||
|
133 | If run from IPython, | |||
|
134 | ||||
|
135 | If unspecified, the connection file for the currently running | |||
|
136 | IPython Kernel will be used, which is only allowed from inside a kernel. | |||
58 | unpack : bool [default: False] |
|
137 | unpack : bool [default: False] | |
59 | if True, return the unpacked dict, otherwise just the string contents |
|
138 | if True, return the unpacked dict, otherwise just the string contents | |
60 | of the file. |
|
139 | of the file. | |
|
140 | profile : str [optional] | |||
|
141 | The name of the profile to use when searching for the connection file, | |||
|
142 | if different from the current IPython session or 'default'. | |||
|
143 | ||||
61 |
|
144 | |||
62 | Returns |
|
145 | Returns | |
63 | ------- |
|
146 | ------- | |
64 | The connection dictionary of the current kernel, as string or dict, |
|
147 | The connection dictionary of the current kernel, as string or dict, | |
65 | depending on `unpack`. |
|
148 | depending on `unpack`. | |
66 | """ |
|
149 | """ | |
67 |
|
|
150 | if connection_file is None: | |
|
151 | # get connection file from current kernel | |||
|
152 | cf = get_connection_file() | |||
|
153 | else: | |||
|
154 | # connection file specified, allow shortnames: | |||
|
155 | cf = find_connection_file(connection_file, profile=profile) | |||
|
156 | ||||
68 | with open(cf) as f: |
|
157 | with open(cf) as f: | |
69 | info = f.read() |
|
158 | info = f.read() | |
70 |
|
159 | |||
@@ -74,7 +163,7 b' def get_connection_info(unpack=False):' | |||||
74 | info['key'] = str_to_bytes(info.get('key', '')) |
|
163 | info['key'] = str_to_bytes(info.get('key', '')) | |
75 | return info |
|
164 | return info | |
76 |
|
165 | |||
77 | def connect_qtconsole(argv=None): |
|
166 | def connect_qtconsole(connection_file=None, argv=None, profile=None): | |
78 | """Connect a qtconsole to the current kernel. |
|
167 | """Connect a qtconsole to the current kernel. | |
79 |
|
168 | |||
80 | This is useful for connecting a second qtconsole to a kernel, or to a |
|
169 | This is useful for connecting a second qtconsole to a kernel, or to a | |
@@ -82,8 +171,19 b' def connect_qtconsole(argv=None):' | |||||
82 |
|
171 | |||
83 | Parameters |
|
172 | Parameters | |
84 | ---------- |
|
173 | ---------- | |
|
174 | connection_file : str [optional] | |||
|
175 | The connection file to be used. Can be given by absolute path, or | |||
|
176 | IPython will search in the security directory of a given profile. | |||
|
177 | If run from IPython, | |||
|
178 | ||||
|
179 | If unspecified, the connection file for the currently running | |||
|
180 | IPython Kernel will be used, which is only allowed from inside a kernel. | |||
85 | argv : list [optional] |
|
181 | argv : list [optional] | |
86 | Any extra args to be passed to the console. |
|
182 | Any extra args to be passed to the console. | |
|
183 | profile : str [optional] | |||
|
184 | The name of the profile to use when searching for the connection file, | |||
|
185 | if different from the current IPython session or 'default'. | |||
|
186 | ||||
87 |
|
187 | |||
88 | Returns |
|
188 | Returns | |
89 | ------- |
|
189 | ------- | |
@@ -91,8 +191,11 b' def connect_qtconsole(argv=None):' | |||||
91 | """ |
|
191 | """ | |
92 | argv = [] if argv is None else argv |
|
192 | argv = [] if argv is None else argv | |
93 |
|
193 | |||
94 |
|
|
194 | if connection_file is None: | |
95 | cf = get_connection_file() |
|
195 | # get connection file from current kernel | |
|
196 | cf = get_connection_file() | |||
|
197 | else: | |||
|
198 | cf = find_connection_file(connection_file, profile=profile) | |||
96 |
|
199 | |||
97 | cmd = ';'.join([ |
|
200 | cmd = ';'.join([ | |
98 | "from IPython.frontend.qt.console import qtconsoleapp", |
|
201 | "from IPython.frontend.qt.console import qtconsoleapp", |
@@ -471,7 +471,7 b' class ZMQInteractiveShell(InteractiveShell):' | |||||
471 | debugging. |
|
471 | debugging. | |
472 | """ |
|
472 | """ | |
473 | try: |
|
473 | try: | |
474 | p = connect_qtconsole(arg_split(arg_s, os.name=='posix')) |
|
474 | p = connect_qtconsole(argv=arg_split(arg_s, os.name=='posix')) | |
475 | except Exception as e: |
|
475 | except Exception as e: | |
476 | error("Could not start qtconsole: %r" % e) |
|
476 | error("Could not start qtconsole: %r" % e) | |
477 | return |
|
477 | return |
General Comments 0
You need to be logged in to leave comments.
Login now