future.c 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. #include "Python.h"
  2. #include "pycore_ast.h" // _PyAST_GetDocString()
  3. #define UNDEFINED_FUTURE_FEATURE "future feature %.100s is not defined"
  4. static int
  5. future_check_features(PyFutureFeatures *ff, stmt_ty s, PyObject *filename)
  6. {
  7. int i;
  8. assert(s->kind == ImportFrom_kind);
  9. asdl_alias_seq *names = s->v.ImportFrom.names;
  10. for (i = 0; i < asdl_seq_LEN(names); i++) {
  11. alias_ty name = (alias_ty)asdl_seq_GET(names, i);
  12. const char *feature = PyUnicode_AsUTF8(name->name);
  13. if (!feature)
  14. return 0;
  15. if (strcmp(feature, FUTURE_NESTED_SCOPES) == 0) {
  16. continue;
  17. } else if (strcmp(feature, FUTURE_GENERATORS) == 0) {
  18. continue;
  19. } else if (strcmp(feature, FUTURE_DIVISION) == 0) {
  20. continue;
  21. } else if (strcmp(feature, FUTURE_ABSOLUTE_IMPORT) == 0) {
  22. continue;
  23. } else if (strcmp(feature, FUTURE_WITH_STATEMENT) == 0) {
  24. continue;
  25. } else if (strcmp(feature, FUTURE_PRINT_FUNCTION) == 0) {
  26. continue;
  27. } else if (strcmp(feature, FUTURE_UNICODE_LITERALS) == 0) {
  28. continue;
  29. } else if (strcmp(feature, FUTURE_BARRY_AS_BDFL) == 0) {
  30. ff->ff_features |= CO_FUTURE_BARRY_AS_BDFL;
  31. } else if (strcmp(feature, FUTURE_GENERATOR_STOP) == 0) {
  32. continue;
  33. } else if (strcmp(feature, FUTURE_ANNOTATIONS) == 0) {
  34. ff->ff_features |= CO_FUTURE_ANNOTATIONS;
  35. } else if (strcmp(feature, "braces") == 0) {
  36. PyErr_SetString(PyExc_SyntaxError,
  37. "not a chance");
  38. PyErr_RangedSyntaxLocationObject(filename,
  39. name->lineno,
  40. name->col_offset + 1,
  41. name->end_lineno,
  42. name->end_col_offset + 1);
  43. return 0;
  44. } else {
  45. PyErr_Format(PyExc_SyntaxError,
  46. UNDEFINED_FUTURE_FEATURE, feature);
  47. PyErr_RangedSyntaxLocationObject(filename,
  48. name->lineno,
  49. name->col_offset + 1,
  50. name->end_lineno,
  51. name->end_col_offset + 1);
  52. return 0;
  53. }
  54. }
  55. return 1;
  56. }
  57. static int
  58. future_parse(PyFutureFeatures *ff, mod_ty mod, PyObject *filename)
  59. {
  60. if (!(mod->kind == Module_kind || mod->kind == Interactive_kind)) {
  61. return 1;
  62. }
  63. Py_ssize_t n = asdl_seq_LEN(mod->v.Module.body);
  64. if (n == 0) {
  65. return 1;
  66. }
  67. Py_ssize_t i = 0;
  68. if (_PyAST_GetDocString(mod->v.Module.body) != NULL) {
  69. i++;
  70. }
  71. for (; i < n; i++) {
  72. stmt_ty s = (stmt_ty)asdl_seq_GET(mod->v.Module.body, i);
  73. /* The only things that can precede a future statement
  74. * are another future statement and a doc string.
  75. */
  76. if (s->kind == ImportFrom_kind) {
  77. identifier modname = s->v.ImportFrom.module;
  78. if (modname &&
  79. _PyUnicode_EqualToASCIIString(modname, "__future__")) {
  80. if (!future_check_features(ff, s, filename)) {
  81. return 0;
  82. }
  83. ff->ff_location = SRC_LOCATION_FROM_AST(s);
  84. }
  85. else {
  86. return 1;
  87. }
  88. }
  89. else {
  90. return 1;
  91. }
  92. }
  93. return 1;
  94. }
  95. int
  96. _PyFuture_FromAST(mod_ty mod, PyObject *filename, PyFutureFeatures *ff)
  97. {
  98. ff->ff_features = 0;
  99. ff->ff_location = (_PyCompilerSrcLocation){-1, -1, -1, -1};
  100. if (!future_parse(ff, mod, filename)) {
  101. return 0;
  102. }
  103. return 1;
  104. }