Show More
@@ -0,0 +1,5 b'' | |||
|
1 | Input transformers are now called only once in the execution path of `InteractiveShell`, allowing to register | |
|
2 | transformer that potentially have side effects (note that this is not recommended). `should_run_async`, and | |
|
3 | `run_cell_async` now take a recommended optional `transformed_cell`, and `preprocessing_exc_tuple` parameters that will | |
|
4 | become mandatory at some point in the future; that is to say cells need to be explicitly transformed to be valid Python | |
|
5 | syntax ahead of trying to run them. :ghpull:`12440` |
@@ -81,7 +81,7 b' from warnings import warn' | |||
|
81 | 81 | from logging import error |
|
82 | 82 | import IPython.core.hooks |
|
83 | 83 | |
|
84 | from typing import List as ListType, Tuple | |
|
84 | from typing import List as ListType, Tuple, Optional | |
|
85 | 85 | from ast import AST |
|
86 | 86 | |
|
87 | 87 | # NoOpContext is deprecated, but ipykernel imports it from here. |
@@ -2877,11 +2877,24 b' class InteractiveShell(SingletonConfigurable):' | |||
|
2877 | 2877 | |
|
2878 | 2878 | def _run_cell(self, raw_cell:str, store_history:bool, silent:bool, shell_futures:bool) -> ExecutionResult: |
|
2879 | 2879 | """Internal method to run a complete IPython cell.""" |
|
2880 | ||
|
2881 | # we need to avoid calling self.transform_cell multiple time on the same thing | |
|
2882 | # so we need to store some results: | |
|
2883 | preprocessing_exc_tuple = None | |
|
2884 | try: | |
|
2885 | transformed_cell = self.transform_cell(raw_cell) | |
|
2886 | except Exception: | |
|
2887 | transformed_cell = raw_cell | |
|
2888 | preprocessing_exc_tuple = sys.exc_info() | |
|
2889 | ||
|
2890 | assert transformed_cell is not None | |
|
2880 | 2891 | coro = self.run_cell_async( |
|
2881 | 2892 | raw_cell, |
|
2882 | 2893 | store_history=store_history, |
|
2883 | 2894 | silent=silent, |
|
2884 | 2895 | shell_futures=shell_futures, |
|
2896 | transformed_cell=transformed_cell, | |
|
2897 | preprocessing_exc_tuple=preprocessing_exc_tuple, | |
|
2885 | 2898 | ) |
|
2886 | 2899 | |
|
2887 | 2900 | # run_cell_async is async, but may not actually need an eventloop. |
@@ -2890,7 +2903,11 b' class InteractiveShell(SingletonConfigurable):' | |||
|
2890 | 2903 | # `%paste` magic. |
|
2891 | 2904 | if self.trio_runner: |
|
2892 | 2905 | runner = self.trio_runner |
|
2893 |
elif self.should_run_async( |
|
|
2906 | elif self.should_run_async( | |
|
2907 | raw_cell, | |
|
2908 | transformed_cell=transformed_cell, | |
|
2909 | preprocessing_exc_tuple=preprocessing_exc_tuple, | |
|
2910 | ): | |
|
2894 | 2911 | runner = self.loop_runner |
|
2895 | 2912 | else: |
|
2896 | 2913 | runner = _pseudo_sync_runner |
@@ -2904,7 +2921,9 b' class InteractiveShell(SingletonConfigurable):' | |||
|
2904 | 2921 | self.showtraceback(running_compiled_code=True) |
|
2905 | 2922 | return result |
|
2906 | 2923 | |
|
2907 |
def should_run_async( |
|
|
2924 | def should_run_async( | |
|
2925 | self, raw_cell: str, *, transformed_cell=None, preprocessing_exc_tuple=None | |
|
2926 | ) -> bool: | |
|
2908 | 2927 | """Return whether a cell should be run asynchronously via a coroutine runner |
|
2909 | 2928 | |
|
2910 | 2929 | Parameters |
@@ -2921,15 +2940,40 b' class InteractiveShell(SingletonConfigurable):' | |||
|
2921 | 2940 | """ |
|
2922 | 2941 | if not self.autoawait: |
|
2923 | 2942 | return False |
|
2924 | try: | |
|
2925 | cell = self.transform_cell(raw_cell) | |
|
2926 | except Exception: | |
|
2927 | # any exception during transform will be raised | |
|
2928 | # prior to execution | |
|
2943 | if preprocessing_exc_tuple is not None: | |
|
2929 | 2944 | return False |
|
2945 | assert preprocessing_exc_tuple is None | |
|
2946 | if transformed_cell is None: | |
|
2947 | warnings.warn( | |
|
2948 | "`should_run_async` will not call `transform_cell`" | |
|
2949 | " automatically in the future. Please pass the result to" | |
|
2950 | " `transformed_cell` argument and any exception that happen" | |
|
2951 | " during the" | |
|
2952 | "transform in `preprocessing_exc_tuple` in" | |
|
2953 | " IPython 7.17 and above.", | |
|
2954 | DeprecationWarning, | |
|
2955 | stacklevel=2, | |
|
2956 | ) | |
|
2957 | try: | |
|
2958 | cell = self.transform_cell(raw_cell) | |
|
2959 | except Exception: | |
|
2960 | # any exception during transform will be raised | |
|
2961 | # prior to execution | |
|
2962 | return False | |
|
2963 | else: | |
|
2964 | cell = transformed_cell | |
|
2930 | 2965 | return _should_be_async(cell) |
|
2931 | 2966 | |
|
2932 | async def run_cell_async(self, raw_cell: str, store_history=False, silent=False, shell_futures=True) -> ExecutionResult: | |
|
2967 | async def run_cell_async( | |
|
2968 | self, | |
|
2969 | raw_cell: str, | |
|
2970 | store_history=False, | |
|
2971 | silent=False, | |
|
2972 | shell_futures=True, | |
|
2973 | *, | |
|
2974 | transformed_cell: Optional[str] = None, | |
|
2975 | preprocessing_exc_tuple: Optional[Any] = None | |
|
2976 | ) -> ExecutionResult: | |
|
2933 | 2977 | """Run a complete IPython cell asynchronously. |
|
2934 | 2978 | |
|
2935 | 2979 | Parameters |
@@ -2948,6 +2992,10 b' class InteractiveShell(SingletonConfigurable):' | |||
|
2948 | 2992 | shell. It will both be affected by previous __future__ imports, and |
|
2949 | 2993 | any __future__ imports in the code will affect the shell. If False, |
|
2950 | 2994 | __future__ imports are not shared in either direction. |
|
2995 | transformed_cell: str | |
|
2996 | cell that was passed through transformers | |
|
2997 | preprocessing_exc_tuple: | |
|
2998 | trace if the transformation failed. | |
|
2951 | 2999 | |
|
2952 | 3000 | Returns |
|
2953 | 3001 | ------- |
@@ -2982,17 +3030,33 b' class InteractiveShell(SingletonConfigurable):' | |||
|
2982 | 3030 | if not silent: |
|
2983 | 3031 | self.events.trigger('pre_run_cell', info) |
|
2984 | 3032 | |
|
2985 | # If any of our input transformation (input_transformer_manager or | |
|
2986 | # prefilter_manager) raises an exception, we store it in this variable | |
|
2987 | # so that we can display the error after logging the input and storing | |
|
2988 | # it in the history. | |
|
2989 | try: | |
|
2990 | cell = self.transform_cell(raw_cell) | |
|
2991 | except Exception: | |
|
2992 | preprocessing_exc_tuple = sys.exc_info() | |
|
2993 | cell = raw_cell # cell has to exist so it can be stored/logged | |
|
3033 | if transformed_cell is None: | |
|
3034 | warnings.warn( | |
|
3035 | "`run_cell_async` will not call `transform_cell`" | |
|
3036 | " automatically in the future. Please pass the result to" | |
|
3037 | " `transformed_cell` argument and any exception that happen" | |
|
3038 | " during the" | |
|
3039 | "transform in `preprocessing_exc_tuple` in" | |
|
3040 | " IPython 7.17 and above.", | |
|
3041 | DeprecationWarning, | |
|
3042 | stacklevel=2, | |
|
3043 | ) | |
|
3044 | # If any of our input transformation (input_transformer_manager or | |
|
3045 | # prefilter_manager) raises an exception, we store it in this variable | |
|
3046 | # so that we can display the error after logging the input and storing | |
|
3047 | # it in the history. | |
|
3048 | try: | |
|
3049 | cell = self.transform_cell(raw_cell) | |
|
3050 | except Exception: | |
|
3051 | preprocessing_exc_tuple = sys.exc_info() | |
|
3052 | cell = raw_cell # cell has to exist so it can be stored/logged | |
|
3053 | else: | |
|
3054 | preprocessing_exc_tuple = None | |
|
2994 | 3055 | else: |
|
2995 |
preprocessing_exc_tuple |
|
|
3056 | if preprocessing_exc_tuple is None: | |
|
3057 | cell = transformed_cell | |
|
3058 | else: | |
|
3059 | cell = raw_cell | |
|
2996 | 3060 | |
|
2997 | 3061 | # Store raw and processed history |
|
2998 | 3062 | if store_history: |
General Comments 0
You need to be logged in to leave comments.
Login now