Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ENH: provide a convenience function to replace npy_load_module #20467

Merged
merged 1 commit into from Nov 26, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 3 additions & 1 deletion numpy/compat/py3k.py
Expand Up @@ -111,7 +111,9 @@ def __exit__(self, *excinfo):

def npy_load_module(name, fn, info=None):
"""
Load a module.
Load a module. Uses ``load_module`` which will be deprecated in python
3.12. An alternative that uses ``exec_module`` is in
numpy.distutils.misc_util.exec_mod_from_location
.. versionadded:: 1.11.2
Expand Down
4 changes: 2 additions & 2 deletions numpy/distutils/ccompiler_opt.py
Expand Up @@ -645,9 +645,9 @@ def dist_log(*args, stderr=False):
@staticmethod
def dist_load_module(name, path):
"""Load a module from file, required by the abstract class '_Cache'."""
from numpy.compat import npy_load_module
from .misc_util import exec_mod_from_location
try:
return npy_load_module(name, path)
return exec_mod_from_location(name, path)
except Exception as e:
_Distutils.dist_log(e, stderr=True)
return None
Expand Down
37 changes: 29 additions & 8 deletions numpy/distutils/misc_util.py
Expand Up @@ -30,8 +30,6 @@ def clean_up_temporary_directory():

atexit.register(clean_up_temporary_directory)

from numpy.compat import npy_load_module

__all__ = ['Configuration', 'get_numpy_include_dirs', 'default_config_dict',
'dict_append', 'appendpath', 'generate_config_py',
'get_cmd', 'allpath', 'get_mathlibs',
Expand All @@ -43,7 +41,8 @@ def clean_up_temporary_directory():
'dot_join', 'get_frame', 'minrelpath', 'njoin',
'is_sequence', 'is_string', 'as_list', 'gpaths', 'get_language',
'quote_args', 'get_build_architecture', 'get_info', 'get_pkg_info',
'get_num_build_jobs']
'get_num_build_jobs', 'sanitize_cxx_flags',
'exec_mod_from_location']

class InstallableLib:
"""
Expand Down Expand Up @@ -905,9 +904,8 @@ def _get_configuration_from_setup_py(self, setup_py,
try:
setup_name = os.path.splitext(os.path.basename(setup_py))[0]
n = dot_join(self.name, subpackage_name, setup_name)
setup_module = npy_load_module('_'.join(n.split('.')),
setup_py,
('.py', 'U', 1))
setup_module = exec_mod_from_location(
'_'.join(n.split('.')), setup_py)
if not hasattr(setup_module, 'configuration'):
if not self.options['assume_default_configuration']:
self.warn('Assuming default configuration '\
Expand Down Expand Up @@ -1953,8 +1951,8 @@ def get_version(self, version_file=None, version_variable=None):
name = os.path.splitext(os.path.basename(fn))[0]
n = dot_join(self.name, name)
try:
version_module = npy_load_module('_'.join(n.split('.')),
fn, info)
version_module = exec_mod_from_location(
'_'.join(n.split('.')), fn)
except ImportError as e:
self.warn(str(e))
version_module = None
Expand Down Expand Up @@ -2415,3 +2413,26 @@ def get_build_architecture():
# systems, so delay the import to here.
from distutils.msvccompiler import get_build_architecture
return get_build_architecture()


_cxx_ignore_flags = {'-Werror=implicit-function-declaration', '-std=c99'}


def sanitize_cxx_flags(cxxflags):
'''
Some flags are valid for C but not C++. Prune them.
'''
return [flag for flag in cxxflags if flag not in _cxx_ignore_flags]


def exec_mod_from_location(modname, modfile):
'''
Use importlib machinery to import a module `modname` from the file
`modfile`. Depending on the `spec.loader`, the module may not be
registered in sys.modules.
'''
spec = importlib.util.spec_from_file_location(modname, modfile)
foo = importlib.util.module_from_spec(spec)
spec.loader.exec_module(foo)
return foo

8 changes: 4 additions & 4 deletions numpy/random/tests/test_extending.py
Expand Up @@ -5,6 +5,7 @@
import sys
import warnings
import numpy as np
from numpy.distutils.misc_util import exec_mod_from_location

try:
import cffi
Expand Down Expand Up @@ -75,10 +76,9 @@ def test_cython(tmp_path):
assert so1 is not None
assert so2 is not None
# import the so's without adding the directory to sys.path
from importlib.machinery import ExtensionFileLoader
extending = ExtensionFileLoader('extending', so1).load_module()
extending_distributions = ExtensionFileLoader('extending_distributions', so2).load_module()

exec_mod_from_location('extending', so1)
extending_distributions = exec_mod_from_location(
'extending_distributions', so2)
# actually test the cython c-extension
from numpy.random import PCG64
values = extending_distributions.uniforms_ex(PCG64(0), 10, 'd')
Expand Down
4 changes: 2 additions & 2 deletions numpy/testing/_private/utils.py
Expand Up @@ -1228,13 +1228,13 @@ def rundocs(filename=None, raise_on_error=True):

>>> np.lib.test(doctests=True) # doctest: +SKIP
"""
from numpy.compat import npy_load_module
from numpy.distutils.misc_util import exec_mod_from_location
import doctest
if filename is None:
f = sys._getframe(1)
filename = f.f_globals['__file__']
name = os.path.splitext(os.path.basename(filename))[0]
m = npy_load_module(name, filename)
m = exec_mod_from_location(name, filename)

tests = doctest.DocTestFinder().find(m)
runner = doctest.DocTestRunner(verbose=False)
Expand Down