aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDylan Baker <dylan@pnwbakers.com>2019-06-11 10:25:36 -0700
committerJussi Pakkanen <jpakkane@gmail.com>2019-06-12 14:13:20 +0300
commit15ab1f64f964ce5d3ab254b5698f7325754cc2b7 (patch)
tree682332298358e35cc40e42819c0e5f7fe1c958de
parent3c461bcf4fe561dd77ba80420c78936b92f07c1b (diff)
downloadmeson-15ab1f64f964ce5d3ab254b5698f7325754cc2b7.zip
meson-15ab1f64f964ce5d3ab254b5698f7325754cc2b7.tar.gz
meson-15ab1f64f964ce5d3ab254b5698f7325754cc2b7.tar.bz2
modules/python: add a modules keyword argument
This mirrors the modules keyword argument that some dependencies (such as qt and llvm) take. This allows an easier method to determine if modules are installed.
-rw-r--r--docs/markdown/Python-module.md2
-rw-r--r--docs/markdown/snippets/python_find_installation_modules.md9
-rw-r--r--mesonbuild/modules/python.py38
-rw-r--r--test cases/python/5 modules kwarg/meson.build7
4 files changed, 52 insertions, 4 deletions
diff --git a/docs/markdown/Python-module.md b/docs/markdown/Python-module.md
index edd10ba..6f9a764 100644
--- a/docs/markdown/Python-module.md
+++ b/docs/markdown/Python-module.md
@@ -51,6 +51,8 @@ Keyword arguments are the following:
- `disabler`: if `true` and no python installation can be found, return a
[disabler object](Reference-manual.md#disabler-object) instead of a not-found object.
*Since 0.49.0*
+- `modules`: a list of module names that this python installation must have.
+ *Since 0.51.0*
**Returns**: a [python installation][`python_installation` object]
diff --git a/docs/markdown/snippets/python_find_installation_modules.md b/docs/markdown/snippets/python_find_installation_modules.md
new file mode 100644
index 0000000..a3719f2
--- /dev/null
+++ b/docs/markdown/snippets/python_find_installation_modules.md
@@ -0,0 +1,9 @@
+## New modules kwarg for python.find_installation
+
+This mirrors the modules argument that some kinds of dependencies (such as
+qt, llvm, and cmake based dependencies) take, allowing you to check that a
+particular module is available when getting a python version.
+
+```meson
+py = import('python').find_installation('python3', modules : ['numpy'])
+``` \ No newline at end of file
diff --git a/mesonbuild/modules/python.py b/mesonbuild/modules/python.py
index 2f4e5d6..9b8f3a3 100644
--- a/mesonbuild/modules/python.py
+++ b/mesonbuild/modules/python.py
@@ -15,6 +15,7 @@
import os
import json
import shutil
+import typing
from pathlib import Path
from .. import mesonlib
@@ -491,11 +492,15 @@ class PythonModule(ExtensionModule):
return True
@FeatureNewKwargs('python.find_installation', '0.49.0', ['disabler'])
+ @FeatureNewKwargs('python.find_installation', '0.51.0', ['modules'])
@disablerIfNotFound
- @permittedKwargs(['required'])
+ @permittedKwargs({'required', 'modules'})
def find_installation(self, interpreter, state, args, kwargs):
feature_check = FeatureNew('Passing "feature" option to find_installation', '0.48.0')
disabled, required, feature = extract_required_kwarg(kwargs, state.subproject, feature_check)
+ want_modules = mesonlib.extract_as_list(kwargs, 'modules') # type: typing.List[str]
+ found_modules = [] # type: typing.List[str]
+ missing_modules = [] # type: typing.List[str]
if len(args) > 1:
raise InvalidArguments('find_installation takes zero or one positional argument.')
@@ -511,7 +516,7 @@ class PythonModule(ExtensionModule):
return ExternalProgramHolder(NonExistingExternalProgram())
if not name_or_path:
- python = ExternalProgram('python3', mesonlib.python_command)
+ python = ExternalProgram('python3', mesonlib.python_command, silent=True)
else:
python = ExternalProgram.from_entry('python3', name_or_path)
@@ -528,13 +533,38 @@ class PythonModule(ExtensionModule):
if not python.found() and name_or_path in ['python2', 'python3']:
python = ExternalProgram('python', silent=True)
- mlog.log('Program', python.name, 'found:',
- *[mlog.green('YES'), '({})'.format(' '.join(python.command))] if python.found() else [mlog.red('NO')])
+ if python.found() and want_modules:
+ for mod in want_modules:
+ p, out, err = mesonlib.Popen_safe(
+ python.command +
+ ['-c', 'import {0}'.format(mod)])
+ if p.returncode != 0:
+ missing_modules.append(mod)
+ else:
+ found_modules.append(mod)
+
+ msg = ['Program', python.name]
+ if want_modules:
+ msg.append('({})'.format(', '.join(want_modules)))
+ msg.append('found:')
+ if python.found() and not missing_modules:
+ msg.extend([mlog.green('YES'), '({})'.format(' '.join(python.command))])
+ else:
+ msg.append(mlog.red('NO'))
+ if found_modules:
+ msg.append('modules:')
+ msg.append(', '.join(found_modules))
+
+ mlog.log(*msg)
if not python.found():
if required:
raise mesonlib.MesonException('{} not found'.format(name_or_path or 'python'))
res = ExternalProgramHolder(NonExistingExternalProgram())
+ elif missing_modules:
+ if required:
+ raise mesonlib.MesonException('{} is missing modules: {}'.format(name_or_path or 'python', ', '.join(missing_modules)))
+ res = ExternalProgramHolder(NonExistingExternalProgram())
else:
# Sanity check, we expect to have something that at least quacks in tune
try:
diff --git a/test cases/python/5 modules kwarg/meson.build b/test cases/python/5 modules kwarg/meson.build
new file mode 100644
index 0000000..3c9d54f
--- /dev/null
+++ b/test cases/python/5 modules kwarg/meson.build
@@ -0,0 +1,7 @@
+project('python kwarg')
+
+py = import('python')
+prog_python = py.find_installation('python3', modules : ['setuptools'])
+assert(prog_python.found() == true, 'python not found when should be')
+prog_python = py.find_installation('python3', modules : ['thisbetternotexistmod'], required : false)
+assert(prog_python.found() == false, 'python not found but reported as found')