Transformar el intérprete de Python en un intérprete de Shaw

The report was reproduced from Transformar el intérprete de Python en un intérprete de shoburn - narbo Blog.

Configurar el intérprete de Python como intérprete de Shaw


Hola, soy narupo.
El intérprete de Python también se cansará de su uso a largo plazo.
Así que decidimos cambiar el Estado de ánimo modificando el intérprete.
¿Si el intérprete muestra (´・ω・`)ショボーン, el intérprete puede volverse encantador?
¿Realmente va a ser así?
Quiero intentarlo.

Obtener cpython


Python tiene una amplia gama de instalaciones, esta adaptación es la instalación más común CPython.
  • Python / cpython: el lenguaje de programación de Python
  • Clonar el proyecto cpython usando Git.
    $ git clone https://github.com/python/cpython.git
    
    Luego está configure, make para establecer Python.
    El entorno utiliza el wsl de Windows 10. Ubuntu 16. ¿04, verdad? Así que la Python generada es python.exe.
    $ cd cpython
    $ ./configure
    $ make
    $ python.exe
    

    Transformar cpython


    El punto de inscripción para el programa Python está en Programs/python.c.
    #ifdef MS_WINDOWS
    int
    wmain(int argc, wchar_t **argv)
    {
        return Py_Main(argc, argv);
    }
    #else
    int
    main(int argc, char **argv)
    {
        return Py_BytesMain(argc, argv);
    }
    #endif
    
    En el entorno wsl (UBUNTU 16.04) de Windows 10, el principal de este último se llama el principal.Py_BytesMain se define por Modules/main.c.
    int
    Py_BytesMain(int argc, char **argv)
    {
        _PyArgv args = {
            .argc = argc,
            .use_bytes_argv = 1,
            .bytes_argv = argv,
            .wchar_argv = NULL};
        return pymain_main(&args);
    }
    
    
    pymain_main también se define en este archivo.
    static int
    pymain_main(_PyArgv *args)
    {
        PyStatus status = pymain_init(args);
        if (_PyStatus_IS_EXIT(status)) {
            pymain_free();
            return status.exitcode;
        }
        if (_PyStatus_EXCEPTION(status)) {
            pymain_exit_error(status);
        }
    
        return Py_RunMain();
    }
    
    
    Lo mismo ocurre con Py_RunMain.
    int
    Py_RunMain(void)
    {
        int exitcode = 0;
    
        pymain_run_python(&exitcode);
    
        if (Py_FinalizeEx() < 0) {
            /* Value unlikely to be confused with a non-error exit status or
               other special meaning */
            exitcode = 120;
        }
    
        pymain_free();
    
        if (_Py_UnhandledKeyboardInterrupt) {
            exitcode = exit_sigint();
        }
    
        return exitcode;
    }
    
    ¿Qué hay en pymain_run_python?
    static void
    pymain_run_python(int *exitcode)
    {
        ...
        pymain_header(config);
        ...
        else {
            *exitcode = pymain_run_stdin(config, &cf);
        }
    }
    
    Función que muestra la versión del modo interactivo pymain_header.
    El modo de interacción parece llamarse pymain_run_stdin.
    Déjame ver primero pymain_header.
    static void
    pymain_header(const PyConfig *config)
    {
        if (config->quiet) {
            return;
        }
    
        if (!config->verbose && (config_run_code(config) || !stdin_is_interactive(config))) {
            return;
        }
    
        fprintf(stderr, "Python %s on %s\n", Py_GetVersion(), Py_GetPlatform());
        if (config->site_import) {
            fprintf(stderr, "%s\n", COPYRIGHT);
        }
    }
    
    
    Se muestran versiones y réplicas. Salida a stderr.
    Cambie el Python aquí por Chopin.
        fprintf(stderr, "(´・ω・`)ショボーン %s on %s\n", Py_GetVersion(), Py_GetPlatform());
    
    Devuelve pymain_run_stdin.
    static int
    pymain_run_stdin(PyConfig *config, PyCompilerFlags *cf)
    {
        ...
        int run = PyRun_AnyFileExFlags(stdin, "<stdin>", 0, cf);
        ...
    }
    
    Veamos PyRun_AnyFileExFlags.
    Definido por Python/pythonrun.c.
    int
    PyRun_AnyFileExFlags(FILE *fp, const char *filename, int closeit,
                         PyCompilerFlags *flags)
    {
        ...
            int err = PyRun_InteractiveLoopFlags(fp, filename, flags);
        ...
    }
    
    PyRun_InteractiveLoopFlags se llama. Mira esta función.
    int
    PyRun_InteractiveLoopFlags(FILE *fp, const char *filename_str, PyCompilerFlags *flags)
    {
        ...
        do {
            ret = PyRun_InteractiveOneObjectEx(fp, filename, flags);
        } while (ret != E_EOF);
        ...
    }
    
    
    Monitorear Stdin para el bucle en la oración do while.
    Aquí está el patrón de diálogo de Python.
    Añade Chopin al bucle.
        ...
        do {
            fprintf(stderr, ">>> (´・ω・`)ショボーン\n");
            ret = PyRun_InteractiveOneObjectEx(fp, filename, flags);
            ...
        } while (ret != E_EOF);
        ...
    
    De esta manera, el intérprete shoburn está completo.
    カ る ソ ス al añadir el error.
        ...
        do {
            fprintf(stderr, ">>> (´・ω・`)ショボーン\n");
            ret = PyRun_InteractiveOneObjectEx(fp, filename, flags);
            if (ret == -1 && PyErr_Occurred()) {
                /* Prevent an endless loop after multiple consecutive MemoryErrors
                 * while still allowing an interactive command to fail with a
                 * MemoryError. */
                if (PyErr_ExceptionMatches(PyExc_MemoryError)) {
                    if (++nomem_count > 16) {
                        PyErr_Clear();
                        err = -1;
                        break;
                    }
                } else {
                    nomem_count = 0;
                }
                PyErr_Print();
    
                // エラー出力のあとにカワイソスを表示
                fprintf(stderr, ">>> (´・ω・`)カワイソス\n");
    
                flush_io();
            } else {
                nomem_count = 0;
            }
    #ifdef Py_REF_DEBUG
            if (show_ref_count) {
                _PyDebug_PrintTotalRefs();
            }
    #endif
        } while (ret != E_EOF);
        ...
    

    Paisaje de acción


    Es el paisaje de acción del intérprete Xiao Ben.

    Observaciones finales


    Esto es lo que siento por usar este intérprete, Chopin es muy feliz.
    Trate de transformar el intérprete para cambiar su estado de ánimo.
    Eso es narupo.

    Informes conexos

  • A ñadir un millón a Python