current scenario -
- on function creation, it has a
__builtins__ attribute (from python 3.10+), that is,
- this includes builtins like
expected scenario -
- the ones which are not related to the function should not be included, as I think it would somewhere contribute towards increasing the memory, time complexity of creating a function
Python 3.10.4 (main, Jun 29 2022, 12:14:53) [GCC 11.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> def f(): pass
>>> def g(): pass
>>> assert f is not g
>>> assert f.__builtins__ is g.__builtins__
>>> import builtins
>>> assert f.__builtins__ is builtins.__dict__
At the C implementation level,
func.__builtins__ is only a pointer to the builtins dict.
Making a copy of a pointer is almost free, so the cost in time complexity and memory use is negligible.
If the interpreter had to:
- analyse the function to work out which builtins were used;
- create a new dict;
- copy the used builtins into that dict;
for every function, it would be much slower and use much more memory.
But even the first step is impossible without analysing the entire application, because builtins is writeable and the interpreter cannot tell in advance what is in builtins. When you write this function:
the interpreter doesn’t know whether
print will refer to a builtin or a global at the time you call it, or even whether
print will exist at all.