0

I have a Python package that has some template files. I'm trying to access the path to them using pkg_resources, but I can't figure out how:

antigravity.py:

import pkg_resources

def my_function():
    print(pkg_resources.resource_listdir('antigravity', 'extras'))
    print(pkg_resources.resource_filename('antigravity', 'foo.dat'))
    print(pkg_resources.resource_filename('antigravity.extras', 'bar.dat'))
    return True

if __name__ == '__main__':
    my_function()

The output is:

python antigravity\antigravity.py
['bar.dat', 'test.txt']
C:\git\swt_root\new_project\antigravity\foo.dat
Traceback (most recent call last):
  File "antigravity\antigravity.py", line 22, in <module>
    my_function()
  File "antigravity\antigravity.py", line 16, in my_function
    print(pkg_resources.resource_filename('antigravity.extras', 'bar.dat'))
  File "C:\Users\my_user\Anaconda3\lib\site-packages\pkg_resources\__init__.py", line 1128, in resource_filename
    return get_provider(package_or_requirement).get_resource_filename(
  File "C:\Users\my_user\Anaconda3\lib\site-packages\pkg_resources\__init__.py", line 345, in get_provider
    __import__(moduleOrReq)
ModuleNotFoundError: No module named 'antigravity.extras'; 'antigravity' is not a package

I'm not trying to read bar.dat, I'm actually trying to replace the following code:

import pathlib

script_folder = pathlib.Path(__file__).parents[0]
bar = script_folder.joinpath('extras', 'bar.dat')

I've installed the package with pip install -e .. I'm using Anaconda on Windows 10.

My package structure is:

new_project
|   MANIFEST.in
|   setup.py
|
\---antigravity
    |   antigravity.py
    |   foo.dat
    |   __init__.py
    |
    \---extras
            bar.dat
            __init__.py

MANIFEST.in:

include antigravity/foo.dat
include antigravity/extras/bar.dat

setup.py:

import setuptools

setuptools.setup(
    name="antigravity",
    version="0.0.1",
    packages=setuptools.find_packages(),
    include_package_data=True,
    test_suite="test",
    python_requires=">=3.6",
)

__init__.py:

from .antigravity import my_function

foo.dat:

foo

bar.dat:

bar
Leonardo
  • 1,533
  • 17
  • 28
  • Try `pkg_resources.resource_string('antigravity', 'extras/bar.dat')`. Personally I don't recommend to use `pkg_resources`, though, see [here](https://stackoverflow.com/a/58941536/674039) for my recommendations. – wim Feb 12 '21 at 20:33
  • Sorry if I wasn't clear: I'm actually trying to get `bar.dat` path. – Leonardo Feb 12 '21 at 20:38
  • Are you sure `antigravity/extras` includes a `__init__.py` file as well? – Green Cloak Guy Feb 12 '21 at 20:49
  • @GreenCloakGuy It's not usual for resource subdirectories to contain an `__init__.py`. They are not subpackages. – wim Feb 12 '21 at 20:51
  • @Leonardo Why do you want to get a path? It is not actually required for package resources to even have a path on the filesystem (e.g. zipfile packaging, dynamically generated resources) – wim Feb 12 '21 at 20:52
  • @wim, the `extras` folder contains a bunch of Mustache templates and partials, I need to pass that path to Mustache: `pystache.Renderer(search_dirs=base_template)`, with `base_template` being the path to my `extras` folder. – Leonardo Feb 12 '21 at 20:56
  • @GreenCloakGuy, I created an `extras/__init__.py` file, `print(pkg_resources.resource_filename('antigravity.extras', 'bar.dat'))` breaks, `print(pkg_resources.resource_filename('antigravity', 'extras/bar.dat'))` works though. – Leonardo Feb 12 '21 at 21:01
  • You should not add the `__init__.py` file into resource directories. It is neither required nor desirable. – wim Feb 12 '21 at 21:02
  • @Leonardo Could you clarify, what do you know, the filename `bar.dat` or the resource subdir name `extras`? Both? Neither? You say you're trying to get `bar.dat` path but that may not be unique, a package could have two `bar.dat` resources in different subpaths. – wim Feb 12 '21 at 21:12
  • @wim, I'm very sorry for not being clear. I've edited the question, and what I really need to know is if there's a better alternative to `pathlib.Path(__file__).parents[0]`, like using `pkg_resources`. If there isn't, that's fine. – Leonardo Feb 12 '21 at 21:39
  • Yes, there is a better alternative - have a read over https://importlib-resources.readthedocs.io/en/latest/using.html#file-system-or-zip-file – wim Feb 12 '21 at 21:44

0 Answers0