this repo has no description
at trunk 292 lines 9.6 kB view raw
1// Copyright (c) Facebook, Inc. and its affiliates. (http://www.facebook.com) 2#include "Python.h" 3#include "gtest/gtest.h" 4 5#include "capi-fixture.h" 6#include "capi-testing.h" 7 8namespace py { 9namespace testing { 10 11using ImportExtensionApiTest = ExtensionApi; 12 13TEST_F(ImportExtensionApiTest, AddNonExistingModuleReturnsNewModule) { 14 const char* c_name = "foo"; 15 PyObject* pyname = PyUnicode_FromString(c_name); 16 PyObject* new_module = PyImport_AddModuleObject(pyname); 17 ASSERT_TRUE(PyModule_CheckExact(new_module)); 18 19 PyObject* module_name = PyModule_GetNameObject(new_module); 20 EXPECT_TRUE(isUnicodeEqualsCStr(module_name, c_name)); 21 Py_DECREF(module_name); 22 23 PyObject* module = testing::importGetModule(pyname); 24 EXPECT_EQ(new_module, module); 25 Py_DECREF(pyname); 26 Py_DECREF(module); 27} 28 29TEST_F(ImportExtensionApiTest, AddExistingModuleReturnsModule) { 30 PyObject* pyname = PyUnicode_FromString("sys"); 31 PyObject* module = PyImport_AddModuleObject(pyname); 32 ASSERT_TRUE(PyModule_CheckExact(module)); 33 34 Py_ssize_t refcnt = Py_REFCNT(module); 35 PyObject* module2 = PyImport_AddModuleObject(pyname); 36 EXPECT_EQ(refcnt, Py_REFCNT(module2)); 37 EXPECT_EQ(module, module2); 38 Py_DECREF(pyname); 39} 40 41TEST_F(ImportExtensionApiTest, ExecCodeModulePopulatesModuleFromCAPI) { 42 PyObjectPtr code_object( 43 Py_CompileString("a = 21 + 21", "test_module.py", Py_file_input)); 44 ASSERT_NE(code_object, nullptr); 45 46 PyObjectPtr module(PyImport_ExecCodeModule("test_module", code_object)); 47 ASSERT_NE(module, nullptr); 48 49 PyObjectPtr a(PyObject_GetAttrString(module, "a")); 50 EXPECT_EQ(PyErr_Occurred(), nullptr); 51 EXPECT_TRUE(isLongEqualsLong(a, 42)); 52} 53 54TEST_F(ImportExtensionApiTest, ExecCodeModuleAddsModuleToModules) { 55 PyObjectPtr code( 56 Py_CompileString("a = 21 + 21", "test_module.py", Py_file_input)); 57 ASSERT_NE(code, nullptr); 58 59 PyObjectPtr module(PyImport_ExecCodeModule("test_module", code)); 60 ASSERT_NE(module, nullptr); 61 62 PyImport_ImportModule("test_module"); 63 ASSERT_EQ(PyErr_Occurred(), nullptr); 64 PyObjectPtr a(moduleGet("test_module", "a")); 65 EXPECT_EQ(PyErr_Occurred(), nullptr); 66 EXPECT_TRUE(isLongEqualsLong(a, 42)); 67} 68 69TEST_F(ImportExtensionApiTest, ExecCodeModuleWithInvalidCodeDoesNotAddModule) { 70 PyObjectPtr code( 71 Py_CompileString("b = nonexistent.foo", "test_module.py", Py_file_input)); 72 ASSERT_NE(code, nullptr); 73 74 PyObjectPtr module(PyImport_ExecCodeModule("test_module", code)); 75 ASSERT_EQ(module, nullptr); 76 PyErr_Clear(); 77 78 PyImport_ImportModule("test_module"); 79 ASSERT_NE(PyErr_Occurred(), nullptr); 80 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_ModuleNotFoundError)); 81} 82 83TEST_F(ImportExtensionApiTest, 84 GetMagicNumberWithNonIntMagicNumberRaisesTypeError) { 85 PyObjectPtr importlib(PyImport_ImportModule("_frozen_importlib_external")); 86 ASSERT_EQ(PyObject_SetAttrString(importlib, "_RAW_MAGIC_NUMBER", Py_None), 0); 87 EXPECT_EQ(PyImport_GetMagicNumber(), -1); 88 ASSERT_NE(PyErr_Occurred(), nullptr); 89 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_TypeError)); 90} 91 92TEST_F(ImportExtensionApiTest, 93 GetMagicNumberReturnsMagicNumberFromImportlibExternal) { 94 EXPECT_NE(PyImport_GetMagicNumber(), -1); 95 EXPECT_EQ(PyErr_Occurred(), nullptr); 96} 97 98TEST_F(ImportExtensionApiTest, GetModuleWithNotExistingModuleNameReturnsNull) { 99 PyObjectPtr name(PyUnicode_FromString("not_existing")); 100 EXPECT_EQ(PyImport_GetModule(name), nullptr); 101 EXPECT_EQ(PyErr_Occurred(), nullptr); 102} 103 104TEST_F(ImportExtensionApiTest, 105 GetModuleWithNotNotYetLoadedModuleNameReturnsNull) { 106 PyObjectPtr name(PyUnicode_FromString("test")); 107 EXPECT_EQ(PyImport_GetModule(name), nullptr); 108 EXPECT_EQ(PyErr_Occurred(), nullptr); 109} 110 111TEST_F(ImportExtensionApiTest, 112 GetModuleWithObjectRaisingNonKeyErrorPropagatesIt) { 113 PyRun_SimpleString(R"( 114class C: 115 def __hash__(self): 116 raise UserWarning("do not call me") 117 118c = C() 119 )"); 120 PyObjectPtr c(mainModuleGet("c")); 121 EXPECT_EQ(PyImport_GetModule(c), nullptr); 122 ASSERT_NE(PyErr_Occurred(), nullptr); 123 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_UserWarning)); 124} 125 126// TODO(T67033642): Add a test verifying that a non-dict modules supresses 127// KeyError. 128TEST_F(ImportExtensionApiTest, GetModuleWithObjectRaisingKeyErrorPropagatesIt) { 129 PyRun_SimpleString(R"( 130class C: 131 def __hash__(self): 132 raise KeyError("key_error") 133 134c = C() 135 )"); 136 PyObjectPtr c(mainModuleGet("c")); 137 EXPECT_EQ(PyImport_GetModule(c), nullptr); 138 ASSERT_NE(PyErr_Occurred(), nullptr); 139 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_KeyError)); 140} 141 142TEST_F(ImportExtensionApiTest, GetModuleWithExistingModuleNameReturnsModule) { 143 PyObjectPtr imported_module(PyImport_ImportModule("test")); 144 ASSERT_TRUE(PyModule_Check(imported_module)); 145 ASSERT_EQ(PyErr_Occurred(), nullptr); 146 147 PyObjectPtr name(PyUnicode_FromString("test")); 148 PyObjectPtr found_module(PyImport_GetModule(name)); 149 EXPECT_EQ(PyErr_Occurred(), nullptr); 150 ASSERT_TRUE(PyModule_Check(found_module)); 151 EXPECT_EQ(imported_module, found_module); 152} 153 154TEST_F(ImportExtensionApiTest, PyImportAcquireLockAndReleaseLockDoesNothing) { 155 _PyImport_AcquireLock(); 156 EXPECT_EQ(_PyImport_ReleaseLock(), 1); 157} 158 159TEST_F(ImportExtensionApiTest, 160 PyImportReleaseLockWithoutAcquireLockReturnsMinusOne) { 161 EXPECT_EQ(_PyImport_ReleaseLock(), -1); 162} 163 164TEST_F(ImportExtensionApiTest, ImportInvalidModuleReturnsNull) { 165 PyObject* module = PyImport_ImportModule("this_file_should_not_exist"); 166 ASSERT_EQ(module, nullptr); 167 EXPECT_NE(PyErr_Occurred(), nullptr); 168 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_ModuleNotFoundError)); 169} 170 171TEST_F(ImportExtensionApiTest, ImportModuleReturnsModule) { 172 PyObject* module = PyImport_ImportModule("operator"); 173 ASSERT_NE(module, nullptr); 174 EXPECT_EQ(PyErr_Occurred(), nullptr); 175 EXPECT_TRUE(PyModule_Check(module)); 176 Py_DECREF(module); 177} 178 179TEST_F(ImportExtensionApiTest, 180 ImportModuleWithSubmoduleReturnsLowestLevelModule) { 181 PyObjectPtr module(PyImport_ImportModule("collections.abc")); 182 ASSERT_NE(module, nullptr); 183 EXPECT_EQ(PyErr_Occurred(), nullptr); 184 EXPECT_TRUE(PyModule_Check(module)); 185 PyObjectPtr name(PyModule_GetNameObject(module)); 186 ASSERT_NE(name, nullptr); 187 EXPECT_TRUE(isUnicodeEqualsCStr(name, "collections.abc")); 188} 189 190TEST_F(ImportExtensionApiTest, ImportModuleNoBlockReturnsModule) { 191 PyObject* module = PyImport_ImportModuleNoBlock("operator"); 192 ASSERT_NE(module, nullptr); 193 EXPECT_EQ(PyErr_Occurred(), nullptr); 194 EXPECT_TRUE(PyModule_Check(module)); 195 Py_DECREF(module); 196} 197 198TEST_F(ImportExtensionApiTest, ImportFrozenModuleReturnsZeroPyro) { 199 int result = PyImport_ImportFrozenModule("operator"); 200 EXPECT_EQ(PyErr_Occurred(), nullptr); 201 EXPECT_EQ(result, 0); 202} 203 204TEST_F(ImportExtensionApiTest, ImportReturnsModule) { 205 PyObject* name = PyUnicode_FromString("operator"); 206 PyObject* module = PyImport_Import(name); 207 ASSERT_NE(module, nullptr); 208 EXPECT_EQ(PyErr_Occurred(), nullptr); 209 EXPECT_TRUE(PyModule_Check(module)); 210 Py_DECREF(name); 211 Py_DECREF(module); 212} 213 214TEST_F(ImportExtensionApiTest, ImportFrozenModuleObjectReturnsZeroPyro) { 215 PyObject* name = PyUnicode_FromString("operator"); 216 int result = PyImport_ImportFrozenModuleObject(name); 217 EXPECT_EQ(PyErr_Occurred(), nullptr); 218 EXPECT_EQ(result, 0); 219 Py_DECREF(name); 220} 221 222TEST_F(ImportExtensionApiTest, ImportModuleLevelReturnsModule) { 223 PyObject* globals = PyDict_New(); 224 PyObject* fromlist = PyList_New(0); 225 PyObject* module = 226 PyImport_ImportModuleLevel("operator", globals, nullptr, fromlist, 0); 227 ASSERT_NE(module, nullptr); 228 EXPECT_EQ(PyErr_Occurred(), nullptr); 229 EXPECT_TRUE(PyModule_Check(module)); 230 Py_DECREF(globals); 231 Py_DECREF(fromlist); 232 Py_DECREF(module); 233} 234 235TEST_F(ImportExtensionApiTest, ImportModuleLevelObjectReturnsModule) { 236 PyObject* name = PyUnicode_FromString("operator"); 237 PyObject* globals = PyDict_New(); 238 PyObject* fromlist = PyList_New(0); 239 PyObject* module = 240 PyImport_ImportModuleLevelObject(name, globals, nullptr, fromlist, 0); 241 ASSERT_NE(module, nullptr); 242 EXPECT_EQ(PyErr_Occurred(), nullptr); 243 EXPECT_TRUE(PyModule_Check(module)); 244 Py_DECREF(globals); 245 Py_DECREF(fromlist); 246 Py_DECREF(name); 247 Py_DECREF(module); 248} 249 250TEST_F(ImportExtensionApiTest, 251 ImportModuleLevelObjectWithNullNameRaisesValueError) { 252 PyObject* globals = PyDict_New(); 253 PyObject* fromlist = PyList_New(0); 254 PyObject* module = 255 PyImport_ImportModuleLevelObject(nullptr, globals, nullptr, fromlist, 0); 256 EXPECT_EQ(module, nullptr); 257 EXPECT_NE(PyErr_Occurred(), nullptr); 258 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_ValueError)); 259 Py_DECREF(globals); 260 Py_DECREF(fromlist); 261} 262 263TEST_F(ImportExtensionApiTest, 264 ImportModuleLevelObjectWithNegativeLevelRaisesValueError) { 265 PyObject* name = PyUnicode_FromString("operator"); 266 PyObject* globals = PyDict_New(); 267 PyObject* fromlist = PyList_New(0); 268 PyObject* module = 269 PyImport_ImportModuleLevelObject(name, globals, nullptr, fromlist, -1); 270 EXPECT_EQ(module, nullptr); 271 EXPECT_NE(PyErr_Occurred(), nullptr); 272 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_ValueError)); 273 Py_DECREF(globals); 274 Py_DECREF(fromlist); 275 Py_DECREF(name); 276} 277 278TEST_F(ImportExtensionApiTest, 279 ImportModuleLevelObjectWithNullGlobalsRaisesKeyError) { 280 PyObject* name = PyUnicode_FromString("operator"); 281 PyObject* fromlist = PyList_New(0); 282 PyObject* module = 283 PyImport_ImportModuleLevelObject(name, nullptr, nullptr, fromlist, 1); 284 EXPECT_EQ(module, nullptr); 285 EXPECT_NE(PyErr_Occurred(), nullptr); 286 EXPECT_TRUE(PyErr_ExceptionMatches(PyExc_KeyError)); 287 Py_DECREF(fromlist); 288 Py_DECREF(name); 289} 290 291} // namespace testing 292} // namespace py