Import a pyi (type stub file) into a normal python module

3.6k Views Asked by At

I have a program (like a macro) that runs within a parent program and imports an API module from that program (lets call it foo). The problem is that that module only exists within that program, so I can't do things like run pydocmd outside the software because the script throws a ReferenceError. To aid in my own development I have create a type stub file, foo.pyi, in my project directory. What I would like to do is import that type stub as a normal Python file if the import fails, to provide dummy functions and properties. Something like:

try:
  import foo
except ImportError:
  from . import foo.pyi

This raises an error, however, as it's trying to import pyi from the foo library that does not exist in the project folder. The only other option I can think of is to have an identical copy of the .pyi file as, say "dummy_foo.py" but then I have to maintain two copies of the same file in one repo. I'd rather not do that.

2

There are 2 best solutions below

0
Graham Wheeler On

I wrote this a while back; should still work I think:

import importlib


def import_stub(stubs_path, module_name):
    sys.path_hooks.insert(0,
        importlib.machinery.FileFinder.path_hook(
            (importlib.machinery.SourceFileLoader, ['.pyi']))
    )
    sys.path.insert(0, stubs_path)
    
    try:
        return importlib.import_module(module_name)
    finally:
        sys.path.pop(0)
        sys.path_hooks.pop(0)
1
kai3341 On

I found this question, but my problem was about type checking. In my case pyi file contains class definition (so type hints are working), but the library doesn't. Solution is in checking typing.TYPE_CHECKING:

from typing import TYPE_CHECKING

if TYPE_CHECKING:
    from library import _PrivateClass

def foo(x: "_PrivateClass"):
    ...