def test_clean_env(): env = { 'foo': '/foo/bar/測試', 'bar': '/spam', 'PYTHONPATH': u'\u6e2c\u8a66', } new_env = clean_env(env) assert new_env['foo'] == '/foo/bar/\xe6\xb8\xac\xe8\xa9\xa6' assert new_env['PYTHONPATH'] == '\xe6\xb8\xac\xe8\xa9\xa6'
def start(self): self.zmq_out_socket = self.context.socket(zmq.PAIR) self.zmq_out_port = self.zmq_out_socket.bind_to_random_port( 'tcp://{}'.format(LOCALHOST)) self.zmq_in_socket = self.context.socket(zmq.PAIR) self.zmq_in_socket.set_hwm(0) self.zmq_in_port = self.zmq_in_socket.bind_to_random_port( 'tcp://{}'.format(LOCALHOST)) self.transport_args += [ '--zmq-in-port', self.zmq_out_port, '--zmq-out-port', self.zmq_in_port ] server_log = subprocess.PIPE pid = os.getpid() if get_debug_level() > 0: # Create server log file server_log_fname = 'server_{0}_{1}.log'.format(self.language, pid) server_log_file = get_conf_path( osp.join('lsp_logs', server_log_fname)) if not osp.exists(osp.dirname(server_log_file)): os.makedirs(osp.dirname(server_log_file)) server_log = open(server_log_file, 'w') if self.stdio: server_log.close() if self.language == 'python': self.server_args += ['--log-file', server_log_file] self.transport_args += ['--server-log-file', server_log_file] # Start server with logging options if self.language != 'cpp': if get_debug_level() == 2: self.server_args.append('-v') elif get_debug_level() == 3: self.server_args.append('-vv') server_stdin = subprocess.PIPE server_stdout = server_log server_stderr = subprocess.STDOUT if not self.external_server: logger.info('Starting server: {0}'.format(' '.join( self.server_args))) creation_flags = 0 if os.name == 'nt': creation_flags = (subprocess.CREATE_NEW_PROCESS_GROUP | 0x08000000) # CREATE_NO_WINDOW if os.environ.get('CI') and os.name == 'nt': # The following patching avoids: # # OSError: [WinError 6] The handle is invalid # # while running our tests in CI services on Windows # (they run fine locally). # See this comment for an explanation: # https://stackoverflow.com/q/43966523/ # 438386#comment74964124_43966523 def patched_cleanup(): pass subprocess._cleanup = patched_cleanup self.lsp_server = subprocess.Popen(self.server_args, stdout=server_stdout, stdin=server_stdin, stderr=server_stderr, creationflags=creation_flags) client_log = subprocess.PIPE if get_debug_level() > 0: # Client log file client_log_fname = 'client_{0}_{1}.log'.format(self.language, pid) client_log_file = get_conf_path( osp.join('lsp_logs', client_log_fname)) if not osp.exists(osp.dirname(client_log_file)): os.makedirs(osp.dirname(client_log_file)) client_log = open(client_log_file, 'w') new_env = dict(os.environ) python_path = os.pathsep.join(sys.path)[1:] new_env['PYTHONPATH'] = python_path # This allows running LSP tests directly without having to install # Spyder if running_under_pytest(): new_env['PYTHONPATH'] = os.pathsep.join(sys.path)[:] # On some CI systems there are unicode characters inside PYTHOPATH # which raise errors if not removed if PY2: new_env = clean_env(new_env) self.transport_args = list(map(str, self.transport_args)) logger.info('Starting transport: {0}'.format(' '.join( self.transport_args))) if self.stdio: transport_stdin = subprocess.PIPE transport_stdout = subprocess.PIPE transport_stderr = client_log self.transport_args += self.server_args else: transport_stdout = client_log transport_stdin = subprocess.PIPE transport_stderr = subprocess.STDOUT self.transport_client = subprocess.Popen(self.transport_args, stdout=transport_stdout, stdin=transport_stdin, stderr=transport_stderr, env=new_env) fid = self.zmq_in_socket.getsockopt(zmq.FD) self.notifier = QSocketNotifier(fid, QSocketNotifier.Read, self) self.notifier.activated.connect(self.on_msg_received) # This is necessary for tests to pass locally! logger.debug('LSP {} client started!'.format(self.language))
def env(self): """Env vars for kernels""" # Add our PYTHONPATH to the kernel pathlist = CONF.get('main', 'spyder_pythonpath', default=[]) default_interpreter = CONF.get('main_interpreter', 'default') pypath = add_pathlist_to_PYTHONPATH([], pathlist, ipyconsole=True, drop_env=False) # Environment variables that we need to pass to our sitecustomize umr_namelist = CONF.get('main_interpreter', 'umr/namelist') if PY2: original_list = umr_namelist[:] for umr_n in umr_namelist: try: umr_n.encode('utf-8') except UnicodeDecodeError: umr_namelist.remove(umr_n) if original_list != umr_namelist: CONF.set('main_interpreter', 'umr/namelist', umr_namelist) env_vars = { 'SPY_EXTERNAL_INTERPRETER': not default_interpreter, 'SPY_UMR_ENABLED': CONF.get('main_interpreter', 'umr/enabled'), 'SPY_UMR_VERBOSE': CONF.get('main_interpreter', 'umr/verbose'), 'SPY_UMR_NAMELIST': ','.join(umr_namelist), 'SPY_RUN_LINES_O': CONF.get('ipython_console', 'startup/run_lines'), 'SPY_PYLAB_O': CONF.get('ipython_console', 'pylab'), 'SPY_BACKEND_O': CONF.get('ipython_console', 'pylab/backend'), 'SPY_AUTOLOAD_PYLAB_O': CONF.get('ipython_console', 'pylab/autoload'), 'SPY_FORMAT_O': CONF.get('ipython_console', 'pylab/inline/figure_format'), 'SPY_BBOX_INCHES_O': CONF.get('ipython_console', 'pylab/inline/bbox_inches'), 'SPY_RESOLUTION_O': CONF.get('ipython_console', 'pylab/inline/resolution'), 'SPY_WIDTH_O': CONF.get('ipython_console', 'pylab/inline/width'), 'SPY_HEIGHT_O': CONF.get('ipython_console', 'pylab/inline/height'), 'SPY_USE_FILE_O': CONF.get('ipython_console', 'startup/use_run_file'), 'SPY_RUN_FILE_O': CONF.get('ipython_console', 'startup/run_file'), 'SPY_AUTOCALL_O': CONF.get('ipython_console', 'autocall'), 'SPY_GREEDY_O': CONF.get('ipython_console', 'greedy_completer'), 'SPY_JEDI_O': CONF.get('ipython_console', 'jedi_completer'), 'SPY_SYMPY_O': CONF.get('ipython_console', 'symbolic_math'), 'SPY_TESTING': running_under_pytest() or SAFE_MODE, 'SPY_HIDE_CMD': CONF.get('ipython_console', 'hide_cmd_windows') } if self.is_pylab is True: env_vars['SPY_AUTOLOAD_PYLAB_O'] = True env_vars['SPY_SYMPY_O'] = False env_vars['SPY_RUN_CYTHON'] = False if self.is_sympy is True: env_vars['SPY_AUTOLOAD_PYLAB_O'] = False env_vars['SPY_SYMPY_O'] = True env_vars['SPY_RUN_CYTHON'] = False if self.is_cython is True: env_vars['SPY_AUTOLOAD_PYLAB_O'] = False env_vars['SPY_SYMPY_O'] = False env_vars['SPY_RUN_CYTHON'] = True # Add our PYTHONPATH to env_vars env_vars.update(pypath) # Making all env_vars strings clean_env_vars = clean_env(env_vars) return clean_env_vars
def env(self): """Env vars for kernels""" default_interpreter = self.get_conf('default', section='main_interpreter') env_vars = os.environ.copy() # Avoid IPython adding the virtualenv on which Spyder is running # to the kernel sys.path env_vars.pop('VIRTUAL_ENV', None) # Add spyder-kernels subrepo path to PYTHONPATH if (DEV or running_under_pytest()) and not running_in_ci(): repo_path = osp.normpath(osp.join(HERE, '..', '..', '..', '..')) subrepo_path = osp.join(repo_path, 'external-deps', 'spyder-kernels') env_vars.update({'PYTHONPATH': subrepo_path}) # List of paths declared by the user, plus project's path, to # add to PYTHONPATH pathlist = self.get_conf('spyder_pythonpath', default=[], section='main') pypath = os.pathsep.join(pathlist) # List of modules to exclude from our UMR umr_namelist = self.get_conf('umr/namelist', section='main_interpreter') # Environment variables that we need to pass to the kernel env_vars.update({ 'SPY_EXTERNAL_INTERPRETER': not default_interpreter, 'SPY_UMR_ENABLED': self.get_conf('umr/enabled', section='main_interpreter'), 'SPY_UMR_VERBOSE': self.get_conf('umr/verbose', section='main_interpreter'), 'SPY_UMR_NAMELIST': ','.join(umr_namelist), 'SPY_RUN_LINES_O': self.get_conf('startup/run_lines'), 'SPY_PYLAB_O': self.get_conf('pylab'), 'SPY_BACKEND_O': self.get_conf('pylab/backend'), 'SPY_AUTOLOAD_PYLAB_O': self.get_conf('pylab/autoload'), 'SPY_FORMAT_O': self.get_conf('pylab/inline/figure_format'), 'SPY_BBOX_INCHES_O': self.get_conf('pylab/inline/bbox_inches'), 'SPY_RESOLUTION_O': self.get_conf('pylab/inline/resolution'), 'SPY_WIDTH_O': self.get_conf('pylab/inline/width'), 'SPY_HEIGHT_O': self.get_conf('pylab/inline/height'), 'SPY_USE_FILE_O': self.get_conf('startup/use_run_file'), 'SPY_RUN_FILE_O': self.get_conf('startup/run_file'), 'SPY_AUTOCALL_O': self.get_conf('autocall'), 'SPY_GREEDY_O': self.get_conf('greedy_completer'), 'SPY_JEDI_O': self.get_conf('jedi_completer'), 'SPY_SYMPY_O': self.get_conf('symbolic_math'), 'SPY_TESTING': running_under_pytest() or get_safe_mode(), 'SPY_HIDE_CMD': self.get_conf('hide_cmd_windows'), 'SPY_PYTHONPATH': pypath }) if self.is_pylab is True: env_vars['SPY_AUTOLOAD_PYLAB_O'] = True env_vars['SPY_SYMPY_O'] = False env_vars['SPY_RUN_CYTHON'] = False if self.is_sympy is True: env_vars['SPY_AUTOLOAD_PYLAB_O'] = False env_vars['SPY_SYMPY_O'] = True env_vars['SPY_RUN_CYTHON'] = False if self.is_cython is True: env_vars['SPY_AUTOLOAD_PYLAB_O'] = False env_vars['SPY_SYMPY_O'] = False env_vars['SPY_RUN_CYTHON'] = True # App considerations if (running_in_mac_app() or is_pynsist()) and not default_interpreter: env_vars.pop('PYTHONHOME', None) env_vars.pop('PYTHONPATH', None) # Remove this variable because it prevents starting kernels for # external interpreters when present. # Fixes spyder-ide/spyder#13252 env_vars.pop('PYTHONEXECUTABLE', None) # Making all env_vars strings clean_env_vars = clean_env(env_vars) return clean_env_vars
def env(self): """Env vars for kernels""" default_interpreter = CONF.get('main_interpreter', 'default') env_vars = os.environ.copy() # Avoid IPython adding the virtualenv on which Spyder is running # to the kernel sys.path env_vars.pop('VIRTUAL_ENV', None) pathlist = CONF.get('main', 'spyder_pythonpath', default=[]) # Add spyder-kernels subrepo path to pathlist if DEV or running_under_pytest(): repo_path = osp.normpath(osp.join(HERE, '..', '..', '..', '..')) subrepo_path = osp.join(repo_path, 'external-deps', 'spyder-kernels') if running_under_pytest(): # Oddly pathlist is not set as an empty list when running # under pytest pathlist = [subrepo_path] else: pathlist += [subrepo_path] + pathlist # Create PYTHONPATH env entry to add it to the kernel pypath = add_pathlist_to_PYTHONPATH([], pathlist, ipyconsole=True, drop_env=True) # Add our PYTHONPATH to env_vars env_vars.update(pypath) # Environment variables that we need to pass to our sitecustomize umr_namelist = CONF.get('main_interpreter', 'umr/namelist') env_vars.update({ 'SPY_EXTERNAL_INTERPRETER': not default_interpreter, 'SPY_UMR_ENABLED': CONF.get('main_interpreter', 'umr/enabled'), 'SPY_UMR_VERBOSE': CONF.get('main_interpreter', 'umr/verbose'), 'SPY_UMR_NAMELIST': ','.join(umr_namelist), 'SPY_RUN_LINES_O': CONF.get('ipython_console', 'startup/run_lines'), 'SPY_PYLAB_O': CONF.get('ipython_console', 'pylab'), 'SPY_BACKEND_O': CONF.get('ipython_console', 'pylab/backend'), 'SPY_AUTOLOAD_PYLAB_O': CONF.get('ipython_console', 'pylab/autoload'), 'SPY_FORMAT_O': CONF.get('ipython_console', 'pylab/inline/figure_format'), 'SPY_BBOX_INCHES_O': CONF.get('ipython_console', 'pylab/inline/bbox_inches'), 'SPY_RESOLUTION_O': CONF.get('ipython_console', 'pylab/inline/resolution'), 'SPY_WIDTH_O': CONF.get('ipython_console', 'pylab/inline/width'), 'SPY_HEIGHT_O': CONF.get('ipython_console', 'pylab/inline/height'), 'SPY_USE_FILE_O': CONF.get('ipython_console', 'startup/use_run_file'), 'SPY_RUN_FILE_O': CONF.get('ipython_console', 'startup/run_file'), 'SPY_AUTOCALL_O': CONF.get('ipython_console', 'autocall'), 'SPY_GREEDY_O': CONF.get('ipython_console', 'greedy_completer'), 'SPY_JEDI_O': CONF.get('ipython_console', 'jedi_completer'), 'SPY_SYMPY_O': CONF.get('ipython_console', 'symbolic_math'), 'SPY_TESTING': running_under_pytest() or SAFE_MODE, 'SPY_HIDE_CMD': CONF.get('ipython_console', 'hide_cmd_windows') }) if self.is_pylab is True: env_vars['SPY_AUTOLOAD_PYLAB_O'] = True env_vars['SPY_SYMPY_O'] = False env_vars['SPY_RUN_CYTHON'] = False if self.is_sympy is True: env_vars['SPY_AUTOLOAD_PYLAB_O'] = False env_vars['SPY_SYMPY_O'] = True env_vars['SPY_RUN_CYTHON'] = False if self.is_cython is True: env_vars['SPY_AUTOLOAD_PYLAB_O'] = False env_vars['SPY_SYMPY_O'] = False env_vars['SPY_RUN_CYTHON'] = True # macOS app considerations if running_in_mac_app() and not default_interpreter: env_vars.pop('PYTHONHOME', None) # Making all env_vars strings clean_env_vars = clean_env(env_vars) return clean_env_vars