pythonpython-3.xpytorchpytestfast-ai

AttributeError only occurs during PyTest run | Custom classes or functions exported with your `Learner` are not available in the namespace currently


Goal: load model and namespace my_func into namespace for pytest run.

The model and its namespace are fine in project code runtime.

AttributeError only occurs during pytest run.

Placing my_func() anywhere in test script doesn't prevent error.

tests/test_predict.py:

import pytest
from fastai.vision.all import *

from project.predict import my_func, prediction


model = load_learner('model_path/', cpu=True)
model.load(fast_ai_params.weights)


def my_test():
    pred = prediction(tile_params, model, full_tile_path)

    assert pred.shape

This test script runs fine statically, via. python3. Indicating that both the model and namespace are loaded in, without errors.

(venv) me@ubuntu-pcs:~/PycharmProjects/project$ python3 tests/test_predict.py 
(venv) me@ubuntu-pcs:~/PycharmProjects/project$ 

However, when I run python -m pytest tests/test_predict.py:

=========================================================================================================================== ERRORS ============================================================================================================================
___________________________________________________________________________________________________________ ERROR collecting tests/test_predict.py ____________________________________________________________________________________________________________
tests/test_predict.py:16: in <module>
    model = load_learner(fast_ai_params.model, cpu=fast_ai_params.cpu)
../../miniconda3/envs/venv/lib/python3.9/site-packages/fastai/learner.py:414: in load_learner
    try: res = torch.load(fname, map_location=map_loc, pickle_module=pickle_module)
../../miniconda3/envs/venv/lib/python3.9/site-packages/torch/serialization.py:594: in load
    return _load(opened_zipfile, map_location, pickle_module, **pickle_load_args)
../../miniconda3/envs/venv/lib/python3.9/site-packages/torch/serialization.py:853: in _load
    result = unpickler.load()
E   AttributeError: Custom classes or functions exported with your `Learner` are not available in the namespace currently.
E   Please re-declare or import them before calling `load_learner`:
E       Can't get attribute 'my_func' on <module 'pytest.__main__' from '/home/me/miniconda3/envs/venv/lib/python3.9/site-packages/pytest/__main__.py'>
====================================================================================================================== warnings summary =======================================================================================================================
../../miniconda3/envs/venv/lib/python3.9/site-packages/torchvision/transforms/functional_pil.py:387
  /home/me/miniconda3/envs/venv/lib/python3.9/site-packages/torchvision/transforms/functional_pil.py:387: DeprecationWarning: BILINEAR is deprecated and will be removed in Pillow 10 (2023-07-01). Use Resampling.BILINEAR instead.
    def resize(img, size, interpolation=Image.BILINEAR):

../../miniconda3/envs/venv/lib/python3.9/site-packages/torchvision/transforms/functional_pil.py:545
  /home/me/miniconda3/envs/venv/lib/python3.9/site-packages/torchvision/transforms/functional_pil.py:545: DeprecationWarning: BICUBIC is deprecated and will be removed in Pillow 10 (2023-07-01). Use Resampling.BICUBIC instead.
    def perspective(img, perspective_coeffs, interpolation=Image.BICUBIC, fill=None):

../../miniconda3/envs/venv/lib/python3.9/site-packages/torchvision/transforms/functional.py:288
  /home/me/miniconda3/envs/venv/lib/python3.9/site-packages/torchvision/transforms/functional.py:288: DeprecationWarning: BILINEAR is deprecated and will be removed in Pillow 10 (2023-07-01). Use Resampling.BILINEAR instead.
    def resize(img: Tensor, size: List[int], interpolation: int = Image.BILINEAR) -> Tensor:

../../miniconda3/envs/venv/lib/python3.9/site-packages/torchvision/transforms/functional.py:419
  /home/me/miniconda3/envs/venv/lib/python3.9/site-packages/torchvision/transforms/functional.py:419: DeprecationWarning: BILINEAR is deprecated and will be removed in Pillow 10 (2023-07-01). Use Resampling.BILINEAR instead.
    img: Tensor, top: int, left: int, height: int, width: int, size: List[int], interpolation: int = Image.BILINEAR

../../miniconda3/envs/venv/lib/python3.9/site-packages/torchvision/transforms/transforms.py:26
  /home/me/miniconda3/envs/venv/lib/python3.9/site-packages/torchvision/transforms/transforms.py:26: DeprecationWarning: NEAREST is deprecated and will be removed in Pillow 10 (2023-07-01). Use Resampling.NEAREST or Dither.NONE instead.
    Image.NEAREST: 'PIL.Image.NEAREST',

../../miniconda3/envs/venv/lib/python3.9/site-packages/torchvision/transforms/transforms.py:27
  /home/me/miniconda3/envs/venv/lib/python3.9/site-packages/torchvision/transforms/transforms.py:27: DeprecationWarning: BILINEAR is deprecated and will be removed in Pillow 10 (2023-07-01). Use Resampling.BILINEAR instead.
    Image.BILINEAR: 'PIL.Image.BILINEAR',

../../miniconda3/envs/venv/lib/python3.9/site-packages/torchvision/transforms/transforms.py:28
  /home/me/miniconda3/envs/venv/lib/python3.9/site-packages/torchvision/transforms/transforms.py:28: DeprecationWarning: BICUBIC is deprecated and will be removed in Pillow 10 (2023-07-01). Use Resampling.BICUBIC instead.
    Image.BICUBIC: 'PIL.Image.BICUBIC',

../../miniconda3/envs/venv/lib/python3.9/site-packages/torchvision/transforms/transforms.py:29
  /home/me/miniconda3/envs/venv/lib/python3.9/site-packages/torchvision/transforms/transforms.py:29: DeprecationWarning: LANCZOS is deprecated and will be removed in Pillow 10 (2023-07-01). Use Resampling.LANCZOS instead.
    Image.LANCZOS: 'PIL.Image.LANCZOS',

../../miniconda3/envs/venv/lib/python3.9/site-packages/torchvision/transforms/transforms.py:30
  /home/me/miniconda3/envs/venv/lib/python3.9/site-packages/torchvision/transforms/transforms.py:30: DeprecationWarning: HAMMING is deprecated and will be removed in Pillow 10 (2023-07-01). Use Resampling.HAMMING instead.
    Image.HAMMING: 'PIL.Image.HAMMING',

../../miniconda3/envs/venv/lib/python3.9/site-packages/torchvision/transforms/transforms.py:31
  /home/me/miniconda3/envs/venv/lib/python3.9/site-packages/torchvision/transforms/transforms.py:31: DeprecationWarning: BOX is deprecated and will be removed in Pillow 10 (2023-07-01). Use Resampling.BOX instead.
    Image.BOX: 'PIL.Image.BOX',

../../miniconda3/envs/venv/lib/python3.9/site-packages/torchvision/transforms/transforms.py:250
  /home/me/miniconda3/envs/venv/lib/python3.9/site-packages/torchvision/transforms/transforms.py:250: DeprecationWarning: BILINEAR is deprecated and will be removed in Pillow 10 (2023-07-01). Use Resampling.BILINEAR instead.
    def __init__(self, size, interpolation=Image.BILINEAR):

../../miniconda3/envs/venv/lib/python3.9/site-packages/torchvision/transforms/transforms.py:671
  /home/me/miniconda3/envs/venv/lib/python3.9/site-packages/torchvision/transforms/transforms.py:671: DeprecationWarning: BILINEAR is deprecated and will be removed in Pillow 10 (2023-07-01). Use Resampling.BILINEAR instead.
    def __init__(self, distortion_scale=0.5, p=0.5, interpolation=Image.BILINEAR, fill=0):

../../miniconda3/envs/venv/lib/python3.9/site-packages/torchvision/transforms/transforms.py:752
  /home/me/miniconda3/envs/venv/lib/python3.9/site-packages/torchvision/transforms/transforms.py:752: DeprecationWarning: BILINEAR is deprecated and will be removed in Pillow 10 (2023-07-01). Use Resampling.BILINEAR instead.
    def __init__(self, size, scale=(0.08, 1.0), ratio=(3. / 4., 4. / 3.), interpolation=Image.BILINEAR):

../../miniconda3/envs/venv/lib/python3.9/site-packages/sklearn/utils/multiclass.py:14
  /home/me/miniconda3/envs/venv/lib/python3.9/site-packages/sklearn/utils/multiclass.py:14: DeprecationWarning: Please use `spmatrix` from the `scipy.sparse` namespace, the `scipy.sparse.base` namespace is deprecated.
    from scipy.sparse.base import spmatrix

-- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html
=================================================================================================================== short test summary info ===================================================================================================================
ERROR tests/test_predict.py - AttributeError: Custom classes or functions exported with your `Learner` are not available in the namespace currently.
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Interrupted: 1 error during collection !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
================================================================================================================ 14 warnings, 1 error in 1.13s ================================================================================================================

Please let me know what else needs included in post.


Solution

  • Place model code underneath boilerplate code, and invoke test functions

    if __name__ == '__main__':
        model = load_learner('model_path/', cpu=True)
        model.load(fast_ai_params.weights)
    
        my_test()
    

    Inspired by solution.