Gdal with pytest on Windows - OSError: [WinError 127] The specified procedure could not be found

Hi,

I have a geodjango application that works fine when I run poetry run python manage.py runserver. However, while trying to use pytest I’m getting the following error:

OSError: [WinError 127] The specified procedure could not be found

If I start the application with manage.py runserver everything runs smoothly so I think I have configured everything according to the documentation steps, setting up gdal library paths on both windows system variables and settings.py.

Running normal Django tests with poetry run python manage.py test also works and I’m only seeing this error if I run poetry run pytest.

Some info about my system:

Windows 11
Django version 4.2.3
GDAL 3.7.1, released 2023/07/06
pytest 7.3.2

Full error:

Traceback (most recent call last):
  File "<frozen runpy>", line 198, in _run_module_as_main
  File "<frozen runpy>", line 88, in _run_code
  File "C:\Users\pedro\AppData\Local\pypoetry\Cache\virtualenvs\health-logistics-platform-EC_zAtyy-py3.11\Scripts\pytest.exe\__main__.py", line 7, in <module>
  File "C:\Users\pedro\AppData\Local\pypoetry\Cache\virtualenvs\health-logistics-platform-EC_zAtyy-py3.11\Lib\site-packages\_pytest\config\__init__.py", line 189, in console_main
    code = main()
           ^^^^^^
  File "C:\Users\pedro\AppData\Local\pypoetry\Cache\virtualenvs\health-logistics-platform-EC_zAtyy-py3.11\Lib\site-packages\_pytest\config\__init__.py", line 147, in main
    config = _prepareconfig(args, plugins)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\pedro\AppData\Local\pypoetry\Cache\virtualenvs\health-logistics-platform-EC_zAtyy-py3.11\Lib\site-packages\_pytest\config\__init__.py", line 328, in _prepareconfig
    config = pluginmanager.hook.pytest_cmdline_parse(
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\pedro\AppData\Local\pypoetry\Cache\virtualenvs\health-logistics-platform-EC_zAtyy-py3.11\Lib\site-packages\pluggy\_hooks.py", line 433, in __call__
    return self._hookexec(self.name, self._hookimpls, kwargs, firstresult)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\pedro\AppData\Local\pypoetry\Cache\virtualenvs\health-logistics-platform-EC_zAtyy-py3.11\Lib\site-packages\pluggy\_manager.py", line 112, in _hookexec
    return self._inner_hookexec(hook_name, methods, kwargs, firstresult)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\pedro\AppData\Local\pypoetry\Cache\virtualenvs\health-logistics-platform-EC_zAtyy-py3.11\Lib\site-packages\pluggy\_callers.py", line 133, in _multicall
    teardown[0].send(outcome)
  File "C:\Users\pedro\AppData\Local\pypoetry\Cache\virtualenvs\health-logistics-platform-EC_zAtyy-py3.11\Lib\site-packages\_pytest\helpconfig.py", line 103, in pytest_cmdline_parse
    config: Config = outcome.get_result()
                     ^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\pedro\AppData\Local\pypoetry\Cache\virtualenvs\health-logistics-platform-EC_zAtyy-py3.11\Lib\site-packages\pluggy\_result.py", line 108, in get_result
    raise exc.with_traceback(exc.__traceback__)
  File "C:\Users\pedro\AppData\Local\pypoetry\Cache\virtualenvs\health-logistics-platform-EC_zAtyy-py3.11\Lib\site-packages\pluggy\_callers.py", line 80, in _multicall
    res = hook_impl.function(*args)
          ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\pedro\AppData\Local\pypoetry\Cache\virtualenvs\health-logistics-platform-EC_zAtyy-py3.11\Lib\site-packages\_pytest\config\__init__.py", line 1075, in pytest_cmdline_parse
    self.parse(args)
  File "C:\Users\pedro\AppData\Local\pypoetry\Cache\virtualenvs\health-logistics-platform-EC_zAtyy-py3.11\Lib\site-packages\_pytest\config\__init__.py", line 1425, in parse
    self._preparse(args, addopts=addopts)
  File "C:\Users\pedro\AppData\Local\pypoetry\Cache\virtualenvs\health-logistics-platform-EC_zAtyy-py3.11\Lib\site-packages\_pytest\config\__init__.py", line 1327, in _preparse
    self.hook.pytest_load_initial_conftests(
  File "C:\Users\pedro\AppData\Local\pypoetry\Cache\virtualenvs\health-logistics-platform-EC_zAtyy-py3.11\Lib\site-packages\pluggy\_hooks.py", line 433, in __call__
    return self._hookexec(self.name, self._hookimpls, kwargs, firstresult)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\pedro\AppData\Local\pypoetry\Cache\virtualenvs\health-logistics-platform-EC_zAtyy-py3.11\Lib\site-packages\pluggy\_manager.py", line 112, in _hookexec
    return self._inner_hookexec(hook_name, methods, kwargs, firstresult)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\pedro\AppData\Local\pypoetry\Cache\virtualenvs\health-logistics-platform-EC_zAtyy-py3.11\Lib\site-packages\pluggy\_callers.py", line 155, in _multicall
    return outcome.get_result()
           ^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\pedro\AppData\Local\pypoetry\Cache\virtualenvs\health-logistics-platform-EC_zAtyy-py3.11\Lib\site-packages\pluggy\_result.py", line 108, in get_result
    raise exc.with_traceback(exc.__traceback__)
  File "C:\Users\pedro\AppData\Local\pypoetry\Cache\virtualenvs\health-logistics-platform-EC_zAtyy-py3.11\Lib\site-packages\pluggy\_callers.py", line 80, in _multicall
    res = hook_impl.function(*args)
          ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\pedro\AppData\Local\pypoetry\Cache\virtualenvs\health-logistics-platform-EC_zAtyy-py3.11\Lib\site-packages\pytest_django\plugin.py", line 353, in pytest_load_initial_conftests
    _setup_django()
  File "C:\Users\pedro\AppData\Local\pypoetry\Cache\virtualenvs\health-logistics-platform-EC_zAtyy-py3.11\Lib\site-packages\pytest_django\plugin.py", line 236, in _setup_django
    django.setup()
  File "C:\Users\pedro\AppData\Local\pypoetry\Cache\virtualenvs\health-logistics-platform-EC_zAtyy-py3.11\Lib\site-packages\django\__init__.py", line 24, in setup
    apps.populate(settings.INSTALLED_APPS)
  File "C:\Users\pedro\AppData\Local\pypoetry\Cache\virtualenvs\health-logistics-platform-EC_zAtyy-py3.11\Lib\site-packages\django\apps\registry.py", line 116, in populate
    app_config.import_models()
  File "C:\Users\pedro\AppData\Local\pypoetry\Cache\virtualenvs\health-logistics-platform-EC_zAtyy-py3.11\Lib\site-packages\django\apps\config.py", line 269, in import_models
    self.models_module = import_module(models_module_name)
                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Python311\Lib\importlib\__init__.py", line 126, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "<frozen importlib._bootstrap>", line 1204, in _gcd_import
  File "<frozen importlib._bootstrap>", line 1176, in _find_and_load
  File "<frozen importlib._bootstrap>", line 1147, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 690, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 940, in exec_module
  File "<frozen importlib._bootstrap>", line 241, in _call_with_frames_removed
  File "C:\Users\pedro\AppData\Local\pypoetry\Cache\virtualenvs\health-logistics-platform-EC_zAtyy-py3.11\Lib\site-packages\django\contrib\auth\models.py", line 3, in <module>
    from django.contrib.auth.base_user import AbstractBaseUser, BaseUserManager
  File "C:\Users\pedro\AppData\Local\pypoetry\Cache\virtualenvs\health-logistics-platform-EC_zAtyy-py3.11\Lib\site-packages\django\contrib\auth\base_user.py", line 57, in <module>
    class AbstractBaseUser(models.Model):
  File "C:\Users\pedro\AppData\Local\pypoetry\Cache\virtualenvs\health-logistics-platform-EC_zAtyy-py3.11\Lib\site-packages\django\db\models\base.py", line 143, in __new__
    new_class.add_to_class("_meta", Options(meta, app_label))
  File "C:\Users\pedro\AppData\Local\pypoetry\Cache\virtualenvs\health-logistics-platform-EC_zAtyy-py3.11\Lib\site-packages\django\db\models\base.py", line 371, in add_to_class
    value.contribute_to_class(cls, name)
  File "C:\Users\pedro\AppData\Local\pypoetry\Cache\virtualenvs\health-logistics-platform-EC_zAtyy-py3.11\Lib\site-packages\django\db\models\options.py", line 243, in contribute_to_class
    self.db_table, connection.ops.max_name_length()
                   ^^^^^^^^^^^^^^
  File "C:\Users\pedro\AppData\Local\pypoetry\Cache\virtualenvs\health-logistics-platform-EC_zAtyy-py3.11\Lib\site-packages\django\utils\connection.py", line 15, in __getattr__
    return getattr(self._connections[self._alias], item)
                   ~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^
  File "C:\Users\pedro\AppData\Local\pypoetry\Cache\virtualenvs\health-logistics-platform-EC_zAtyy-py3.11\Lib\site-packages\django\utils\connection.py", line 62, in __getitem__
    conn = self.create_connection(alias)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\pedro\AppData\Local\pypoetry\Cache\virtualenvs\health-logistics-platform-EC_zAtyy-py3.11\Lib\site-packages\django\db\utils.py", line 193, in create_connection
    backend = load_backend(db["ENGINE"])
              ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\pedro\AppData\Local\pypoetry\Cache\virtualenvs\health-logistics-platform-EC_zAtyy-py3.11\Lib\site-packages\django\db\utils.py", line 113, in load_backend
    return import_module("%s.base" % backend_name)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\pedro\AppData\Local\pypoetry\Cache\virtualenvs\health-logistics-platform-EC_zAtyy-py3.11\Lib\site-packages\django\contrib\gis\gdal\datasource.py", line 40, in <module>
    from django.contrib.gis.gdal.driver import Driver
  File "C:\Users\pedro\AppData\Local\pypoetry\Cache\virtualenvs\health-logistics-platform-EC_zAtyy-py3.11\Lib\site-packages\django\contrib\gis\gdal\driver.py", line 5, in <module>
    from django.contrib.gis.gdal.prototypes import ds as vcapi
  File "C:\Users\pedro\AppData\Local\pypoetry\Cache\virtualenvs\health-logistics-platform-EC_zAtyy-py3.11\Lib\site-packages\django\contrib\gis\gdal\prototypes\ds.py", line 9, in <module>
    from django.contrib.gis.gdal.libgdal import lgdal
  File "C:\Users\pedro\AppData\Local\pypoetry\Cache\virtualenvs\health-logistics-platform-EC_zAtyy-py3.11\Lib\site-packages\django\contrib\gis\gdal\libgdal.py", line 71, in <module>
    lgdal = CDLL(lib_path)
            ^^^^^^^^^^^^^^
  File "C:\Python311\Lib\ctypes\__init__.py", line 376, in __init__
    self._handle = _dlopen(self._name, mode)
                   ^^^^^^^^^^^^^^^^^^^^^^^^^
OSError: [WinError 127] The specified procedure could not be found

Since this appears to be a poetry issue and not a Django issue, I’d like to suggest that you’re going to get faster and probably more accurate assistance if you try to address this through whatever support channels they make available.

(I don’t think I’ve ever even seen a reference to poetry here before. I believe you’re the first person to mention using it. I know that I don’t know anything about it.)

Thank you, I will try their channels