ast3.py 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470
  1. # Copyright (c) 2016, Serge Guelton
  2. # All rights reserved.
  3. # Redistribution and use in source and binary forms, with or without
  4. # modification, are permitted provided that the following conditions are met:
  5. # Redistributions of source code must retain the above copyright notice, this
  6. # list of conditions and the following disclaimer.
  7. # Redistributions in binary form must reproduce the above copyright notice,
  8. # this list of conditions and the following disclaimer in the documentation
  9. # and/or other materials provided with the distribution.
  10. # Neither the name of HPCProject, Serge Guelton nor the names of its
  11. # contributors may be used to endorse or promote products derived from this
  12. # software without specific prior written permission.
  13. # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  14. # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  15. # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  16. # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
  17. # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  18. # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  19. # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  20. # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  21. # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  22. # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  23. # NOTE(paddle-dev): We introduce third-party library Gast as unified AST
  24. # representation. See https://github.com/serge-sans-paille/gast for details.
  25. from .astn import AstToGAst, GAstToAst
  26. from . import gast
  27. import ast
  28. import sys
  29. class Ast3ToGAst(AstToGAst):
  30. if sys.version_info.minor < 9:
  31. def visit_ExtSlice(self, node):
  32. new_node = gast.Tuple(self._visit(node.dims), gast.Load())
  33. gast.copy_location(new_node, node)
  34. return new_node
  35. def visit_Index(self, node):
  36. return self._visit(node.value)
  37. if sys.version_info.minor < 8:
  38. def visit_Module(self, node):
  39. new_node = gast.Module(self._visit(node.body), []) # type_ignores
  40. return new_node
  41. def visit_Num(self, node):
  42. new_node = gast.Constant(
  43. node.n,
  44. None,
  45. )
  46. gast.copy_location(new_node, node)
  47. return new_node
  48. def visit_Ellipsis(self, node):
  49. new_node = gast.Constant(
  50. Ellipsis,
  51. None,
  52. )
  53. gast.copy_location(new_node, node)
  54. new_node.end_lineno = new_node.end_col_offset = None
  55. return new_node
  56. def visit_Str(self, node):
  57. new_node = gast.Constant(
  58. node.s,
  59. None,
  60. )
  61. gast.copy_location(new_node, node)
  62. return new_node
  63. def visit_Bytes(self, node):
  64. new_node = gast.Constant(
  65. node.s,
  66. None,
  67. )
  68. gast.copy_location(new_node, node)
  69. return new_node
  70. def visit_FunctionDef(self, node):
  71. new_node = gast.FunctionDef(
  72. self._visit(node.name),
  73. self._visit(node.args),
  74. self._visit(node.body),
  75. self._visit(node.decorator_list),
  76. self._visit(node.returns),
  77. None, # type_comment
  78. )
  79. gast.copy_location(new_node, node)
  80. return new_node
  81. def visit_AsyncFunctionDef(self, node):
  82. new_node = gast.AsyncFunctionDef(
  83. self._visit(node.name),
  84. self._visit(node.args),
  85. self._visit(node.body),
  86. self._visit(node.decorator_list),
  87. self._visit(node.returns),
  88. None, # type_comment
  89. )
  90. gast.copy_location(new_node, node)
  91. return new_node
  92. def visit_For(self, node):
  93. new_node = gast.For(
  94. self._visit(node.target),
  95. self._visit(node.iter),
  96. self._visit(node.body),
  97. self._visit(node.orelse),
  98. None, # type_comment
  99. )
  100. gast.copy_location(new_node, node)
  101. return new_node
  102. def visit_AsyncFor(self, node):
  103. new_node = gast.AsyncFor(
  104. self._visit(node.target),
  105. self._visit(node.iter),
  106. self._visit(node.body),
  107. self._visit(node.orelse),
  108. None, # type_comment
  109. )
  110. gast.copy_location(new_node, node)
  111. return new_node
  112. def visit_With(self, node):
  113. new_node = gast.With(
  114. self._visit(node.items),
  115. self._visit(node.body),
  116. None, # type_comment
  117. )
  118. gast.copy_location(new_node, node)
  119. return new_node
  120. def visit_AsyncWith(self, node):
  121. new_node = gast.AsyncWith(
  122. self._visit(node.items),
  123. self._visit(node.body),
  124. None, # type_comment
  125. )
  126. gast.copy_location(new_node, node)
  127. return new_node
  128. def visit_Call(self, node):
  129. if sys.version_info.minor < 5:
  130. if node.starargs:
  131. star = gast.Starred(self._visit(node.starargs), gast.Load())
  132. gast.copy_location(star, node)
  133. starred = [star]
  134. else:
  135. starred = []
  136. if node.kwargs:
  137. kw = gast.keyword(None, self._visit(node.kwargs))
  138. gast.copy_location(kw, node.kwargs)
  139. kwargs = [kw]
  140. else:
  141. kwargs = []
  142. else:
  143. starred = kwargs = []
  144. new_node = gast.Call(
  145. self._visit(node.func),
  146. self._visit(node.args) + starred,
  147. self._visit(node.keywords) + kwargs,
  148. )
  149. gast.copy_location(new_node, node)
  150. return new_node
  151. def visit_NameConstant(self, node):
  152. if node.value is None:
  153. new_node = gast.Constant(None, None)
  154. elif node.value is True:
  155. new_node = gast.Constant(True, None)
  156. elif node.value is False:
  157. new_node = gast.Constant(False, None)
  158. gast.copy_location(new_node, node)
  159. return new_node
  160. def visit_arguments(self, node):
  161. new_node = gast.arguments(
  162. self._visit(node.args),
  163. [], # posonlyargs
  164. self._visit(node.vararg),
  165. self._visit(node.kwonlyargs),
  166. self._visit(node.kw_defaults),
  167. self._visit(node.kwarg),
  168. self._visit(node.defaults),
  169. )
  170. gast.copy_location(new_node, node)
  171. return new_node
  172. def visit_Name(self, node):
  173. new_node = gast.Name(
  174. self._visit(node.id),
  175. self._visit(node.ctx),
  176. None,
  177. None,
  178. )
  179. ast.copy_location(new_node, node)
  180. return new_node
  181. def visit_arg(self, node):
  182. if sys.version_info.minor < 8:
  183. extra_args = [None]
  184. else:
  185. extra_args = [self._visit(node.type_comment)]
  186. new_node = gast.Name(
  187. self._visit(node.arg),
  188. gast.Param(),
  189. self._visit(node.annotation),
  190. *extra_args # type_comment
  191. )
  192. ast.copy_location(new_node, node)
  193. return new_node
  194. def visit_ExceptHandler(self, node):
  195. if node.name:
  196. new_node = gast.ExceptHandler(
  197. self._visit(node.type),
  198. gast.Name(node.name, gast.Store(), None, None),
  199. self._visit(node.body),
  200. )
  201. ast.copy_location(new_node, node)
  202. return new_node
  203. else:
  204. return self.generic_visit(node)
  205. if sys.version_info.minor < 6:
  206. def visit_comprehension(self, node):
  207. new_node = gast.comprehension(
  208. target=self._visit(node.target),
  209. iter=self._visit(node.iter),
  210. ifs=self._visit(node.ifs),
  211. is_async=0,
  212. )
  213. return ast.copy_location(new_node, node)
  214. class GAstToAst3(GAstToAst):
  215. if sys.version_info.minor < 9:
  216. def visit_Subscript(self, node):
  217. def adjust_slice(s):
  218. if isinstance(s, ast.Slice):
  219. return s
  220. else:
  221. return ast.Index(s)
  222. if isinstance(node.slice, gast.Tuple):
  223. if any(isinstance(elt, gast.slice) for elt in node.slice.elts):
  224. new_slice = ast.ExtSlice(
  225. [adjust_slice(x) for x in self._visit(node.slice.elts)]
  226. )
  227. else:
  228. value = ast.Tuple(self._visit(node.slice.elts), ast.Load())
  229. ast.copy_location(value, node.slice)
  230. new_slice = ast.Index(value)
  231. else:
  232. new_slice = adjust_slice(self._visit(node.slice))
  233. ast.copy_location(new_slice, node.slice)
  234. new_node = ast.Subscript(
  235. self._visit(node.value),
  236. new_slice,
  237. self._visit(node.ctx),
  238. )
  239. ast.copy_location(new_node, node)
  240. return new_node
  241. if sys.version_info.minor < 8:
  242. def visit_Module(self, node):
  243. new_node = ast.Module(self._visit(node.body))
  244. return new_node
  245. def visit_Constant(self, node):
  246. if node.value is None:
  247. new_node = ast.NameConstant(node.value)
  248. elif node.value is Ellipsis:
  249. new_node = ast.Ellipsis()
  250. elif isinstance(node.value, bool):
  251. new_node = ast.NameConstant(node.value)
  252. elif isinstance(node.value, (int, float, complex)):
  253. new_node = ast.Num(node.value)
  254. elif isinstance(node.value, str):
  255. new_node = ast.Str(node.value)
  256. else:
  257. new_node = ast.Bytes(node.value)
  258. ast.copy_location(new_node, node)
  259. return new_node
  260. def _make_arg(self, node):
  261. if node is None:
  262. return None
  263. if sys.version_info.minor < 8:
  264. extra_args = tuple()
  265. else:
  266. extra_args = (self._visit(node.type_comment),)
  267. new_node = ast.arg(
  268. self._visit(node.id), self._visit(node.annotation), *extra_args
  269. )
  270. return ast.copy_location(new_node, node)
  271. def visit_Name(self, node):
  272. new_node = ast.Name(
  273. self._visit(node.id),
  274. self._visit(node.ctx),
  275. )
  276. ast.copy_location(new_node, node)
  277. return new_node
  278. def visit_ExceptHandler(self, node):
  279. if node.name:
  280. new_node = ast.ExceptHandler(
  281. self._visit(node.type), node.name.id, self._visit(node.body)
  282. )
  283. return ast.copy_location(new_node, node)
  284. else:
  285. return self.generic_visit(node)
  286. if sys.version_info.minor < 5:
  287. def visit_Call(self, node):
  288. if node.args and isinstance(node.args[-1], gast.Starred):
  289. args = node.args[:-1]
  290. starargs = node.args[-1].value
  291. else:
  292. args = node.args
  293. starargs = None
  294. if node.keywords and node.keywords[-1].arg is None:
  295. keywords = node.keywords[:-1]
  296. kwargs = node.keywords[-1].value
  297. else:
  298. keywords = node.keywords
  299. kwargs = None
  300. new_node = ast.Call(
  301. self._visit(node.func),
  302. self._visit(args),
  303. self._visit(keywords),
  304. self._visit(starargs),
  305. self._visit(kwargs),
  306. )
  307. ast.copy_location(new_node, node)
  308. return new_node
  309. def visit_ClassDef(self, node):
  310. self.generic_visit(node)
  311. new_node = ast.ClassDef(
  312. name=self._visit(node.name),
  313. bases=self._visit(node.bases),
  314. keywords=self._visit(node.keywords),
  315. body=self._visit(node.body),
  316. decorator_list=self._visit(node.decorator_list),
  317. starargs=None,
  318. kwargs=None,
  319. )
  320. return ast.copy_location(new_node, node)
  321. elif sys.version_info.minor < 8:
  322. def visit_FunctionDef(self, node):
  323. new_node = ast.FunctionDef(
  324. self._visit(node.name),
  325. self._visit(node.args),
  326. self._visit(node.body),
  327. self._visit(node.decorator_list),
  328. self._visit(node.returns),
  329. )
  330. ast.copy_location(new_node, node)
  331. return new_node
  332. def visit_AsyncFunctionDef(self, node):
  333. new_node = ast.AsyncFunctionDef(
  334. self._visit(node.name),
  335. self._visit(node.args),
  336. self._visit(node.body),
  337. self._visit(node.decorator_list),
  338. self._visit(node.returns),
  339. )
  340. ast.copy_location(new_node, node)
  341. return new_node
  342. def visit_For(self, node):
  343. new_node = ast.For(
  344. self._visit(node.target),
  345. self._visit(node.iter),
  346. self._visit(node.body),
  347. self._visit(node.orelse),
  348. )
  349. ast.copy_location(new_node, node)
  350. return new_node
  351. def visit_AsyncFor(self, node):
  352. new_node = ast.AsyncFor(
  353. self._visit(node.target),
  354. self._visit(node.iter),
  355. self._visit(node.body),
  356. self._visit(node.orelse),
  357. None, # type_comment
  358. )
  359. ast.copy_location(new_node, node)
  360. return new_node
  361. def visit_With(self, node):
  362. new_node = ast.With(
  363. self._visit(node.items),
  364. self._visit(node.body),
  365. )
  366. ast.copy_location(new_node, node)
  367. return new_node
  368. def visit_AsyncWith(self, node):
  369. new_node = ast.AsyncWith(
  370. self._visit(node.items),
  371. self._visit(node.body),
  372. )
  373. ast.copy_location(new_node, node)
  374. return new_node
  375. def visit_Call(self, node):
  376. new_node = ast.Call(
  377. self._visit(node.func),
  378. self._visit(node.args),
  379. self._visit(node.keywords),
  380. )
  381. ast.copy_location(new_node, node)
  382. return new_node
  383. def visit_arguments(self, node):
  384. extra_args = [
  385. self._make_arg(node.vararg),
  386. [self._make_arg(n) for n in node.kwonlyargs],
  387. self._visit(node.kw_defaults),
  388. self._make_arg(node.kwarg),
  389. self._visit(node.defaults),
  390. ]
  391. if sys.version_info.minor >= 8:
  392. new_node = ast.arguments(
  393. [self._make_arg(arg) for arg in node.posonlyargs],
  394. [self._make_arg(n) for n in node.args],
  395. *extra_args
  396. )
  397. else:
  398. new_node = ast.arguments(
  399. [self._make_arg(n) for n in node.args], *extra_args
  400. )
  401. return new_node
  402. def ast_to_gast(node):
  403. return Ast3ToGAst().visit(node)
  404. def gast_to_ast(node):
  405. return GAstToAst3().visit(node)