<commit_before>import {BaseDebugServer} from "../DebugServers/BaseDebugServer";
import {LocalDebugServer} from "../DebugServers/LocalDebugServer";
import {IPythonProcess, IPythonThread, IDebugServer} from "../Common/Contracts";
import {DebugSession, OutputEvent} from "vscode-debugadapter";
import * as path from "path";
import * as child_process from "child_process";
import {LaunchRequestArguments} from "../Common/Contracts";
import {DebugClient, DebugType} from "./DebugClient";
import * as fs from "fs";
import {open} from "../../common/open";
let fsExtra = require("fs-extra");
let tmp = require("tmp");
let prependFile = require("prepend-file");
let LineByLineReader = require("line-by-line");

const PTVS_FILES = ["visualstudio_ipython_repl.py", "visualstudio_py_debugger.py",
    "visualstudio_py_launcher.py", "visualstudio_py_repl.py", "visualstudio_py_util.py"];

export class LocalDebugClient extends DebugClient {
    protected args: LaunchRequestArguments;
    constructor(args: any, debugSession: DebugSession) {
        super(args, debugSession);
        this.args = args;
    }

    private pyProc: child_process.ChildProcess;
    private pythonProcess: IPythonProcess;
    private debugServer: BaseDebugServer;
    public CreateDebugServer(pythonProcess: IPythonProcess): BaseDebugServer {
        this.pythonProcess = pythonProcess;
        this.debugServer = new LocalDebugServer(this.debugSession, this.pythonProcess);
        return this.debugServer;
    }

    public get DebugType(): DebugType {
        return DebugType.Local;
    }

    public Stop() {
        if (this.debugServer) {
            this.debugServer.Stop();
            this.debugServer = null;
        }

        if (this.pyProc) {
            try { this.pyProc.send("EXIT"); }
            catch (ex) { }
            try { this.pyProc.stdin.write("EXIT"); }
            catch (ex) { }
            try { this.pyProc.disconnect(); }
            catch (ex) { }
            this.pyProc = null;
        }
    }
    private getPTVSToolsFilePath(): string {
        let currentFileName = module.filename;
        let ptVSToolsPath = path.join(path.dirname(currentFileName), "..", "..", "..", "..", "pythonFiles", "PythonTools");
        return path.join(ptVSToolsPath, "visualstudio_py_launcher.py");
    }
    private displayError(error: any, context: string = "") {
        if (!error) { return; }
        let errorMsg = typeof error === "string" ? error : ((error.message && error.message.length > 0) ? error.message : "");
        if (errorMsg.length > 0) {
            this.debugSession.sendEvent(new OutputEvent(context + (context.length > 0 ? ": " : "") + errorMsg + "\n", "stderr"));
        }
    }
    public LaunchApplicationToDebug(dbgServer: IDebugServer): Promise<any> {
        return new Promise<any>((resolve, reject) => {
            let fileDir = path.dirname(this.args.program);
            let processCwd = fileDir;
            if (typeof this.args.cwd === "string" && this.args.cwd.length > 0) {
                processCwd = this.args.cwd;
            }
            let fileNameWithoutPath = path.basename(this.args.program);
            let pythonPath = "python";
            if (typeof this.args.pythonPath === "string" && this.args.pythonPath.trim().length > 0) {
                pythonPath = this.args.pythonPath;
            }
            let environmentVariables = this.args.env ? this.args.env : {};
            if (environmentVariables) {
                for (let setting in process.env) {
                    if (!environmentVariables[setting]) {
                        environmentVariables[setting] = process.env[setting];
                    }
                }
            }
            if (!environmentVariables.hasOwnProperty("PYTHONIOENCODING")) {
                environmentVariables["PYTHONIOENCODING"] = "UTF-8";
            }
            let currentFileName = module.filename;
            let ptVSToolsFilePath = this.getPTVSToolsFilePath();
            let launcherArgs = this.buildLauncherArguments();

            let args = [ptVSToolsFilePath, processCwd, dbgServer.port.toString(), "34806ad9-833a-4524-8cd6-18ca4aa74f14"].concat(launcherArgs);
            if (this.args.externalConsole === true) {
                open({ wait: false, app: [pythonPath].concat(args), cwd: processCwd, env: environmentVariables }).then(proc => {
                    this.pyProc = proc;
                    resolve();
                }, error => {
                    // TODO: This condition makes no sense (refactor)
                    if (!this.debugServer && this.debugServer.IsRunning) {
                        return;
                    }
                    reject(error);
                });

                return;
            }

            this.pyProc = child_process.spawn(pythonPath, args, { cwd: processCwd, env: environmentVariables });
            this.pyProc.on("error", error => {
                // TODO: This condition makes no sense (refactor)
                if (!this.debugServer && this.debugServer.IsRunning) {
                    return;
                }
                this.displayError(error, "pyProc.error");
            });
            this.pyProc.stderr.setEncoding("utf8");
            this.pyProc.stderr.on("data", error => {
                // TODO: This condition makes no sense (refactor)
                if (!this.debugServer && this.debugServer.IsRunning) {
                    return;
                }
                this.displayError(error, "pyProc.stderr");
            });

            resolve();
        });
    }
    protected buildLauncherArguments(): string[] {
        let vsDebugOptions = "WaitOnAbnormalExit,WaitOnNormalExit,RedirectOutput";
        if (Array.isArray(this.args.debugOptions)) {
            vsDebugOptions = this.args.debugOptions.join(",");
        }

        let programArgs = Array.isArray(this.args.args) && this.args.args.length > 0 ? this.args.args : [];
        return [vsDebugOptions, this.args.program].concat(programArgs);
    }
}<commit_msg>read stdout of python process #203, #52<commit_after>import {BaseDebugServer} from "../DebugServers/BaseDebugServer";
import {LocalDebugServer} from "../DebugServers/LocalDebugServer";
import {IPythonProcess, IPythonThread, IDebugServer} from "../Common/Contracts";
import {DebugSession, OutputEvent} from "vscode-debugadapter";
import * as path from "path";
import * as child_process from "child_process";
import {LaunchRequestArguments} from "../Common/Contracts";
import {DebugClient, DebugType} from "./DebugClient";
import * as fs from "fs";
import {open} from "../../common/open";
let fsExtra = require("fs-extra");
let tmp = require("tmp");
let prependFile = require("prepend-file");
let LineByLineReader = require("line-by-line");

const PTVS_FILES = ["visualstudio_ipython_repl.py", "visualstudio_py_debugger.py",
    "visualstudio_py_launcher.py", "visualstudio_py_repl.py", "visualstudio_py_util.py"];

export class LocalDebugClient extends DebugClient {
    protected args: LaunchRequestArguments;
    constructor(args: any, debugSession: DebugSession) {
        super(args, debugSession);
        this.args = args;
    }

    private pyProc: child_process.ChildProcess;
    private pythonProcess: IPythonProcess;
    private debugServer: BaseDebugServer;
    public CreateDebugServer(pythonProcess: IPythonProcess): BaseDebugServer {
        this.pythonProcess = pythonProcess;
        this.debugServer = new LocalDebugServer(this.debugSession, this.pythonProcess);
        return this.debugServer;
    }

    public get DebugType(): DebugType {
        return DebugType.Local;
    }

    public Stop() {
        if (this.debugServer) {
            this.debugServer.Stop();
            this.debugServer = null;
        }

        if (this.pyProc) {
            try { this.pyProc.send("EXIT"); }
            catch (ex) { }
            try { this.pyProc.stdin.write("EXIT"); }
            catch (ex) { }
            try { this.pyProc.disconnect(); }
            catch (ex) { }
            this.pyProc = null;
        }
    }
    private getPTVSToolsFilePath(): string {
        let currentFileName = module.filename;
        let ptVSToolsPath = path.join(path.dirname(currentFileName), "..", "..", "..", "..", "pythonFiles", "PythonTools");
        return path.join(ptVSToolsPath, "visualstudio_py_launcher.py");
    }
    private displayError(error: any, context: string = "") {
        if (!error) { return; }
        let errorMsg = typeof error === "string" ? error : ((error.message && error.message.length > 0) ? error.message : "");
        if (errorMsg.length > 0) {
            this.debugSession.sendEvent(new OutputEvent(context + (context.length > 0 ? ": " : "") + errorMsg + "\n", "stderr"));
        }
    }
    public LaunchApplicationToDebug(dbgServer: IDebugServer): Promise<any> {
        return new Promise<any>((resolve, reject) => {
            let fileDir = path.dirname(this.args.program);
            let processCwd = fileDir;
            if (typeof this.args.cwd === "string" && this.args.cwd.length > 0) {
                processCwd = this.args.cwd;
            }
            let fileNameWithoutPath = path.basename(this.args.program);
            let pythonPath = "python";
            if (typeof this.args.pythonPath === "string" && this.args.pythonPath.trim().length > 0) {
                pythonPath = this.args.pythonPath;
            }
            let environmentVariables = this.args.env ? this.args.env : {};
            if (environmentVariables) {
                for (let setting in process.env) {
                    if (!environmentVariables[setting]) {
                        environmentVariables[setting] = process.env[setting];
                    }
                }
            }
            if (!environmentVariables.hasOwnProperty("PYTHONIOENCODING")) {
                environmentVariables["PYTHONIOENCODING"] = "UTF-8";
            }
            let currentFileName = module.filename;
            let ptVSToolsFilePath = this.getPTVSToolsFilePath();
            let launcherArgs = this.buildLauncherArguments();

            let args = [ptVSToolsFilePath, processCwd, dbgServer.port.toString(), "34806ad9-833a-4524-8cd6-18ca4aa74f14"].concat(launcherArgs);
            if (this.args.externalConsole === true) {
                open({ wait: false, app: [pythonPath].concat(args), cwd: processCwd, env: environmentVariables }).then(proc => {
                    this.pyProc = proc;
                    resolve();
                }, error => {
                    // TODO: This condition makes no sense (refactor)
                    if (!this.debugServer && this.debugServer.IsRunning) {
                        return;
                    }
                    reject(error);
                });

                return;
            }

            this.pyProc = child_process.spawn(pythonPath, args, { cwd: processCwd, env: environmentVariables });
            this.pyProc.on("error", error => {
                // TODO: This condition makes no sense (refactor)
                if (!this.debugServer && this.debugServer.IsRunning) {
                    return;
                }
                this.displayError(error, "pyProc.error");
            });
            this.pyProc.stderr.setEncoding("utf8");
            this.pyProc.stderr.on("data", error => {
                // TODO: This condition makes no sense (refactor)
                if (!this.debugServer && this.debugServer.IsRunning) {
                    return;
                }
                this.displayError(error, "pyProc.stderr");
            });
            this.pyProc.stdout.on("data", d => {
                // This is necessary so we read the stdout of the python process
                // Else it just keep building up (related to issue #203 and #52)
            })
            resolve();
        });
    }
    protected buildLauncherArguments(): string[] {
        let vsDebugOptions = "WaitOnAbnormalExit,WaitOnNormalExit,RedirectOutput";
        if (Array.isArray(this.args.debugOptions)) {
            vsDebugOptions = this.args.debugOptions.join(",");
        }

        let programArgs = Array.isArray(this.args.args) && this.args.args.length > 0 ? this.args.args : [];
        return [vsDebugOptions, this.args.program].concat(programArgs);
    }
}
{'fraction_non_alphanumeric': 0.12505071816927696, 'fraction_numerical': 0.005680434959019719, 'mean_word_length': 2.1503067484662575, 'pattern_counts': {'":': 2, '<': 7, '<?xml version=': 0, '>': 30, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '367613', 'n_tokens_mistral': 3441, 'n_tokens_neox': 3301, 'n_words': 696}