Parse a cell with top-level await and modify the AST to be able to run it later. Parameter --------- cell: str The code cell to asyncronify wrapper_name: str The name of the function to be used to wrap the passed `cell`. It is advised to **not** use a p
(cell:str, wrapper_name:str)
| 170 | |
| 171 | |
| 172 | def _ast_asyncify(cell:str, wrapper_name:str) -> ast.Module: |
| 173 | """ |
| 174 | Parse a cell with top-level await and modify the AST to be able to run it later. |
| 175 | |
| 176 | Parameter |
| 177 | --------- |
| 178 | |
| 179 | cell: str |
| 180 | The code cell to asyncronify |
| 181 | wrapper_name: str |
| 182 | The name of the function to be used to wrap the passed `cell`. It is |
| 183 | advised to **not** use a python identifier in order to not pollute the |
| 184 | global namespace in which the function will be ran. |
| 185 | |
| 186 | Return |
| 187 | ------ |
| 188 | |
| 189 | A module object AST containing **one** function named `wrapper_name`. |
| 190 | |
| 191 | The given code is wrapped in a async-def function, parsed into an AST, and |
| 192 | the resulting function definition AST is modified to return the last |
| 193 | expression. |
| 194 | |
| 195 | The last expression or await node is moved into a return statement at the |
| 196 | end of the function, and removed from its original location. If the last |
| 197 | node is not Expr or Await nothing is done. |
| 198 | |
| 199 | The function `__code__` will need to be later modified (by |
| 200 | ``removed_co_newlocals``) in a subsequent step to not create new `locals()` |
| 201 | meaning that the local and global scope are the same, ie as if the body of |
| 202 | the function was at module level. |
| 203 | |
| 204 | Lastly a call to `locals()` is made just before the last expression of the |
| 205 | function, or just after the last assignment or statement to make sure the |
| 206 | global dict is updated as python function work with a local fast cache which |
| 207 | is updated only on `local()` calls. |
| 208 | """ |
| 209 | |
| 210 | from ast import Expr, Await, Return |
| 211 | if sys.version_info >= (3,8): |
| 212 | return ast.parse(cell) |
| 213 | tree = ast.parse(_asyncify(cell)) |
| 214 | |
| 215 | function_def = tree.body[0] |
| 216 | function_def.name = wrapper_name |
| 217 | try_block = function_def.body[0] |
| 218 | lastexpr = try_block.body[-1] |
| 219 | if isinstance(lastexpr, (Expr, Await)): |
| 220 | try_block.body[-1] = Return(lastexpr.value) |
| 221 | ast.fix_missing_locations(tree) |
| 222 | return tree |
| 223 | #----------------------------------------------------------------------------- |
| 224 | # Globals |
| 225 | #----------------------------------------------------------------------------- |
no test coverage detected