|
46 | 46 | from ddtrace.debugging._safety import safe_getitem
|
47 | 47 | from ddtrace.internal.compat import PYTHON_VERSION_INFO as PY
|
48 | 48 | from ddtrace.internal.logger import get_logger
|
| 49 | +from ddtrace.internal.safety import _isinstance |
49 | 50 |
|
50 | 51 |
|
51 | 52 | DDASTType = Union[Dict[str, Any], Dict[str, List[Any]], Any]
|
@@ -126,7 +127,7 @@ def _make_function(self, ast: DDASTType, args: Tuple[str, ...], name: str) -> Fu
|
126 | 127 | return FunctionType(abstract_code.to_code(), {}, name, (), None)
|
127 | 128 |
|
128 | 129 | def _make_lambda(self, ast: DDASTType) -> Callable[[Any, Any], Any]:
|
129 |
| - return self._make_function(ast, ("_dd_it", "_locals"), "<lambda>") |
| 130 | + return self._make_function(ast, ("_dd_it", "_dd_key", "_dd_value", "_locals"), "<lambda>") |
130 | 131 |
|
131 | 132 | def _compile_direct_predicate(self, ast: DDASTType) -> Optional[List[Instr]]:
|
132 | 133 | # direct_predicate => {"<direct_predicate_type>": <predicate>}
|
@@ -200,12 +201,12 @@ def _compile_arg_predicate(self, ast: DDASTType) -> Optional[List[Instr]]:
|
200 | 201 | if ca is None:
|
201 | 202 | raise ValueError("Invalid argument: %r" % a)
|
202 | 203 |
|
203 |
| - return self._call_function( |
204 |
| - lambda i, c, _locals: f(c(_, _locals) for _ in i), |
205 |
| - ca, |
206 |
| - [Instr("LOAD_CONST", fb)], |
207 |
| - [Instr("LOAD_FAST", "_locals")], |
208 |
| - ) |
| 204 | + def coll_iter(it, cond, _locals): |
| 205 | + if _isinstance(it, dict): |
| 206 | + return f(cond(k, k, v, _locals) for k, v in it.items()) |
| 207 | + return f(cond(e, None, None, _locals) for e in it) |
| 208 | + |
| 209 | + return self._call_function(coll_iter, ca, [Instr("LOAD_CONST", fb)], [Instr("LOAD_FAST", "_locals")]) |
209 | 210 |
|
210 | 211 | if _type in {"startsWith", "endsWith"}:
|
211 | 212 | a, b = args
|
@@ -245,8 +246,8 @@ def _compile_direct_operation(self, ast: DDASTType) -> Optional[List[Instr]]:
|
245 | 246 | if not isinstance(arg, str):
|
246 | 247 | return None
|
247 | 248 |
|
248 |
| - if arg == "@it": |
249 |
| - return [Instr("LOAD_FAST", "_dd_it")] |
| 249 | + if arg in {"@it", "@key", "@value"}: |
| 250 | + return [Instr("LOAD_FAST", f"_dd_{arg[1:]}")] |
250 | 251 |
|
251 | 252 | return self._call_function(
|
252 | 253 | get_local, [Instr("LOAD_FAST", "_locals")], [Instr("LOAD_CONST", self.__ref__(arg))]
|
@@ -297,12 +298,12 @@ def _compile_arg_operation(self, ast: DDASTType) -> Optional[List[Instr]]:
|
297 | 298 | if ca is None:
|
298 | 299 | raise ValueError("Invalid argument: %r" % a)
|
299 | 300 |
|
300 |
| - return self._call_function( |
301 |
| - lambda i, c, _locals: type(i)(_ for _ in i if c(_, _locals)), |
302 |
| - ca, |
303 |
| - [Instr("LOAD_CONST", fb)], |
304 |
| - [Instr("LOAD_FAST", "_locals")], |
305 |
| - ) |
| 301 | + def coll_filter(it, cond, _locals): |
| 302 | + if _isinstance(it, dict): |
| 303 | + return type(it)({k: v for k, v in it.items() if cond(k, k, v, _locals)}) |
| 304 | + return type(it)(e for e in it if cond(e, None, None, _locals)) |
| 305 | + |
| 306 | + return self._call_function(coll_filter, ca, [Instr("LOAD_CONST", fb)], [Instr("LOAD_FAST", "_locals")]) |
306 | 307 |
|
307 | 308 | if _type == "getmember":
|
308 | 309 | v, attr = args
|
|
0 commit comments