mirror of https://github.com/python/cpython.git
Generate docstrings.
Fixes SF buf #217004 Add method fixDocstring() to CodeGenerator. It converts the Discard node containing the docstring into an assignment to __doc__.
This commit is contained in:
parent
4c1f42733c
commit
9ab019bee7
|
@ -141,13 +141,16 @@ def set_lineno(self, node):
|
|||
def visitModule(self, node):
|
||||
lnf = walk(node.node, LocalNameFinder(), 0)
|
||||
self.locals.push(lnf.getLocals())
|
||||
self.setDocstring(node.doc)
|
||||
if node.doc:
|
||||
self.fixDocstring(node.node)
|
||||
self.visit(node.node)
|
||||
self.emit('LOAD_CONST', None)
|
||||
self.emit('RETURN_VALUE')
|
||||
|
||||
def visitFunction(self, node):
|
||||
self._visitFuncOrLambda(node, isLambda=0)
|
||||
if node.doc:
|
||||
self.setDocstring(node.doc)
|
||||
self.storeName(node.name)
|
||||
|
||||
def visitLambda(self, node):
|
||||
|
@ -165,6 +168,8 @@ def _visitFuncOrLambda(self, node, isLambda):
|
|||
|
||||
def visitClass(self, node):
|
||||
gen = ClassCodeGenerator(node, self.filename)
|
||||
if node.doc:
|
||||
self.fixDocstring(node.code)
|
||||
walk(node.code, gen)
|
||||
gen.finish()
|
||||
self.set_lineno(node)
|
||||
|
@ -178,6 +183,19 @@ def visitClass(self, node):
|
|||
self.emit('BUILD_CLASS')
|
||||
self.storeName(node.name)
|
||||
|
||||
def fixDocstring(self, node):
|
||||
"""Rewrite the ast for a class with a docstring.
|
||||
|
||||
The AST includes a Discard(Const(docstring)) node. Replace
|
||||
this with an Assign([AssName('__doc__', ...])
|
||||
"""
|
||||
assert isinstance(node, ast.Stmt)
|
||||
stmts = node.nodes
|
||||
discard = stmts[0]
|
||||
assert isinstance(discard, ast.Discard)
|
||||
stmts[0] = ast.Assign([ast.AssName('__doc__', 'OP_ASSIGN')],
|
||||
discard.expr)
|
||||
stmts[0].lineno = discard.lineno
|
||||
# The rest are standard visitor methods
|
||||
|
||||
# The next few implement control-flow statements
|
||||
|
@ -627,7 +645,7 @@ def visitAugGetattr(self, node, mode):
|
|||
|
||||
def visitAugSlice(self, node, mode):
|
||||
if mode == "load":
|
||||
self.visitSlice(node, 1)
|
||||
self.visitlSice(node, 1)
|
||||
elif mode == "store":
|
||||
slice = 0
|
||||
if node.lower:
|
||||
|
@ -896,10 +914,13 @@ def __init__(self, func, filename, isLambda=0):
|
|||
name = func.name
|
||||
args, hasTupleArg = generateArgList(func.argnames)
|
||||
self.graph = pyassem.PyFlowGraph(name, filename, args,
|
||||
optimized=1)
|
||||
optimized=1)
|
||||
self.isLambda = isLambda
|
||||
self.super_init(filename)
|
||||
|
||||
if not isLambda and func.doc:
|
||||
self.setDocstring(func.doc)
|
||||
|
||||
lnf = walk(func.code, LocalNameFinder(args), 0)
|
||||
self.locals.push(lnf.getLocals())
|
||||
if func.varargs:
|
||||
|
@ -947,6 +968,8 @@ def __init__(self, klass, filename):
|
|||
lnf = walk(klass.code, LocalNameFinder(), 0)
|
||||
self.locals.push(lnf.getLocals())
|
||||
self.graph.setFlag(CO_NEWLOCALS)
|
||||
if klass.doc:
|
||||
self.setDocstring(klass.doc)
|
||||
|
||||
def finish(self):
|
||||
self.graph.startExitBlock()
|
||||
|
|
|
@ -141,13 +141,16 @@ def set_lineno(self, node):
|
|||
def visitModule(self, node):
|
||||
lnf = walk(node.node, LocalNameFinder(), 0)
|
||||
self.locals.push(lnf.getLocals())
|
||||
self.setDocstring(node.doc)
|
||||
if node.doc:
|
||||
self.fixDocstring(node.node)
|
||||
self.visit(node.node)
|
||||
self.emit('LOAD_CONST', None)
|
||||
self.emit('RETURN_VALUE')
|
||||
|
||||
def visitFunction(self, node):
|
||||
self._visitFuncOrLambda(node, isLambda=0)
|
||||
if node.doc:
|
||||
self.setDocstring(node.doc)
|
||||
self.storeName(node.name)
|
||||
|
||||
def visitLambda(self, node):
|
||||
|
@ -165,6 +168,8 @@ def _visitFuncOrLambda(self, node, isLambda):
|
|||
|
||||
def visitClass(self, node):
|
||||
gen = ClassCodeGenerator(node, self.filename)
|
||||
if node.doc:
|
||||
self.fixDocstring(node.code)
|
||||
walk(node.code, gen)
|
||||
gen.finish()
|
||||
self.set_lineno(node)
|
||||
|
@ -178,6 +183,19 @@ def visitClass(self, node):
|
|||
self.emit('BUILD_CLASS')
|
||||
self.storeName(node.name)
|
||||
|
||||
def fixDocstring(self, node):
|
||||
"""Rewrite the ast for a class with a docstring.
|
||||
|
||||
The AST includes a Discard(Const(docstring)) node. Replace
|
||||
this with an Assign([AssName('__doc__', ...])
|
||||
"""
|
||||
assert isinstance(node, ast.Stmt)
|
||||
stmts = node.nodes
|
||||
discard = stmts[0]
|
||||
assert isinstance(discard, ast.Discard)
|
||||
stmts[0] = ast.Assign([ast.AssName('__doc__', 'OP_ASSIGN')],
|
||||
discard.expr)
|
||||
stmts[0].lineno = discard.lineno
|
||||
# The rest are standard visitor methods
|
||||
|
||||
# The next few implement control-flow statements
|
||||
|
@ -627,7 +645,7 @@ def visitAugGetattr(self, node, mode):
|
|||
|
||||
def visitAugSlice(self, node, mode):
|
||||
if mode == "load":
|
||||
self.visitSlice(node, 1)
|
||||
self.visitlSice(node, 1)
|
||||
elif mode == "store":
|
||||
slice = 0
|
||||
if node.lower:
|
||||
|
@ -896,10 +914,13 @@ def __init__(self, func, filename, isLambda=0):
|
|||
name = func.name
|
||||
args, hasTupleArg = generateArgList(func.argnames)
|
||||
self.graph = pyassem.PyFlowGraph(name, filename, args,
|
||||
optimized=1)
|
||||
optimized=1)
|
||||
self.isLambda = isLambda
|
||||
self.super_init(filename)
|
||||
|
||||
if not isLambda and func.doc:
|
||||
self.setDocstring(func.doc)
|
||||
|
||||
lnf = walk(func.code, LocalNameFinder(args), 0)
|
||||
self.locals.push(lnf.getLocals())
|
||||
if func.varargs:
|
||||
|
@ -947,6 +968,8 @@ def __init__(self, klass, filename):
|
|||
lnf = walk(klass.code, LocalNameFinder(), 0)
|
||||
self.locals.push(lnf.getLocals())
|
||||
self.graph.setFlag(CO_NEWLOCALS)
|
||||
if klass.doc:
|
||||
self.setDocstring(klass.doc)
|
||||
|
||||
def finish(self):
|
||||
self.graph.startExitBlock()
|
||||
|
|
Loading…
Reference in New Issue