微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

添加一个新的cpython关键字

如何解决添加一个新的cpython关键字

我目前正在使用cpython指南:https://realpython.com/products/cpython-internals-book/

我将详细说明我的工作以及问题所在。 就像书上所说的,我克隆了github:

git clone directory https://github.com/python/cpython

然后我编译了:

./configure --with-pydebug --enable-shared
make -j2 -s

然后,在讨论语法的部分中,我修改python.gram文件,并在small_stmt行中添加一个内容

| ('pass' | 'proceed') { _Py_Pass(EXTRA) }

然后,我尝试运行命令make regen-pegen。 我的dataclass模块出错,所以我决定从头开始。

新安装后,我运行了命令make all。 我不知道这是否是一个错误,但是我已经没有python 3.9了,而是python 3.10。

这次命令make regen-pegen有效,但是当我尝试使用它时,出现了proceed is not defined错误

我尝试从pass删除关键字python.gram,以查看是否考虑了更改。

在尝试重新编译时,出现了pass is not defined错误,因此对该文件所做的更改可以正常工作。

然后我检查了新关键字是否确实出现在生成的C文件中,是的,它在其中。

    (KeywordToken[]) {{NULL,-1}},(KeywordToken[]) {{NULL,(KeywordToken[]) {
        {"if",509},{"in",517},{"ace",519},{"is",526},{"gold",532},{NULL,-1},},(KeywordToken[]) {
        {"del",502},{"try",510},{"for",516},{"def",522},{"not",525},{"and",533},(KeywordToken[]) {
        {"from",513},{"elif",514},{"else",515},{"with",518},{"True",527},{"None",529},{"pass",530},(KeywordToken[]) {
        {"raise",501},{"yield",503},{"break",505},{"while",511},{"class",523},{"False",528},(KeywordToken[]) {
        {"return",500},{"assert",504},{"global",507},{"import",512},{"except",520},{"lambda",524},(KeywordToken[]) {
        {"finally",521},{"proceed",531},(KeywordToken[]) {
        {"continue",506},{"non-local",508},};

我不明白为什么不考虑更改。 谢谢

解决方法

我没有这本书,这是我第一次编辑Python的语法,但是我可以使用它。


  1. 构建“常规” Python 3.10并安装到某个临时目录,例如cpython/build/INSTALL

    git clone https://github.com/python/cpython
    mkdir cpython/build && cd cpython/build
    mkdir INSTALL
    ../configure --prefix=/full/path/to/cpython/build/INSTALL
    make -j4 install
    

    我认为某些早期版本(例如3.9 might )可以工作(我在3.6上遇到了有关walrus运算符的错误,而在3.8上遇到了其他错误,因此对于构建3.10而言似乎“太老了”) ,但Python的构建速度很快,因此,以防万一,为什么不这样做呢?

  2. 修改python.gram

    small_stmt[stmt_ty] (memo):
        | assignment
        ...
        | ('pass' | 'proceed') { _Py_Pass(EXTRA) }  # HERE
        | &'del' del_stmt
        ...
    
  3. 使用新建的Python 重新生成解析器:

    $ make PYTHON_FOR_REGEN=INSTALL/bin/python3 regen-pegen
    PYTHONPATH=../Tools/peg_generator INSTALL/bin/python3 -m pegen -q c \
            ../Grammar/python.gram \
            ../Grammar/Tokens \
            -o ../Parser/parser.new.c
    python3 ../Tools/scripts/update_file.py ../Parser/parser.c ../Parser/parser.new.c
    $
    
  4. 清洁(可能还需要重新配置以安装到其他路径)并重建:

    make clean
    rm -rf INSTALL/*
    make -j4 install
    

    这将像以前一样安装到build/INSTALL

现在,有趣的部分。您收到此错误:

# huge huge huge traceback...
File "/var/folders/qv/bsx06c394yzb1dlrtcj_9gkc0000gn/T/tmpzt58rw8n/pip-20.2.3-py2.py3-none-any.whl/pip/_vendor/distlib/util.py",line 318
    def proceed(prompt,allowed_chars,error_prompt=None,default=None):
        ^
SyntaxError: invalid syntax

如您所见,new关键字已经存在,现在您没有名为proceed的函数,因此有些事情会中断。在这种情况下,pip中断了,因此此修改后的Python版本将没有pip,但您也可以编辑该特定文件,查看是否有其他中断,然后进行编辑等。

但是谁在乎-Python本身是成功构建的:

$ INSTALL/bin/python3 
Python 3.10.0a2+ (heads/master-dirty:f3cb814315,Nov  5 2020,xx:xx:xx) 
[Clang 11.0.0 (clang-1100.0.33.16)] on darwin
Type "help","copyright","credits" or "license" for more information.
>>> proceed # works!
>>> pass
>>> 

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。