Skip to content

Commit 2816ac6

Browse files
committed
DOC: document how to use installed data files with editable installs
1 parent 1c520a8 commit 2816ac6

File tree

6 files changed

+117
-0
lines changed

6 files changed

+117
-0
lines changed

docs/how-to-guides/editable-installs.rst

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,74 @@ An alternative build directory can be specified using the
108108
:option:`build-dir` config setting.
109109

110110

111+
Data files
112+
----------
113+
114+
It is relatively common to install data files needed at runtime
115+
alongside the package's Python code or extension modules. For a Python
116+
package named ``package`` this would look like this:
117+
118+
.. TODO update the text block below to 'meson' when
119+
.. meson lexer is updated to fix
120+
.. https://github.com/pygments/pygments/issues/2918
121+
122+
.. code-block:: text
123+
124+
py = import('python').find_installation()
125+
126+
py.install_sources(
127+
'__init__.py',
128+
subdir: 'package',
129+
)
130+
131+
install_data(
132+
'data.txt',
133+
install_dir: py.get_install_dir() / 'package',
134+
)
135+
136+
custom_target(
137+
output: 'uuid.txt',
138+
command: [py, '-m', 'uuid''],
139+
capture: true,
140+
install: true,
141+
install_dir: py.get_install_dir() / 'package',
142+
)
143+
144+
In most circumstances, these files can be accessed deriving their
145+
filesystem path from the filesystem path of the Python module next to
146+
them via the ``__file__`` special variable. For example, within the
147+
package ``__init__.py``:
148+
149+
.. code-block:: python
150+
151+
import pathlib
152+
153+
data = pathlib.Path(__file__).parent.joinpath('data.txt').read_text()
154+
uuid = pathlib.Path(__file__).parent.joinpath('uuid.txt').read_text() # WRONG!
155+
156+
However, this does not work when modules are not loaded from a package
157+
installed in the Python library path in the filesystem but with a
158+
special module loader, as used to implement editable installs in
159+
``meson-python``. In the example above, the second read would fail
160+
when the package is installed in editable mode. For this reason, data
161+
files need to be accessed using :mod:`importlib.resources`. The code
162+
above should be replaced with:
163+
164+
.. code-block:: python
165+
166+
import importlib.resources
167+
168+
data = importlib.resources.files().joinpath('data.txt').read_text()
169+
uuid = importlib.resources.files().joinpath('uuid.txt').read_text()
170+
171+
:mod:`importlib.resources` implements a virtual filesystem that allows
172+
to access individual files as if they were in their install location.
173+
However, there is not way to expose this file structure outside of the
174+
python runtime. In the example above, it is not possible to make the
175+
``data.txt`` and ``uuid.txt`` files appear in the same fileystem
176+
directory.
177+
178+
111179
.. _how-to-guides-editable-installs-verbose:
112180

113181
Verbose mode
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# SPDX-FileCopyrightText: 2025 The meson-python developers
2+
#
3+
# SPDX-License-Identifier: MIT
4+
5+
import importlib.resources
6+
import pathlib
7+
8+
9+
data = pathlib.Path(__file__).parent.joinpath('data.txt').read_text()
10+
uuid = pathlib.Path(__file__).parent.joinpath('uuid.txt').read_text() # WRONG!
11+
12+
data = importlib.resources.files().joinpath('data.txt').read_text()
13+
uuid = importlib.resources.files().joinpath('uuid.txt').read_text()
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
DATA
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# SPDX-FileCopyrightText: 2025 The meson-python developers
2+
#
3+
# SPDX-License-Identifier: MIT
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# SPDX-FileCopyrightText: 2025 The meson-python developers
2+
#
3+
# SPDX-License-Identifier: MIT
4+
5+
project('install-data', version: '1.0.0')
6+
7+
py = import('python').find_installation()
8+
9+
py.install_sources(
10+
'__init__.py',
11+
subdir: 'package',
12+
)
13+
14+
install_data(
15+
'data.txt',
16+
install_dir: py.get_install_dir() / 'package',
17+
)
18+
19+
custom_target(
20+
output: 'uuid.txt',
21+
command: [py, '-m', 'uuid'],
22+
capture: true,
23+
install: true,
24+
install_dir: py.get_install_dir() / 'package',
25+
)
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# SPDX-FileCopyrightText: 2023 The meson-python developers
2+
#
3+
# SPDX-License-Identifier: MIT
4+
5+
[build-system]
6+
build-backend = 'mesonpy'
7+
requires = ['meson-python']

0 commit comments

Comments
 (0)