Search code examples
python-3.xpython-modulebuilt-in

Exclude __builtin__ module


The __builtin__ module in Python clutters a developers namespace with lots of functions and classes that have very generic names (e.g. max, sum, id, hash etc.) that often get in the way of naming variables and when outside of a context-aware IDE one can accidentally overwrite a name without noticing.

Is there a way to stop this module from being implicitly accessed from a certain file and require explicit imports instead?

Something along the lines of:

from __builtins__ import hash as builtin_hash

hash = builtin_hash(foo)

I am aware that this is bad practice.


Solution

  • You can simply delete __builtins__, the name Python uses to find the built-in namespace:

    >>> del __builtins__
    >>> max
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    NameError: name 'max' is not defined
    

    Warning: If you do this in someone else's namespace, they will hate you.

    ...and require explicit imports instead?

    Note that import statements are resolved using builtins ;)

    >>> del __builtins__
    >>> from builtins import max
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    ImportError: __import__ not found
    

    ... very generic names (e.g. max, sum, id, hash etc.) that often get in the way of naming variables and when outside of a context-aware IDE one can accidentally overwrite a name without noticing

    You will only create a local variable which shadows the name. This is actually fairly inconsequential if you do it from within a limited scope, although it's still bad form (readability counts).

    # this shadows built-in hash function in this namespace ... meh?
    hash = '38762cf7f55934b34d179ae6a4c80cadccbb7f0a'
    
    # this stomps built-in hash ... not a honking great idea!
    import builtins
    builtins.hash = lambda obj: -1
    

    Best practice:

    • Use a context-aware editor which will give you a squiggly underline for name collisions, or
    • Use Python long enough that you know the built-in names by heart (seriously!)
    • Avoid name shadowing by using a synonym (e.g. checksum) or appending a trailing underscore on the name (e.g. hash_)