Проверить модуль, если он содержит funcs / coros / methods - PullRequest
1 голос
/ 06 мая 2020

У меня есть каталог, например:

my_directory/
|
├── sub_dir/
|   ├── bar.py
|   └── foo.py
|
├── sub_dir_b/
|   └── file4.txt
|
├── sub_dir_c/
|   ├── config.py
|   └── my_test_file.py
|
├── file1.py
├── file2.py
└── file3.txt

Теперь я хочу проверить каждую функцию и метод каждого python -файла, если ожидаемое возвращаемое значение является типом Coroutine.

Вопрос: есть ли способ проверить эти файлы (по абсолютному пути)?

В my_test_file.py у меня есть функция, которая возвращает краткую информацию о моих файлах Python (через os.walk), но похоже, что это мне больше не поможет. Должен ли я импортировать их как модуль в любом случае, потому что тогда может быть решение с inspect.getmembers() или есть лучший способ без их импорта?

Я знаю, что могу проверить тип возвращаемого значения, получив функции / методы __annotations__ например:

async def bar(j):
    return None

def foo(i:int,j:int)-> Coroutine:
    res = i+j
    return bar

foo.__annotations__["return"]

Вернут: typing.Coroutine, с которым я могу сравнить.

1 Ответ

1 голос
/ 06 мая 2020

Должен сработать, не знаю, для чего вам это нужно на самом деле, поскольку в python ничего не заставляет вас возвращать аннотированный тип, но, эй, было весело решить эту проблему.

from importlib import import_module
from inspect import getmembers, isfunction
from pathlib import Path

modules = {}
for f in Path('.').rglob('*.py'):
    if f.as_posix() != __file__:
        module = '.'.join(f.parts[:-1]+('',)) + f.stem
        modules[f.stem] = import_module(module)

for members in map(getmembers, modules.values()):
    for member in members:
        name, function = member
        if isfunction(function):
            return_type = function.__annotations__.get('return', None)
            print(name, return_type)
...