Get the variables required by the `expression`. A new dictionary defining the variables used in the `expression` is returned. Required variables are first looked up in the `uservars` mapping, then in the set of top-level columns of the table. Unknown variables caus
(
self,
expression: str,
uservars: dict[str, Any] | None,
depth: int = 2,
)
| 245 | # The next method is similar to their counterpart in `Table`, but |
| 246 | # adapted to the `Expr` own requirements. |
| 247 | def _required_expr_vars( |
| 248 | self, |
| 249 | expression: str, |
| 250 | uservars: dict[str, Any] | None, |
| 251 | depth: int = 2, |
| 252 | ) -> dict[str, Any]: |
| 253 | """Get the variables required by the `expression`. |
| 254 | |
| 255 | A new dictionary defining the variables used in the `expression` |
| 256 | is returned. Required variables are first looked up in the |
| 257 | `uservars` mapping, then in the set of top-level columns of the |
| 258 | table. Unknown variables cause a `NameError` to be raised. |
| 259 | |
| 260 | When `uservars` is `None`, the local and global namespace where |
| 261 | the API callable which uses this method is called is sought |
| 262 | instead. To disable this mechanism, just specify a mapping as |
| 263 | `uservars`. |
| 264 | |
| 265 | Nested columns and variables with an ``uint64`` type are not |
| 266 | allowed (`TypeError` and `NotImplementedError` are raised, |
| 267 | respectively). |
| 268 | |
| 269 | `depth` specifies the depth of the frame in order to reach local |
| 270 | or global variables. |
| 271 | |
| 272 | """ |
| 273 | # Get the names of variables used in the expression. |
| 274 | exprvars_cache = self._exprvars_cache |
| 275 | if expression not in exprvars_cache: |
| 276 | # Protection against growing the cache too much |
| 277 | if len(exprvars_cache) > 256: |
| 278 | # Remove 10 (arbitrary) elements from the cache |
| 279 | for k in list(exprvars_cache)[:10]: |
| 280 | del exprvars_cache[k] |
| 281 | cexpr = compile(expression, "<string>", "eval") |
| 282 | exprvars = [ |
| 283 | var |
| 284 | for var in cexpr.co_names |
| 285 | if var not in ["None", "False", "True"] |
| 286 | and var not in ne.expressions.functions |
| 287 | ] |
| 288 | exprvars_cache[expression] = exprvars |
| 289 | else: |
| 290 | exprvars = exprvars_cache[expression] |
| 291 | |
| 292 | # Get the local and global variable mappings of the user frame |
| 293 | # if no mapping has been explicitly given for user variables. |
| 294 | user_locals, user_globals = {}, {} |
| 295 | if uservars is None: |
| 296 | user_frame = sys._getframe(depth) |
| 297 | user_locals = user_frame.f_locals |
| 298 | user_globals = user_frame.f_globals |
| 299 | |
| 300 | # Look for the required variables first among the ones |
| 301 | # explicitly provided by the user. |
| 302 | reqvars = {} |
| 303 | for var in exprvars: |
| 304 | # Get the value. |