Merge pull request #4616 from dcbaker/python-module-path
add path() method to python modulepull/4646/head
commit
cb45e9e836
26 changed files with 445 additions and 44 deletions
@ -0,0 +1,2 @@ |
||||
def gluoninate(): |
||||
return 42 |
@ -0,0 +1,26 @@ |
||||
project('python sample', 'c') |
||||
|
||||
py_mod = import('python') |
||||
py = py_mod.find_installation() |
||||
|
||||
py_version = py.language_version() |
||||
if py_version.version_compare('< 3.2') |
||||
error('MESON_SKIP_TEST python 3 required for tests') |
||||
endif |
||||
|
||||
py_purelib = py.get_path('purelib') |
||||
if not py_purelib.endswith('site-packages') |
||||
error('Python3 purelib path seems invalid? ' + py_purelib) |
||||
endif |
||||
|
||||
# could be 'lib64' or 'Lib' on some systems |
||||
py_platlib = py.get_path('platlib') |
||||
if not py_platlib.endswith('site-packages') |
||||
error('Python3 platlib path seems invalid? ' + py_platlib) |
||||
endif |
||||
|
||||
main = files('prog.py') |
||||
|
||||
test('toplevel', py, args : main) |
||||
|
||||
subdir('subdir') |
@ -0,0 +1,9 @@ |
||||
#!/usr/bin/env python3 |
||||
|
||||
from gluon import gluonator |
||||
import sys |
||||
|
||||
print('Running mainprog from root dir.') |
||||
|
||||
if gluonator.gluoninate() != 42: |
||||
sys.exit(1) |
@ -0,0 +1,4 @@ |
||||
test('subdir', |
||||
py, |
||||
args : files('subprog.py'), |
||||
env : 'PYTHONPATH=' + meson.source_root()) |
@ -0,0 +1,12 @@ |
||||
#!/usr/bin/env python3 |
||||
|
||||
# In order to run this program, PYTHONPATH must be set to |
||||
# point to source root. |
||||
|
||||
from gluon import gluonator |
||||
import sys |
||||
|
||||
print('Running mainprog from subdir.') |
||||
|
||||
if gluonator.gluoninate() != 42: |
||||
sys.exit(1) |
@ -0,0 +1,14 @@ |
||||
#!/usr/bin/env python3 |
||||
|
||||
import tachyon |
||||
import sys |
||||
|
||||
result = tachyon.phaserize('shoot') |
||||
|
||||
if not isinstance(result, int): |
||||
print('Returned result not an integer.') |
||||
sys.exit(1) |
||||
|
||||
if result != 1: |
||||
print('Returned result {} is not 1.'.format(result)) |
||||
sys.exit(1) |
@ -0,0 +1,6 @@ |
||||
pylib = py.extension_module('tachyon', |
||||
'tachyon_module.c', |
||||
dependencies : py_dep, |
||||
) |
||||
|
||||
pypathdir = meson.current_build_dir() |
@ -0,0 +1,49 @@ |
||||
/*
|
||||
Copyright 2016 The Meson development team |
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License"); |
||||
you may not use this file except in compliance with the License. |
||||
You may obtain a copy of the License at |
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software |
||||
distributed under the License is distributed on an "AS IS" BASIS, |
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
See the License for the specific language governing permissions and |
||||
limitations under the License. |
||||
*/ |
||||
|
||||
/* A very simple Python extension module. */ |
||||
|
||||
#include <Python.h> |
||||
#include <string.h> |
||||
|
||||
static PyObject* phaserize(PyObject *self, PyObject *args) { |
||||
const char *message; |
||||
int result; |
||||
|
||||
if(!PyArg_ParseTuple(args, "s", &message)) |
||||
return NULL; |
||||
|
||||
result = strcmp(message, "shoot") ? 0 : 1; |
||||
return PyLong_FromLong(result); |
||||
} |
||||
|
||||
static PyMethodDef TachyonMethods[] = { |
||||
{"phaserize", phaserize, METH_VARARGS, |
||||
"Shoot tachyon cannons."}, |
||||
{NULL, NULL, 0, NULL} |
||||
}; |
||||
|
||||
static struct PyModuleDef tachyonmodule = { |
||||
PyModuleDef_HEAD_INIT, |
||||
"tachyon", |
||||
NULL, |
||||
-1, |
||||
TachyonMethods |
||||
}; |
||||
|
||||
PyMODINIT_FUNC PyInit_tachyon(void) { |
||||
return PyModule_Create(&tachyonmodule); |
||||
} |
@ -0,0 +1,28 @@ |
||||
project('Python extension module', 'c', |
||||
default_options : ['buildtype=release']) |
||||
# Because Windows Python ships only with optimized libs, |
||||
# we must build this project the same way. |
||||
|
||||
py_mod = import('python') |
||||
py = py_mod.find_installation() |
||||
py_dep = py.dependency() |
||||
|
||||
if py_dep.found() |
||||
subdir('ext') |
||||
|
||||
test('extmod', |
||||
py, |
||||
args : files('blaster.py'), |
||||
env : ['PYTHONPATH=' + pypathdir]) |
||||
|
||||
# Check we can apply a version constraint |
||||
dependency('python3', version: '>=@0@'.format(py_dep.version())) |
||||
|
||||
else |
||||
error('MESON_SKIP_TEST: Python3 libraries not found, skipping test.') |
||||
endif |
||||
|
||||
py3_pkg_dep = dependency('python3', method: 'pkg-config', required : false) |
||||
if py3_pkg_dep.found() |
||||
python_lib_dir = py3_pkg_dep.get_pkgconfig_variable('libdir') |
||||
endif |
@ -0,0 +1,23 @@ |
||||
#!/usr/bin/env python3 |
||||
|
||||
from storer import Storer |
||||
import sys |
||||
|
||||
s = Storer() |
||||
|
||||
if s.get_value() != 0: |
||||
print('Initial value incorrect.') |
||||
sys.exit(1) |
||||
|
||||
s.set_value(42) |
||||
|
||||
if s.get_value() != 42: |
||||
print('Setting value failed.') |
||||
sys.exit(1) |
||||
|
||||
try: |
||||
s.set_value('not a number') |
||||
print('Using wrong argument type did not fail.') |
||||
sys.exit(1) |
||||
except TypeError: |
||||
pass |
@ -0,0 +1,9 @@ |
||||
|
||||
cdef extern from "storer.h": |
||||
ctypedef struct Storer: |
||||
pass |
||||
|
||||
Storer* storer_new(); |
||||
void storer_destroy(Storer *s); |
||||
int storer_get_value(Storer *s); |
||||
void storer_set_value(Storer *s, int v); |
@ -0,0 +1,11 @@ |
||||
pyx_c = custom_target('storer_pyx', |
||||
output : 'storer_pyx.c', |
||||
input : 'storer.pyx', |
||||
command : [cython, '@INPUT@', '-o', '@OUTPUT@'], |
||||
) |
||||
|
||||
slib = py3.extension_module('storer', |
||||
'storer.c', pyx_c, |
||||
dependencies : py3_dep) |
||||
|
||||
pydir = meson.current_build_dir() |
@ -0,0 +1,24 @@ |
||||
#include"storer.h" |
||||
#include<stdlib.h> |
||||
|
||||
struct _Storer { |
||||
int value; |
||||
}; |
||||
|
||||
Storer* storer_new() { |
||||
Storer *s = malloc(sizeof(struct _Storer)); |
||||
s->value = 0; |
||||
return s; |
||||
} |
||||
|
||||
void storer_destroy(Storer *s) { |
||||
free(s); |
||||
} |
||||
|
||||
int storer_get_value(Storer *s) { |
||||
return s->value; |
||||
} |
||||
|
||||
void storer_set_value(Storer *s, int v) { |
||||
s->value = v; |
||||
} |
@ -0,0 +1,8 @@ |
||||
#pragma once |
||||
|
||||
typedef struct _Storer Storer; |
||||
|
||||
Storer* storer_new(); |
||||
void storer_destroy(Storer *s); |
||||
int storer_get_value(Storer *s); |
||||
void storer_set_value(Storer *s, int v); |
@ -0,0 +1,16 @@ |
||||
cimport cstorer |
||||
|
||||
cdef class Storer: |
||||
cdef cstorer.Storer* _c_storer |
||||
|
||||
def __cinit__(self): |
||||
self._c_storer = cstorer.storer_new() |
||||
|
||||
def __dealloc__(self): |
||||
cstorer.storer_destroy(self._c_storer) |
||||
|
||||
cpdef int get_value(self): |
||||
return cstorer.storer_get_value(self._c_storer) |
||||
|
||||
cpdef set_value(self, int value): |
||||
cstorer.storer_set_value(self._c_storer, value) |
@ -0,0 +1,20 @@ |
||||
project('cython', 'c', |
||||
default_options : ['warning_level=3']) |
||||
|
||||
cython = find_program('cython3', required : false) |
||||
py3_dep = dependency('python3', required : false) |
||||
|
||||
if cython.found() and py3_dep.found() |
||||
py_mod = import('python') |
||||
py3 = py_mod.find_installation() |
||||
py3_dep = py3.dependency() |
||||
subdir('libdir') |
||||
|
||||
test('cython tester', |
||||
py3, |
||||
args : files('cytest.py'), |
||||
env : ['PYTHONPATH=' + pydir] |
||||
) |
||||
else |
||||
error('MESON_SKIP_TEST: Cython3 or Python3 libraries not found, skipping test.') |
||||
endif |
@ -0,0 +1,32 @@ |
||||
#!/usr/bin/env python3 |
||||
|
||||
import os |
||||
import sys |
||||
import argparse |
||||
|
||||
from pathlib import Path |
||||
|
||||
filedir = Path(os.path.dirname(__file__)).resolve() |
||||
if list(filedir.glob('ext/*tachyon*')): |
||||
sys.path.insert(0, (filedir / 'ext').as_posix()) |
||||
|
||||
import tachyon |
||||
|
||||
parser = argparse.ArgumentParser() |
||||
parser.add_argument('-o', dest='output', default=None) |
||||
|
||||
options = parser.parse_args(sys.argv[1:]) |
||||
|
||||
result = tachyon.phaserize('shoot') |
||||
|
||||
if options.output: |
||||
with open(options.output, 'w') as f: |
||||
f.write('success') |
||||
|
||||
if not isinstance(result, int): |
||||
print('Returned result not an integer.') |
||||
sys.exit(1) |
||||
|
||||
if result != 1: |
||||
print('Returned result {} is not 1.'.format(result)) |
||||
sys.exit(1) |
@ -0,0 +1,8 @@ |
||||
#ifdef _MSC_VER |
||||
__declspec(dllexport) |
||||
#endif |
||||
const char* |
||||
tachyon_phaser_command (void) |
||||
{ |
||||
return "shoot"; |
||||
} |
@ -0,0 +1,6 @@ |
||||
#pragma once |
||||
|
||||
#ifdef _MSC_VER |
||||
__declspec(dllimport) |
||||
#endif |
||||
const char* tachyon_phaser_command (void); |
@ -0,0 +1,4 @@ |
||||
libtachyon = shared_library('tachyonlib', 'meson-tachyonlib.c') |
||||
|
||||
libtachyon_dep = declare_dependency(link_with : libtachyon, |
||||
include_directories : include_directories('.')) |
@ -0,0 +1,6 @@ |
||||
subdir('lib') |
||||
|
||||
pylib = py3.extension_module('tachyon', |
||||
'tachyon_module.c', |
||||
dependencies : [libtachyon_dep, py3_dep], |
||||
) |
@ -0,0 +1,51 @@ |
||||
/*
|
||||
Copyright 2016 The Meson development team |
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License"); |
||||
you may not use this file except in compliance with the License. |
||||
You may obtain a copy of the License at |
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software |
||||
distributed under the License is distributed on an "AS IS" BASIS, |
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
See the License for the specific language governing permissions and |
||||
limitations under the License. |
||||
*/ |
||||
|
||||
/* A very simple Python extension module. */ |
||||
|
||||
#include <Python.h> |
||||
#include <string.h> |
||||
|
||||
#include "meson-tachyonlib.h" |
||||
|
||||
static PyObject* phaserize(PyObject *self, PyObject *args) { |
||||
const char *message; |
||||
int result; |
||||
|
||||
if(!PyArg_ParseTuple(args, "s", &message)) |
||||
return NULL; |
||||
|
||||
result = strcmp(message, tachyon_phaser_command()) ? 0 : 1; |
||||
return PyLong_FromLong(result); |
||||
} |
||||
|
||||
static PyMethodDef TachyonMethods[] = { |
||||
{"phaserize", phaserize, METH_VARARGS, |
||||
"Shoot tachyon cannons."}, |
||||
{NULL, NULL, 0, NULL} |
||||
}; |
||||
|
||||
static struct PyModuleDef tachyonmodule = { |
||||
PyModuleDef_HEAD_INIT, |
||||
"tachyon", |
||||
NULL, |
||||
-1, |
||||
TachyonMethods |
||||
}; |
||||
|
||||
PyMODINIT_FUNC PyInit_tachyon(void) { |
||||
return PyModule_Create(&tachyonmodule); |
||||
} |
@ -0,0 +1,35 @@ |
||||
project('Python extension module', 'c', |
||||
default_options : ['buildtype=release']) |
||||
# Because Windows Python ships only with optimized libs, |
||||
# we must build this project the same way. |
||||
|
||||
py_mod = import('python') |
||||
py3 = py_mod.find_installation() |
||||
py3_dep = py3.dependency(required : false) |
||||
|
||||
# Copy to the builddir so that blaster.py can find the built tachyon module |
||||
# FIXME: We should automatically detect this case and append the correct paths |
||||
# to PYTHONLIBDIR |
||||
blaster_py = configure_file(input : 'blaster.py', |
||||
output : 'blaster.py', |
||||
copy : true) |
||||
|
||||
check_exists = ''' |
||||
import os, sys |
||||
with open(sys.argv[1], 'rb') as f: |
||||
assert(f.read() == b'success') |
||||
''' |
||||
if py3_dep.found() |
||||
subdir('ext') |
||||
|
||||
out_txt = custom_target('tachyon flux', |
||||
input : blaster_py, |
||||
output : 'out.txt', |
||||
command : [py3, '@INPUT@', '-o', '@OUTPUT@'], |
||||
depends : pylib, |
||||
build_by_default: true) |
||||
|
||||
test('flux', py3, args : ['-c', check_exists, out_txt]) |
||||
else |
||||
error('MESON_SKIP_TEST: Python3 libraries not found, skipping test.') |
||||
endif |
Loading…
Reference in new issue