this repo has no description
at trunk 144 lines 4.8 kB view raw
1#!/usr/bin/env python3 2# Copyright (c) Facebook, Inc. and its affiliates. (http://www.facebook.com) 3import _imp 4import distutils.sysconfig 5import importlib.machinery 6import os 7import tempfile 8import unittest 9from distutils.core import setup 10from distutils.dist import Distribution 11from distutils.extension import Extension 12 13 14class DistutilsModuleTest(unittest.TestCase): 15 def test_sysconfig_get_python_inc_returns_string(self): 16 python_inc = distutils.sysconfig.get_python_inc() 17 self.assertTrue(os.path.isdir(python_inc)) 18 self.assertTrue(os.path.isfile(os.path.join(python_inc, "Python.h"))) 19 20 def test_sysconfig_get_python_lib_returns_string(self): 21 python_lib = distutils.sysconfig.get_python_lib() 22 self.assertIn("site-packages", python_lib) 23 24 def test_build_ext_with_c_file_creates_library(self): 25 with tempfile.TemporaryDirectory() as dir_path: 26 source_dir = f"{dir_path}/src" 27 build_dir = f"{dir_path}/build" 28 os.makedirs(source_dir) 29 os.makedirs(build_dir) 30 file_path = f"{source_dir}/foo.c" 31 with open(file_path, "w") as fp: 32 fp.write( 33 """\ 34#include "Python.h" 35PyObject *func(PyObject *a0, PyObject *a1) { 36 (void)a0; 37 (void)a1; 38 return PyUnicode_FromString("and now for something completely different"); 39} 40static PyMethodDef methods[] = { 41 {"announce", func, METH_NOARGS, "bar docu"}, 42 {NULL, NULL}, 43}; 44static PyModuleDef def = { 45 PyModuleDef_HEAD_INIT, 46 "foo", 47 NULL, 48 0, 49 methods, 50}; 51PyMODINIT_FUNC PyInit_foo(void) { 52 return PyModule_Create(&def); 53} 54""" 55 ) 56 self.assertEqual(len(os.listdir(source_dir)), 1) 57 58 # Setup compilation settings 59 ext = Extension(name="foo", sources=[file_path]) 60 self.assertIsInstance(ext, Extension) 61 62 # Compile C File 63 dist = setup( 64 name="test_so_compilation", 65 ext_modules=[ext], 66 script_args=["--quiet", "build_ext", "--build-temp", build_dir], 67 options={"build_ext": {"build_lib": source_dir}}, 68 ) 69 self.assertIsInstance(dist, Distribution) 70 71 # Check directory contents 72 dir_contents = sorted(os.listdir(source_dir)) 73 self.assertEqual(len(dir_contents), 2) 74 self.assertTrue(dir_contents[0].endswith(".c")) 75 self.assertTrue(dir_contents[1].endswith(".so")) 76 77 lib_file = f"{source_dir}/{dir_contents[1]}" 78 spec = importlib.machinery.ModuleSpec("foo", None, origin=lib_file) 79 module = _imp.create_dynamic(spec) 80 self.assertEqual( 81 module.announce(), "and now for something completely different" 82 ) 83 84 def test_build_ext_with_cpp_file_creates_library(self): 85 with tempfile.TemporaryDirectory() as dir_path: 86 source_dir = f"{dir_path}/src" 87 build_dir = f"{dir_path}/build" 88 os.makedirs(source_dir) 89 os.makedirs(build_dir) 90 file_path = f"{source_dir}/foo.cpp" 91 with open(file_path, "w") as fp: 92 fp.write( 93 """\ 94#include <sstream> 95#include "Python.h" 96PyObject* func(PyObject*, PyObject*) { 97 std::stringstream ss; 98 ss << "Hello" << ' ' << "world"; 99 return PyUnicode_FromString(ss.str().c_str()); 100} 101static PyMethodDef methods[] = { 102 {"greet", func, METH_NOARGS, "bar docu"}, 103 {nullptr, nullptr}, 104}; 105static PyModuleDef def = { 106 PyModuleDef_HEAD_INIT, 107 "foo", 108 nullptr, 109 0, 110 methods, 111}; 112PyMODINIT_FUNC PyInit_foo() { 113 return PyModule_Create(&def); 114} 115""" 116 ) 117 self.assertEqual(len(os.listdir(source_dir)), 1) 118 119 # Setup compilation settings 120 ext = Extension(name="foo", sources=[file_path]) 121 self.assertIsInstance(ext, Extension) 122 123 dist = setup( 124 name="test_so_compilation", 125 ext_modules=[ext], 126 script_args=["--quiet", "build_ext", "--build-temp", build_dir], 127 options={"build_ext": {"build_lib": source_dir}}, 128 ) 129 self.assertIsInstance(dist, Distribution) 130 131 # Check directory contents 132 dir_contents = sorted(os.listdir(source_dir)) 133 self.assertEqual(len(dir_contents), 2) 134 self.assertTrue(dir_contents[0].endswith(".cpp")) 135 self.assertTrue(dir_contents[1].endswith(".so")) 136 137 lib_file = f"{source_dir}/{dir_contents[1]}" 138 spec = importlib.machinery.ModuleSpec("foo", None, origin=lib_file) 139 module = _imp.create_dynamic(spec) 140 self.assertEqual(module.greet(), "Hello world") 141 142 143if __name__ == "__main__": 144 unittest.main()