def for_popen(self): """Returns a copy of this dict, with all strings converted to the type suitable for subprocess.Popen() and other similar APIs. """ return { compat.filename_str(k): compat.filename_str(v) for k, v in self.items() }
def spawn_debuggee(self, args, cwd=None, exe=sys.executable, debug_me=None): assert self.debuggee is None assert not len(self.captured_output - {"stdout", "stderr"}) args = [exe] + [ compat.filename_str( s.strpath if isinstance(s, py.path.local) else s) for s in args ] cwd = compat.filename_str(cwd) if isinstance(cwd, py.path.local) else cwd env = self._make_env(self.spawn_debuggee.env, codecov=False) env["PTVSD_ADAPTER_ENDPOINTS"] = self.adapter_endpoints = ( self.tmpdir / "adapter_endpoints") if debug_me is not None: env["PTVSD_TEST_DEBUG_ME"] = debug_me log.info( "Spawning {0}:\n\n" "Current directory: {1!j}\n\n" "Command line: {2!j}\n\n" "Environment variables: {3!j}\n\n", self.debuggee_id, cwd, args, env, ) popen_fds = {} capture_fds = {} for stream_name in self.captured_output: rfd, wfd = os.pipe() popen_fds[stream_name] = wfd capture_fds[stream_name] = rfd self.debuggee = psutil.Popen(args, cwd=cwd, env=env.for_popen(), bufsize=0, stdin=subprocess.PIPE, **popen_fds) log.info("Spawned {0} with PID={1}", self.debuggee_id, self.debuggee.pid) watchdog.register_spawn(self.debuggee.pid, self.debuggee_id) if len(capture_fds): self.captured_output = output.CapturedOutput(self, **capture_fds) for fd in popen_fds.values(): os.close(fd)
def spawn_debuggee(self, args, cwd=None, exe=sys.executable, debug_me=None): assert self.debuggee is None args = [exe] + [ compat.filename_str( s.strpath if isinstance(s, py.path.local) else s) for s in args ] cwd = compat.filename_str(cwd) if isinstance(cwd, py.path.local) else cwd env = self._make_env(self.spawn_debuggee.env, codecov=False) env["PTVSD_LISTENER_FILE"] = self.listener_file = self.tmpdir / "listener" if debug_me is not None: env["PTVSD_TEST_DEBUG_ME"] = debug_me log.info( "Spawning {0}:\n\n" "Current directory: {1!j}\n\n" "Command line: {2!j}\n\n" "Environment variables: {3!j}\n\n", self.debuggee_id, cwd, args, env, ) self.debuggee = psutil.Popen( args, cwd=cwd, env=env.for_popen(), bufsize=0, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, ) log.info("Spawned {0} with PID={1}", self.debuggee_id, self.debuggee.pid) watchdog.register_spawn(self.debuggee.pid, self.debuggee_id) if self.captured_output: self.captured_output = output.CapturedOutput(self)
def attach_by_socket(session, target, method, listener="server", cwd=None, wait=True, log_dir=None): log.info("Attaching {0} to {1} by socket using {2}.", session, target, method.upper()) assert method in ("api", "cli") assert listener in ("server") # TODO: ("adapter", "server") config = _attach_common_config(session, target, cwd) host = config["host"] = attach_by_socket.host port = config["port"] = attach_by_socket.port if method == "cli": args = [os.path.dirname(ptvsd.__file__)] if wait: args += ["--wait"] args += ["--host", compat.filename_str(host), "--port", str(port)] if not config["subProcess"]: args += ["--no-subprocesses"] if log_dir is not None: args += ["--log-dir", log_dir] debug_me = None elif method == "api": args = [] debug_me = """ import ptvsd ptvsd.enable_attach(({host!r}, {port!r}), {args}) if {wait!r}: ptvsd.wait_for_attach() """ attach_args = "" if log_dir is None else fmt("log_dir={0!r}", log_dir) debug_me = fmt(debug_me, host=host, port=port, wait=wait, args=attach_args) else: raise ValueError args += target.cli(session.spawn_debuggee.env) session.spawn_debuggee(args, cwd=cwd, debug_me=debug_me) if wait: session.wait_for_enable_attach() session.connect_to_adapter((host, port)) return session.request_attach()
def spawn_launcher(): with session.accept_connection_from_launcher() as (_, launcher_port): env[str("PTVSD_LAUNCHER_PORT")] = str(launcher_port) if common_options.log_dir is not None: env[str("PTVSD_LOG_DIR")] = compat.filename_str( common_options.log_dir) if adapter_options.log_stderr: env[str("PTVSD_LOG_STDERR")] = str("debug info warning error") if console == "internalConsole": log.info("{0} spawning launcher: {1!r}", session, cmdline) # If we are talking to the IDE over stdio, sys.stdin and sys.stdout are # redirected to avoid mangling the DAP message stream. Make sure the # launcher also respects that. subprocess.Popen( cmdline, env=dict(list(os.environ.items()) + list(env.items())), stdin=sys.stdin, stdout=sys.stdout, stderr=sys.stderr, ) else: log.info('{0} spawning launcher via "runInTerminal" request.', session) session.ide.capabilities.require( "supportsRunInTerminalRequest") kinds = { "integratedTerminal": "integrated", "externalTerminal": "external", } session.ide.channel.request( "runInTerminal", { "kind": kinds[console], "title": console_title, "args": cmdline, "env": env, }, ) try: session.launcher.channel.request(start_request.command, arguments) except messaging.MessageHandlingError as exc: exc.propagate(start_request)
def __str__(self): return compat.filename_str(self.path)