##// END OF EJS Templates
Polish documentation, hide private functions
krassowski -
Show More
@@ -50,7 +50,7 b' Backward latex completion'
50
50
51 It is sometime challenging to know how to type a character, if you are using
51 It is sometime challenging to know how to type a character, if you are using
52 IPython, or any compatible frontend you can prepend backslash to the character
52 IPython, or any compatible frontend you can prepend backslash to the character
53 and press ``<tab>`` to expand it to its latex form.
53 and press :kbd:`Tab` to expand it to its latex form.
54
54
55 .. code::
55 .. code::
56
56
@@ -59,7 +59,7 b' and press ``<tab>`` to expand it to its latex form.'
59
59
60
60
61 Both forward and backward completions can be deactivated by setting the
61 Both forward and backward completions can be deactivated by setting the
62 ``Completer.backslash_combining_completions`` option to ``False``.
62 :any:`Completer.backslash_combining_completions` option to ``False``.
63
63
64
64
65 Experimental
65 Experimental
@@ -95,7 +95,7 b' having to execute any code:'
95 ... myvar[1].bi<tab>
95 ... myvar[1].bi<tab>
96
96
97 Tab completion will be able to infer that ``myvar[1]`` is a real number without
97 Tab completion will be able to infer that ``myvar[1]`` is a real number without
98 executing any code unlike the previously available ``IPCompleter.greedy``
98 executing almost any code unlike the deprecated :any:`IPCompleter.greedy`
99 option.
99 option.
100
100
101 Be sure to update :any:`jedi` to the latest stable version or to try the
101 Be sure to update :any:`jedi` to the latest stable version or to try the
@@ -972,29 +972,38 b' class Completer(Configurable):'
972 help="""Activate greedy completion.
972 help="""Activate greedy completion.
973
973
974 .. deprecated:: 8.8
974 .. deprecated:: 8.8
975 Use :any:`evaluation` and :any:`auto_close_dict_keys` instead.
975 Use :any:`Completer.evaluation` and :any:`Completer.auto_close_dict_keys` instead.
976
976
977 When enabled in IPython 8.8+ activates following settings for compatibility:
977 When enabled in IPython 8.8 or newer, changes configuration as follows:
978 - ``evaluation = 'unsafe'``
978
979 - ``auto_close_dict_keys = True``
979 - ``Completer.evaluation = 'unsafe'``
980 - ``Completer.auto_close_dict_keys = True``
980 """,
981 """,
981 ).tag(config=True)
982 ).tag(config=True)
982
983
983 evaluation = Enum(
984 evaluation = Enum(
984 ("forbidden", "minimal", "limited", "unsafe", "dangerous"),
985 ("forbidden", "minimal", "limited", "unsafe", "dangerous"),
985 default_value="limited",
986 default_value="limited",
986 help="""Code evaluation under completion.
987 help="""Policy for code evaluation under completion.
987
988
988 Successive options allow to enable more eager evaluation for more accurate completion suggestions,
989 Successive options allow to enable more eager evaluation for better
989 including for nested dictionaries, nested lists, or even results of function calls. Setting `unsafe`
990 completion suggestions, including for nested dictionaries, nested lists,
990 or higher can lead to evaluation of arbitrary user code on TAB with potentially dangerous side effects.
991 or even results of function calls.
992 Setting ``unsafe`` or higher can lead to evaluation of arbitrary user
993 code on :kbd:`Tab` with potentially unwanted or dangerous side effects.
991
994
992 Allowed values are:
995 Allowed values are:
993 - `forbidden`: no evaluation at all
996
994 - `minimal`: evaluation of literals and access to built-in namespaces; no item/attribute evaluation nor access to locals/globals
997 - ``forbidden``: no evaluation of code is permitted,
995 - `limited` (default): access to all namespaces, evaluation of hard-coded methods (``keys()``, ``__getattr__``, ``__getitems__``, etc) on allow-listed objects (e.g. ``dict``, ``list``, ``tuple``, ``pandas.Series``)
998 - ``minimal``: evaluation of literals and access to built-in namespace;
996 - `unsafe`: evaluation of all methods and function calls but not of syntax with side-effects like `del x`,
999 no item/attribute evaluation nor access to locals/globals,
997 - `dangerous`: completely arbitrary evaluation
1000 - ``limited``: access to all namespaces, evaluation of hard-coded methods
1001 (for example: :any:`dict.keys`, :any:`object.__getattr__`,
1002 :any:`object.__getitem__`) on allow-listed objects (for example:
1003 :any:`dict`, :any:`list`, :any:`tuple`, ``pandas.Series``),
1004 - ``unsafe``: evaluation of all methods and function calls but not of
1005 syntax with side-effects like `del x`,
1006 - ``dangerous``: completely arbitrary evaluation.
998 """,
1007 """,
999 ).tag(config=True)
1008 ).tag(config=True)
1000
1009
@@ -1019,7 +1028,15 b' class Completer(Configurable):'
1019 "unicode characters back to latex commands.").tag(config=True)
1028 "unicode characters back to latex commands.").tag(config=True)
1020
1029
1021 auto_close_dict_keys = Bool(
1030 auto_close_dict_keys = Bool(
1022 False, help="""Enable auto-closing dictionary keys."""
1031 False,
1032 help="""
1033 Enable auto-closing dictionary keys.
1034
1035 When enabled string keys will be suffixed with a final quote
1036 (matching the opening quote), tuple keys will also receive a
1037 separating comma if needed, and keys which are final will
1038 receive a closing bracket (``]``).
1039 """,
1023 ).tag(config=True)
1040 ).tag(config=True)
1024
1041
1025 def __init__(self, namespace=None, global_namespace=None, **kwargs):
1042 def __init__(self, namespace=None, global_namespace=None, **kwargs):
@@ -1157,8 +1174,8 b' class Completer(Configurable):'
1157 obj = guarded_eval(
1174 obj = guarded_eval(
1158 expr,
1175 expr,
1159 EvaluationContext(
1176 EvaluationContext(
1160 globals_=self.global_namespace,
1177 globals=self.global_namespace,
1161 locals_=self.namespace,
1178 locals=self.namespace,
1162 evaluation=self.evaluation,
1179 evaluation=self.evaluation,
1163 ),
1180 ),
1164 )
1181 )
@@ -1183,7 +1200,7 b' def get__all__entries(obj):'
1183 return [w for w in words if isinstance(w, str)]
1200 return [w for w in words if isinstance(w, str)]
1184
1201
1185
1202
1186 class DictKeyState(enum.Flag):
1203 class _DictKeyState(enum.Flag):
1187 """Represent state of the key match in context of other possible matches.
1204 """Represent state of the key match in context of other possible matches.
1188
1205
1189 - given `d1 = {'a': 1}` completion on `d1['<tab>` will yield `{'a': END_OF_ITEM}` as there is no tuple.
1206 - given `d1 = {'a': 1}` completion on `d1['<tab>` will yield `{'a': END_OF_ITEM}` as there is no tuple.
@@ -1199,6 +1216,7 b' class DictKeyState(enum.Flag):'
1199
1216
1200
1217
1201 def _parse_tokens(c):
1218 def _parse_tokens(c):
1219 """Parse tokens even if there is an error."""
1202 tokens = []
1220 tokens = []
1203 token_generator = tokenize.generate_tokens(iter(c.splitlines()).__next__)
1221 token_generator = tokenize.generate_tokens(iter(c.splitlines()).__next__)
1204 while True:
1222 while True:
@@ -1257,7 +1275,7 b' def match_dict_keys('
1257 prefix: str,
1275 prefix: str,
1258 delims: str,
1276 delims: str,
1259 extra_prefix: Optional[Tuple[Union[str, bytes], ...]] = None,
1277 extra_prefix: Optional[Tuple[Union[str, bytes], ...]] = None,
1260 ) -> Tuple[str, int, Dict[str, DictKeyState]]:
1278 ) -> Tuple[str, int, Dict[str, _DictKeyState]]:
1261 """Used by dict_key_matches, matching the prefix to a list of keys
1279 """Used by dict_key_matches, matching the prefix to a list of keys
1262
1280
1263 Parameters
1281 Parameters
@@ -1307,8 +1325,8 b' def match_dict_keys('
1307 return True
1325 return True
1308
1326
1309 filtered_key_is_final: Dict[
1327 filtered_key_is_final: Dict[
1310 Union[str, bytes, int, float], DictKeyState
1328 Union[str, bytes, int, float], _DictKeyState
1311 ] = defaultdict(lambda: DictKeyState.BASELINE)
1329 ] = defaultdict(lambda: _DictKeyState.BASELINE)
1312
1330
1313 for k in keys:
1331 for k in keys:
1314 # If at least one of the matches is not final, mark as undetermined.
1332 # If at least one of the matches is not final, mark as undetermined.
@@ -1319,9 +1337,9 b' def match_dict_keys('
1319 if filter_prefix_tuple(k):
1337 if filter_prefix_tuple(k):
1320 key_fragment = k[prefix_tuple_size]
1338 key_fragment = k[prefix_tuple_size]
1321 filtered_key_is_final[key_fragment] |= (
1339 filtered_key_is_final[key_fragment] |= (
1322 DictKeyState.END_OF_TUPLE
1340 _DictKeyState.END_OF_TUPLE
1323 if len(k) == prefix_tuple_size + 1
1341 if len(k) == prefix_tuple_size + 1
1324 else DictKeyState.IN_TUPLE
1342 else _DictKeyState.IN_TUPLE
1325 )
1343 )
1326 elif prefix_tuple_size > 0:
1344 elif prefix_tuple_size > 0:
1327 # we are completing a tuple but this key is not a tuple,
1345 # we are completing a tuple but this key is not a tuple,
@@ -1329,7 +1347,7 b' def match_dict_keys('
1329 pass
1347 pass
1330 else:
1348 else:
1331 if isinstance(k, text_serializable_types):
1349 if isinstance(k, text_serializable_types):
1332 filtered_key_is_final[k] |= DictKeyState.END_OF_ITEM
1350 filtered_key_is_final[k] |= _DictKeyState.END_OF_ITEM
1333
1351
1334 filtered_keys = filtered_key_is_final.keys()
1352 filtered_keys = filtered_key_is_final.keys()
1335
1353
@@ -1367,7 +1385,7 b' def match_dict_keys('
1367 token_start = token_match.start()
1385 token_start = token_match.start()
1368 token_prefix = token_match.group()
1386 token_prefix = token_match.group()
1369
1387
1370 matched: Dict[str, DictKeyState] = {}
1388 matched: Dict[str, _DictKeyState] = {}
1371
1389
1372 str_key: Union[str, bytes]
1390 str_key: Union[str, bytes]
1373
1391
@@ -2503,8 +2521,8 b' class IPCompleter(Completer):'
2503 tuple_prefix = guarded_eval(
2521 tuple_prefix = guarded_eval(
2504 prior_tuple_keys,
2522 prior_tuple_keys,
2505 EvaluationContext(
2523 EvaluationContext(
2506 globals_=self.global_namespace,
2524 globals=self.global_namespace,
2507 locals_=self.namespace,
2525 locals=self.namespace,
2508 evaluation=self.evaluation,
2526 evaluation=self.evaluation,
2509 in_subscript=True,
2527 in_subscript=True,
2510 ),
2528 ),
@@ -2569,7 +2587,7 b' class IPCompleter(Completer):'
2569
2587
2570 results = []
2588 results = []
2571
2589
2572 end_of_tuple_or_item = DictKeyState.END_OF_TUPLE | DictKeyState.END_OF_ITEM
2590 end_of_tuple_or_item = _DictKeyState.END_OF_TUPLE | _DictKeyState.END_OF_ITEM
2573
2591
2574 for k, state_flag in matches.items():
2592 for k, state_flag in matches.items():
2575 result = leading + k
2593 result = leading + k
@@ -2584,7 +2602,7 b' class IPCompleter(Completer):'
2584
2602
2585 if state_flag in end_of_tuple_or_item and can_close_bracket:
2603 if state_flag in end_of_tuple_or_item and can_close_bracket:
2586 result += "]"
2604 result += "]"
2587 if state_flag == DictKeyState.IN_TUPLE and can_close_tuple_item:
2605 if state_flag == _DictKeyState.IN_TUPLE and can_close_tuple_item:
2588 result += ", "
2606 result += ", "
2589 results.append(result)
2607 results.append(result)
2590 return results
2608 return results
@@ -17,6 +17,7 b' from functools import cached_property'
17 from dataclasses import dataclass, field
17 from dataclasses import dataclass, field
18
18
19 from IPython.utils.docs import GENERATING_DOCUMENTATION
19 from IPython.utils.docs import GENERATING_DOCUMENTATION
20 from IPython.utils.decorators import undoc
20
21
21
22
22 if TYPE_CHECKING or GENERATING_DOCUMENTATION:
23 if TYPE_CHECKING or GENERATING_DOCUMENTATION:
@@ -26,21 +27,25 b' else:'
26 Protocol = object # requires Python >=3.8
27 Protocol = object # requires Python >=3.8
27
28
28
29
30 @undoc
29 class HasGetItem(Protocol):
31 class HasGetItem(Protocol):
30 def __getitem__(self, key) -> None:
32 def __getitem__(self, key) -> None:
31 ...
33 ...
32
34
33
35
36 @undoc
34 class InstancesHaveGetItem(Protocol):
37 class InstancesHaveGetItem(Protocol):
35 def __call__(self, *args, **kwargs) -> HasGetItem:
38 def __call__(self, *args, **kwargs) -> HasGetItem:
36 ...
39 ...
37
40
38
41
42 @undoc
39 class HasGetAttr(Protocol):
43 class HasGetAttr(Protocol):
40 def __getattr__(self, key) -> None:
44 def __getattr__(self, key) -> None:
41 ...
45 ...
42
46
43
47
48 @undoc
44 class DoesNotHaveGetAttr(Protocol):
49 class DoesNotHaveGetAttr(Protocol):
45 pass
50 pass
46
51
@@ -49,7 +54,7 b' class DoesNotHaveGetAttr(Protocol):'
49 MayHaveGetattr = Union[HasGetAttr, DoesNotHaveGetAttr]
54 MayHaveGetattr = Union[HasGetAttr, DoesNotHaveGetAttr]
50
55
51
56
52 def unbind_method(func: Callable) -> Union[Callable, None]:
57 def _unbind_method(func: Callable) -> Union[Callable, None]:
53 """Get unbound method for given bound method.
58 """Get unbound method for given bound method.
54
59
55 Returns None if cannot get unbound method."""
60 Returns None if cannot get unbound method."""
@@ -69,8 +74,11 b' def unbind_method(func: Callable) -> Union[Callable, None]:'
69 return None
74 return None
70
75
71
76
77 @undoc
72 @dataclass
78 @dataclass
73 class EvaluationPolicy:
79 class EvaluationPolicy:
80 """Definition of evaluation policy."""
81
74 allow_locals_access: bool = False
82 allow_locals_access: bool = False
75 allow_globals_access: bool = False
83 allow_globals_access: bool = False
76 allow_item_access: bool = False
84 allow_item_access: bool = False
@@ -92,12 +100,12 b' class EvaluationPolicy:'
92 if func in self.allowed_calls:
100 if func in self.allowed_calls:
93 return True
101 return True
94
102
95 owner_method = unbind_method(func)
103 owner_method = _unbind_method(func)
96 if owner_method and owner_method in self.allowed_calls:
104 if owner_method and owner_method in self.allowed_calls:
97 return True
105 return True
98
106
99
107
100 def has_original_dunder_external(
108 def _has_original_dunder_external(
101 value,
109 value,
102 module_name,
110 module_name,
103 access_path,
111 access_path,
@@ -121,7 +129,7 b' def has_original_dunder_external('
121 return False
129 return False
122
130
123
131
124 def has_original_dunder(
132 def _has_original_dunder(
125 value, allowed_types, allowed_methods, allowed_external, method_name
133 value, allowed_types, allowed_methods, allowed_external, method_name
126 ):
134 ):
127 # note: Python ignores `__getattr__`/`__getitem__` on instances,
135 # note: Python ignores `__getattr__`/`__getitem__` on instances,
@@ -141,12 +149,13 b' def has_original_dunder('
141 return True
149 return True
142
150
143 for module_name, *access_path in allowed_external:
151 for module_name, *access_path in allowed_external:
144 if has_original_dunder_external(value, module_name, access_path, method_name):
152 if _has_original_dunder_external(value, module_name, access_path, method_name):
145 return True
153 return True
146
154
147 return False
155 return False
148
156
149
157
158 @undoc
150 @dataclass
159 @dataclass
151 class SelectivePolicy(EvaluationPolicy):
160 class SelectivePolicy(EvaluationPolicy):
152 allowed_getitem: Set[InstancesHaveGetItem] = field(default_factory=set)
161 allowed_getitem: Set[InstancesHaveGetItem] = field(default_factory=set)
@@ -155,14 +164,14 b' class SelectivePolicy(EvaluationPolicy):'
155 allowed_getattr_external: Set[Tuple[str, ...]] = field(default_factory=set)
164 allowed_getattr_external: Set[Tuple[str, ...]] = field(default_factory=set)
156
165
157 def can_get_attr(self, value, attr):
166 def can_get_attr(self, value, attr):
158 has_original_attribute = has_original_dunder(
167 has_original_attribute = _has_original_dunder(
159 value,
168 value,
160 allowed_types=self.allowed_getattr,
169 allowed_types=self.allowed_getattr,
161 allowed_methods=self._getattribute_methods,
170 allowed_methods=self._getattribute_methods,
162 allowed_external=self.allowed_getattr_external,
171 allowed_external=self.allowed_getattr_external,
163 method_name="__getattribute__",
172 method_name="__getattribute__",
164 )
173 )
165 has_original_attr = has_original_dunder(
174 has_original_attr = _has_original_dunder(
166 value,
175 value,
167 allowed_types=self.allowed_getattr,
176 allowed_types=self.allowed_getattr,
168 allowed_methods=self._getattr_methods,
177 allowed_methods=self._getattr_methods,
@@ -182,7 +191,7 b' class SelectivePolicy(EvaluationPolicy):'
182
191
183 def can_get_item(self, value, item):
192 def can_get_item(self, value, item):
184 """Allow accessing `__getiitem__` of allow-listed instances unless it was not modified."""
193 """Allow accessing `__getiitem__` of allow-listed instances unless it was not modified."""
185 return has_original_dunder(
194 return _has_original_dunder(
186 value,
195 value,
187 allowed_types=self.allowed_getitem,
196 allowed_types=self.allowed_getitem,
188 allowed_methods=self._getitem_methods,
197 allowed_methods=self._getitem_methods,
@@ -211,34 +220,50 b' class SelectivePolicy(EvaluationPolicy):'
211 }
220 }
212
221
213
222
214 class DummyNamedTuple(NamedTuple):
223 class _DummyNamedTuple(NamedTuple):
215 pass
224 pass
216
225
217
226
218 class EvaluationContext(NamedTuple):
227 class EvaluationContext(NamedTuple):
219 locals_: dict
228 #: Local namespace
220 globals_: dict
229 locals: dict
230 #: Global namespace
231 globals: dict
232 #: Evaluation policy identifier
221 evaluation: Literal[
233 evaluation: Literal[
222 "forbidden", "minimal", "limited", "unsafe", "dangerous"
234 "forbidden", "minimal", "limited", "unsafe", "dangerous"
223 ] = "forbidden"
235 ] = "forbidden"
236 #: Whether the evalution of code takes place inside of a subscript.
237 #: Useful for evaluating ``:-1, 'col'`` in ``df[:-1, 'col']``.
224 in_subscript: bool = False
238 in_subscript: bool = False
225
239
226
240
227 class IdentitySubscript:
241 class _IdentitySubscript:
242 """Returns the key itself when item is requested via subscript."""
243
228 def __getitem__(self, key):
244 def __getitem__(self, key):
229 return key
245 return key
230
246
231
247
232 IDENTITY_SUBSCRIPT = IdentitySubscript()
248 IDENTITY_SUBSCRIPT = _IdentitySubscript()
233 SUBSCRIPT_MARKER = "__SUBSCRIPT_SENTINEL__"
249 SUBSCRIPT_MARKER = "__SUBSCRIPT_SENTINEL__"
234
250
235
251
236 class GuardRejection(ValueError):
252 class GuardRejection(Exception):
253 """Exception raised when guard rejects evaluation attempt."""
254
237 pass
255 pass
238
256
239
257
240 def guarded_eval(code: str, context: EvaluationContext):
258 def guarded_eval(code: str, context: EvaluationContext):
241 locals_ = context.locals_
259 """Evaluate provided code in the evaluation context.
260
261 If evaluation policy given by context is set to ``forbidden``
262 no evaluation will be performed; if it is set to ``dangerous``
263 standard :func:`eval` will be used; finally, for any other,
264 policy :func:`eval_node` will be called on parsed AST.
265 """
266 locals_ = context.locals
242
267
243 if context.evaluation == "forbidden":
268 if context.evaluation == "forbidden":
244 raise GuardRejection("Forbidden mode")
269 raise GuardRejection("Forbidden mode")
@@ -256,10 +281,10 b' def guarded_eval(code: str, context: EvaluationContext):'
256 locals_ = locals_.copy()
281 locals_ = locals_.copy()
257 locals_[SUBSCRIPT_MARKER] = IDENTITY_SUBSCRIPT
282 locals_[SUBSCRIPT_MARKER] = IDENTITY_SUBSCRIPT
258 code = SUBSCRIPT_MARKER + "[" + code + "]"
283 code = SUBSCRIPT_MARKER + "[" + code + "]"
259 context = EvaluationContext(**{**context._asdict(), **{"locals_": locals_}})
284 context = EvaluationContext(**{**context._asdict(), **{"locals": locals_}})
260
285
261 if context.evaluation == "dangerous":
286 if context.evaluation == "dangerous":
262 return eval(code, context.globals_, context.locals_)
287 return eval(code, context.globals, context.locals)
263
288
264 expression = ast.parse(code, mode="eval")
289 expression = ast.parse(code, mode="eval")
265
290
@@ -267,14 +292,12 b' def guarded_eval(code: str, context: EvaluationContext):'
267
292
268
293
269 def eval_node(node: Union[ast.AST, None], context: EvaluationContext):
294 def eval_node(node: Union[ast.AST, None], context: EvaluationContext):
270 """
295 """Evaluate AST node in provided context.
271 Evaluate AST node in provided context.
272
296
273 Applies evaluation restrictions defined in the context.
297 Applies evaluation restrictions defined in the context. Currently does not support evaluation of functions with keyword arguments.
274
298
275 Currently does not support evaluation of functions with keyword arguments.
299 Does not evaluate actions that always have side effects:
276
300
277 Does not evaluate actions which always have side effects:
278 - class definitions (``class sth: ...``)
301 - class definitions (``class sth: ...``)
279 - function definitions (``def sth: ...``)
302 - function definitions (``def sth: ...``)
280 - variable assignments (``x = 1``)
303 - variable assignments (``x = 1``)
@@ -282,13 +305,15 b' def eval_node(node: Union[ast.AST, None], context: EvaluationContext):'
282 - deletions (``del x``)
305 - deletions (``del x``)
283
306
284 Does not evaluate operations which do not return values:
307 Does not evaluate operations which do not return values:
308
285 - assertions (``assert x``)
309 - assertions (``assert x``)
286 - pass (``pass``)
310 - pass (``pass``)
287 - imports (``import x``)
311 - imports (``import x``)
288 - control flow
312 - control flow:
289 - conditionals (``if x:``) except for ternary IfExp (``a if x else b``)
313
290 - loops (``for`` and `while``)
314 - conditionals (``if x:``) except for ternary IfExp (``a if x else b``)
291 - exception handling
315 - loops (``for`` and `while``)
316 - exception handling
292
317
293 The purpose of this function is to guard against unwanted side-effects;
318 The purpose of this function is to guard against unwanted side-effects;
294 it does not give guarantees on protection from malicious code execution.
319 it does not give guarantees on protection from malicious code execution.
@@ -376,10 +401,10 b' def eval_node(node: Union[ast.AST, None], context: EvaluationContext):'
376 f" not allowed in {context.evaluation} mode",
401 f" not allowed in {context.evaluation} mode",
377 )
402 )
378 if isinstance(node, ast.Name):
403 if isinstance(node, ast.Name):
379 if policy.allow_locals_access and node.id in context.locals_:
404 if policy.allow_locals_access and node.id in context.locals:
380 return context.locals_[node.id]
405 return context.locals[node.id]
381 if policy.allow_globals_access and node.id in context.globals_:
406 if policy.allow_globals_access and node.id in context.globals:
382 return context.globals_[node.id]
407 return context.globals[node.id]
383 if policy.allow_builtins_access and hasattr(builtins, node.id):
408 if policy.allow_builtins_access and hasattr(builtins, node.id):
384 # note: do not use __builtins__, it is implementation detail of Python
409 # note: do not use __builtins__, it is implementation detail of Python
385 return getattr(builtins, node.id)
410 return getattr(builtins, node.id)
@@ -439,8 +464,8 b' BUILTIN_GETITEM: Set[InstancesHaveGetItem] = {'
439 collections.UserDict,
464 collections.UserDict,
440 collections.UserList,
465 collections.UserList,
441 collections.UserString,
466 collections.UserString,
442 DummyNamedTuple,
467 _DummyNamedTuple,
443 IdentitySubscript,
468 _IdentitySubscript,
444 }
469 }
445
470
446
471
@@ -537,3 +562,12 b' EVALUATION_POLICIES = {'
537 allow_any_calls=True,
562 allow_any_calls=True,
538 ),
563 ),
539 }
564 }
565
566
567 __all__ = [
568 "guarded_eval",
569 "eval_node",
570 "GuardRejection",
571 "EvaluationContext",
572 "_unbind_method",
573 ]
@@ -68,94 +68,22 b' class ConfigMagics(Magics):'
68 To view what is configurable on a given class, just pass the class
68 To view what is configurable on a given class, just pass the class
69 name::
69 name::
70
70
71 In [2]: %config IPCompleter
71 In [2]: %config LoggingMagics
72 IPCompleter(Completer) options
72 LoggingMagics(Magics) options
73 ----------------------------
73 ---------------------------
74 IPCompleter.backslash_combining_completions=<Bool>
74 LoggingMagics.quiet=<Bool>
75 Enable unicode completions, e.g. \\alpha<tab> . Includes completion of latex
75 Suppress output of log state when logging is enabled
76 commands, unicode names, and expanding unicode characters back to latex
77 commands.
78 Current: True
79 IPCompleter.debug=<Bool>
80 Enable debug for the Completer. Mostly print extra information for
81 experimental jedi integration.
82 Current: False
76 Current: False
83 IPCompleter.disable_matchers=<list-item-1>...
84 List of matchers to disable.
85 The list should contain matcher identifiers (see
86 :any:`completion_matcher`).
87 Current: []
88 IPCompleter.greedy=<Bool>
89 Activate greedy completion
90 PENDING DEPRECATION. this is now mostly taken care of with Jedi.
91 This will enable completion on elements of lists, results of function calls, etc.,
92 but can be unsafe because the code is actually evaluated on TAB.
93 Current: False
94 IPCompleter.jedi_compute_type_timeout=<Int>
95 Experimental: restrict time (in milliseconds) during which Jedi can compute types.
96 Set to 0 to stop computing types. Non-zero value lower than 100ms may hurt
97 performance by preventing jedi to build its cache.
98 Current: 400
99 IPCompleter.limit_to__all__=<Bool>
100 DEPRECATED as of version 5.0.
101 Instruct the completer to use __all__ for the completion
102 Specifically, when completing on ``object.<tab>``.
103 When True: only those names in obj.__all__ will be included.
104 When False [default]: the __all__ attribute is ignored
105 Current: False
106 IPCompleter.merge_completions=<Bool>
107 Whether to merge completion results into a single list
108 If False, only the completion results from the first non-empty
109 completer will be returned.
110 As of version 8.6.0, setting the value to ``False`` is an alias for:
111 ``IPCompleter.suppress_competing_matchers = True.``.
112 Current: True
113 IPCompleter.omit__names=<Enum>
114 Instruct the completer to omit private method names
115 Specifically, when completing on ``object.<tab>``.
116 When 2 [default]: all names that start with '_' will be excluded.
117 When 1: all 'magic' names (``__foo__``) will be excluded.
118 When 0: nothing will be excluded.
119 Choices: any of [0, 1, 2]
120 Current: 2
121 IPCompleter.profile_completions=<Bool>
122 If True, emit profiling data for completion subsystem using cProfile.
123 Current: False
124 IPCompleter.profiler_output_dir=<Unicode>
125 Template for path at which to output profile data for completions.
126 Current: '.completion_profiles'
127 IPCompleter.suppress_competing_matchers=<Union>
128 Whether to suppress completions from other *Matchers*.
129 When set to ``None`` (default) the matchers will attempt to auto-detect
130 whether suppression of other matchers is desirable. For example, at the
131 beginning of a line followed by `%` we expect a magic completion to be the
132 only applicable option, and after ``my_dict['`` we usually expect a
133 completion with an existing dictionary key.
134 If you want to disable this heuristic and see completions from all matchers,
135 set ``IPCompleter.suppress_competing_matchers = False``. To disable the
136 heuristic for specific matchers provide a dictionary mapping:
137 ``IPCompleter.suppress_competing_matchers = {'IPCompleter.dict_key_matcher':
138 False}``.
139 Set ``IPCompleter.suppress_competing_matchers = True`` to limit completions
140 to the set of matchers with the highest priority; this is equivalent to
141 ``IPCompleter.merge_completions`` and can be beneficial for performance, but
142 will sometimes omit relevant candidates from matchers further down the
143 priority list.
144 Current: None
145 IPCompleter.use_jedi=<Bool>
146 Experimental: Use Jedi to generate autocompletions. Default to True if jedi
147 is installed.
148 Current: True
149
77
150 but the real use is in setting values::
78 but the real use is in setting values::
151
79
152 In [3]: %config IPCompleter.greedy = True
80 In [3]: %config LoggingMagics.quiet = True
153
81
154 and these values are read from the user_ns if they are variables::
82 and these values are read from the user_ns if they are variables::
155
83
156 In [4]: feeling_greedy=False
84 In [4]: feeling_quiet=False
157
85
158 In [5]: %config IPCompleter.greedy = feeling_greedy
86 In [5]: %config LoggingMagics.quiet = feeling_quiet
159
87
160 """
88 """
161 from traitlets.config.loader import Config
89 from traitlets.config.loader import Config
@@ -3,18 +3,18 b' from IPython.core.guarded_eval import ('
3 EvaluationContext,
3 EvaluationContext,
4 GuardRejection,
4 GuardRejection,
5 guarded_eval,
5 guarded_eval,
6 unbind_method,
6 _unbind_method,
7 )
7 )
8 from IPython.testing import decorators as dec
8 from IPython.testing import decorators as dec
9 import pytest
9 import pytest
10
10
11
11
12 def limited(**kwargs):
12 def limited(**kwargs):
13 return EvaluationContext(locals_=kwargs, globals_={}, evaluation="limited")
13 return EvaluationContext(locals=kwargs, globals={}, evaluation="limited")
14
14
15
15
16 def unsafe(**kwargs):
16 def unsafe(**kwargs):
17 return EvaluationContext(locals_=kwargs, globals_={}, evaluation="unsafe")
17 return EvaluationContext(locals=kwargs, globals={}, evaluation="unsafe")
18
18
19
19
20 @dec.skip_without("pandas")
20 @dec.skip_without("pandas")
@@ -206,7 +206,7 b' def test_access_builtins():'
206
206
207 def test_subscript():
207 def test_subscript():
208 context = EvaluationContext(
208 context = EvaluationContext(
209 locals_={}, globals_={}, evaluation="limited", in_subscript=True
209 locals={}, globals={}, evaluation="limited", in_subscript=True
210 )
210 )
211 empty_slice = slice(None, None, None)
211 empty_slice = slice(None, None, None)
212 assert guarded_eval("", context) == tuple()
212 assert guarded_eval("", context) == tuple()
@@ -221,8 +221,8 b' def test_unbind_method():'
221 return "CUSTOM"
221 return "CUSTOM"
222
222
223 x = X()
223 x = X()
224 assert unbind_method(x.index) is X.index
224 assert _unbind_method(x.index) is X.index
225 assert unbind_method([].index) is list.index
225 assert _unbind_method([].index) is list.index
226
226
227
227
228 def test_assumption_instance_attr_do_not_matter():
228 def test_assumption_instance_attr_do_not_matter():
General Comments 0
You need to be logged in to leave comments. Login now