diff options
author | Eli Schwartz <eschwartz@archlinux.org> | 2022-03-10 19:03:03 -0500 |
---|---|---|
committer | Jussi Pakkanen <jpakkane@gmail.com> | 2022-03-15 11:22:59 +0200 |
commit | 68b8fbcf6d684e93fe11e08f383945e6661e071b (patch) | |
tree | ba39d8d6c8c60a8eaab42ca4d0fee1ef8ea8593e | |
parent | 7c20890a05481e97eee57a147f50237087a1c94e (diff) | |
download | meson-68b8fbcf6d684e93fe11e08f383945e6661e071b.zip meson-68b8fbcf6d684e93fe11e08f383945e6661e071b.tar.gz meson-68b8fbcf6d684e93fe11e08f383945e6661e071b.tar.bz2 |
Revert "devenv: Set PYTHONPATH where we install python modules"
This reverts commit 79c6075b560dbf1c3e4e0b30f1c472dc2086421e.
# Conflicts:
# docs/markdown/snippets/devenv.md
# mesonbuild/modules/python.py
# test cases/unit/91 devenv/test-devenv.py
PYTHONPATH cannot be reliably determined. The standard use case for
installing python modules with Meson is mixed pure sources (at least
`__init__.py`) and compiled extension_modules or configured files.
Unfortunately that doesn't actually work because python will not load
the same package hierarchy from two different directories, one a source
directory and one a (mandatory) out of tree build directory.
(It kind of can, but you need to do what this test case accidentally
stumbled upon, which is namespace packages. Namespace packages are a
very specific use case and you are NOT SUPPOSED to use them outside that
use case, so people are not going to use them just to circumvent Meson
devenv stuff as that would have negative install-time effects.)
Adding PYTHONPATH anyway will just lead to documentation commitments
which we cannot actually uphold, and confusing issues at time of use
because some imports *will* work... and some will *not*. The end result
will be a half-created tree of modules which just doesn't work together
at all, but because it partially works, users attempting to debug it
will spend time wondering why parts of it do import.
For any case where the automatic devenv would work correctly, it will
also work correctly to use `meson.add_devenv()` a single time, which is
very easy to manually get correct and doesn't provide any significant
value to automate.
In the long run, an uninstalled python package environment will require
"editable installs" support.
-rw-r--r-- | docs/markdown/Commands.md | 9 | ||||
-rw-r--r-- | docs/markdown/snippets/devenv.md | 6 | ||||
-rw-r--r-- | mesonbuild/modules/python.py | 49 | ||||
-rw-r--r-- | test cases/unit/91 devenv/meson.build | 10 | ||||
-rw-r--r-- | test cases/unit/91 devenv/src/mymod/mod.py | 1 | ||||
-rw-r--r-- | test cases/unit/91 devenv/src/mymod2/meson.build | 5 | ||||
-rw-r--r-- | test cases/unit/91 devenv/src/mymod2/mod2.c | 14 | ||||
-rwxr-xr-x | test cases/unit/91 devenv/test-devenv.py | 7 |
8 files changed, 7 insertions, 94 deletions
diff --git a/docs/markdown/Commands.md b/docs/markdown/Commands.md index f905d2c..b137166 100644 --- a/docs/markdown/Commands.md +++ b/docs/markdown/Commands.md @@ -340,15 +340,6 @@ These variables are set in environment in addition to those set using `meson.add schemas is compiled. This is automatically set when using `gnome.compile_schemas()`. Note that this requires GLib >= 2.64 when `gnome.compile_schemas()` is used in more than one directory. -- `PYTHONPATH` *Since 0.62.0* includes every directory where a python module is being - installed using [`python.install_sources()`](Python-module.md#install_sources) - and [`python.extension_module()`](Python-module.md#extension_module). Python - modules installed by other means, such as `install_data()` or `install_subdir()`, - will not be included and should be added to `PYTHONPATH` manually using - [`meson.add_devenv()`](Reference-manual_builtin_meson.md#mesonadd_devenv). - Note that when modules are installed into subdirectories the source tree - layout must match the installed tree layout otherwise `import subdir.mod` - cannot work. Since *Since 0.62.0* if bash-completion scripts are being installed and the shell is bash, they will be automatically sourced. diff --git a/docs/markdown/snippets/devenv.md b/docs/markdown/snippets/devenv.md index 104cfd9..bffa5fa 100644 --- a/docs/markdown/snippets/devenv.md +++ b/docs/markdown/snippets/devenv.md @@ -1,9 +1,3 @@ -## `PYTHONPATH` automatically defined in `meson devenv` - -`PYTHONPATH` now includes every directory where a python module is being -installed using [`python.install_sources()`](Python-module.md#install_sources) -and [`python.extension_module()`](Python-module.md#extension_module). - ## Bash completion scripts sourced in `meson devenv` If bash-completion scripts are being installed and the shell is bash, they will diff --git a/mesonbuild/modules/python.py b/mesonbuild/modules/python.py index 3eac33f..70ae3c1 100644 --- a/mesonbuild/modules/python.py +++ b/mesonbuild/modules/python.py @@ -23,7 +23,7 @@ from . import ExtensionModule from .. import mesonlib from .. import mlog from ..coredata import UserFeatureOption -from ..build import known_shmod_kwargs, EnvironmentVariables +from ..build import known_shmod_kwargs from ..dependencies import DependencyMethods, PkgConfigDependency, NotFoundDependency, SystemDependency, ExtraFrameworkDependency from ..dependencies.base import process_method_kw from ..environment import detect_cpu_family @@ -48,7 +48,6 @@ if T.TYPE_CHECKING: from ..interpreter import Interpreter from ..interpreter.kwargs import ExtractRequired from ..interpreterbase.interpreterbase import TYPE_var, TYPE_kwargs - from ..backends import InstallData class PythonIntrospectionDict(TypedDict): @@ -400,20 +399,6 @@ class PythonExternalProgram(ExternalProgram): 'variables': {}, 'version': '0.0', } - self.devenv_pythonpath: T.Set[str] = set() - - def add_devenv_pythonpath(self, basedir: str, subdir: str, install_subdir: str) -> None: - # If we install python module into 'foo/bar' subdir, we need the last 2 - # parts of source dir to be ['foo', 'bar'] and set PYTHONPATH - # pointing grandparent directory. That way scripts will be able to - # `import foo.bar.something` just like when the are installed. - # If the source tree layout does not match installed layout there is - # nothing we can do. - install_subdir_parts = Path(install_subdir).parts - subdir_parts = Path(subdir).parts - if subdir_parts[-len(install_subdir_parts):] == install_subdir_parts: - pypath = os.path.join(basedir, *subdir_parts[:-len(install_subdir_parts)]) - self.devenv_pythonpath.add(pypath) def _check_version(self, version: str) -> bool: if self.name == 'python2': @@ -522,10 +507,8 @@ class PythonInstallation(ExternalProgramHolder): subdir = kwargs.pop('subdir', '') if not isinstance(subdir, str): raise InvalidArguments('"subdir" argument must be a string.') + kwargs['install_dir'] = os.path.join(self.platlib_install_path, subdir) - self.held_object.add_devenv_pythonpath( - self.interpreter.environment.get_build_dir(), - self.interpreter.subdir, subdir) # On macOS and some Linux distros (Debian) distutils doesn't link # extensions against libpython. We call into distutils and mirror its @@ -580,19 +563,11 @@ class PythonInstallation(ExternalProgramHolder): def install_sources_method(self, args: T.Tuple[T.List[T.Union[str, mesonlib.File]]], kwargs: 'PyInstallKw') -> 'Data': tag = kwargs['install_tag'] or 'runtime' - pure = kwargs['pure'] - sources = self.interpreter.source_strings_to_files(args[0]) - install_subdir = kwargs['subdir'] - install_dir = self._get_install_dir_impl(pure, install_subdir) - builddir = self.interpreter.environment.get_build_dir() - srcdir = self.interpreter.environment.get_source_dir() - for src in sources: - basedir = builddir if src.is_built else srcdir - subdir = os.path.dirname(src.relative_name()) - self.held_object.add_devenv_pythonpath(basedir, subdir, install_subdir) - return self.interpreter.install_data_impl(sources, install_dir, + return self.interpreter.install_data_impl( + self.interpreter.source_strings_to_files(args[0]), + self._get_install_dir_impl(kwargs['pure'], kwargs['subdir']), mesonlib.FileMode(), rename=None, tag=tag, install_data_type='python', - install_dir_name=self._get_install_dir_name_impl(pure, install_subdir)) + install_dir_name=self._get_install_dir_name_impl(kwargs['pure'], kwargs['subdir'])) @noPosargs @typed_kwargs('python_installation.install_dir', _PURE_KW, _SUBDIR_KW) @@ -660,18 +635,6 @@ class PythonModule(ExtensionModule): 'find_installation': self.find_installation, }) - def get_devenv(self) -> T.Optional[EnvironmentVariables]: - pythonpath = set() - for python in self.installations.values(): - version = python.info['version'] - if mesonlib.version_compare(version, '>=3.0'): - pythonpath |= python.devenv_pythonpath - if pythonpath: - env = EnvironmentVariables() - env.prepend('PYTHONPATH', list(pythonpath)) - return env - return None - # https://www.python.org/dev/peps/pep-0397/ @staticmethod def _get_win_pythonpath(name_or_path: str) -> T.Optional[str]: diff --git a/test cases/unit/91 devenv/meson.build b/test cases/unit/91 devenv/meson.build index f5c24d8..3b0bb6a 100644 --- a/test cases/unit/91 devenv/meson.build +++ b/test cases/unit/91 devenv/meson.build @@ -1,8 +1,4 @@ -project('devenv', 'c', - # Because Windows Python ships only with optimized libs, - # we must build this project the same way. - default_options : ['buildtype=release'], -) +project('devenv', 'c') meson.add_devenv('TEST_A=1') foo_dep = dependency('foo', fallback: 'sub') @@ -19,7 +15,3 @@ meson.add_devenv(env) # This exe links on a library built in another directory. On Windows this means # PATH must contain builddir/subprojects/sub to be able to run it. executable('app', 'main.c', dependencies: foo_dep, install: true) - -py = import('python').find_installation() -py.install_sources('src/mymod/mod.py', subdir: 'mymod') -subdir('src/mymod2') diff --git a/test cases/unit/91 devenv/src/mymod/mod.py b/test cases/unit/91 devenv/src/mymod/mod.py deleted file mode 100644 index 75d6edb..0000000 --- a/test cases/unit/91 devenv/src/mymod/mod.py +++ /dev/null @@ -1 +0,0 @@ -hello = 'world' diff --git a/test cases/unit/91 devenv/src/mymod2/meson.build b/test cases/unit/91 devenv/src/mymod2/meson.build deleted file mode 100644 index 95883fd..0000000 --- a/test cases/unit/91 devenv/src/mymod2/meson.build +++ /dev/null @@ -1,5 +0,0 @@ -py.extension_module('mod2', 'mod2.c', - dependencies: py.dependency(), - subdir: 'mymod2', - install: true -) diff --git a/test cases/unit/91 devenv/src/mymod2/mod2.c b/test cases/unit/91 devenv/src/mymod2/mod2.c deleted file mode 100644 index fe8323e..0000000 --- a/test cases/unit/91 devenv/src/mymod2/mod2.c +++ /dev/null @@ -1,14 +0,0 @@ -#include <Python.h> -#include <string.h> - -static PyObject *hello(PyObject *self, PyObject *args) { - return PyLong_FromLong(42); -} - -static PyMethodDef methods[] = {{"hello", hello, METH_NOARGS, "Hello World"}, - {NULL, NULL, 0, NULL}}; - -static struct PyModuleDef mod = {PyModuleDef_HEAD_INIT, "test", NULL, -1, - methods}; - -PyMODINIT_FUNC PyInit_mod2(void) { return PyModule_Create(&mod); } diff --git a/test cases/unit/91 devenv/test-devenv.py b/test cases/unit/91 devenv/test-devenv.py index 8273805..75497ff 100755 --- a/test cases/unit/91 devenv/test-devenv.py +++ b/test cases/unit/91 devenv/test-devenv.py @@ -1,15 +1,8 @@ #! /usr/bin/python import os -from pathlib import Path assert os.environ['MESON_DEVENV'] == '1' assert os.environ['MESON_PROJECT_NAME'] == 'devenv' assert os.environ['TEST_A'] == '1' assert os.environ['TEST_B'] == '0+1+2+3+4' - -from mymod.mod import hello -assert hello == 'world' - -from mymod2.mod2 import hello -assert hello() == 42 |