Why cant I access builtins if I use a custom dict as a functions globals?

2024/10/7 2:20:54

I have a dict subclass like this:

class MyDict(dict):def __getitem__(self, name):return globals()[name]

This class can be used with eval and exec without issues:

>>> eval('bytearray', MyDict())
<class 'bytearray'>
>>> exec('print(bytearray)', MyDict())
<class 'bytearray'>

But if I instantiate a function object with the types.FunctionType constructor, the function can't access any builtins:

import typesfunc = lambda: bytearray
func_copy = types.FunctionType(func.__code__,MyDict(),func.__name__,func.__defaults__,func.__closure__)print(func_copy())
# Traceback (most recent call last):
#   File "untitled.py", line 16, in <module>
#     print(func_copy())
#   File "untitled.py", line 8, in <lambda>
#     func = lambda: bytearray
# NameError: name 'bytearray' is not defined

Replacing MyDict() with globals() or dict(globals()) or event {'__builtins__': __builtins__} makes the code print <class 'bytearray'> as expected.

I don't understand where this exception is coming from. Can anyone explain this behavior? Why does it work with eval but not with a function object?

Answer

Not a complete answer, but what seems to be happening is that CPython ignores the custom __getitem__ when it accesses the builtins. It seems to treat MyDict like a normal (not subclassed) dict. If the '__builtins__' key is actually present in the dict, then everything works correctly:

class MyDict(dict):def __getitem__(self, name):return globals()[name]import typesglobs = MyDict()
globs['__builtins__'] = __builtins__func = lambda: bytearray
func_copy = types.FunctionType(func.__code__,globs,func.__name__,func.__defaults__,func.__closure__)print(func_copy())
# output: <class 'bytearray'>

The question remains why this only happens with FunctionType, and not with eval and exec.

https://en.xdnf.cn/q/70294.html

Related Q&A

How to enable autocomplete (IntelliSense) for python package modules?

This question is not about Pygame, Im usin Pygame as an example.While experimenting with Pygame Ive noticed that autocomplete is not working for some modules. For example, if I start typing pygame.mixe…

Integrating a redirection-included method of payment in django-oscar

I am developing a shopping website using django-oscar framework, in fact I am using their sandbox site. I want to add payment to the checkout process, but the thing is, I am totally confused!Ive read t…

How can I unpack sequence?

Why cant I do this:d = [x for x in range(7)] a, b, c, d, e, f, g = *dWhere is it possible to unpack? Only between parentheses of a function?

Can I statically link Cython modules into an executable which embeds python?

I currently have an executable compiled from C++ that embeds python. The embedded executable runs a python script which load several Cython modules. Both the Cython modules and the executable are lin…

How to Store Graphs?

Lets say i have a class Graph defined.graph iowa = {.....nodes:{edges.......}}and similar graph clusters.once the script is running its all in the object. But how do you store the Graph info (including…

regex for only numbers in string?

I cant find the regex for strings containing only whitespaces or integers. The string is an input from user on keyboard. It can contain everything but \n (but it doesnt matter I guess), but we can focu…

How to build a chi-square distribution table

I would like to generate a chi-square distribution table in python as a function of the probability level and degree of freedom.How to calculate the probability, given a known chi-value and degree of f…

Reset all weights of Keras model

I would like to be able to reset the weights of my entire Keras model so that I do not have to compile it again. Compiling the model is currently the main bottleneck of my code. Here is an example of w…

How to fix NaN or infinity issue for sparse matrix in python?

Im totally new to python. Ive used some code found online and I tried to work on it. So Im creating a text-document-matrix and I want to add some extra features before training a logistic regression mo…

Mutable default argument for a Python namedtuple

I came across a neat way of having namedtuples use default arguments from here.from collections import namedtuple Node = namedtuple(Node, val left right) Node.__new__.__defaults__ = (None, None, None) …