python Sphinx“模块执行模块级语句,它可能调用sys.exit()”

时间:2016-01-02 19:57:52

标签: python python-sphinx

我尝试使用Sphinx记录我的代码。但我看到了错误

  

模块执行模块级语句,它可能会调用sys.exit()。

我发现此错误与代码相关:

import argparse
# parse command line arguments
parser = argparse.ArgumentParser(description='AWS VPN status checker.')
parser.add_argument('account', type=str, help='AWS account name.')
parser.add_argument('region', type=str, help='region of VPN tunnel.')
parser.add_argument('ipaddress', type=str, help='Tunnel IP address.')
parser.add_argument("-d", "--debug", help="debug", action="store_true")
args = parser.parse_args()

我认为在导入模块时它与“副作用”有关。

为什么不好,我该如何解决?

3 个答案:

答案 0 :(得分:3)

Sphinx警告是由前面的parse_args()错误引起的。 arg_parse()函数被调用,在期望解析的参数中找到一个正常错误并存在。

Invalid arguments

在解析命令行时, parse_args()检查各种错误,包括模棱两可的选项,无效的类型,无效的选项,位置参数的数量错误等。遇到此类错误时,它会退出并显示错误以及使用情况消息:

parse_args()在生成Sphinx文档时退出的最可能原因是因为您真正调用的是sphinx-buildmake html。因此,在您的python shell上执行的是以下签名:

sphinx-build

简介

sphinx-build [选项] [文件名...]

这意味着您可能没有使用编码为ArgumentParser的参数来执行脚本。运行sphinx-buildmake html,其中包含命令行参数arg_parse()要求输入ArgumentParser(),或者在生成文档时不调用arg_parse()

如何解决此问题?

一种可能的方法如下:

entry_script.py

from sys import argv
from pathlib import Path

import cmd_line_module

# Checking what the command line contains can be useful.
print(argv)

EXAMPLE_ARGS = ['-i', '../in_dir_test', '-o', 'out_dir_test']

# Script.
if __name__ == "__main__":

    # default Namespace
    print(cmd_line_params.args)

    # command-line
    cmd_line_module.set_args()
    print(cmd_line_params.args)

    # test case
    cmd_line_module.set_args(EXAMPLE_ARGS)
    print(cmd_line_params.args)

# Sphinx-build or make.
elif Path(argv[0]).name == "sphinx-build" or Path(argv[0]).name == "build.py":

    cmd_line_module.set_args(EXAMPLE_ARGS)

# Module only.
else:
    cmd_line_module.set_args(EXAMPLE_ARGS)

cmd_line_module.py

import argparse


_DEFAULT = argparse.Namespace(in_dir=None, out_dir=None)
args = _DEFAULT


def command_line_args():

    parser = argparse.ArgumentParser(prog='entry_script', description='Does magic :) .')
    parser.add_argument("-i", "--in_dir", help="Input directory/file. Use absolute or relative path.")
    parser.add_argument("-o", "--out_dir", help="Output directory. Use absolute or relative path.")

    return parser


def set_args(cmd_line=None):

    parser = command_line_args()
    global args
    args = parser.parse_args(cmd_line)

该解决方案的一些注意事项可能对读者有用:

1。cmd_line_module.py在模块级别上将args保留为变量,以尽可能类似于argparse tutorial示例。 on this thread可以找到argparse的特定Sphinx扩展名。

2。。为args使用默认的Namespace可能很方便,这已包含在建议中。 (预期的默认值可以帮助在导入模块中进行测试。)

3。可能不需要进行__main __sphinx-build的测试,具体取决于3个if测试只是为了为问题添加上下文。< / p>

4。。使用DEFAULT_ARGS可以显示如何使用parse_args(),而无需阅读sys.argv,以及如何进行sphinx-build分配使用的if __name __ == "__main __":(出于任何原因,您应该觉得方便)...

5。sphinx-build脚本的名称和路径可能会因操作系统而异。

最后的注意:如果您想编写自我初始化变量的模块(例如我),请特别注意在导入可能具有变量的模块之前运行parse_args()

6.1。 More on Modules

模块可以包含可执行语句以及函数定义。这些语句旨在初始化模块。仅在import语句中第一次遇到模块名称时才执行它们。 (如果文件是作为脚本执行的,它们也会运行。)

答案 1 :(得分:0)

就我而言,我有一个带有第三方库导入的子模块,该库是问题的根源(pyautogui)。 但是我花了几个小时试图弄清楚,因为错误是这样的:

FOO.a import error the module executes module level statement and it might call sys.exit()
FOO.b import error the module executes module level statement and it might call sys.exit()
FOO.d.foo import error the module executes module level statement and it might call sys.exit()
FOO.d.bar import error the module executes module level statement and it might call sys.exit()
FOO.d.baz import error the module executes module level statement and it might call sys.exit()
FOO.d import error the module executes module level statement and it might call sys.exit()
FOO import error the module executes module level statement and it might call sys.exit()

虽然我的包装结构与此类似:

FOO
├── a
├── b
│   ├── ci
|   └── __init__.py|
└── d
    ├── foo
    ├── bar
    ├── baz
    └── __init__.py

其中ab中包含import d字符串。并且import pyautoguiFOO.d.bar子模块中。

答案 2 :(得分:-1)

我也遇到了这个问题。我的解决方案是在ifpar语句的argparse代码之前添加脚本:

if __name__ == "__main__":
   parser = argparse.ArgumentParser(description="some description", formatter_class=RawTextHelpFormatter)
   parser.add_argument(....)
   args = parser.parse_args()
   ......