0

I want to load a file from my python module using importlib.resources (see also this question). If the file is inside a submodule, this is straight forward (run using python -m, see here):

import importlib.resources
from . import submodule

print(importlib.resources.files(submodule).joinpath("file.txt").read_bytes())

For files in the same module, it is possible to use __package__:

import importlib.resources

print(importlib.resources.files(__package__).joinpath("file.txt").read_bytes())

However, I cannot get this approach to work for files inside the top level module, if I want to access them from a submodule:

module
├── file.txt
├── __init__.py
└── submodule
    ├── __init__.py
    └── submodule_script.py
import importlib.resources

from ... import module # ImportError: attempted relative import beyond top-level package
import .. as module # SyntaxError: invalid syntax
from .. import . as module # SyntaxError: invalid syntax

print(importlib.resources.files(module).joinpath("file.txt").read_bytes())

How can I obtain an import-like reference to the top level module location, such that importlib.resources can understand it?

One option is to use an absolute import (import module), but I use relative imports everywhere else in my project and would prefer consistency. Is it possible using relative imports?

3
  • did you try .joinpath("..", "file.txt")? Commented Jul 17 at 18:32
  • 2
    Why do you need relative imports? If you know the module is top-level, why not just do an absolute import (ie. import module)? Commented Jul 17 at 19:02
  • @Dunes this works (it is actually what I am using currently). But I use relative imports for everything else, so it feels weird to use absolute imports for this one use case. But you are right, this is definitely an option, I will mention it in an edit Commented Jul 17 at 20:05

1 Answer 1

0

It seems importlib.resources.files() gives object Path() from module pathlib

It can use .. to get parent folder - like .joinpath("..", "file.txt")

import importlib.resources

print(importlib.resources.files(submodule).joinpath("..", "file.txt").read_bytes())

or with .parent like .parent.joinpath("file.txt")

import importlib.resources

print(importlib.resources.files(submodule).parent.joinpath("file.txt").read_bytes())

It should also work for files in other submodules

... .joinpath("..", "other_submodule", "file.txt").read_bytes()

... .parent.joinpath("other_submodule", "file.txt").read_bytes()

It also allow to check files in directory

list(... .joinpath("..").iterdir())
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks for the answer! While this should work, it depends on a specific submodule to be present, which is not involved in the process otherwise. This feels not like the intended use, so I would rather like to avoid it.
you was using .. so I thought you need parent. And it is relative. If you need top then you should import directly module without any ... And if you wanted to use ... then you can use .parent.parent instead. I don't know other relative method.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.