1

As I dig further into Python internals, I start to see abc's more often in the documentation. Unfortunately the docs don't explain how they can be used. I haven't even been able to use the "concrete implementations" of these abstract base classes.

For example, reading about class importlib.abc.SourceLoader, one learns that "is_package" is a concrete implementation of InspectLoader.is_package(). But what if I'd like to use that in my code? Is it possible? I've tried many ways but the method can't be imported.

ExtensionFileLoader is documented as a concrete implementation of importlib.abc.ExecutionLoader, but if I try to use it (such as: from importlib import machinery.ExecutionLoader), once again it can't be found.

If these methods can't be imported, why are they documented? is there any sample code to show how they can be used? Example:

import importlib.abc.SourceLoader     # doesn't work

class try_pkg_check():

    def main(self, source_file_name):   
        possible_pkgs = ['math', 'numpy']           
        for posbl_pkg in possible_pkgs:         
            answer = SourceLoader.is_package(posbl_pkg)            
            print("For {}, the answer is: {}".format(posbl_pkg, answer))                
        return None         

if __name__ == "__main__":    
    instantiated_obj = try_pkg_check()      
    instantiated_obj.main()

People might comment that I shouldn't try to import an abstract class. But "is_package" is documented as concrete, so I should be able to use it somehow, which is my question.

jwodder
  • 54,758
  • 12
  • 108
  • 124
Ben_Z
  • 19
  • 3
  • `importlib.abc.ExecutionLoader` is in `importlib.abc`, but `from importlib import machinery.ExecutionLoader` assumes it's in `importlib.machinery`. – jwodder May 27 '18 at 17:32
  • Actually, `from importlib import machinery.ExecutionLoader` is invalid syntax, so you'd get a different error than "it can't be found". Can you please show us some actual code you're trying to run that doesn't do what you expect? – jwodder May 27 '18 at 17:34
  • Is your question about abc and ExecutionLoader as example or do you know about abc and want more details on ExecutionLoader6 – Olivier Melançon May 27 '18 at 17:56
  • As soon as I learn how to prevent line breaks being removed when I post code, I'll post code. Reading the help docs but do not see it mentioned, which is odd, because it should be the first topic covered. – Ben_Z May 27 '18 at 18:20

1 Answers1

0
import importlib.abc.SourceLoader

The error message that this line produces should give you a hint where you've gone wrong:

ModuleNotFoundError: No module named 'importlib.abc.SourceLoader'; 'importlib.abc' is not a package

"import foo" requires that foo be a module, but SourceLoader is a class inside a module. You need to instead write:

from importlib.abc import SourceLoader

However, there are further problems with this line:

answer = SourceLoader.is_package(posbl_pkg)

First of all, SourceLoader.is_package is an instance method, not a class or static method; it has to be called on an instance of SourceLoader, not on the class itself. However, SourceLoader is an abstract class, so it can't be directly instantiated; you need to use a concrete subclass like SourceFileLoader instead. (When the docs call SourceLoader.is_package a "concrete implementation" of InspectLoader.is_package, I believe what they mean is that SourceLoader provides a default implementation for is_package so that its subclasses don't need to override it in order to be non-abstract.)

Hence, you need to write:

from importlib.machinery import SourceFileLoader

...

answer = SourceFileLoader(fullname, path).is_package(fullname)

where fullname is "a fully resolved name of the module the loader is to handle" and path is "the path to the file for the module."

jwodder
  • 54,758
  • 12
  • 108
  • 124