1+ import json
2+ import tempfile
13from ipykernel .kernelbase import Kernel
4+ from jupyter_client .kernelspec import find_kernel_specs
25from pexpect import replwrap , EOF
36import pexpect
7+ from pathlib import Path
48
59from subprocess import check_output
610import os .path
711import uuid
812import random
913import string
1014
15+ try :
16+ import bash_kernel
17+ # installation reads __version__. since the package isn't ready yet
18+ # this will fail, so we add the except clause
19+ except ModuleNotFoundError :
20+ bash_kernel = None
21+
22+
1123import re
1224import signal
1325
@@ -101,9 +113,42 @@ def __init__(self, **kwargs):
101113 rand = '' .join (random .choices (string .ascii_uppercase , k = 12 ))
102114 self .unique_prompt = "PROMPT_" + rand
103115 Kernel .__init__ (self , ** kwargs )
104- self ._start_bash ()
116+
117+ # determine which bashrc to use
118+ kernelspecs = find_kernel_specs ()
119+ kernelspec_bash = kernelspecs ['bash' ]
120+
121+ if not kernelspec_bash :
122+ raise RuntimeError ("Can't find bash kernelspec" )
123+
124+ settings = json .loads (Path (kernelspec_bash , 'settings.json' ).read_text ())
125+ CONDA_DEFAULT_ENV = settings .get ("conda_default_env" )
126+
127+ if CONDA_DEFAULT_ENV :
128+ print ("Generating temporary bashrc..." )
129+ template = os .path .join (os .path .dirname (bash_kernel .__file__ ), 'assets' ,
130+ 'bashrc-conda' )
131+ template_content = (Path (template ).read_text ()
132+ .format (CONDA_DEFAULT_ENV = CONDA_DEFAULT_ENV ))
133+
134+ self ._bashrc_tmp = tempfile .NamedTemporaryFile (mode = 'w' )
135+ self ._bashrc_tmp .write (template_content )
136+ self ._bashrc_tmp .flush ()
137+ self ._path_to_bashrc = self ._bashrc_tmp .name
138+ self ._start_bash ()
139+ else :
140+ bashrc = os .path .join (os .path .dirname (pexpect .__file__ ), 'bashrc.sh' )
141+ self ._bashrc_tmp = None
142+ self ._path_to_bashrc = bashrc
143+ self ._start_bash ()
144+
145+
105146 self ._known_display_ids = set ()
106147
148+ def __del__ (self ):
149+ if self ._bashrc_tmp :
150+ self ._bashrc_tmp .close ()
151+
107152 def _start_bash (self ):
108153 # Signal handlers are inherited by forked processes, and we can't easily
109154 # reset it from the subprocess. Since kernelapp ignores SIGINT except in
@@ -115,8 +160,7 @@ def _start_bash(self):
115160 # bash() function of pexpect/replwrap.py. Look at the
116161 # source code there for comments and context for
117162 # understanding the code here.
118- bashrc = os .path .join (os .path .dirname (pexpect .__file__ ), 'bashrc.sh' )
119- child = pexpect .spawn ("bash" , ['--rcfile' , bashrc ], echo = False ,
163+ child = pexpect .spawn ("bash" , ['--rcfile' , self ._path_to_bashrc ], echo = False ,
120164 encoding = 'utf-8' , codec_errors = 'replace' )
121165 # Following comment stolen from upstream's REPLWrap:
122166 # If the user runs 'env', the value of PS1 will be in the output. To avoid
0 commit comments