Package: painless-import-extension
PIEInstallation & Documentationpip install painless-import-extension.Basically there's only one thing exported from packagepie:frompieimportLoaderForBetterLifeIt's an abstract generic type. When you want to load a file to typeA,
write such a loader:classALoader(LoaderForBetterLife[A]):passIDEs and static type checkers will help you to finish the following steps of implementing your expecting loader, and this is what I'd call a documentation here.MotivationFuck it, I must say something at first.Once you use the Python import hooks to support files with extensions other than '.py',
you will feel extremely disgusting, and if you're expert enough to use Python internal stuffs
to track the implementation ofPathFinder.find_spec(usuallysys.meta_path[2].find_specorsys.meta_path[1].find_spec),
the awfulness of the module finding mechanism will lead you to a strong suspicion of the reliability of Pythonimportstatements,
and finally, likely to bring about the crash of one's faith in writing reliable codes.I for one encountered this, and fortunately I didn't jump down from my dormitory after working with that for months(and knew it for years).Hence, I realized that it should be my duty to keep people away from being killed when working with Python's module finding mechanism,
which might save several people's lives.What is PIE?PIE, akapainless-import-extension, is not aimed at providing a higher level interface of Python's
import system, but is actually useful for solving most of the related problems.Technically, PIE "did nothing", all the codes involved in this project are so far pretty easy,
that even a newbie to Python could understand it thoroughly with any question. However,
PIE is useful, because it shows ahealthy mental modelfor using Python import system,
in a simplest way, and also a most practical way if you want to use the same module file search strategy of Python's.For instance, if you want to importdata.jsonvia PIE, other than the JSON file,
you should also prepare a file with just suffix changed to.py(hence you gotdata.py), and
fill the following contents:frompie.json_loaderimportJsonLoaderdata=JsonLoader(__file__,__name__).load()where,JsonLoader(__file__, __name__).load()will load the JSON data.Looks trivial? Yes, that's expected, and I'm telling you that this way is powerful,
and subtly, much more powerful thanjson.load(pathlib.Path(__file__).with_suffix('.json').open()).A PIE loader, and what happened when invokingLoaderForBetterLife.load()?Given such a file directory:- proj
    - data.json
    - data.pyAnd we filldata.pywithfrompie.json_loaderimportJsonLoaderdata=JsonLoader(__file__,__name__).load()Next, when you're importproj.data,for the first time,
things similar tojson.loadhappened, JSON is loaded fromdata.json.
However, a default caching system is introduced, and when you exit
current Python interpreter, and reopen the interpreter to importproj.datafor the second time,json.loadmight not be invoked.
There're some cases:whenproj/data.jsondoesn't exist, we'll get the JSON
from a binary file cached on disk.whenproj/data.jsonexists, we'll check if the content
ofproj/data.jsonhas changed. If true, we importproj/data.jsonjust as what we did at the first time; otherwise, we use the cached
binary contents.Things become quite useful when you're loading DSLs(domain specific languages),
or other programming languages that compile to the Python.For example, we give an implementation of loading the script ofmuridesulanguage(Python 3.7 only).Checktest/zenzen_muridesu.py, note that if you're using an IDE,
you will have a good experience of auto completion and static checking
due to our thorough support of Python type hints.frompathlibimportPathfromtypingimportUnion,Tuplefrommuridesu.parse_stmtsimportparse_stmtsasparsefrompieimportLoaderForBetterLifefromtypesimportCodeTypeimportmarshalclassMuridesuLoader(LoaderForBetterLife[CodeType]):defsource_to_prog(self,src:bytes,path:Path):mod=parse(src.decode('utf8'),str(path.absolute()))code=compile(mod,self.file.with_suffix(self.suffix()),'exec')returncodedefload_program(self,b:bytes):returnmarshal.loads(b)defdump_program(self,prog:CodeType):returnmarshal.dumps(prog)defsuffix(self)->Union[str,Tuple[str,...]]:return'.muridesu'exec(MuridesuLoader(__file__,__name__).load(),globals())Intest/zenzen_muridesu.muridesu, write downclass Animal {
    func bark(self){
        print("hoho")
    }
}

class Dog <: Animal {
    bark = fn (self) -> {
        print("dogy")
    }
}

list(
    map(
        fn (it) -> {
            print(it.__class__)
            it.bark()
        },
        [Dog(), Animal()]
    )
)Importingtest/zenzen_muridesu.pywill give following STD output:<class '__main__.Dog'>
dogy
<class '__main__.Animal'>
hohoConclusionMake sure if you really want to introduce the complexity ofimportlib?When you just need searching extension files just as searching normal python files,
use PIE.