|
14 | 14 | from compiler.consts import (CO_VARARGS, CO_VARKEYWORDS, CO_NEWLOCALS, |
15 | 15 | CO_NESTED, CO_GENERATOR, CO_FUTURE_DIVISION, |
16 | 16 | CO_FUTURE_ABSIMPORT, CO_FUTURE_WITH_STATEMENT, CO_FUTURE_PRINT_FUNCTION, |
17 | | - CO_COROUTINE, CO_ASYNC_GENERATOR, CO_FUTURE_BARRY_AS_BDFL, CO_FUTURE_GENERATOR_STOP) |
| 17 | + CO_COROUTINE, CO_ASYNC_GENERATOR, CO_FUTURE_BARRY_AS_BDFL, CO_FUTURE_GENERATOR_STOP, |
| 18 | + CO_FUTURE_ANNOTATIONS) |
| 19 | +from compiler.unparse import to_expr |
18 | 20 | from .visitor import ASTVisitor |
19 | 21 |
|
20 | 22 | from . import config |
@@ -265,16 +267,18 @@ def visitInteractive(self, node): |
265 | 267 | self.emit('LOAD_CONST', None) |
266 | 268 | self.emit('RETURN_VALUE') |
267 | 269 |
|
268 | | - def visitModule(self, node): |
| 270 | + def findFutures(self, node): |
269 | 271 | future_flags = 0 |
270 | 272 | for feature in future.find_futures(node): |
271 | 273 | if feature == "generator_stop": |
272 | 274 | future_flags |= CO_FUTURE_GENERATOR_STOP |
273 | 275 | elif feature == "barry_as_FLUFL": |
274 | 276 | future_flags |= CO_FUTURE_BARRY_AS_BDFL |
| 277 | + return future_flags |
275 | 278 |
|
276 | | - self.future_flags = future_flags |
277 | | - self.graph.setFlag(future_flags) |
| 279 | + def visitModule(self, node): |
| 280 | + self.future_flags = self.findFutures(node) |
| 281 | + self.graph.setFlag(self.future_flags) |
278 | 282 |
|
279 | 283 | if node.body: |
280 | 284 | self.set_lineno(node.body[0]) |
@@ -349,6 +353,9 @@ def processBody(self, body, gen): |
349 | 353 | else: |
350 | 354 | gen.visit(body) |
351 | 355 |
|
| 356 | + def _visitAnnotation(self, node): |
| 357 | + return self.visit(node) |
| 358 | + |
352 | 359 | def _visitFuncOrLambda(self, node, isLambda=0): |
353 | 360 | if not isLambda and node.decorator_list: |
354 | 361 | for decorator in node.decorator_list: |
@@ -387,23 +394,23 @@ def _visitFuncOrLambda(self, node, isLambda=0): |
387 | 394 | ann_num = 0 |
388 | 395 | for arg in node.args.args: |
389 | 396 | if arg.annotation: |
390 | | - self.visit(arg.annotation) |
| 397 | + self._visitAnnotation(arg.annotation) |
391 | 398 | ann_args.append(self.mangle(arg.arg)) |
392 | 399 | if node.args.vararg: |
393 | 400 | if node.args.vararg.annotation: |
394 | | - self.visit(node.args.vararg.annotation) |
| 401 | + self._visitAnnotation(node.args.vararg.annotation) |
395 | 402 | ann_args.append(self.mangle(node.args.vararg.arg)) |
396 | 403 | for arg in node.args.kwonlyargs: |
397 | 404 | if arg.annotation: |
398 | | - self.visit(arg.annotation) |
| 405 | + self._visitAnnotation(arg.annotation) |
399 | 406 | ann_args.append(self.mangle(arg.arg)) |
400 | 407 | if node.args.kwarg: |
401 | 408 | if node.args.kwarg.annotation: |
402 | | - self.visit(node.args.kwarg.annotation) |
| 409 | + self._visitAnnotation(node.args.kwarg.annotation) |
403 | 410 | ann_args.append(self.mangle(node.args.kwarg.arg)) |
404 | 411 | # Cannot annotate return type for lambda |
405 | 412 | if isinstance(node, (ast.FunctionDef, ast.AsyncFunctionDef)) and node.returns: |
406 | | - self.visit(node.returns) |
| 413 | + self._visitAnnotation(node.returns) |
407 | 414 | ann_args.append("return") |
408 | 415 | if ann_args: |
409 | 416 | flags |= 0x04 |
@@ -1299,7 +1306,7 @@ def visitAssign(self, node): |
1299 | 1306 | self.visit(elt) |
1300 | 1307 |
|
1301 | 1308 | def checkAnnExpr(self, node): |
1302 | | - self.visit(node) |
| 1309 | + self._visitAnnotation(node) |
1303 | 1310 | self.emit('POP_TOP') |
1304 | 1311 |
|
1305 | 1312 | def checkAnnSlice(self, node): |
@@ -1349,7 +1356,7 @@ def visitAnnAssign(self, node): |
1349 | 1356 | # If we have a simple name in a module or class, store the annotation |
1350 | 1357 | if node.simple and isinstance(self.tree, (ast.Module, ast.ClassDef)): |
1351 | 1358 | assert self.did_setup_annotations |
1352 | | - self.visit(node.annotation) |
| 1359 | + self._visitAnnotation(node.annotation) |
1353 | 1360 | mangled = self.mangle(node.target.id) |
1354 | 1361 | self.emit('STORE_ANNOTATION', mangled) |
1355 | 1362 | elif isinstance(node.target, ast.Attribute): |
@@ -1953,6 +1960,22 @@ def visitCall(self, node): |
1953 | 1960 | self.visit(arg) |
1954 | 1961 | self.emit('CALL_METHOD', len(node.args)) |
1955 | 1962 |
|
| 1963 | + def findFutures(self, node): |
| 1964 | + future_flags = 0 |
| 1965 | + for feature in future.find_futures(node): |
| 1966 | + if feature == "barry_as_FLUFL": |
| 1967 | + future_flags |= CO_FUTURE_BARRY_AS_BDFL |
| 1968 | + elif feature == "annotations": |
| 1969 | + future_flags |= CO_FUTURE_ANNOTATIONS |
| 1970 | + return future_flags |
| 1971 | + |
| 1972 | + def _visitAnnotation(self, node): |
| 1973 | + if self.module.future_flags & CO_FUTURE_ANNOTATIONS: |
| 1974 | + self.emit('LOAD_CONST', to_expr(node)) |
| 1975 | + else: |
| 1976 | + self.visit(node) |
| 1977 | + |
| 1978 | + |
1956 | 1979 |
|
1957 | 1980 | def get_docstring(node): |
1958 | 1981 | if node.body and isinstance(node.body[0], ast.Expr) \ |
|
0 commit comments