13

I have the following Python code:

function = "Developer"
module = "something"
print(function + " on " + module)

With PyCharm 2017, I have a bubble which says “Shadows built-in names "function"/"module" with PyCharm”.

I’m surprised because "function" and "module" are not built-in names. They are not keywords either:

import __builtin__
import keyword

assert "function" not in dir(__builtin__)  # -> OK
assert "module" not in dir(__builtin__)    # -> OK
assert "function" not in keyword.kwlist    # -> OK
assert "module" not in keyword.kwlist      # -> OK

What’s wrong?

I’m using CPython 2.7, but have the same trouble with 3.5 & 3.6.

EDIT:

__builtin__ is now builtins in Python 3.

Laurent LAPORTE
  • 21,958
  • 6
  • 58
  • 103

2 Answers2

11

function is "defined" in builtins.pyi:

class function:
    # TODO not defined in builtins!   
    __name__ = ...  # type: str
    __qualname__ = ...  # type: str
    __module__ = ...  # type: str
    __code__ = ...  # type: Any
    __annotations__ = ...  # type: Dict[str, Any] 

Keep in mind I used "defined" vs defined. Check out this absurdity:

foo = function

raises

Traceback (most recent call last):
  File "main.py", line 117, in <module>
    foo = function
NameError: name 'function' is not defined

Yet if you do function = 'a' the IDE will complain (as you noticed) that this shadows a built-in name (even though function is clearly not actually defined).

The exact behavior repeats with module.

This is because (as far as I understand, anyone please correct me if I'm wrong) pyi files are only there to provide type hints (as PEP-484 suggests).

So, I'm not sure if this warning is a bug in Pycharm's linter (perhaps it should not be looking at "definitions" in .pyi files) or an intended behavior.

Either way, module and function are probably not good variable names anyway.

DeepSpace
  • 78,697
  • 11
  • 109
  • 154
  • I still don't understand why "function" exist in PyCharm stubs… – Laurent LAPORTE Jul 20 '17 at 12:54
  • @LaurentLAPORTE That you'll need to ask JetBrains, but like I explained in my answer, it is most probably to somehow assist with type hinting. – DeepSpace Jul 20 '17 at 12:56
  • I found the [Typeshed](https://github.com/python/typeshed/) reference on GitHub. Quote: “Each Python module is represented by a `.pyi` "stub". This is a normal Python file (i.e., it can be interpreted by Python 3), except all the methods are empty. Python function annotations ([PEP 3107](https://www.python.org/dev/peps/pep-3107/)) are used to describe the types the function has.” – Laurent LAPORTE Jul 20 '17 at 15:59
  • 1
    Currently, the best answer I had: This is a historic artefact. Probably it will be removed at some point, the problem is that will require lots of tiny tedious changes in [mypy](https://github.com/python/mypy/) code. – Laurent LAPORTE Jul 20 '17 at 16:18
2

Per PY-8672, since March 2014 there is an ability to ignore certain names with this inspection. Open Settings, search "Shadowing built-ins", click on the inspection name, and use the Options section to add names the inspection should whitelist.

theY4Kman
  • 5,572
  • 2
  • 32
  • 38