使用Python格式化堆栈溢出问题

使用Python格式化堆栈溢出问题,python,python-3.x,metadata,code-formatting,traceback,Python,Python 3.x,Metadata,Code Formatting,Traceback,我正在编写一个脚本,该脚本将运行另一个脚本,并根据脚本遇到的问题自动生成一个格式化堆栈溢出问题。我希望能够提供准确的代码样本和回溯,同时避免所有的复制和粘贴。以下是我目前掌握的情况: # script.py # usage: python3 script.py > stack_overflow_question.txt from os.path import basename from traceback import format_exc def stack_overflow_que

我正在编写一个脚本,该脚本将运行另一个脚本,并根据脚本遇到的问题自动生成一个格式化堆栈溢出问题。我希望能够提供准确的代码样本和回溯,同时避免所有的复制和粘贴。以下是我目前掌握的情况:

# script.py
# usage: python3 script.py > stack_overflow_question.txt

from os.path import basename
from traceback import format_exc

def stack_overflow_question_generator(q_params):
    "takes a source script & descriptions and returns a Stack Overflow question"
    # get the code from the source script & pad each line with spaces
    with open(q_params['source']) as f:
        source = f.readlines()
    code = ''.join(4 * ' ' + i for i in source)

    # run the source script and get the traceback object
    try:
        trace_obj = None
        try:
            source_module = q_params['source'][:q_params['source'].index('.')]
            __import__(source_module)
        except Exception as e:
            raise RuntimeError from e
    except RuntimeError:
        trace_obj = format_exc()

    # raise a warning if the source script doesn't raise an error
    if not trace_obj:
        no_error_message = 'No exception raised by ' + q_params['source']
        raise UserWarning(no_error_message)

    # break the trace up into lines
    trace_lines = trace_obj.split('\n')

    # find the first line in the trace from the source and target it & its index
    for i, t in enumerate(trace_lines):
        if q_params['source'] in t:
            target_line = t
            index_one = i + 1
            break

    # find the first line of the outer trace and target its index
    break_trace = ' '.join(['The above exception was the direct',
                            'cause of the following exception:'])
    index_two = trace_lines.index(break_trace) - 1

    # find the source script name in the target line & rebuild it with that name 
    quotes_index = [i for i, x in enumerate(target_line) if x == '"'][:2]
    source_name = basename(target_line[quotes_index[0] + 1:quotes_index[1]])
    filename = ''.join(['  File "', source_name, target_line[quotes_index[1]:]])

    # format the source traceback as a string & pad each line with spaces
    trace = '\n'.join(4 * ' ' + i
                        for i in [trace_lines[0],
                                  filename] + trace_lines[index_one:index_two])

    # build and return the question formatted as a string
    return '\n'.join([q_params['issue'], code, q_params['error'], trace,
                      q_params['request']])


# Example: set source script & other question params (issue, error, request):
question_params = {
    'source': 'script.py',
    'issue': ' '.join(['I\'m working on a script that will run another script',
                       'and automatically generate a formatted Stack Overflow',
                       'question based on the problem the script is having.',
                       'I\'d like to be able to provide accurate code samples',
                       'and tracebacks while avoiding all the copying and',
                       'pasting. Here\'s what I have so far:\n']),
    'error': ' '.join(['However, when the source script doesn\'t actually',
                       'raise an exception, the question-generator script',
                       'can\'t really format the question appropriately and',
                       'just raises a warning:\n']),
    'request': ' '.join(['Is there a better way for this script to generate',
                         'questions when the original script doesn\'t raise',
                         'any errors but still has some issue? I\'d also love',
                         'to see any implementations that accomplish the task',
                         'more efficiently or that improve the quality of the',
                         'question. (Also, apologies if this question is',
                         'better suited to stack overflow meta or code review;',
                         'I figured it made more sense here since I\'m trying',
                         'to build a tool in python for formatting output from',
                         'a python script.)'])
}

# Generate & print formatted SO question
print(stack_overflow_question_generator(question_params))
但是,当源脚本实际上没有引发异常时,问题生成器脚本无法正确格式化问题,只会引发警告:

Traceback (most recent call last):
  File "script.py", line 19, in stack_overflow_question_generator
    __import__(source_module)
  File "/Users/alecrasmussen/script.py", line 86, in <module>
    print(stack_overflow_question_generator(question_params))
  File "/Users/alecrasmussen/script.py", line 28, in stack_overflow_question_generator
    raise UserWarning(no_error_message)
UserWarning: No exception raised by script.py
回溯(最近一次呼叫最后一次):
堆栈溢出问题生成器中第19行的文件“script.py”
__导入(源模块)
文件“/Users/alecrasmussen/script.py”,第86行,在
打印(堆栈溢出问题生成器(问题参数))
文件“/Users/alecrasmussen/script.py”,第28行,在堆栈溢出问题生成器中
raise UserWarning(无错误消息)
UserWarning:script.py未引发异常

当原始脚本没有出现任何错误但仍有一些问题时,是否有更好的方法让该脚本生成问题?我还希望看到任何能够更有效地完成任务或提高问题质量的实现。(另外,如果这个问题更适合堆栈溢出元数据或代码审查,我也深表歉意;我认为这更有意义,因为我正在尝试用python构建一个工具,用于格式化python脚本的输出。)

虽然我们很乐意帮您调试脚本,但请不要在自动化的基础上发布问题。这根本不太可能顺利。目标不是自动发布,而只是自动生成格式良好的帖子。如果相关脚本有测试,理论上,当结果与预期不符时,您可以生成格式问题。虽然我们很乐意帮助您调试脚本,请不要自动向SO发布问题。这根本不太可能顺利。目标本身不是自动发布,而是自动生成格式良好的帖子。如果相关脚本有测试,理论上,当结果与预期不匹配时,您可以生成格式问题。