2

I have a custom module loader that basically does some redirection. I would like pylint to recognize this custom loader. This is my situation:

root/
    __init__.py
    new/
        __init__.py
        foo.py
        bar.py
    old/
        __init__.py

I have a lot of clients importing old.foo. I wrote a custom loader in old/__init__.py to redirect these to import new.foo under the hood. How do I get pylint to recognize this? When it lints import old.foo, it complains that it can't find old.foo. This is only a problem with pylint. I can get client code to recognize the custom loader without any issue.

Srikanth
  • 973
  • 2
  • 9
  • 19
  • 1
    I think you want to use the [`__path__`](https://docs.python.org/3/tutorial/modules.html#packages-in-multiple-directories) special name that packages can use to spread across multiple directories basically redirecting any reference to `old` around to `new` – Tadhg McDonald-Jensen Apr 01 '16 at 15:01
  • does this help at all: [how to tell pylint to ignore certain imports?](http://stackoverflow.com/questions/9602811/how-to-tell-pylint-to-ignore-certain-imports) – Tadhg McDonald-Jensen Apr 01 '16 at 15:56

2 Answers2

1

from the documentation on modules:

Packages support one more special attribute, __path__. This is initialized to be a list containing the name of the directory holding the package’s __init__.py before the code in that file is executed. This variable can be modified; doing so affects future searches for modules and subpackages contained in the package.

So if I understand correctly you want to redirect any references to old to redirect to new, so all you would need to do is replace the old folder with old.py that contains this:

__path__ = ["new"]

Then when anything tries to import old.foo it will end up importing new.foo.

Tadhg McDonald-Jensen
  • 20,699
  • 5
  • 35
  • 59
  • Thanks, that is a great solution to replace my custom loader. But pylint is still not happy. It doesn't recognize `__path__` changes in `__init__.py`. Appears this problem is unsolvabe, based on http://stackoverflow.com/q/5394786/1330434 – Srikanth Apr 01 '16 at 15:23
  • I don't think you fully understood, you need to replace the __folder__ with a `old.py`, if that doesn't work either then I'm not sure what to suggest. – Tadhg McDonald-Jensen Apr 01 '16 at 15:25
  • Tried that. That changes the error from `No name 'foo' in module 'old' (no-name-in-module)` to `Unable to import 'old.foo' (import-error)`. – Srikanth Apr 01 '16 at 15:29
  • ok, well if putting `from new import *` doesn't work in the `old.py` then I am out of ideas. Haven't worked with pylint but I wish you luck! – Tadhg McDonald-Jensen Apr 01 '16 at 15:32
  • Nope, that doesn't work either. Thanks for your help. Appreciate it. – Srikanth Apr 01 '16 at 15:36
0

You have to remember that pylint is a static analyser and as such doesn't actually load python file (except in some cases where it can't do otherwise, e.g. compiled code). As such it's not aware of custom importer or other tricks taking part of python's high dynamicity.

That being said:

  • you may still write a "brain" plugin for astroid (the library under pylint) that will help pylint understand your code's specificity

  • by relying on standard mecanism such as __path__ manipulation you'll get more chance to avoid such need, either because at some point pylint may understand this or because someone else will have contributed a plugin for that purpose.

sthenault
  • 14,397
  • 5
  • 38
  • 32