Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Access builtin functions by __builtins__

I have the following script:

a.py

print(__builtins__.max)
import b

and the following module:

b.py

print(__builtins__.max)

Launching them with python3 a.py I get:

<built-in function max>
Traceback (most recent call last):
  File "a.py", line 2, in <module>
    import b
  File "/home/antonio/Scrivania/b.py", line 1, in <module>
    print(__builtins__.max)
AttributeError: 'dict' object has no attribute 'max'

so I don't understand. Why in the script __builtins__ is assigned to the builtins module instead in the module __builtins__ is assigned to a dict?

like image 497
zer0uno Avatar asked Mar 18 '23 07:03

zer0uno


2 Answers

Don't use __builtins__; use the builtins module instead.

The __builtins__ object is an implementation detail you should not rely on. From the builtins module documentation:

As an implementation detail, most modules have the name __builtins__ made available as part of their globals. The value of __builtins__ is normally either this module or the value of this module’s __dict__ attribute. Since this is an implementation detail, it may not be used by alternate implementations of Python.

Note my emphasis there; you can either have a dictionary or the module object when you access __builtins__.

like image 113
Martijn Pieters Avatar answered Mar 27 '23 17:03

Martijn Pieters


Honestly? I can't imagine what they were thinking when they made __builtins__ mean different things in a script and in a module. I was using __builtins__ to access built-in ImportError from a library that defines its own ImportError as a public API and it worked for me until today.

I do not know the exact difference. My __builtins__.ImportError was working in a module for both Python 2.x and Python 3.x. Now with some upstream changes in the code the same construct fails exactly like in your case. I found your question using web search and I'm going to answer for others who might get into the same situations.

You cannot use __builtins__ due to the above problem and you cannot use builtins in Python 2.x, but I managed to fix that using the six python module.

from six.moves import builtins

This works for me both in Python 2.x and in Python 3.x and it works in the exact same place where __builtins__ fails. Hope that helps.

like image 20
Pavel Šimerda Avatar answered Mar 27 '23 16:03

Pavel Šimerda