forked from Alsan/Post_finder
venv
This commit is contained in:
88
venv/lib/python3.12/site-packages/numpy/f2py/__init__.py
Normal file
88
venv/lib/python3.12/site-packages/numpy/f2py/__init__.py
Normal file
@ -0,0 +1,88 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Fortran to Python Interface Generator.
|
||||
|
||||
Copyright 1999 -- 2011 Pearu Peterson all rights reserved.
|
||||
Copyright 2011 -- present NumPy Developers.
|
||||
Permission to use, modify, and distribute this software is given under the terms
|
||||
of the NumPy License.
|
||||
|
||||
NO WARRANTY IS EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
|
||||
"""
|
||||
__all__ = ['run_main', 'get_include']
|
||||
|
||||
import sys
|
||||
import subprocess
|
||||
import os
|
||||
import warnings
|
||||
|
||||
from numpy.exceptions import VisibleDeprecationWarning
|
||||
from . import f2py2e
|
||||
from . import diagnose
|
||||
|
||||
run_main = f2py2e.run_main
|
||||
main = f2py2e.main
|
||||
|
||||
|
||||
def get_include():
|
||||
"""
|
||||
Return the directory that contains the ``fortranobject.c`` and ``.h`` files.
|
||||
|
||||
.. note::
|
||||
|
||||
This function is not needed when building an extension with
|
||||
`numpy.distutils` directly from ``.f`` and/or ``.pyf`` files
|
||||
in one go.
|
||||
|
||||
Python extension modules built with f2py-generated code need to use
|
||||
``fortranobject.c`` as a source file, and include the ``fortranobject.h``
|
||||
header. This function can be used to obtain the directory containing
|
||||
both of these files.
|
||||
|
||||
Returns
|
||||
-------
|
||||
include_path : str
|
||||
Absolute path to the directory containing ``fortranobject.c`` and
|
||||
``fortranobject.h``.
|
||||
|
||||
Notes
|
||||
-----
|
||||
.. versionadded:: 1.21.1
|
||||
|
||||
Unless the build system you are using has specific support for f2py,
|
||||
building a Python extension using a ``.pyf`` signature file is a two-step
|
||||
process. For a module ``mymod``:
|
||||
|
||||
* Step 1: run ``python -m numpy.f2py mymod.pyf --quiet``. This
|
||||
generates ``mymodmodule.c`` and (if needed)
|
||||
``mymod-f2pywrappers.f`` files next to ``mymod.pyf``.
|
||||
* Step 2: build your Python extension module. This requires the
|
||||
following source files:
|
||||
|
||||
* ``mymodmodule.c``
|
||||
* ``mymod-f2pywrappers.f`` (if it was generated in Step 1)
|
||||
* ``fortranobject.c``
|
||||
|
||||
See Also
|
||||
--------
|
||||
numpy.get_include : function that returns the numpy include directory
|
||||
|
||||
"""
|
||||
return os.path.join(os.path.dirname(__file__), 'src')
|
||||
|
||||
|
||||
def __getattr__(attr):
|
||||
|
||||
# Avoid importing things that aren't needed for building
|
||||
# which might import the main numpy module
|
||||
if attr == "test":
|
||||
from numpy._pytesttester import PytestTester
|
||||
test = PytestTester(__name__)
|
||||
return test
|
||||
|
||||
else:
|
||||
raise AttributeError("module {!r} has no attribute "
|
||||
"{!r}".format(__name__, attr))
|
||||
|
||||
|
||||
def __dir__():
|
||||
return list(globals().keys() | {"test"})
|
42
venv/lib/python3.12/site-packages/numpy/f2py/__init__.pyi
Normal file
42
venv/lib/python3.12/site-packages/numpy/f2py/__init__.pyi
Normal file
@ -0,0 +1,42 @@
|
||||
import os
|
||||
import subprocess
|
||||
from collections.abc import Iterable
|
||||
from typing import Literal as L, Any, overload, TypedDict
|
||||
|
||||
from numpy._pytesttester import PytestTester
|
||||
|
||||
class _F2PyDictBase(TypedDict):
|
||||
csrc: list[str]
|
||||
h: list[str]
|
||||
|
||||
class _F2PyDict(_F2PyDictBase, total=False):
|
||||
fsrc: list[str]
|
||||
ltx: list[str]
|
||||
|
||||
__all__: list[str]
|
||||
test: PytestTester
|
||||
|
||||
def run_main(comline_list: Iterable[str]) -> dict[str, _F2PyDict]: ...
|
||||
|
||||
@overload
|
||||
def compile( # type: ignore[misc]
|
||||
source: str | bytes,
|
||||
modulename: str = ...,
|
||||
extra_args: str | list[str] = ...,
|
||||
verbose: bool = ...,
|
||||
source_fn: None | str | bytes | os.PathLike[Any] = ...,
|
||||
extension: L[".f", ".f90"] = ...,
|
||||
full_output: L[False] = ...,
|
||||
) -> int: ...
|
||||
@overload
|
||||
def compile(
|
||||
source: str | bytes,
|
||||
modulename: str = ...,
|
||||
extra_args: str | list[str] = ...,
|
||||
verbose: bool = ...,
|
||||
source_fn: None | str | bytes | os.PathLike[Any] = ...,
|
||||
extension: L[".f", ".f90"] = ...,
|
||||
full_output: L[True] = ...,
|
||||
) -> subprocess.CompletedProcess[bytes]: ...
|
||||
|
||||
def get_include() -> str: ...
|
5
venv/lib/python3.12/site-packages/numpy/f2py/__main__.py
Normal file
5
venv/lib/python3.12/site-packages/numpy/f2py/__main__.py
Normal file
@ -0,0 +1,5 @@
|
||||
# See:
|
||||
# https://web.archive.org/web/20140822061353/http://cens.ioc.ee/projects/f2py2e
|
||||
from numpy.f2py.f2py2e import main
|
||||
|
||||
main()
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -0,0 +1 @@
|
||||
from numpy.version import version
|
@ -0,0 +1,9 @@
|
||||
def f2py_build_generator(name):
|
||||
if name == "meson":
|
||||
from ._meson import MesonBackend
|
||||
return MesonBackend
|
||||
elif name == "distutils":
|
||||
from ._distutils import DistutilsBackend
|
||||
return DistutilsBackend
|
||||
else:
|
||||
raise ValueError(f"Unknown backend: {name}")
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -0,0 +1,46 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from abc import ABC, abstractmethod
|
||||
|
||||
|
||||
class Backend(ABC):
|
||||
def __init__(
|
||||
self,
|
||||
modulename,
|
||||
sources,
|
||||
extra_objects,
|
||||
build_dir,
|
||||
include_dirs,
|
||||
library_dirs,
|
||||
libraries,
|
||||
define_macros,
|
||||
undef_macros,
|
||||
f2py_flags,
|
||||
sysinfo_flags,
|
||||
fc_flags,
|
||||
flib_flags,
|
||||
setup_flags,
|
||||
remove_build_dir,
|
||||
extra_dat,
|
||||
):
|
||||
self.modulename = modulename
|
||||
self.sources = sources
|
||||
self.extra_objects = extra_objects
|
||||
self.build_dir = build_dir
|
||||
self.include_dirs = include_dirs
|
||||
self.library_dirs = library_dirs
|
||||
self.libraries = libraries
|
||||
self.define_macros = define_macros
|
||||
self.undef_macros = undef_macros
|
||||
self.f2py_flags = f2py_flags
|
||||
self.sysinfo_flags = sysinfo_flags
|
||||
self.fc_flags = fc_flags
|
||||
self.flib_flags = flib_flags
|
||||
self.setup_flags = setup_flags
|
||||
self.remove_build_dir = remove_build_dir
|
||||
self.extra_dat = extra_dat
|
||||
|
||||
@abstractmethod
|
||||
def compile(self) -> None:
|
||||
"""Compile the wrapper."""
|
||||
pass
|
@ -0,0 +1,75 @@
|
||||
from ._backend import Backend
|
||||
|
||||
from numpy.distutils.core import setup, Extension
|
||||
from numpy.distutils.system_info import get_info
|
||||
from numpy.distutils.misc_util import dict_append
|
||||
from numpy.exceptions import VisibleDeprecationWarning
|
||||
import os
|
||||
import sys
|
||||
import shutil
|
||||
import warnings
|
||||
|
||||
|
||||
class DistutilsBackend(Backend):
|
||||
def __init__(sef, *args, **kwargs):
|
||||
warnings.warn(
|
||||
"\ndistutils has been deprecated since NumPy 1.26.x\n"
|
||||
"Use the Meson backend instead, or generate wrappers"
|
||||
" without -c and use a custom build script",
|
||||
VisibleDeprecationWarning,
|
||||
stacklevel=2,
|
||||
)
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
def compile(self):
|
||||
num_info = {}
|
||||
if num_info:
|
||||
self.include_dirs.extend(num_info.get("include_dirs", []))
|
||||
ext_args = {
|
||||
"name": self.modulename,
|
||||
"sources": self.sources,
|
||||
"include_dirs": self.include_dirs,
|
||||
"library_dirs": self.library_dirs,
|
||||
"libraries": self.libraries,
|
||||
"define_macros": self.define_macros,
|
||||
"undef_macros": self.undef_macros,
|
||||
"extra_objects": self.extra_objects,
|
||||
"f2py_options": self.f2py_flags,
|
||||
}
|
||||
|
||||
if self.sysinfo_flags:
|
||||
for n in self.sysinfo_flags:
|
||||
i = get_info(n)
|
||||
if not i:
|
||||
print(
|
||||
f"No {repr(n)} resources found"
|
||||
"in system (try `f2py --help-link`)"
|
||||
)
|
||||
dict_append(ext_args, **i)
|
||||
|
||||
ext = Extension(**ext_args)
|
||||
|
||||
sys.argv = [sys.argv[0]] + self.setup_flags
|
||||
sys.argv.extend(
|
||||
[
|
||||
"build",
|
||||
"--build-temp",
|
||||
self.build_dir,
|
||||
"--build-base",
|
||||
self.build_dir,
|
||||
"--build-platlib",
|
||||
".",
|
||||
"--disable-optimization",
|
||||
]
|
||||
)
|
||||
|
||||
if self.fc_flags:
|
||||
sys.argv.extend(["config_fc"] + self.fc_flags)
|
||||
if self.flib_flags:
|
||||
sys.argv.extend(["build_ext"] + self.flib_flags)
|
||||
|
||||
setup(ext_modules=[ext])
|
||||
|
||||
if self.remove_build_dir and os.path.exists(self.build_dir):
|
||||
print(f"Removing build directory {self.build_dir}")
|
||||
shutil.rmtree(self.build_dir)
|
234
venv/lib/python3.12/site-packages/numpy/f2py/_backends/_meson.py
Normal file
234
venv/lib/python3.12/site-packages/numpy/f2py/_backends/_meson.py
Normal file
@ -0,0 +1,234 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import os
|
||||
import errno
|
||||
import shutil
|
||||
import subprocess
|
||||
import sys
|
||||
import re
|
||||
from pathlib import Path
|
||||
|
||||
from ._backend import Backend
|
||||
from string import Template
|
||||
from itertools import chain
|
||||
|
||||
import warnings
|
||||
|
||||
|
||||
class MesonTemplate:
|
||||
"""Template meson build file generation class."""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
modulename: str,
|
||||
sources: list[Path],
|
||||
deps: list[str],
|
||||
libraries: list[str],
|
||||
library_dirs: list[Path],
|
||||
include_dirs: list[Path],
|
||||
object_files: list[Path],
|
||||
linker_args: list[str],
|
||||
fortran_args: list[str],
|
||||
build_type: str,
|
||||
python_exe: str,
|
||||
):
|
||||
self.modulename = modulename
|
||||
self.build_template_path = (
|
||||
Path(__file__).parent.absolute() / "meson.build.template"
|
||||
)
|
||||
self.sources = sources
|
||||
self.deps = deps
|
||||
self.libraries = libraries
|
||||
self.library_dirs = library_dirs
|
||||
if include_dirs is not None:
|
||||
self.include_dirs = include_dirs
|
||||
else:
|
||||
self.include_dirs = []
|
||||
self.substitutions = {}
|
||||
self.objects = object_files
|
||||
# Convert args to '' wrapped variant for meson
|
||||
self.fortran_args = [
|
||||
f"'{x}'" if not (x.startswith("'") and x.endswith("'")) else x
|
||||
for x in fortran_args
|
||||
]
|
||||
self.pipeline = [
|
||||
self.initialize_template,
|
||||
self.sources_substitution,
|
||||
self.deps_substitution,
|
||||
self.include_substitution,
|
||||
self.libraries_substitution,
|
||||
self.fortran_args_substitution,
|
||||
]
|
||||
self.build_type = build_type
|
||||
self.python_exe = python_exe
|
||||
self.indent = " " * 21
|
||||
|
||||
def meson_build_template(self) -> str:
|
||||
if not self.build_template_path.is_file():
|
||||
raise FileNotFoundError(
|
||||
errno.ENOENT,
|
||||
"Meson build template"
|
||||
f" {self.build_template_path.absolute()}"
|
||||
" does not exist.",
|
||||
)
|
||||
return self.build_template_path.read_text()
|
||||
|
||||
def initialize_template(self) -> None:
|
||||
self.substitutions["modulename"] = self.modulename
|
||||
self.substitutions["buildtype"] = self.build_type
|
||||
self.substitutions["python"] = self.python_exe
|
||||
|
||||
def sources_substitution(self) -> None:
|
||||
self.substitutions["source_list"] = ",\n".join(
|
||||
[f"{self.indent}'''{source}'''," for source in self.sources]
|
||||
)
|
||||
|
||||
def deps_substitution(self) -> None:
|
||||
self.substitutions["dep_list"] = f",\n{self.indent}".join(
|
||||
[f"{self.indent}dependency('{dep}')," for dep in self.deps]
|
||||
)
|
||||
|
||||
def libraries_substitution(self) -> None:
|
||||
self.substitutions["lib_dir_declarations"] = "\n".join(
|
||||
[
|
||||
f"lib_dir_{i} = declare_dependency(link_args : ['''-L{lib_dir}'''])"
|
||||
for i, lib_dir in enumerate(self.library_dirs)
|
||||
]
|
||||
)
|
||||
|
||||
self.substitutions["lib_declarations"] = "\n".join(
|
||||
[
|
||||
f"{lib.replace('.','_')} = declare_dependency(link_args : ['-l{lib}'])"
|
||||
for lib in self.libraries
|
||||
]
|
||||
)
|
||||
|
||||
self.substitutions["lib_list"] = f"\n{self.indent}".join(
|
||||
[f"{self.indent}{lib.replace('.','_')}," for lib in self.libraries]
|
||||
)
|
||||
self.substitutions["lib_dir_list"] = f"\n{self.indent}".join(
|
||||
[f"{self.indent}lib_dir_{i}," for i in range(len(self.library_dirs))]
|
||||
)
|
||||
|
||||
def include_substitution(self) -> None:
|
||||
self.substitutions["inc_list"] = f",\n{self.indent}".join(
|
||||
[f"{self.indent}'''{inc}'''," for inc in self.include_dirs]
|
||||
)
|
||||
|
||||
def fortran_args_substitution(self) -> None:
|
||||
if self.fortran_args:
|
||||
self.substitutions["fortran_args"] = (
|
||||
f"{self.indent}fortran_args: [{', '.join([arg for arg in self.fortran_args])}],"
|
||||
)
|
||||
else:
|
||||
self.substitutions["fortran_args"] = ""
|
||||
|
||||
def generate_meson_build(self):
|
||||
for node in self.pipeline:
|
||||
node()
|
||||
template = Template(self.meson_build_template())
|
||||
meson_build = template.substitute(self.substitutions)
|
||||
meson_build = re.sub(r",,", ",", meson_build)
|
||||
return meson_build
|
||||
|
||||
|
||||
class MesonBackend(Backend):
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
self.dependencies = self.extra_dat.get("dependencies", [])
|
||||
self.meson_build_dir = "bbdir"
|
||||
self.build_type = (
|
||||
"debug" if any("debug" in flag for flag in self.fc_flags) else "release"
|
||||
)
|
||||
self.fc_flags = _get_flags(self.fc_flags)
|
||||
|
||||
def _move_exec_to_root(self, build_dir: Path):
|
||||
walk_dir = Path(build_dir) / self.meson_build_dir
|
||||
path_objects = chain(
|
||||
walk_dir.glob(f"{self.modulename}*.so"),
|
||||
walk_dir.glob(f"{self.modulename}*.pyd"),
|
||||
)
|
||||
# Same behavior as distutils
|
||||
# https://github.com/numpy/numpy/issues/24874#issuecomment-1835632293
|
||||
for path_object in path_objects:
|
||||
dest_path = Path.cwd() / path_object.name
|
||||
if dest_path.exists():
|
||||
dest_path.unlink()
|
||||
shutil.copy2(path_object, dest_path)
|
||||
os.remove(path_object)
|
||||
|
||||
def write_meson_build(self, build_dir: Path) -> None:
|
||||
"""Writes the meson build file at specified location"""
|
||||
meson_template = MesonTemplate(
|
||||
self.modulename,
|
||||
self.sources,
|
||||
self.dependencies,
|
||||
self.libraries,
|
||||
self.library_dirs,
|
||||
self.include_dirs,
|
||||
self.extra_objects,
|
||||
self.flib_flags,
|
||||
self.fc_flags,
|
||||
self.build_type,
|
||||
sys.executable,
|
||||
)
|
||||
src = meson_template.generate_meson_build()
|
||||
Path(build_dir).mkdir(parents=True, exist_ok=True)
|
||||
meson_build_file = Path(build_dir) / "meson.build"
|
||||
meson_build_file.write_text(src)
|
||||
return meson_build_file
|
||||
|
||||
def _run_subprocess_command(self, command, cwd):
|
||||
subprocess.run(command, cwd=cwd, check=True)
|
||||
|
||||
def run_meson(self, build_dir: Path):
|
||||
setup_command = ["meson", "setup", self.meson_build_dir]
|
||||
self._run_subprocess_command(setup_command, build_dir)
|
||||
compile_command = ["meson", "compile", "-C", self.meson_build_dir]
|
||||
self._run_subprocess_command(compile_command, build_dir)
|
||||
|
||||
def compile(self) -> None:
|
||||
self.sources = _prepare_sources(self.modulename, self.sources, self.build_dir)
|
||||
self.write_meson_build(self.build_dir)
|
||||
self.run_meson(self.build_dir)
|
||||
self._move_exec_to_root(self.build_dir)
|
||||
|
||||
|
||||
def _prepare_sources(mname, sources, bdir):
|
||||
extended_sources = sources.copy()
|
||||
Path(bdir).mkdir(parents=True, exist_ok=True)
|
||||
# Copy sources
|
||||
for source in sources:
|
||||
if Path(source).exists() and Path(source).is_file():
|
||||
shutil.copy(source, bdir)
|
||||
generated_sources = [
|
||||
Path(f"{mname}module.c"),
|
||||
Path(f"{mname}-f2pywrappers2.f90"),
|
||||
Path(f"{mname}-f2pywrappers.f"),
|
||||
]
|
||||
bdir = Path(bdir)
|
||||
for generated_source in generated_sources:
|
||||
if generated_source.exists():
|
||||
shutil.copy(generated_source, bdir / generated_source.name)
|
||||
extended_sources.append(generated_source.name)
|
||||
generated_source.unlink()
|
||||
extended_sources = [
|
||||
Path(source).name
|
||||
for source in extended_sources
|
||||
if not Path(source).suffix == ".pyf"
|
||||
]
|
||||
return extended_sources
|
||||
|
||||
|
||||
def _get_flags(fc_flags):
|
||||
flag_values = []
|
||||
flag_pattern = re.compile(r"--f(77|90)flags=(.*)")
|
||||
for flag in fc_flags:
|
||||
match_result = flag_pattern.match(flag)
|
||||
if match_result:
|
||||
values = match_result.group(2).strip().split()
|
||||
values = [val.strip("'\"") for val in values]
|
||||
flag_values.extend(values)
|
||||
# Hacky way to preserve order of flags
|
||||
unique_flags = list(dict.fromkeys(flag_values))
|
||||
return unique_flags
|
@ -0,0 +1,55 @@
|
||||
project('${modulename}',
|
||||
['c', 'fortran'],
|
||||
version : '0.1',
|
||||
meson_version: '>= 1.1.0',
|
||||
default_options : [
|
||||
'warning_level=1',
|
||||
'buildtype=${buildtype}'
|
||||
])
|
||||
fc = meson.get_compiler('fortran')
|
||||
|
||||
py = import('python').find_installation('''${python}''', pure: false)
|
||||
py_dep = py.dependency()
|
||||
|
||||
incdir_numpy = run_command(py,
|
||||
['-c', 'import os; os.chdir(".."); import numpy; print(numpy.get_include())'],
|
||||
check : true
|
||||
).stdout().strip()
|
||||
|
||||
incdir_f2py = run_command(py,
|
||||
['-c', 'import os; os.chdir(".."); import numpy.f2py; print(numpy.f2py.get_include())'],
|
||||
check : true
|
||||
).stdout().strip()
|
||||
|
||||
inc_np = include_directories(incdir_numpy)
|
||||
np_dep = declare_dependency(include_directories: inc_np)
|
||||
|
||||
incdir_f2py = incdir_numpy / '..' / '..' / 'f2py' / 'src'
|
||||
inc_f2py = include_directories(incdir_f2py)
|
||||
fortranobject_c = incdir_f2py / 'fortranobject.c'
|
||||
|
||||
inc_np = include_directories(incdir_numpy, incdir_f2py)
|
||||
# gh-25000
|
||||
quadmath_dep = fc.find_library('quadmath', required: false)
|
||||
|
||||
${lib_declarations}
|
||||
${lib_dir_declarations}
|
||||
|
||||
py.extension_module('${modulename}',
|
||||
[
|
||||
${source_list},
|
||||
fortranobject_c
|
||||
],
|
||||
include_directories: [
|
||||
inc_np,
|
||||
${inc_list}
|
||||
],
|
||||
dependencies : [
|
||||
py_dep,
|
||||
quadmath_dep,
|
||||
${dep_list}
|
||||
${lib_list}
|
||||
${lib_dir_list}
|
||||
],
|
||||
${fortran_args}
|
||||
install : true)
|
62
venv/lib/python3.12/site-packages/numpy/f2py/_isocbind.py
Normal file
62
venv/lib/python3.12/site-packages/numpy/f2py/_isocbind.py
Normal file
@ -0,0 +1,62 @@
|
||||
"""
|
||||
ISO_C_BINDING maps for f2py2e.
|
||||
Only required declarations/macros/functions will be used.
|
||||
|
||||
Copyright 1999 -- 2011 Pearu Peterson all rights reserved.
|
||||
Copyright 2011 -- present NumPy Developers.
|
||||
Permission to use, modify, and distribute this software is given under the
|
||||
terms of the NumPy License.
|
||||
|
||||
NO WARRANTY IS EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
|
||||
"""
|
||||
# These map to keys in c2py_map, via forced casting for now, see gh-25229
|
||||
iso_c_binding_map = {
|
||||
'integer': {
|
||||
'c_int': 'int',
|
||||
'c_short': 'short', # 'short' <=> 'int' for now
|
||||
'c_long': 'long', # 'long' <=> 'int' for now
|
||||
'c_long_long': 'long_long',
|
||||
'c_signed_char': 'signed_char',
|
||||
'c_size_t': 'unsigned', # size_t <=> 'unsigned' for now
|
||||
'c_int8_t': 'signed_char', # int8_t <=> 'signed_char' for now
|
||||
'c_int16_t': 'short', # int16_t <=> 'short' for now
|
||||
'c_int32_t': 'int', # int32_t <=> 'int' for now
|
||||
'c_int64_t': 'long_long',
|
||||
'c_int_least8_t': 'signed_char', # int_least8_t <=> 'signed_char' for now
|
||||
'c_int_least16_t': 'short', # int_least16_t <=> 'short' for now
|
||||
'c_int_least32_t': 'int', # int_least32_t <=> 'int' for now
|
||||
'c_int_least64_t': 'long_long',
|
||||
'c_int_fast8_t': 'signed_char', # int_fast8_t <=> 'signed_char' for now
|
||||
'c_int_fast16_t': 'short', # int_fast16_t <=> 'short' for now
|
||||
'c_int_fast32_t': 'int', # int_fast32_t <=> 'int' for now
|
||||
'c_int_fast64_t': 'long_long',
|
||||
'c_intmax_t': 'long_long', # intmax_t <=> 'long_long' for now
|
||||
'c_intptr_t': 'long', # intptr_t <=> 'long' for now
|
||||
'c_ptrdiff_t': 'long', # ptrdiff_t <=> 'long' for now
|
||||
},
|
||||
'real': {
|
||||
'c_float': 'float',
|
||||
'c_double': 'double',
|
||||
'c_long_double': 'long_double'
|
||||
},
|
||||
'complex': {
|
||||
'c_float_complex': 'complex_float',
|
||||
'c_double_complex': 'complex_double',
|
||||
'c_long_double_complex': 'complex_long_double'
|
||||
},
|
||||
'logical': {
|
||||
'c_bool': 'unsigned_char' # _Bool <=> 'unsigned_char' for now
|
||||
},
|
||||
'character': {
|
||||
'c_char': 'char'
|
||||
}
|
||||
}
|
||||
|
||||
# TODO: See gh-25229
|
||||
isoc_c2pycode_map = {}
|
||||
iso_c2py_map = {}
|
||||
|
||||
isoc_kindmap = {}
|
||||
for fortran_type, c_type_dict in iso_c_binding_map.items():
|
||||
for c_type in c_type_dict.keys():
|
||||
isoc_kindmap[c_type] = fortran_type
|
239
venv/lib/python3.12/site-packages/numpy/f2py/_src_pyf.py
Normal file
239
venv/lib/python3.12/site-packages/numpy/f2py/_src_pyf.py
Normal file
@ -0,0 +1,239 @@
|
||||
import re
|
||||
|
||||
# START OF CODE VENDORED FROM `numpy.distutils.from_template`
|
||||
#############################################################
|
||||
"""
|
||||
process_file(filename)
|
||||
|
||||
takes templated file .xxx.src and produces .xxx file where .xxx
|
||||
is .pyf .f90 or .f using the following template rules:
|
||||
|
||||
'<..>' denotes a template.
|
||||
|
||||
All function and subroutine blocks in a source file with names that
|
||||
contain '<..>' will be replicated according to the rules in '<..>'.
|
||||
|
||||
The number of comma-separated words in '<..>' will determine the number of
|
||||
replicates.
|
||||
|
||||
'<..>' may have two different forms, named and short. For example,
|
||||
|
||||
named:
|
||||
<p=d,s,z,c> where anywhere inside a block '<p>' will be replaced with
|
||||
'd', 's', 'z', and 'c' for each replicate of the block.
|
||||
|
||||
<_c> is already defined: <_c=s,d,c,z>
|
||||
<_t> is already defined: <_t=real,double precision,complex,double complex>
|
||||
|
||||
short:
|
||||
<s,d,c,z>, a short form of the named, useful when no <p> appears inside
|
||||
a block.
|
||||
|
||||
In general, '<..>' contains a comma separated list of arbitrary
|
||||
expressions. If these expression must contain a comma|leftarrow|rightarrow,
|
||||
then prepend the comma|leftarrow|rightarrow with a backslash.
|
||||
|
||||
If an expression matches '\\<index>' then it will be replaced
|
||||
by <index>-th expression.
|
||||
|
||||
Note that all '<..>' forms in a block must have the same number of
|
||||
comma-separated entries.
|
||||
|
||||
Predefined named template rules:
|
||||
<prefix=s,d,c,z>
|
||||
<ftype=real,double precision,complex,double complex>
|
||||
<ftypereal=real,double precision,\\0,\\1>
|
||||
<ctype=float,double,complex_float,complex_double>
|
||||
<ctypereal=float,double,\\0,\\1>
|
||||
"""
|
||||
|
||||
routine_start_re = re.compile(r'(\n|\A)(( (\$|\*))|)\s*(subroutine|function)\b', re.I)
|
||||
routine_end_re = re.compile(r'\n\s*end\s*(subroutine|function)\b.*(\n|\Z)', re.I)
|
||||
function_start_re = re.compile(r'\n (\$|\*)\s*function\b', re.I)
|
||||
|
||||
def parse_structure(astr):
|
||||
""" Return a list of tuples for each function or subroutine each
|
||||
tuple is the start and end of a subroutine or function to be
|
||||
expanded.
|
||||
"""
|
||||
|
||||
spanlist = []
|
||||
ind = 0
|
||||
while True:
|
||||
m = routine_start_re.search(astr, ind)
|
||||
if m is None:
|
||||
break
|
||||
start = m.start()
|
||||
if function_start_re.match(astr, start, m.end()):
|
||||
while True:
|
||||
i = astr.rfind('\n', ind, start)
|
||||
if i==-1:
|
||||
break
|
||||
start = i
|
||||
if astr[i:i+7]!='\n $':
|
||||
break
|
||||
start += 1
|
||||
m = routine_end_re.search(astr, m.end())
|
||||
ind = end = m and m.end()-1 or len(astr)
|
||||
spanlist.append((start, end))
|
||||
return spanlist
|
||||
|
||||
template_re = re.compile(r"<\s*(\w[\w\d]*)\s*>")
|
||||
named_re = re.compile(r"<\s*(\w[\w\d]*)\s*=\s*(.*?)\s*>")
|
||||
list_re = re.compile(r"<\s*((.*?))\s*>")
|
||||
|
||||
def find_repl_patterns(astr):
|
||||
reps = named_re.findall(astr)
|
||||
names = {}
|
||||
for rep in reps:
|
||||
name = rep[0].strip() or unique_key(names)
|
||||
repl = rep[1].replace(r'\,', '@comma@')
|
||||
thelist = conv(repl)
|
||||
names[name] = thelist
|
||||
return names
|
||||
|
||||
def find_and_remove_repl_patterns(astr):
|
||||
names = find_repl_patterns(astr)
|
||||
astr = re.subn(named_re, '', astr)[0]
|
||||
return astr, names
|
||||
|
||||
item_re = re.compile(r"\A\\(?P<index>\d+)\Z")
|
||||
def conv(astr):
|
||||
b = astr.split(',')
|
||||
l = [x.strip() for x in b]
|
||||
for i in range(len(l)):
|
||||
m = item_re.match(l[i])
|
||||
if m:
|
||||
j = int(m.group('index'))
|
||||
l[i] = l[j]
|
||||
return ','.join(l)
|
||||
|
||||
def unique_key(adict):
|
||||
""" Obtain a unique key given a dictionary."""
|
||||
allkeys = list(adict.keys())
|
||||
done = False
|
||||
n = 1
|
||||
while not done:
|
||||
newkey = '__l%s' % (n)
|
||||
if newkey in allkeys:
|
||||
n += 1
|
||||
else:
|
||||
done = True
|
||||
return newkey
|
||||
|
||||
|
||||
template_name_re = re.compile(r'\A\s*(\w[\w\d]*)\s*\Z')
|
||||
def expand_sub(substr, names):
|
||||
substr = substr.replace(r'\>', '@rightarrow@')
|
||||
substr = substr.replace(r'\<', '@leftarrow@')
|
||||
lnames = find_repl_patterns(substr)
|
||||
substr = named_re.sub(r"<\1>", substr) # get rid of definition templates
|
||||
|
||||
def listrepl(mobj):
|
||||
thelist = conv(mobj.group(1).replace(r'\,', '@comma@'))
|
||||
if template_name_re.match(thelist):
|
||||
return "<%s>" % (thelist)
|
||||
name = None
|
||||
for key in lnames.keys(): # see if list is already in dictionary
|
||||
if lnames[key] == thelist:
|
||||
name = key
|
||||
if name is None: # this list is not in the dictionary yet
|
||||
name = unique_key(lnames)
|
||||
lnames[name] = thelist
|
||||
return "<%s>" % name
|
||||
|
||||
substr = list_re.sub(listrepl, substr) # convert all lists to named templates
|
||||
# newnames are constructed as needed
|
||||
|
||||
numsubs = None
|
||||
base_rule = None
|
||||
rules = {}
|
||||
for r in template_re.findall(substr):
|
||||
if r not in rules:
|
||||
thelist = lnames.get(r, names.get(r, None))
|
||||
if thelist is None:
|
||||
raise ValueError('No replicates found for <%s>' % (r))
|
||||
if r not in names and not thelist.startswith('_'):
|
||||
names[r] = thelist
|
||||
rule = [i.replace('@comma@', ',') for i in thelist.split(',')]
|
||||
num = len(rule)
|
||||
|
||||
if numsubs is None:
|
||||
numsubs = num
|
||||
rules[r] = rule
|
||||
base_rule = r
|
||||
elif num == numsubs:
|
||||
rules[r] = rule
|
||||
else:
|
||||
print("Mismatch in number of replacements (base <{}={}>) "
|
||||
"for <{}={}>. Ignoring.".format(base_rule, ','.join(rules[base_rule]), r, thelist))
|
||||
if not rules:
|
||||
return substr
|
||||
|
||||
def namerepl(mobj):
|
||||
name = mobj.group(1)
|
||||
return rules.get(name, (k+1)*[name])[k]
|
||||
|
||||
newstr = ''
|
||||
for k in range(numsubs):
|
||||
newstr += template_re.sub(namerepl, substr) + '\n\n'
|
||||
|
||||
newstr = newstr.replace('@rightarrow@', '>')
|
||||
newstr = newstr.replace('@leftarrow@', '<')
|
||||
return newstr
|
||||
|
||||
def process_str(allstr):
|
||||
newstr = allstr
|
||||
writestr = ''
|
||||
|
||||
struct = parse_structure(newstr)
|
||||
|
||||
oldend = 0
|
||||
names = {}
|
||||
names.update(_special_names)
|
||||
for sub in struct:
|
||||
cleanedstr, defs = find_and_remove_repl_patterns(newstr[oldend:sub[0]])
|
||||
writestr += cleanedstr
|
||||
names.update(defs)
|
||||
writestr += expand_sub(newstr[sub[0]:sub[1]], names)
|
||||
oldend = sub[1]
|
||||
writestr += newstr[oldend:]
|
||||
|
||||
return writestr
|
||||
|
||||
include_src_re = re.compile(r"(\n|\A)\s*include\s*['\"](?P<name>[\w\d./\\]+\.src)['\"]", re.I)
|
||||
|
||||
def resolve_includes(source):
|
||||
d = os.path.dirname(source)
|
||||
with open(source) as fid:
|
||||
lines = []
|
||||
for line in fid:
|
||||
m = include_src_re.match(line)
|
||||
if m:
|
||||
fn = m.group('name')
|
||||
if not os.path.isabs(fn):
|
||||
fn = os.path.join(d, fn)
|
||||
if os.path.isfile(fn):
|
||||
lines.extend(resolve_includes(fn))
|
||||
else:
|
||||
lines.append(line)
|
||||
else:
|
||||
lines.append(line)
|
||||
return lines
|
||||
|
||||
def process_file(source):
|
||||
lines = resolve_includes(source)
|
||||
return process_str(''.join(lines))
|
||||
|
||||
_special_names = find_repl_patterns('''
|
||||
<_c=s,d,c,z>
|
||||
<_t=real,double precision,complex,double complex>
|
||||
<prefix=s,d,c,z>
|
||||
<ftype=real,double precision,complex,double complex>
|
||||
<ctype=float,double,complex_float,complex_double>
|
||||
<ftypereal=real,double precision,\\0,\\1>
|
||||
<ctypereal=float,double,\\0,\\1>
|
||||
''')
|
||||
|
||||
# END OF CODE VENDORED FROM `numpy.distutils.from_template`
|
||||
###########################################################
|
996
venv/lib/python3.12/site-packages/numpy/f2py/auxfuncs.py
Normal file
996
venv/lib/python3.12/site-packages/numpy/f2py/auxfuncs.py
Normal file
@ -0,0 +1,996 @@
|
||||
"""
|
||||
Auxiliary functions for f2py2e.
|
||||
|
||||
Copyright 1999 -- 2011 Pearu Peterson all rights reserved.
|
||||
Copyright 2011 -- present NumPy Developers.
|
||||
Permission to use, modify, and distribute this software is given under the
|
||||
terms of the NumPy (BSD style) LICENSE.
|
||||
|
||||
NO WARRANTY IS EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
|
||||
"""
|
||||
import pprint
|
||||
import sys
|
||||
import re
|
||||
import types
|
||||
from functools import reduce
|
||||
from copy import deepcopy
|
||||
|
||||
from . import __version__
|
||||
from . import cfuncs
|
||||
from .cfuncs import errmess
|
||||
|
||||
__all__ = [
|
||||
'applyrules', 'debugcapi', 'dictappend', 'errmess', 'gentitle',
|
||||
'getargs2', 'getcallprotoargument', 'getcallstatement',
|
||||
'getfortranname', 'getpymethoddef', 'getrestdoc', 'getusercode',
|
||||
'getusercode1', 'getdimension', 'hasbody', 'hascallstatement', 'hascommon',
|
||||
'hasexternals', 'hasinitvalue', 'hasnote', 'hasresultnote',
|
||||
'isallocatable', 'isarray', 'isarrayofstrings',
|
||||
'ischaracter', 'ischaracterarray', 'ischaracter_or_characterarray',
|
||||
'iscomplex',
|
||||
'iscomplexarray', 'iscomplexfunction', 'iscomplexfunction_warn',
|
||||
'isdouble', 'isdummyroutine', 'isexternal', 'isfunction',
|
||||
'isfunction_wrap', 'isint1', 'isint1array', 'isinteger', 'isintent_aux',
|
||||
'isintent_c', 'isintent_callback', 'isintent_copy', 'isintent_dict',
|
||||
'isintent_hide', 'isintent_in', 'isintent_inout', 'isintent_inplace',
|
||||
'isintent_nothide', 'isintent_out', 'isintent_overwrite', 'islogical',
|
||||
'islogicalfunction', 'islong_complex', 'islong_double',
|
||||
'islong_doublefunction', 'islong_long', 'islong_longfunction',
|
||||
'ismodule', 'ismoduleroutine', 'isoptional', 'isprivate', 'isvariable',
|
||||
'isrequired', 'isroutine', 'isscalar', 'issigned_long_longarray',
|
||||
'isstring', 'isstringarray', 'isstring_or_stringarray', 'isstringfunction',
|
||||
'issubroutine', 'get_f2py_modulename', 'issubroutine_wrap', 'isthreadsafe',
|
||||
'isunsigned', 'isunsigned_char', 'isunsigned_chararray',
|
||||
'isunsigned_long_long', 'isunsigned_long_longarray', 'isunsigned_short',
|
||||
'isunsigned_shortarray', 'l_and', 'l_not', 'l_or', 'outmess', 'replace',
|
||||
'show', 'stripcomma', 'throw_error', 'isattr_value', 'getuseblocks',
|
||||
'process_f2cmap_dict'
|
||||
]
|
||||
|
||||
|
||||
f2py_version = __version__.version
|
||||
|
||||
|
||||
show = pprint.pprint
|
||||
|
||||
options = {}
|
||||
debugoptions = []
|
||||
wrapfuncs = 1
|
||||
|
||||
|
||||
def outmess(t):
|
||||
if options.get('verbose', 1):
|
||||
sys.stdout.write(t)
|
||||
|
||||
|
||||
def debugcapi(var):
|
||||
return 'capi' in debugoptions
|
||||
|
||||
|
||||
def _ischaracter(var):
|
||||
return 'typespec' in var and var['typespec'] == 'character' and \
|
||||
not isexternal(var)
|
||||
|
||||
|
||||
def _isstring(var):
|
||||
return 'typespec' in var and var['typespec'] == 'character' and \
|
||||
not isexternal(var)
|
||||
|
||||
|
||||
def ischaracter_or_characterarray(var):
|
||||
return _ischaracter(var) and 'charselector' not in var
|
||||
|
||||
|
||||
def ischaracter(var):
|
||||
return ischaracter_or_characterarray(var) and not isarray(var)
|
||||
|
||||
|
||||
def ischaracterarray(var):
|
||||
return ischaracter_or_characterarray(var) and isarray(var)
|
||||
|
||||
|
||||
def isstring_or_stringarray(var):
|
||||
return _ischaracter(var) and 'charselector' in var
|
||||
|
||||
|
||||
def isstring(var):
|
||||
return isstring_or_stringarray(var) and not isarray(var)
|
||||
|
||||
|
||||
def isstringarray(var):
|
||||
return isstring_or_stringarray(var) and isarray(var)
|
||||
|
||||
|
||||
def isarrayofstrings(var): # obsolete?
|
||||
# leaving out '*' for now so that `character*(*) a(m)` and `character
|
||||
# a(m,*)` are treated differently. Luckily `character**` is illegal.
|
||||
return isstringarray(var) and var['dimension'][-1] == '(*)'
|
||||
|
||||
|
||||
def isarray(var):
|
||||
return 'dimension' in var and not isexternal(var)
|
||||
|
||||
|
||||
def isscalar(var):
|
||||
return not (isarray(var) or isstring(var) or isexternal(var))
|
||||
|
||||
|
||||
def iscomplex(var):
|
||||
return isscalar(var) and \
|
||||
var.get('typespec') in ['complex', 'double complex']
|
||||
|
||||
|
||||
def islogical(var):
|
||||
return isscalar(var) and var.get('typespec') == 'logical'
|
||||
|
||||
|
||||
def isinteger(var):
|
||||
return isscalar(var) and var.get('typespec') == 'integer'
|
||||
|
||||
|
||||
def isreal(var):
|
||||
return isscalar(var) and var.get('typespec') == 'real'
|
||||
|
||||
|
||||
def get_kind(var):
|
||||
try:
|
||||
return var['kindselector']['*']
|
||||
except KeyError:
|
||||
try:
|
||||
return var['kindselector']['kind']
|
||||
except KeyError:
|
||||
pass
|
||||
|
||||
|
||||
def isint1(var):
|
||||
return var.get('typespec') == 'integer' \
|
||||
and get_kind(var) == '1' and not isarray(var)
|
||||
|
||||
|
||||
def islong_long(var):
|
||||
if not isscalar(var):
|
||||
return 0
|
||||
if var.get('typespec') not in ['integer', 'logical']:
|
||||
return 0
|
||||
return get_kind(var) == '8'
|
||||
|
||||
|
||||
def isunsigned_char(var):
|
||||
if not isscalar(var):
|
||||
return 0
|
||||
if var.get('typespec') != 'integer':
|
||||
return 0
|
||||
return get_kind(var) == '-1'
|
||||
|
||||
|
||||
def isunsigned_short(var):
|
||||
if not isscalar(var):
|
||||
return 0
|
||||
if var.get('typespec') != 'integer':
|
||||
return 0
|
||||
return get_kind(var) == '-2'
|
||||
|
||||
|
||||
def isunsigned(var):
|
||||
if not isscalar(var):
|
||||
return 0
|
||||
if var.get('typespec') != 'integer':
|
||||
return 0
|
||||
return get_kind(var) == '-4'
|
||||
|
||||
|
||||
def isunsigned_long_long(var):
|
||||
if not isscalar(var):
|
||||
return 0
|
||||
if var.get('typespec') != 'integer':
|
||||
return 0
|
||||
return get_kind(var) == '-8'
|
||||
|
||||
|
||||
def isdouble(var):
|
||||
if not isscalar(var):
|
||||
return 0
|
||||
if not var.get('typespec') == 'real':
|
||||
return 0
|
||||
return get_kind(var) == '8'
|
||||
|
||||
|
||||
def islong_double(var):
|
||||
if not isscalar(var):
|
||||
return 0
|
||||
if not var.get('typespec') == 'real':
|
||||
return 0
|
||||
return get_kind(var) == '16'
|
||||
|
||||
|
||||
def islong_complex(var):
|
||||
if not iscomplex(var):
|
||||
return 0
|
||||
return get_kind(var) == '32'
|
||||
|
||||
|
||||
def iscomplexarray(var):
|
||||
return isarray(var) and \
|
||||
var.get('typespec') in ['complex', 'double complex']
|
||||
|
||||
|
||||
def isint1array(var):
|
||||
return isarray(var) and var.get('typespec') == 'integer' \
|
||||
and get_kind(var) == '1'
|
||||
|
||||
|
||||
def isunsigned_chararray(var):
|
||||
return isarray(var) and var.get('typespec') in ['integer', 'logical']\
|
||||
and get_kind(var) == '-1'
|
||||
|
||||
|
||||
def isunsigned_shortarray(var):
|
||||
return isarray(var) and var.get('typespec') in ['integer', 'logical']\
|
||||
and get_kind(var) == '-2'
|
||||
|
||||
|
||||
def isunsignedarray(var):
|
||||
return isarray(var) and var.get('typespec') in ['integer', 'logical']\
|
||||
and get_kind(var) == '-4'
|
||||
|
||||
|
||||
def isunsigned_long_longarray(var):
|
||||
return isarray(var) and var.get('typespec') in ['integer', 'logical']\
|
||||
and get_kind(var) == '-8'
|
||||
|
||||
|
||||
def issigned_chararray(var):
|
||||
return isarray(var) and var.get('typespec') in ['integer', 'logical']\
|
||||
and get_kind(var) == '1'
|
||||
|
||||
|
||||
def issigned_shortarray(var):
|
||||
return isarray(var) and var.get('typespec') in ['integer', 'logical']\
|
||||
and get_kind(var) == '2'
|
||||
|
||||
|
||||
def issigned_array(var):
|
||||
return isarray(var) and var.get('typespec') in ['integer', 'logical']\
|
||||
and get_kind(var) == '4'
|
||||
|
||||
|
||||
def issigned_long_longarray(var):
|
||||
return isarray(var) and var.get('typespec') in ['integer', 'logical']\
|
||||
and get_kind(var) == '8'
|
||||
|
||||
|
||||
def isallocatable(var):
|
||||
return 'attrspec' in var and 'allocatable' in var['attrspec']
|
||||
|
||||
|
||||
def ismutable(var):
|
||||
return not ('dimension' not in var or isstring(var))
|
||||
|
||||
|
||||
def ismoduleroutine(rout):
|
||||
return 'modulename' in rout
|
||||
|
||||
|
||||
def ismodule(rout):
|
||||
return 'block' in rout and 'module' == rout['block']
|
||||
|
||||
|
||||
def isfunction(rout):
|
||||
return 'block' in rout and 'function' == rout['block']
|
||||
|
||||
|
||||
def isfunction_wrap(rout):
|
||||
if isintent_c(rout):
|
||||
return 0
|
||||
return wrapfuncs and isfunction(rout) and (not isexternal(rout))
|
||||
|
||||
|
||||
def issubroutine(rout):
|
||||
return 'block' in rout and 'subroutine' == rout['block']
|
||||
|
||||
|
||||
def issubroutine_wrap(rout):
|
||||
if isintent_c(rout):
|
||||
return 0
|
||||
return issubroutine(rout) and hasassumedshape(rout)
|
||||
|
||||
def isattr_value(var):
|
||||
return 'value' in var.get('attrspec', [])
|
||||
|
||||
|
||||
def hasassumedshape(rout):
|
||||
if rout.get('hasassumedshape'):
|
||||
return True
|
||||
for a in rout['args']:
|
||||
for d in rout['vars'].get(a, {}).get('dimension', []):
|
||||
if d == ':':
|
||||
rout['hasassumedshape'] = True
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def requiresf90wrapper(rout):
|
||||
return ismoduleroutine(rout) or hasassumedshape(rout)
|
||||
|
||||
|
||||
def isroutine(rout):
|
||||
return isfunction(rout) or issubroutine(rout)
|
||||
|
||||
|
||||
def islogicalfunction(rout):
|
||||
if not isfunction(rout):
|
||||
return 0
|
||||
if 'result' in rout:
|
||||
a = rout['result']
|
||||
else:
|
||||
a = rout['name']
|
||||
if a in rout['vars']:
|
||||
return islogical(rout['vars'][a])
|
||||
return 0
|
||||
|
||||
|
||||
def islong_longfunction(rout):
|
||||
if not isfunction(rout):
|
||||
return 0
|
||||
if 'result' in rout:
|
||||
a = rout['result']
|
||||
else:
|
||||
a = rout['name']
|
||||
if a in rout['vars']:
|
||||
return islong_long(rout['vars'][a])
|
||||
return 0
|
||||
|
||||
|
||||
def islong_doublefunction(rout):
|
||||
if not isfunction(rout):
|
||||
return 0
|
||||
if 'result' in rout:
|
||||
a = rout['result']
|
||||
else:
|
||||
a = rout['name']
|
||||
if a in rout['vars']:
|
||||
return islong_double(rout['vars'][a])
|
||||
return 0
|
||||
|
||||
|
||||
def iscomplexfunction(rout):
|
||||
if not isfunction(rout):
|
||||
return 0
|
||||
if 'result' in rout:
|
||||
a = rout['result']
|
||||
else:
|
||||
a = rout['name']
|
||||
if a in rout['vars']:
|
||||
return iscomplex(rout['vars'][a])
|
||||
return 0
|
||||
|
||||
|
||||
def iscomplexfunction_warn(rout):
|
||||
if iscomplexfunction(rout):
|
||||
outmess("""\
|
||||
**************************************************************
|
||||
Warning: code with a function returning complex value
|
||||
may not work correctly with your Fortran compiler.
|
||||
When using GNU gcc/g77 compilers, codes should work
|
||||
correctly for callbacks with:
|
||||
f2py -c -DF2PY_CB_RETURNCOMPLEX
|
||||
**************************************************************\n""")
|
||||
return 1
|
||||
return 0
|
||||
|
||||
|
||||
def isstringfunction(rout):
|
||||
if not isfunction(rout):
|
||||
return 0
|
||||
if 'result' in rout:
|
||||
a = rout['result']
|
||||
else:
|
||||
a = rout['name']
|
||||
if a in rout['vars']:
|
||||
return isstring(rout['vars'][a])
|
||||
return 0
|
||||
|
||||
|
||||
def hasexternals(rout):
|
||||
return 'externals' in rout and rout['externals']
|
||||
|
||||
|
||||
def isthreadsafe(rout):
|
||||
return 'f2pyenhancements' in rout and \
|
||||
'threadsafe' in rout['f2pyenhancements']
|
||||
|
||||
|
||||
def hasvariables(rout):
|
||||
return 'vars' in rout and rout['vars']
|
||||
|
||||
|
||||
def isoptional(var):
|
||||
return ('attrspec' in var and 'optional' in var['attrspec'] and
|
||||
'required' not in var['attrspec']) and isintent_nothide(var)
|
||||
|
||||
|
||||
def isexternal(var):
|
||||
return 'attrspec' in var and 'external' in var['attrspec']
|
||||
|
||||
|
||||
def getdimension(var):
|
||||
dimpattern = r"\((.*?)\)"
|
||||
if 'attrspec' in var.keys():
|
||||
if any('dimension' in s for s in var['attrspec']):
|
||||
return [re.findall(dimpattern, v) for v in var['attrspec']][0]
|
||||
|
||||
|
||||
def isrequired(var):
|
||||
return not isoptional(var) and isintent_nothide(var)
|
||||
|
||||
|
||||
def isintent_in(var):
|
||||
if 'intent' not in var:
|
||||
return 1
|
||||
if 'hide' in var['intent']:
|
||||
return 0
|
||||
if 'inplace' in var['intent']:
|
||||
return 0
|
||||
if 'in' in var['intent']:
|
||||
return 1
|
||||
if 'out' in var['intent']:
|
||||
return 0
|
||||
if 'inout' in var['intent']:
|
||||
return 0
|
||||
if 'outin' in var['intent']:
|
||||
return 0
|
||||
return 1
|
||||
|
||||
|
||||
def isintent_inout(var):
|
||||
return ('intent' in var and ('inout' in var['intent'] or
|
||||
'outin' in var['intent']) and 'in' not in var['intent'] and
|
||||
'hide' not in var['intent'] and 'inplace' not in var['intent'])
|
||||
|
||||
|
||||
def isintent_out(var):
|
||||
return 'out' in var.get('intent', [])
|
||||
|
||||
|
||||
def isintent_hide(var):
|
||||
return ('intent' in var and ('hide' in var['intent'] or
|
||||
('out' in var['intent'] and 'in' not in var['intent'] and
|
||||
(not l_or(isintent_inout, isintent_inplace)(var)))))
|
||||
|
||||
|
||||
def isintent_nothide(var):
|
||||
return not isintent_hide(var)
|
||||
|
||||
|
||||
def isintent_c(var):
|
||||
return 'c' in var.get('intent', [])
|
||||
|
||||
|
||||
def isintent_cache(var):
|
||||
return 'cache' in var.get('intent', [])
|
||||
|
||||
|
||||
def isintent_copy(var):
|
||||
return 'copy' in var.get('intent', [])
|
||||
|
||||
|
||||
def isintent_overwrite(var):
|
||||
return 'overwrite' in var.get('intent', [])
|
||||
|
||||
|
||||
def isintent_callback(var):
|
||||
return 'callback' in var.get('intent', [])
|
||||
|
||||
|
||||
def isintent_inplace(var):
|
||||
return 'inplace' in var.get('intent', [])
|
||||
|
||||
|
||||
def isintent_aux(var):
|
||||
return 'aux' in var.get('intent', [])
|
||||
|
||||
|
||||
def isintent_aligned4(var):
|
||||
return 'aligned4' in var.get('intent', [])
|
||||
|
||||
|
||||
def isintent_aligned8(var):
|
||||
return 'aligned8' in var.get('intent', [])
|
||||
|
||||
|
||||
def isintent_aligned16(var):
|
||||
return 'aligned16' in var.get('intent', [])
|
||||
|
||||
|
||||
isintent_dict = {isintent_in: 'INTENT_IN', isintent_inout: 'INTENT_INOUT',
|
||||
isintent_out: 'INTENT_OUT', isintent_hide: 'INTENT_HIDE',
|
||||
isintent_cache: 'INTENT_CACHE',
|
||||
isintent_c: 'INTENT_C', isoptional: 'OPTIONAL',
|
||||
isintent_inplace: 'INTENT_INPLACE',
|
||||
isintent_aligned4: 'INTENT_ALIGNED4',
|
||||
isintent_aligned8: 'INTENT_ALIGNED8',
|
||||
isintent_aligned16: 'INTENT_ALIGNED16',
|
||||
}
|
||||
|
||||
|
||||
def isprivate(var):
|
||||
return 'attrspec' in var and 'private' in var['attrspec']
|
||||
|
||||
|
||||
def isvariable(var):
|
||||
# heuristic to find public/private declarations of filtered subroutines
|
||||
if len(var) == 1 and 'attrspec' in var and \
|
||||
var['attrspec'][0] in ('public', 'private'):
|
||||
is_var = False
|
||||
else:
|
||||
is_var = True
|
||||
return is_var
|
||||
|
||||
def hasinitvalue(var):
|
||||
return '=' in var
|
||||
|
||||
|
||||
def hasinitvalueasstring(var):
|
||||
if not hasinitvalue(var):
|
||||
return 0
|
||||
return var['='][0] in ['"', "'"]
|
||||
|
||||
|
||||
def hasnote(var):
|
||||
return 'note' in var
|
||||
|
||||
|
||||
def hasresultnote(rout):
|
||||
if not isfunction(rout):
|
||||
return 0
|
||||
if 'result' in rout:
|
||||
a = rout['result']
|
||||
else:
|
||||
a = rout['name']
|
||||
if a in rout['vars']:
|
||||
return hasnote(rout['vars'][a])
|
||||
return 0
|
||||
|
||||
|
||||
def hascommon(rout):
|
||||
return 'common' in rout
|
||||
|
||||
|
||||
def containscommon(rout):
|
||||
if hascommon(rout):
|
||||
return 1
|
||||
if hasbody(rout):
|
||||
for b in rout['body']:
|
||||
if containscommon(b):
|
||||
return 1
|
||||
return 0
|
||||
|
||||
|
||||
def containsmodule(block):
|
||||
if ismodule(block):
|
||||
return 1
|
||||
if not hasbody(block):
|
||||
return 0
|
||||
for b in block['body']:
|
||||
if containsmodule(b):
|
||||
return 1
|
||||
return 0
|
||||
|
||||
|
||||
def hasbody(rout):
|
||||
return 'body' in rout
|
||||
|
||||
|
||||
def hascallstatement(rout):
|
||||
return getcallstatement(rout) is not None
|
||||
|
||||
|
||||
def istrue(var):
|
||||
return 1
|
||||
|
||||
|
||||
def isfalse(var):
|
||||
return 0
|
||||
|
||||
|
||||
class F2PYError(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class throw_error:
|
||||
|
||||
def __init__(self, mess):
|
||||
self.mess = mess
|
||||
|
||||
def __call__(self, var):
|
||||
mess = '\n\n var = %s\n Message: %s\n' % (var, self.mess)
|
||||
raise F2PYError(mess)
|
||||
|
||||
|
||||
def l_and(*f):
|
||||
l1, l2 = 'lambda v', []
|
||||
for i in range(len(f)):
|
||||
l1 = '%s,f%d=f[%d]' % (l1, i, i)
|
||||
l2.append('f%d(v)' % (i))
|
||||
return eval('%s:%s' % (l1, ' and '.join(l2)))
|
||||
|
||||
|
||||
def l_or(*f):
|
||||
l1, l2 = 'lambda v', []
|
||||
for i in range(len(f)):
|
||||
l1 = '%s,f%d=f[%d]' % (l1, i, i)
|
||||
l2.append('f%d(v)' % (i))
|
||||
return eval('%s:%s' % (l1, ' or '.join(l2)))
|
||||
|
||||
|
||||
def l_not(f):
|
||||
return eval('lambda v,f=f:not f(v)')
|
||||
|
||||
|
||||
def isdummyroutine(rout):
|
||||
try:
|
||||
return rout['f2pyenhancements']['fortranname'] == ''
|
||||
except KeyError:
|
||||
return 0
|
||||
|
||||
|
||||
def getfortranname(rout):
|
||||
try:
|
||||
name = rout['f2pyenhancements']['fortranname']
|
||||
if name == '':
|
||||
raise KeyError
|
||||
if not name:
|
||||
errmess('Failed to use fortranname from %s\n' %
|
||||
(rout['f2pyenhancements']))
|
||||
raise KeyError
|
||||
except KeyError:
|
||||
name = rout['name']
|
||||
return name
|
||||
|
||||
|
||||
def getmultilineblock(rout, blockname, comment=1, counter=0):
|
||||
try:
|
||||
r = rout['f2pyenhancements'].get(blockname)
|
||||
except KeyError:
|
||||
return
|
||||
if not r:
|
||||
return
|
||||
if counter > 0 and isinstance(r, str):
|
||||
return
|
||||
if isinstance(r, list):
|
||||
if counter >= len(r):
|
||||
return
|
||||
r = r[counter]
|
||||
if r[:3] == "'''":
|
||||
if comment:
|
||||
r = '\t/* start ' + blockname + \
|
||||
' multiline (' + repr(counter) + ') */\n' + r[3:]
|
||||
else:
|
||||
r = r[3:]
|
||||
if r[-3:] == "'''":
|
||||
if comment:
|
||||
r = r[:-3] + '\n\t/* end multiline (' + repr(counter) + ')*/'
|
||||
else:
|
||||
r = r[:-3]
|
||||
else:
|
||||
errmess("%s multiline block should end with `'''`: %s\n"
|
||||
% (blockname, repr(r)))
|
||||
return r
|
||||
|
||||
|
||||
def getcallstatement(rout):
|
||||
return getmultilineblock(rout, 'callstatement')
|
||||
|
||||
|
||||
def getcallprotoargument(rout, cb_map={}):
|
||||
r = getmultilineblock(rout, 'callprotoargument', comment=0)
|
||||
if r:
|
||||
return r
|
||||
if hascallstatement(rout):
|
||||
outmess(
|
||||
'warning: callstatement is defined without callprotoargument\n')
|
||||
return
|
||||
from .capi_maps import getctype
|
||||
arg_types, arg_types2 = [], []
|
||||
if l_and(isstringfunction, l_not(isfunction_wrap))(rout):
|
||||
arg_types.extend(['char*', 'size_t'])
|
||||
for n in rout['args']:
|
||||
var = rout['vars'][n]
|
||||
if isintent_callback(var):
|
||||
continue
|
||||
if n in cb_map:
|
||||
ctype = cb_map[n] + '_typedef'
|
||||
else:
|
||||
ctype = getctype(var)
|
||||
if l_and(isintent_c, l_or(isscalar, iscomplex))(var):
|
||||
pass
|
||||
elif isstring(var):
|
||||
pass
|
||||
else:
|
||||
if not isattr_value(var):
|
||||
ctype = ctype + '*'
|
||||
if (isstring(var)
|
||||
or isarrayofstrings(var) # obsolete?
|
||||
or isstringarray(var)):
|
||||
arg_types2.append('size_t')
|
||||
arg_types.append(ctype)
|
||||
|
||||
proto_args = ','.join(arg_types + arg_types2)
|
||||
if not proto_args:
|
||||
proto_args = 'void'
|
||||
return proto_args
|
||||
|
||||
|
||||
def getusercode(rout):
|
||||
return getmultilineblock(rout, 'usercode')
|
||||
|
||||
|
||||
def getusercode1(rout):
|
||||
return getmultilineblock(rout, 'usercode', counter=1)
|
||||
|
||||
|
||||
def getpymethoddef(rout):
|
||||
return getmultilineblock(rout, 'pymethoddef')
|
||||
|
||||
|
||||
def getargs(rout):
|
||||
sortargs, args = [], []
|
||||
if 'args' in rout:
|
||||
args = rout['args']
|
||||
if 'sortvars' in rout:
|
||||
for a in rout['sortvars']:
|
||||
if a in args:
|
||||
sortargs.append(a)
|
||||
for a in args:
|
||||
if a not in sortargs:
|
||||
sortargs.append(a)
|
||||
else:
|
||||
sortargs = rout['args']
|
||||
return args, sortargs
|
||||
|
||||
|
||||
def getargs2(rout):
|
||||
sortargs, args = [], rout.get('args', [])
|
||||
auxvars = [a for a in rout['vars'].keys() if isintent_aux(rout['vars'][a])
|
||||
and a not in args]
|
||||
args = auxvars + args
|
||||
if 'sortvars' in rout:
|
||||
for a in rout['sortvars']:
|
||||
if a in args:
|
||||
sortargs.append(a)
|
||||
for a in args:
|
||||
if a not in sortargs:
|
||||
sortargs.append(a)
|
||||
else:
|
||||
sortargs = auxvars + rout['args']
|
||||
return args, sortargs
|
||||
|
||||
|
||||
def getrestdoc(rout):
|
||||
if 'f2pymultilines' not in rout:
|
||||
return None
|
||||
k = None
|
||||
if rout['block'] == 'python module':
|
||||
k = rout['block'], rout['name']
|
||||
return rout['f2pymultilines'].get(k, None)
|
||||
|
||||
|
||||
def gentitle(name):
|
||||
ln = (80 - len(name) - 6) // 2
|
||||
return '/*%s %s %s*/' % (ln * '*', name, ln * '*')
|
||||
|
||||
|
||||
def flatlist(lst):
|
||||
if isinstance(lst, list):
|
||||
return reduce(lambda x, y, f=flatlist: x + f(y), lst, [])
|
||||
return [lst]
|
||||
|
||||
|
||||
def stripcomma(s):
|
||||
if s and s[-1] == ',':
|
||||
return s[:-1]
|
||||
return s
|
||||
|
||||
|
||||
def replace(str, d, defaultsep=''):
|
||||
if isinstance(d, list):
|
||||
return [replace(str, _m, defaultsep) for _m in d]
|
||||
if isinstance(str, list):
|
||||
return [replace(_m, d, defaultsep) for _m in str]
|
||||
for k in 2 * list(d.keys()):
|
||||
if k == 'separatorsfor':
|
||||
continue
|
||||
if 'separatorsfor' in d and k in d['separatorsfor']:
|
||||
sep = d['separatorsfor'][k]
|
||||
else:
|
||||
sep = defaultsep
|
||||
if isinstance(d[k], list):
|
||||
str = str.replace('#%s#' % (k), sep.join(flatlist(d[k])))
|
||||
else:
|
||||
str = str.replace('#%s#' % (k), d[k])
|
||||
return str
|
||||
|
||||
|
||||
def dictappend(rd, ar):
|
||||
if isinstance(ar, list):
|
||||
for a in ar:
|
||||
rd = dictappend(rd, a)
|
||||
return rd
|
||||
for k in ar.keys():
|
||||
if k[0] == '_':
|
||||
continue
|
||||
if k in rd:
|
||||
if isinstance(rd[k], str):
|
||||
rd[k] = [rd[k]]
|
||||
if isinstance(rd[k], list):
|
||||
if isinstance(ar[k], list):
|
||||
rd[k] = rd[k] + ar[k]
|
||||
else:
|
||||
rd[k].append(ar[k])
|
||||
elif isinstance(rd[k], dict):
|
||||
if isinstance(ar[k], dict):
|
||||
if k == 'separatorsfor':
|
||||
for k1 in ar[k].keys():
|
||||
if k1 not in rd[k]:
|
||||
rd[k][k1] = ar[k][k1]
|
||||
else:
|
||||
rd[k] = dictappend(rd[k], ar[k])
|
||||
else:
|
||||
rd[k] = ar[k]
|
||||
return rd
|
||||
|
||||
|
||||
def applyrules(rules, d, var={}):
|
||||
ret = {}
|
||||
if isinstance(rules, list):
|
||||
for r in rules:
|
||||
rr = applyrules(r, d, var)
|
||||
ret = dictappend(ret, rr)
|
||||
if '_break' in rr:
|
||||
break
|
||||
return ret
|
||||
if '_check' in rules and (not rules['_check'](var)):
|
||||
return ret
|
||||
if 'need' in rules:
|
||||
res = applyrules({'needs': rules['need']}, d, var)
|
||||
if 'needs' in res:
|
||||
cfuncs.append_needs(res['needs'])
|
||||
|
||||
for k in rules.keys():
|
||||
if k == 'separatorsfor':
|
||||
ret[k] = rules[k]
|
||||
continue
|
||||
if isinstance(rules[k], str):
|
||||
ret[k] = replace(rules[k], d)
|
||||
elif isinstance(rules[k], list):
|
||||
ret[k] = []
|
||||
for i in rules[k]:
|
||||
ar = applyrules({k: i}, d, var)
|
||||
if k in ar:
|
||||
ret[k].append(ar[k])
|
||||
elif k[0] == '_':
|
||||
continue
|
||||
elif isinstance(rules[k], dict):
|
||||
ret[k] = []
|
||||
for k1 in rules[k].keys():
|
||||
if isinstance(k1, types.FunctionType) and k1(var):
|
||||
if isinstance(rules[k][k1], list):
|
||||
for i in rules[k][k1]:
|
||||
if isinstance(i, dict):
|
||||
res = applyrules({'supertext': i}, d, var)
|
||||
if 'supertext' in res:
|
||||
i = res['supertext']
|
||||
else:
|
||||
i = ''
|
||||
ret[k].append(replace(i, d))
|
||||
else:
|
||||
i = rules[k][k1]
|
||||
if isinstance(i, dict):
|
||||
res = applyrules({'supertext': i}, d)
|
||||
if 'supertext' in res:
|
||||
i = res['supertext']
|
||||
else:
|
||||
i = ''
|
||||
ret[k].append(replace(i, d))
|
||||
else:
|
||||
errmess('applyrules: ignoring rule %s.\n' % repr(rules[k]))
|
||||
if isinstance(ret[k], list):
|
||||
if len(ret[k]) == 1:
|
||||
ret[k] = ret[k][0]
|
||||
if ret[k] == []:
|
||||
del ret[k]
|
||||
return ret
|
||||
|
||||
_f2py_module_name_match = re.compile(r'\s*python\s*module\s*(?P<name>[\w_]+)',
|
||||
re.I).match
|
||||
_f2py_user_module_name_match = re.compile(r'\s*python\s*module\s*(?P<name>[\w_]*?'
|
||||
r'__user__[\w_]*)', re.I).match
|
||||
|
||||
def get_f2py_modulename(source):
|
||||
name = None
|
||||
with open(source) as f:
|
||||
for line in f:
|
||||
m = _f2py_module_name_match(line)
|
||||
if m:
|
||||
if _f2py_user_module_name_match(line): # skip *__user__* names
|
||||
continue
|
||||
name = m.group('name')
|
||||
break
|
||||
return name
|
||||
|
||||
def getuseblocks(pymod):
|
||||
all_uses = []
|
||||
for inner in pymod['body']:
|
||||
for modblock in inner['body']:
|
||||
if modblock.get('use'):
|
||||
all_uses.extend([x for x in modblock.get("use").keys() if "__" not in x])
|
||||
return all_uses
|
||||
|
||||
def process_f2cmap_dict(f2cmap_all, new_map, c2py_map, verbose = False):
|
||||
"""
|
||||
Update the Fortran-to-C type mapping dictionary with new mappings and
|
||||
return a list of successfully mapped C types.
|
||||
|
||||
This function integrates a new mapping dictionary into an existing
|
||||
Fortran-to-C type mapping dictionary. It ensures that all keys are in
|
||||
lowercase and validates new entries against a given C-to-Python mapping
|
||||
dictionary. Redefinitions and invalid entries are reported with a warning.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
f2cmap_all : dict
|
||||
The existing Fortran-to-C type mapping dictionary that will be updated.
|
||||
It should be a dictionary of dictionaries where the main keys represent
|
||||
Fortran types and the nested dictionaries map Fortran type specifiers
|
||||
to corresponding C types.
|
||||
|
||||
new_map : dict
|
||||
A dictionary containing new type mappings to be added to `f2cmap_all`.
|
||||
The structure should be similar to `f2cmap_all`, with keys representing
|
||||
Fortran types and values being dictionaries of type specifiers and their
|
||||
C type equivalents.
|
||||
|
||||
c2py_map : dict
|
||||
A dictionary used for validating the C types in `new_map`. It maps C
|
||||
types to corresponding Python types and is used to ensure that the C
|
||||
types specified in `new_map` are valid.
|
||||
|
||||
verbose : boolean
|
||||
A flag used to provide information about the types mapped
|
||||
|
||||
Returns
|
||||
-------
|
||||
tuple of (dict, list)
|
||||
The updated Fortran-to-C type mapping dictionary and a list of
|
||||
successfully mapped C types.
|
||||
"""
|
||||
f2cmap_mapped = []
|
||||
|
||||
new_map_lower = {}
|
||||
for k, d1 in new_map.items():
|
||||
d1_lower = {k1.lower(): v1 for k1, v1 in d1.items()}
|
||||
new_map_lower[k.lower()] = d1_lower
|
||||
|
||||
for k, d1 in new_map_lower.items():
|
||||
if k not in f2cmap_all:
|
||||
f2cmap_all[k] = {}
|
||||
|
||||
for k1, v1 in d1.items():
|
||||
if v1 in c2py_map:
|
||||
if k1 in f2cmap_all[k]:
|
||||
outmess(
|
||||
"\tWarning: redefinition of {'%s':{'%s':'%s'->'%s'}}\n"
|
||||
% (k, k1, f2cmap_all[k][k1], v1)
|
||||
)
|
||||
f2cmap_all[k][k1] = v1
|
||||
if verbose:
|
||||
outmess('\tMapping "%s(kind=%s)" to "%s"\n' % (k, k1, v1))
|
||||
f2cmap_mapped.append(v1)
|
||||
else:
|
||||
if verbose:
|
||||
errmess(
|
||||
"\tIgnoring map {'%s':{'%s':'%s'}}: '%s' must be in %s\n"
|
||||
% (k, k1, v1, v1, list(c2py_map.keys()))
|
||||
)
|
||||
|
||||
return f2cmap_all, f2cmap_mapped
|
821
venv/lib/python3.12/site-packages/numpy/f2py/capi_maps.py
Normal file
821
venv/lib/python3.12/site-packages/numpy/f2py/capi_maps.py
Normal file
@ -0,0 +1,821 @@
|
||||
"""
|
||||
Copyright 1999 -- 2011 Pearu Peterson all rights reserved.
|
||||
Copyright 2011 -- present NumPy Developers.
|
||||
Permission to use, modify, and distribute this software is given under the
|
||||
terms of the NumPy License.
|
||||
|
||||
NO WARRANTY IS EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
|
||||
"""
|
||||
from . import __version__
|
||||
f2py_version = __version__.version
|
||||
|
||||
import copy
|
||||
import re
|
||||
import os
|
||||
from .crackfortran import markoutercomma
|
||||
from . import cb_rules
|
||||
from ._isocbind import iso_c_binding_map, isoc_c2pycode_map, iso_c2py_map
|
||||
|
||||
# The environment provided by auxfuncs.py is needed for some calls to eval.
|
||||
# As the needed functions cannot be determined by static inspection of the
|
||||
# code, it is safest to use import * pending a major refactoring of f2py.
|
||||
from .auxfuncs import *
|
||||
|
||||
__all__ = [
|
||||
'getctype', 'getstrlength', 'getarrdims', 'getpydocsign',
|
||||
'getarrdocsign', 'getinit', 'sign2map', 'routsign2map', 'modsign2map',
|
||||
'cb_sign2map', 'cb_routsign2map', 'common_sign2map', 'process_f2cmap_dict'
|
||||
]
|
||||
|
||||
|
||||
depargs = []
|
||||
lcb_map = {}
|
||||
lcb2_map = {}
|
||||
# forced casting: mainly caused by the fact that Python or Numeric
|
||||
# C/APIs do not support the corresponding C types.
|
||||
c2py_map = {'double': 'float',
|
||||
'float': 'float', # forced casting
|
||||
'long_double': 'float', # forced casting
|
||||
'char': 'int', # forced casting
|
||||
'signed_char': 'int', # forced casting
|
||||
'unsigned_char': 'int', # forced casting
|
||||
'short': 'int', # forced casting
|
||||
'unsigned_short': 'int', # forced casting
|
||||
'int': 'int', # forced casting
|
||||
'long': 'int',
|
||||
'long_long': 'long',
|
||||
'unsigned': 'int', # forced casting
|
||||
'complex_float': 'complex', # forced casting
|
||||
'complex_double': 'complex',
|
||||
'complex_long_double': 'complex', # forced casting
|
||||
'string': 'string',
|
||||
'character': 'bytes',
|
||||
}
|
||||
|
||||
c2capi_map = {'double': 'NPY_DOUBLE',
|
||||
'float': 'NPY_FLOAT',
|
||||
'long_double': 'NPY_LONGDOUBLE',
|
||||
'char': 'NPY_BYTE',
|
||||
'unsigned_char': 'NPY_UBYTE',
|
||||
'signed_char': 'NPY_BYTE',
|
||||
'short': 'NPY_SHORT',
|
||||
'unsigned_short': 'NPY_USHORT',
|
||||
'int': 'NPY_INT',
|
||||
'unsigned': 'NPY_UINT',
|
||||
'long': 'NPY_LONG',
|
||||
'unsigned_long': 'NPY_ULONG',
|
||||
'long_long': 'NPY_LONGLONG',
|
||||
'unsigned_long_long': 'NPY_ULONGLONG',
|
||||
'complex_float': 'NPY_CFLOAT',
|
||||
'complex_double': 'NPY_CDOUBLE',
|
||||
'complex_long_double': 'NPY_CDOUBLE',
|
||||
'string': 'NPY_STRING',
|
||||
'character': 'NPY_STRING'}
|
||||
|
||||
c2pycode_map = {'double': 'd',
|
||||
'float': 'f',
|
||||
'long_double': 'g',
|
||||
'char': 'b',
|
||||
'unsigned_char': 'B',
|
||||
'signed_char': 'b',
|
||||
'short': 'h',
|
||||
'unsigned_short': 'H',
|
||||
'int': 'i',
|
||||
'unsigned': 'I',
|
||||
'long': 'l',
|
||||
'unsigned_long': 'L',
|
||||
'long_long': 'q',
|
||||
'unsigned_long_long': 'Q',
|
||||
'complex_float': 'F',
|
||||
'complex_double': 'D',
|
||||
'complex_long_double': 'G',
|
||||
'string': 'S',
|
||||
'character': 'c'}
|
||||
|
||||
# https://docs.python.org/3/c-api/arg.html#building-values
|
||||
c2buildvalue_map = {'double': 'd',
|
||||
'float': 'f',
|
||||
'char': 'b',
|
||||
'signed_char': 'b',
|
||||
'short': 'h',
|
||||
'int': 'i',
|
||||
'long': 'l',
|
||||
'long_long': 'L',
|
||||
'complex_float': 'N',
|
||||
'complex_double': 'N',
|
||||
'complex_long_double': 'N',
|
||||
'string': 'y',
|
||||
'character': 'c'}
|
||||
|
||||
f2cmap_all = {'real': {'': 'float', '4': 'float', '8': 'double',
|
||||
'12': 'long_double', '16': 'long_double'},
|
||||
'integer': {'': 'int', '1': 'signed_char', '2': 'short',
|
||||
'4': 'int', '8': 'long_long',
|
||||
'-1': 'unsigned_char', '-2': 'unsigned_short',
|
||||
'-4': 'unsigned', '-8': 'unsigned_long_long'},
|
||||
'complex': {'': 'complex_float', '8': 'complex_float',
|
||||
'16': 'complex_double', '24': 'complex_long_double',
|
||||
'32': 'complex_long_double'},
|
||||
'complexkind': {'': 'complex_float', '4': 'complex_float',
|
||||
'8': 'complex_double', '12': 'complex_long_double',
|
||||
'16': 'complex_long_double'},
|
||||
'logical': {'': 'int', '1': 'char', '2': 'short', '4': 'int',
|
||||
'8': 'long_long'},
|
||||
'double complex': {'': 'complex_double'},
|
||||
'double precision': {'': 'double'},
|
||||
'byte': {'': 'char'},
|
||||
}
|
||||
|
||||
# Add ISO_C handling
|
||||
c2pycode_map.update(isoc_c2pycode_map)
|
||||
c2py_map.update(iso_c2py_map)
|
||||
f2cmap_all, _ = process_f2cmap_dict(f2cmap_all, iso_c_binding_map, c2py_map)
|
||||
# End ISO_C handling
|
||||
f2cmap_default = copy.deepcopy(f2cmap_all)
|
||||
|
||||
f2cmap_mapped = []
|
||||
|
||||
def load_f2cmap_file(f2cmap_file):
|
||||
global f2cmap_all, f2cmap_mapped
|
||||
|
||||
f2cmap_all = copy.deepcopy(f2cmap_default)
|
||||
|
||||
if f2cmap_file is None:
|
||||
# Default value
|
||||
f2cmap_file = '.f2py_f2cmap'
|
||||
if not os.path.isfile(f2cmap_file):
|
||||
return
|
||||
|
||||
# User defined additions to f2cmap_all.
|
||||
# f2cmap_file must contain a dictionary of dictionaries, only. For
|
||||
# example, {'real':{'low':'float'}} means that Fortran 'real(low)' is
|
||||
# interpreted as C 'float'. This feature is useful for F90/95 users if
|
||||
# they use PARAMETERS in type specifications.
|
||||
try:
|
||||
outmess('Reading f2cmap from {!r} ...\n'.format(f2cmap_file))
|
||||
with open(f2cmap_file) as f:
|
||||
d = eval(f.read().lower(), {}, {})
|
||||
f2cmap_all, f2cmap_mapped = process_f2cmap_dict(f2cmap_all, d, c2py_map, True)
|
||||
outmess('Successfully applied user defined f2cmap changes\n')
|
||||
except Exception as msg:
|
||||
errmess('Failed to apply user defined f2cmap changes: %s. Skipping.\n' % (msg))
|
||||
|
||||
|
||||
cformat_map = {'double': '%g',
|
||||
'float': '%g',
|
||||
'long_double': '%Lg',
|
||||
'char': '%d',
|
||||
'signed_char': '%d',
|
||||
'unsigned_char': '%hhu',
|
||||
'short': '%hd',
|
||||
'unsigned_short': '%hu',
|
||||
'int': '%d',
|
||||
'unsigned': '%u',
|
||||
'long': '%ld',
|
||||
'unsigned_long': '%lu',
|
||||
'long_long': '%ld',
|
||||
'complex_float': '(%g,%g)',
|
||||
'complex_double': '(%g,%g)',
|
||||
'complex_long_double': '(%Lg,%Lg)',
|
||||
'string': '\\"%s\\"',
|
||||
'character': "'%c'",
|
||||
}
|
||||
|
||||
# Auxiliary functions
|
||||
|
||||
|
||||
def getctype(var):
|
||||
"""
|
||||
Determines C type
|
||||
"""
|
||||
ctype = 'void'
|
||||
if isfunction(var):
|
||||
if 'result' in var:
|
||||
a = var['result']
|
||||
else:
|
||||
a = var['name']
|
||||
if a in var['vars']:
|
||||
return getctype(var['vars'][a])
|
||||
else:
|
||||
errmess('getctype: function %s has no return value?!\n' % a)
|
||||
elif issubroutine(var):
|
||||
return ctype
|
||||
elif ischaracter_or_characterarray(var):
|
||||
return 'character'
|
||||
elif isstring_or_stringarray(var):
|
||||
return 'string'
|
||||
elif 'typespec' in var and var['typespec'].lower() in f2cmap_all:
|
||||
typespec = var['typespec'].lower()
|
||||
f2cmap = f2cmap_all[typespec]
|
||||
ctype = f2cmap[''] # default type
|
||||
if 'kindselector' in var:
|
||||
if '*' in var['kindselector']:
|
||||
try:
|
||||
ctype = f2cmap[var['kindselector']['*']]
|
||||
except KeyError:
|
||||
errmess('getctype: "%s %s %s" not supported.\n' %
|
||||
(var['typespec'], '*', var['kindselector']['*']))
|
||||
elif 'kind' in var['kindselector']:
|
||||
if typespec + 'kind' in f2cmap_all:
|
||||
f2cmap = f2cmap_all[typespec + 'kind']
|
||||
try:
|
||||
ctype = f2cmap[var['kindselector']['kind']]
|
||||
except KeyError:
|
||||
if typespec in f2cmap_all:
|
||||
f2cmap = f2cmap_all[typespec]
|
||||
try:
|
||||
ctype = f2cmap[str(var['kindselector']['kind'])]
|
||||
except KeyError:
|
||||
errmess('getctype: "%s(kind=%s)" is mapped to C "%s" (to override define dict(%s = dict(%s="<C typespec>")) in %s/.f2py_f2cmap file).\n'
|
||||
% (typespec, var['kindselector']['kind'], ctype,
|
||||
typespec, var['kindselector']['kind'], os.getcwd()))
|
||||
else:
|
||||
if not isexternal(var):
|
||||
errmess('getctype: No C-type found in "%s", assuming void.\n' % var)
|
||||
return ctype
|
||||
|
||||
|
||||
def f2cexpr(expr):
|
||||
"""Rewrite Fortran expression as f2py supported C expression.
|
||||
|
||||
Due to the lack of a proper expression parser in f2py, this
|
||||
function uses a heuristic approach that assumes that Fortran
|
||||
arithmetic expressions are valid C arithmetic expressions when
|
||||
mapping Fortran function calls to the corresponding C function/CPP
|
||||
macros calls.
|
||||
|
||||
"""
|
||||
# TODO: support Fortran `len` function with optional kind parameter
|
||||
expr = re.sub(r'\blen\b', 'f2py_slen', expr)
|
||||
return expr
|
||||
|
||||
|
||||
def getstrlength(var):
|
||||
if isstringfunction(var):
|
||||
if 'result' in var:
|
||||
a = var['result']
|
||||
else:
|
||||
a = var['name']
|
||||
if a in var['vars']:
|
||||
return getstrlength(var['vars'][a])
|
||||
else:
|
||||
errmess('getstrlength: function %s has no return value?!\n' % a)
|
||||
if not isstring(var):
|
||||
errmess(
|
||||
'getstrlength: expected a signature of a string but got: %s\n' % (repr(var)))
|
||||
len = '1'
|
||||
if 'charselector' in var:
|
||||
a = var['charselector']
|
||||
if '*' in a:
|
||||
len = a['*']
|
||||
elif 'len' in a:
|
||||
len = f2cexpr(a['len'])
|
||||
if re.match(r'\(\s*(\*|:)\s*\)', len) or re.match(r'(\*|:)', len):
|
||||
if isintent_hide(var):
|
||||
errmess('getstrlength:intent(hide): expected a string with defined length but got: %s\n' % (
|
||||
repr(var)))
|
||||
len = '-1'
|
||||
return len
|
||||
|
||||
|
||||
def getarrdims(a, var, verbose=0):
|
||||
ret = {}
|
||||
if isstring(var) and not isarray(var):
|
||||
ret['size'] = getstrlength(var)
|
||||
ret['rank'] = '0'
|
||||
ret['dims'] = ''
|
||||
elif isscalar(var):
|
||||
ret['size'] = '1'
|
||||
ret['rank'] = '0'
|
||||
ret['dims'] = ''
|
||||
elif isarray(var):
|
||||
dim = copy.copy(var['dimension'])
|
||||
ret['size'] = '*'.join(dim)
|
||||
try:
|
||||
ret['size'] = repr(eval(ret['size']))
|
||||
except Exception:
|
||||
pass
|
||||
ret['dims'] = ','.join(dim)
|
||||
ret['rank'] = repr(len(dim))
|
||||
ret['rank*[-1]'] = repr(len(dim) * [-1])[1:-1]
|
||||
for i in range(len(dim)): # solve dim for dependencies
|
||||
v = []
|
||||
if dim[i] in depargs:
|
||||
v = [dim[i]]
|
||||
else:
|
||||
for va in depargs:
|
||||
if re.match(r'.*?\b%s\b.*' % va, dim[i]):
|
||||
v.append(va)
|
||||
for va in v:
|
||||
if depargs.index(va) > depargs.index(a):
|
||||
dim[i] = '*'
|
||||
break
|
||||
ret['setdims'], i = '', -1
|
||||
for d in dim:
|
||||
i = i + 1
|
||||
if d not in ['*', ':', '(*)', '(:)']:
|
||||
ret['setdims'] = '%s#varname#_Dims[%d]=%s,' % (
|
||||
ret['setdims'], i, d)
|
||||
if ret['setdims']:
|
||||
ret['setdims'] = ret['setdims'][:-1]
|
||||
ret['cbsetdims'], i = '', -1
|
||||
for d in var['dimension']:
|
||||
i = i + 1
|
||||
if d not in ['*', ':', '(*)', '(:)']:
|
||||
ret['cbsetdims'] = '%s#varname#_Dims[%d]=%s,' % (
|
||||
ret['cbsetdims'], i, d)
|
||||
elif isintent_in(var):
|
||||
outmess('getarrdims:warning: assumed shape array, using 0 instead of %r\n'
|
||||
% (d))
|
||||
ret['cbsetdims'] = '%s#varname#_Dims[%d]=%s,' % (
|
||||
ret['cbsetdims'], i, 0)
|
||||
elif verbose:
|
||||
errmess(
|
||||
'getarrdims: If in call-back function: array argument %s must have bounded dimensions: got %s\n' % (repr(a), repr(d)))
|
||||
if ret['cbsetdims']:
|
||||
ret['cbsetdims'] = ret['cbsetdims'][:-1]
|
||||
# if not isintent_c(var):
|
||||
# var['dimension'].reverse()
|
||||
return ret
|
||||
|
||||
|
||||
def getpydocsign(a, var):
|
||||
global lcb_map
|
||||
if isfunction(var):
|
||||
if 'result' in var:
|
||||
af = var['result']
|
||||
else:
|
||||
af = var['name']
|
||||
if af in var['vars']:
|
||||
return getpydocsign(af, var['vars'][af])
|
||||
else:
|
||||
errmess('getctype: function %s has no return value?!\n' % af)
|
||||
return '', ''
|
||||
sig, sigout = a, a
|
||||
opt = ''
|
||||
if isintent_in(var):
|
||||
opt = 'input'
|
||||
elif isintent_inout(var):
|
||||
opt = 'in/output'
|
||||
out_a = a
|
||||
if isintent_out(var):
|
||||
for k in var['intent']:
|
||||
if k[:4] == 'out=':
|
||||
out_a = k[4:]
|
||||
break
|
||||
init = ''
|
||||
ctype = getctype(var)
|
||||
|
||||
if hasinitvalue(var):
|
||||
init, showinit = getinit(a, var)
|
||||
init = ', optional\\n Default: %s' % showinit
|
||||
if isscalar(var):
|
||||
if isintent_inout(var):
|
||||
sig = '%s : %s rank-0 array(%s,\'%s\')%s' % (a, opt, c2py_map[ctype],
|
||||
c2pycode_map[ctype], init)
|
||||
else:
|
||||
sig = '%s : %s %s%s' % (a, opt, c2py_map[ctype], init)
|
||||
sigout = '%s : %s' % (out_a, c2py_map[ctype])
|
||||
elif isstring(var):
|
||||
if isintent_inout(var):
|
||||
sig = '%s : %s rank-0 array(string(len=%s),\'c\')%s' % (
|
||||
a, opt, getstrlength(var), init)
|
||||
else:
|
||||
sig = '%s : %s string(len=%s)%s' % (
|
||||
a, opt, getstrlength(var), init)
|
||||
sigout = '%s : string(len=%s)' % (out_a, getstrlength(var))
|
||||
elif isarray(var):
|
||||
dim = var['dimension']
|
||||
rank = repr(len(dim))
|
||||
sig = '%s : %s rank-%s array(\'%s\') with bounds (%s)%s' % (a, opt, rank,
|
||||
c2pycode_map[
|
||||
ctype],
|
||||
','.join(dim), init)
|
||||
if a == out_a:
|
||||
sigout = '%s : rank-%s array(\'%s\') with bounds (%s)'\
|
||||
% (a, rank, c2pycode_map[ctype], ','.join(dim))
|
||||
else:
|
||||
sigout = '%s : rank-%s array(\'%s\') with bounds (%s) and %s storage'\
|
||||
% (out_a, rank, c2pycode_map[ctype], ','.join(dim), a)
|
||||
elif isexternal(var):
|
||||
ua = ''
|
||||
if a in lcb_map and lcb_map[a] in lcb2_map and 'argname' in lcb2_map[lcb_map[a]]:
|
||||
ua = lcb2_map[lcb_map[a]]['argname']
|
||||
if not ua == a:
|
||||
ua = ' => %s' % ua
|
||||
else:
|
||||
ua = ''
|
||||
sig = '%s : call-back function%s' % (a, ua)
|
||||
sigout = sig
|
||||
else:
|
||||
errmess(
|
||||
'getpydocsign: Could not resolve docsignature for "%s".\n' % a)
|
||||
return sig, sigout
|
||||
|
||||
|
||||
def getarrdocsign(a, var):
|
||||
ctype = getctype(var)
|
||||
if isstring(var) and (not isarray(var)):
|
||||
sig = '%s : rank-0 array(string(len=%s),\'c\')' % (a,
|
||||
getstrlength(var))
|
||||
elif isscalar(var):
|
||||
sig = '%s : rank-0 array(%s,\'%s\')' % (a, c2py_map[ctype],
|
||||
c2pycode_map[ctype],)
|
||||
elif isarray(var):
|
||||
dim = var['dimension']
|
||||
rank = repr(len(dim))
|
||||
sig = '%s : rank-%s array(\'%s\') with bounds (%s)' % (a, rank,
|
||||
c2pycode_map[
|
||||
ctype],
|
||||
','.join(dim))
|
||||
return sig
|
||||
|
||||
|
||||
def getinit(a, var):
|
||||
if isstring(var):
|
||||
init, showinit = '""', "''"
|
||||
else:
|
||||
init, showinit = '', ''
|
||||
if hasinitvalue(var):
|
||||
init = var['=']
|
||||
showinit = init
|
||||
if iscomplex(var) or iscomplexarray(var):
|
||||
ret = {}
|
||||
|
||||
try:
|
||||
v = var["="]
|
||||
if ',' in v:
|
||||
ret['init.r'], ret['init.i'] = markoutercomma(
|
||||
v[1:-1]).split('@,@')
|
||||
else:
|
||||
v = eval(v, {}, {})
|
||||
ret['init.r'], ret['init.i'] = str(v.real), str(v.imag)
|
||||
except Exception:
|
||||
raise ValueError(
|
||||
'getinit: expected complex number `(r,i)\' but got `%s\' as initial value of %r.' % (init, a))
|
||||
if isarray(var):
|
||||
init = '(capi_c.r=%s,capi_c.i=%s,capi_c)' % (
|
||||
ret['init.r'], ret['init.i'])
|
||||
elif isstring(var):
|
||||
if not init:
|
||||
init, showinit = '""', "''"
|
||||
if init[0] == "'":
|
||||
init = '"%s"' % (init[1:-1].replace('"', '\\"'))
|
||||
if init[0] == '"':
|
||||
showinit = "'%s'" % (init[1:-1])
|
||||
return init, showinit
|
||||
|
||||
|
||||
def get_elsize(var):
|
||||
if isstring(var) or isstringarray(var):
|
||||
elsize = getstrlength(var)
|
||||
# override with user-specified length when available:
|
||||
elsize = var['charselector'].get('f2py_len', elsize)
|
||||
return elsize
|
||||
if ischaracter(var) or ischaracterarray(var):
|
||||
return '1'
|
||||
# for numerical types, PyArray_New* functions ignore specified
|
||||
# elsize, so we just return 1 and let elsize be determined at
|
||||
# runtime, see fortranobject.c
|
||||
return '1'
|
||||
|
||||
|
||||
def sign2map(a, var):
|
||||
"""
|
||||
varname,ctype,atype
|
||||
init,init.r,init.i,pytype
|
||||
vardebuginfo,vardebugshowvalue,varshowvalue
|
||||
varrformat
|
||||
|
||||
intent
|
||||
"""
|
||||
out_a = a
|
||||
if isintent_out(var):
|
||||
for k in var['intent']:
|
||||
if k[:4] == 'out=':
|
||||
out_a = k[4:]
|
||||
break
|
||||
ret = {'varname': a, 'outvarname': out_a, 'ctype': getctype(var)}
|
||||
intent_flags = []
|
||||
for f, s in isintent_dict.items():
|
||||
if f(var):
|
||||
intent_flags.append('F2PY_%s' % s)
|
||||
if intent_flags:
|
||||
# TODO: Evaluate intent_flags here.
|
||||
ret['intent'] = '|'.join(intent_flags)
|
||||
else:
|
||||
ret['intent'] = 'F2PY_INTENT_IN'
|
||||
if isarray(var):
|
||||
ret['varrformat'] = 'N'
|
||||
elif ret['ctype'] in c2buildvalue_map:
|
||||
ret['varrformat'] = c2buildvalue_map[ret['ctype']]
|
||||
else:
|
||||
ret['varrformat'] = 'O'
|
||||
ret['init'], ret['showinit'] = getinit(a, var)
|
||||
if hasinitvalue(var) and iscomplex(var) and not isarray(var):
|
||||
ret['init.r'], ret['init.i'] = markoutercomma(
|
||||
ret['init'][1:-1]).split('@,@')
|
||||
if isexternal(var):
|
||||
ret['cbnamekey'] = a
|
||||
if a in lcb_map:
|
||||
ret['cbname'] = lcb_map[a]
|
||||
ret['maxnofargs'] = lcb2_map[lcb_map[a]]['maxnofargs']
|
||||
ret['nofoptargs'] = lcb2_map[lcb_map[a]]['nofoptargs']
|
||||
ret['cbdocstr'] = lcb2_map[lcb_map[a]]['docstr']
|
||||
ret['cblatexdocstr'] = lcb2_map[lcb_map[a]]['latexdocstr']
|
||||
else:
|
||||
ret['cbname'] = a
|
||||
errmess('sign2map: Confused: external %s is not in lcb_map%s.\n' % (
|
||||
a, list(lcb_map.keys())))
|
||||
if isstring(var):
|
||||
ret['length'] = getstrlength(var)
|
||||
if isarray(var):
|
||||
ret = dictappend(ret, getarrdims(a, var))
|
||||
dim = copy.copy(var['dimension'])
|
||||
if ret['ctype'] in c2capi_map:
|
||||
ret['atype'] = c2capi_map[ret['ctype']]
|
||||
ret['elsize'] = get_elsize(var)
|
||||
# Debug info
|
||||
if debugcapi(var):
|
||||
il = [isintent_in, 'input', isintent_out, 'output',
|
||||
isintent_inout, 'inoutput', isrequired, 'required',
|
||||
isoptional, 'optional', isintent_hide, 'hidden',
|
||||
iscomplex, 'complex scalar',
|
||||
l_and(isscalar, l_not(iscomplex)), 'scalar',
|
||||
isstring, 'string', isarray, 'array',
|
||||
iscomplexarray, 'complex array', isstringarray, 'string array',
|
||||
iscomplexfunction, 'complex function',
|
||||
l_and(isfunction, l_not(iscomplexfunction)), 'function',
|
||||
isexternal, 'callback',
|
||||
isintent_callback, 'callback',
|
||||
isintent_aux, 'auxiliary',
|
||||
]
|
||||
rl = []
|
||||
for i in range(0, len(il), 2):
|
||||
if il[i](var):
|
||||
rl.append(il[i + 1])
|
||||
if isstring(var):
|
||||
rl.append('slen(%s)=%s' % (a, ret['length']))
|
||||
if isarray(var):
|
||||
ddim = ','.join(
|
||||
map(lambda x, y: '%s|%s' % (x, y), var['dimension'], dim))
|
||||
rl.append('dims(%s)' % ddim)
|
||||
if isexternal(var):
|
||||
ret['vardebuginfo'] = 'debug-capi:%s=>%s:%s' % (
|
||||
a, ret['cbname'], ','.join(rl))
|
||||
else:
|
||||
ret['vardebuginfo'] = 'debug-capi:%s %s=%s:%s' % (
|
||||
ret['ctype'], a, ret['showinit'], ','.join(rl))
|
||||
if isscalar(var):
|
||||
if ret['ctype'] in cformat_map:
|
||||
ret['vardebugshowvalue'] = 'debug-capi:%s=%s' % (
|
||||
a, cformat_map[ret['ctype']])
|
||||
if isstring(var):
|
||||
ret['vardebugshowvalue'] = 'debug-capi:slen(%s)=%%d %s=\\"%%s\\"' % (
|
||||
a, a)
|
||||
if isexternal(var):
|
||||
ret['vardebugshowvalue'] = 'debug-capi:%s=%%p' % (a)
|
||||
if ret['ctype'] in cformat_map:
|
||||
ret['varshowvalue'] = '#name#:%s=%s' % (a, cformat_map[ret['ctype']])
|
||||
ret['showvalueformat'] = '%s' % (cformat_map[ret['ctype']])
|
||||
if isstring(var):
|
||||
ret['varshowvalue'] = '#name#:slen(%s)=%%d %s=\\"%%s\\"' % (a, a)
|
||||
ret['pydocsign'], ret['pydocsignout'] = getpydocsign(a, var)
|
||||
if hasnote(var):
|
||||
ret['note'] = var['note']
|
||||
return ret
|
||||
|
||||
|
||||
def routsign2map(rout):
|
||||
"""
|
||||
name,NAME,begintitle,endtitle
|
||||
rname,ctype,rformat
|
||||
routdebugshowvalue
|
||||
"""
|
||||
global lcb_map
|
||||
name = rout['name']
|
||||
fname = getfortranname(rout)
|
||||
ret = {'name': name,
|
||||
'texname': name.replace('_', '\\_'),
|
||||
'name_lower': name.lower(),
|
||||
'NAME': name.upper(),
|
||||
'begintitle': gentitle(name),
|
||||
'endtitle': gentitle('end of %s' % name),
|
||||
'fortranname': fname,
|
||||
'FORTRANNAME': fname.upper(),
|
||||
'callstatement': getcallstatement(rout) or '',
|
||||
'usercode': getusercode(rout) or '',
|
||||
'usercode1': getusercode1(rout) or '',
|
||||
}
|
||||
if '_' in fname:
|
||||
ret['F_FUNC'] = 'F_FUNC_US'
|
||||
else:
|
||||
ret['F_FUNC'] = 'F_FUNC'
|
||||
if '_' in name:
|
||||
ret['F_WRAPPEDFUNC'] = 'F_WRAPPEDFUNC_US'
|
||||
else:
|
||||
ret['F_WRAPPEDFUNC'] = 'F_WRAPPEDFUNC'
|
||||
lcb_map = {}
|
||||
if 'use' in rout:
|
||||
for u in rout['use'].keys():
|
||||
if u in cb_rules.cb_map:
|
||||
for un in cb_rules.cb_map[u]:
|
||||
ln = un[0]
|
||||
if 'map' in rout['use'][u]:
|
||||
for k in rout['use'][u]['map'].keys():
|
||||
if rout['use'][u]['map'][k] == un[0]:
|
||||
ln = k
|
||||
break
|
||||
lcb_map[ln] = un[1]
|
||||
elif 'externals' in rout and rout['externals']:
|
||||
errmess('routsign2map: Confused: function %s has externals %s but no "use" statement.\n' % (
|
||||
ret['name'], repr(rout['externals'])))
|
||||
ret['callprotoargument'] = getcallprotoargument(rout, lcb_map) or ''
|
||||
if isfunction(rout):
|
||||
if 'result' in rout:
|
||||
a = rout['result']
|
||||
else:
|
||||
a = rout['name']
|
||||
ret['rname'] = a
|
||||
ret['pydocsign'], ret['pydocsignout'] = getpydocsign(a, rout)
|
||||
ret['ctype'] = getctype(rout['vars'][a])
|
||||
if hasresultnote(rout):
|
||||
ret['resultnote'] = rout['vars'][a]['note']
|
||||
rout['vars'][a]['note'] = ['See elsewhere.']
|
||||
if ret['ctype'] in c2buildvalue_map:
|
||||
ret['rformat'] = c2buildvalue_map[ret['ctype']]
|
||||
else:
|
||||
ret['rformat'] = 'O'
|
||||
errmess('routsign2map: no c2buildvalue key for type %s\n' %
|
||||
(repr(ret['ctype'])))
|
||||
if debugcapi(rout):
|
||||
if ret['ctype'] in cformat_map:
|
||||
ret['routdebugshowvalue'] = 'debug-capi:%s=%s' % (
|
||||
a, cformat_map[ret['ctype']])
|
||||
if isstringfunction(rout):
|
||||
ret['routdebugshowvalue'] = 'debug-capi:slen(%s)=%%d %s=\\"%%s\\"' % (
|
||||
a, a)
|
||||
if isstringfunction(rout):
|
||||
ret['rlength'] = getstrlength(rout['vars'][a])
|
||||
if ret['rlength'] == '-1':
|
||||
errmess('routsign2map: expected explicit specification of the length of the string returned by the fortran function %s; taking 10.\n' % (
|
||||
repr(rout['name'])))
|
||||
ret['rlength'] = '10'
|
||||
if hasnote(rout):
|
||||
ret['note'] = rout['note']
|
||||
rout['note'] = ['See elsewhere.']
|
||||
return ret
|
||||
|
||||
|
||||
def modsign2map(m):
|
||||
"""
|
||||
modulename
|
||||
"""
|
||||
if ismodule(m):
|
||||
ret = {'f90modulename': m['name'],
|
||||
'F90MODULENAME': m['name'].upper(),
|
||||
'texf90modulename': m['name'].replace('_', '\\_')}
|
||||
else:
|
||||
ret = {'modulename': m['name'],
|
||||
'MODULENAME': m['name'].upper(),
|
||||
'texmodulename': m['name'].replace('_', '\\_')}
|
||||
ret['restdoc'] = getrestdoc(m) or []
|
||||
if hasnote(m):
|
||||
ret['note'] = m['note']
|
||||
ret['usercode'] = getusercode(m) or ''
|
||||
ret['usercode1'] = getusercode1(m) or ''
|
||||
if m['body']:
|
||||
ret['interface_usercode'] = getusercode(m['body'][0]) or ''
|
||||
else:
|
||||
ret['interface_usercode'] = ''
|
||||
ret['pymethoddef'] = getpymethoddef(m) or ''
|
||||
if 'gil_used' in m:
|
||||
ret['gil_used'] = m['gil_used']
|
||||
if 'coutput' in m:
|
||||
ret['coutput'] = m['coutput']
|
||||
if 'f2py_wrapper_output' in m:
|
||||
ret['f2py_wrapper_output'] = m['f2py_wrapper_output']
|
||||
return ret
|
||||
|
||||
|
||||
def cb_sign2map(a, var, index=None):
|
||||
ret = {'varname': a}
|
||||
ret['varname_i'] = ret['varname']
|
||||
ret['ctype'] = getctype(var)
|
||||
if ret['ctype'] in c2capi_map:
|
||||
ret['atype'] = c2capi_map[ret['ctype']]
|
||||
ret['elsize'] = get_elsize(var)
|
||||
if ret['ctype'] in cformat_map:
|
||||
ret['showvalueformat'] = '%s' % (cformat_map[ret['ctype']])
|
||||
if isarray(var):
|
||||
ret = dictappend(ret, getarrdims(a, var))
|
||||
ret['pydocsign'], ret['pydocsignout'] = getpydocsign(a, var)
|
||||
if hasnote(var):
|
||||
ret['note'] = var['note']
|
||||
var['note'] = ['See elsewhere.']
|
||||
return ret
|
||||
|
||||
|
||||
def cb_routsign2map(rout, um):
|
||||
"""
|
||||
name,begintitle,endtitle,argname
|
||||
ctype,rctype,maxnofargs,nofoptargs,returncptr
|
||||
"""
|
||||
ret = {'name': 'cb_%s_in_%s' % (rout['name'], um),
|
||||
'returncptr': ''}
|
||||
if isintent_callback(rout):
|
||||
if '_' in rout['name']:
|
||||
F_FUNC = 'F_FUNC_US'
|
||||
else:
|
||||
F_FUNC = 'F_FUNC'
|
||||
ret['callbackname'] = '%s(%s,%s)' \
|
||||
% (F_FUNC,
|
||||
rout['name'].lower(),
|
||||
rout['name'].upper(),
|
||||
)
|
||||
ret['static'] = 'extern'
|
||||
else:
|
||||
ret['callbackname'] = ret['name']
|
||||
ret['static'] = 'static'
|
||||
ret['argname'] = rout['name']
|
||||
ret['begintitle'] = gentitle(ret['name'])
|
||||
ret['endtitle'] = gentitle('end of %s' % ret['name'])
|
||||
ret['ctype'] = getctype(rout)
|
||||
ret['rctype'] = 'void'
|
||||
if ret['ctype'] == 'string':
|
||||
ret['rctype'] = 'void'
|
||||
else:
|
||||
ret['rctype'] = ret['ctype']
|
||||
if ret['rctype'] != 'void':
|
||||
if iscomplexfunction(rout):
|
||||
ret['returncptr'] = """
|
||||
#ifdef F2PY_CB_RETURNCOMPLEX
|
||||
return_value=
|
||||
#endif
|
||||
"""
|
||||
else:
|
||||
ret['returncptr'] = 'return_value='
|
||||
if ret['ctype'] in cformat_map:
|
||||
ret['showvalueformat'] = '%s' % (cformat_map[ret['ctype']])
|
||||
if isstringfunction(rout):
|
||||
ret['strlength'] = getstrlength(rout)
|
||||
if isfunction(rout):
|
||||
if 'result' in rout:
|
||||
a = rout['result']
|
||||
else:
|
||||
a = rout['name']
|
||||
if hasnote(rout['vars'][a]):
|
||||
ret['note'] = rout['vars'][a]['note']
|
||||
rout['vars'][a]['note'] = ['See elsewhere.']
|
||||
ret['rname'] = a
|
||||
ret['pydocsign'], ret['pydocsignout'] = getpydocsign(a, rout)
|
||||
if iscomplexfunction(rout):
|
||||
ret['rctype'] = """
|
||||
#ifdef F2PY_CB_RETURNCOMPLEX
|
||||
#ctype#
|
||||
#else
|
||||
void
|
||||
#endif
|
||||
"""
|
||||
else:
|
||||
if hasnote(rout):
|
||||
ret['note'] = rout['note']
|
||||
rout['note'] = ['See elsewhere.']
|
||||
nofargs = 0
|
||||
nofoptargs = 0
|
||||
if 'args' in rout and 'vars' in rout:
|
||||
for a in rout['args']:
|
||||
var = rout['vars'][a]
|
||||
if l_or(isintent_in, isintent_inout)(var):
|
||||
nofargs = nofargs + 1
|
||||
if isoptional(var):
|
||||
nofoptargs = nofoptargs + 1
|
||||
ret['maxnofargs'] = repr(nofargs)
|
||||
ret['nofoptargs'] = repr(nofoptargs)
|
||||
if hasnote(rout) and isfunction(rout) and 'result' in rout:
|
||||
ret['routnote'] = rout['note']
|
||||
rout['note'] = ['See elsewhere.']
|
||||
return ret
|
||||
|
||||
|
||||
def common_sign2map(a, var): # obsolute
|
||||
ret = {'varname': a, 'ctype': getctype(var)}
|
||||
if isstringarray(var):
|
||||
ret['ctype'] = 'char'
|
||||
if ret['ctype'] in c2capi_map:
|
||||
ret['atype'] = c2capi_map[ret['ctype']]
|
||||
ret['elsize'] = get_elsize(var)
|
||||
if ret['ctype'] in cformat_map:
|
||||
ret['showvalueformat'] = '%s' % (cformat_map[ret['ctype']])
|
||||
if isarray(var):
|
||||
ret = dictappend(ret, getarrdims(a, var))
|
||||
elif isstring(var):
|
||||
ret['size'] = getstrlength(var)
|
||||
ret['rank'] = '1'
|
||||
ret['pydocsign'], ret['pydocsignout'] = getpydocsign(a, var)
|
||||
if hasnote(var):
|
||||
ret['note'] = var['note']
|
||||
var['note'] = ['See elsewhere.']
|
||||
# for strings this returns 0-rank but actually is 1-rank
|
||||
ret['arrdocstr'] = getarrdocsign(a, var)
|
||||
return ret
|
644
venv/lib/python3.12/site-packages/numpy/f2py/cb_rules.py
Normal file
644
venv/lib/python3.12/site-packages/numpy/f2py/cb_rules.py
Normal file
@ -0,0 +1,644 @@
|
||||
"""
|
||||
Build call-back mechanism for f2py2e.
|
||||
|
||||
Copyright 1999 -- 2011 Pearu Peterson all rights reserved.
|
||||
Copyright 2011 -- present NumPy Developers.
|
||||
Permission to use, modify, and distribute this software is given under the
|
||||
terms of the NumPy License.
|
||||
|
||||
NO WARRANTY IS EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
|
||||
"""
|
||||
from . import __version__
|
||||
from .auxfuncs import (
|
||||
applyrules, debugcapi, dictappend, errmess, getargs, hasnote, isarray,
|
||||
iscomplex, iscomplexarray, iscomplexfunction, isfunction, isintent_c,
|
||||
isintent_hide, isintent_in, isintent_inout, isintent_nothide,
|
||||
isintent_out, isoptional, isrequired, isscalar, isstring,
|
||||
isstringfunction, issubroutine, l_and, l_not, l_or, outmess, replace,
|
||||
stripcomma, throw_error
|
||||
)
|
||||
from . import cfuncs
|
||||
|
||||
f2py_version = __version__.version
|
||||
|
||||
|
||||
################## Rules for callback function ##############
|
||||
|
||||
cb_routine_rules = {
|
||||
'cbtypedefs': 'typedef #rctype#(*#name#_typedef)(#optargs_td##args_td##strarglens_td##noargs#);',
|
||||
'body': """
|
||||
#begintitle#
|
||||
typedef struct {
|
||||
PyObject *capi;
|
||||
PyTupleObject *args_capi;
|
||||
int nofargs;
|
||||
jmp_buf jmpbuf;
|
||||
} #name#_t;
|
||||
|
||||
#if defined(F2PY_THREAD_LOCAL_DECL) && !defined(F2PY_USE_PYTHON_TLS)
|
||||
|
||||
static F2PY_THREAD_LOCAL_DECL #name#_t *_active_#name# = NULL;
|
||||
|
||||
static #name#_t *swap_active_#name#(#name#_t *ptr) {
|
||||
#name#_t *prev = _active_#name#;
|
||||
_active_#name# = ptr;
|
||||
return prev;
|
||||
}
|
||||
|
||||
static #name#_t *get_active_#name#(void) {
|
||||
return _active_#name#;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static #name#_t *swap_active_#name#(#name#_t *ptr) {
|
||||
char *key = "__f2py_cb_#name#";
|
||||
return (#name#_t *)F2PySwapThreadLocalCallbackPtr(key, ptr);
|
||||
}
|
||||
|
||||
static #name#_t *get_active_#name#(void) {
|
||||
char *key = "__f2py_cb_#name#";
|
||||
return (#name#_t *)F2PyGetThreadLocalCallbackPtr(key);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/*typedef #rctype#(*#name#_typedef)(#optargs_td##args_td##strarglens_td##noargs#);*/
|
||||
#static# #rctype# #callbackname# (#optargs##args##strarglens##noargs#) {
|
||||
#name#_t cb_local = { NULL, NULL, 0 };
|
||||
#name#_t *cb = NULL;
|
||||
PyTupleObject *capi_arglist = NULL;
|
||||
PyObject *capi_return = NULL;
|
||||
PyObject *capi_tmp = NULL;
|
||||
PyObject *capi_arglist_list = NULL;
|
||||
int capi_j,capi_i = 0;
|
||||
int capi_longjmp_ok = 1;
|
||||
#decl#
|
||||
#ifdef F2PY_REPORT_ATEXIT
|
||||
f2py_cb_start_clock();
|
||||
#endif
|
||||
cb = get_active_#name#();
|
||||
if (cb == NULL) {
|
||||
capi_longjmp_ok = 0;
|
||||
cb = &cb_local;
|
||||
}
|
||||
capi_arglist = cb->args_capi;
|
||||
CFUNCSMESS(\"cb:Call-back function #name# (maxnofargs=#maxnofargs#(-#nofoptargs#))\\n\");
|
||||
CFUNCSMESSPY(\"cb:#name#_capi=\",cb->capi);
|
||||
if (cb->capi==NULL) {
|
||||
capi_longjmp_ok = 0;
|
||||
cb->capi = PyObject_GetAttrString(#modulename#_module,\"#argname#\");
|
||||
CFUNCSMESSPY(\"cb:#name#_capi=\",cb->capi);
|
||||
}
|
||||
if (cb->capi==NULL) {
|
||||
PyErr_SetString(#modulename#_error,\"cb: Callback #argname# not defined (as an argument or module #modulename# attribute).\\n\");
|
||||
goto capi_fail;
|
||||
}
|
||||
if (F2PyCapsule_Check(cb->capi)) {
|
||||
#name#_typedef #name#_cptr;
|
||||
#name#_cptr = F2PyCapsule_AsVoidPtr(cb->capi);
|
||||
#returncptr#(*#name#_cptr)(#optargs_nm##args_nm##strarglens_nm#);
|
||||
#return#
|
||||
}
|
||||
if (capi_arglist==NULL) {
|
||||
capi_longjmp_ok = 0;
|
||||
capi_tmp = PyObject_GetAttrString(#modulename#_module,\"#argname#_extra_args\");
|
||||
if (capi_tmp) {
|
||||
capi_arglist = (PyTupleObject *)PySequence_Tuple(capi_tmp);
|
||||
Py_DECREF(capi_tmp);
|
||||
if (capi_arglist==NULL) {
|
||||
PyErr_SetString(#modulename#_error,\"Failed to convert #modulename#.#argname#_extra_args to tuple.\\n\");
|
||||
goto capi_fail;
|
||||
}
|
||||
} else {
|
||||
PyErr_Clear();
|
||||
capi_arglist = (PyTupleObject *)Py_BuildValue(\"()\");
|
||||
}
|
||||
}
|
||||
if (capi_arglist == NULL) {
|
||||
PyErr_SetString(#modulename#_error,\"Callback #argname# argument list is not set.\\n\");
|
||||
goto capi_fail;
|
||||
}
|
||||
#setdims#
|
||||
#ifdef PYPY_VERSION
|
||||
#define CAPI_ARGLIST_SETITEM(idx, value) PyList_SetItem((PyObject *)capi_arglist_list, idx, value)
|
||||
capi_arglist_list = PySequence_List((PyObject *)capi_arglist);
|
||||
if (capi_arglist_list == NULL) goto capi_fail;
|
||||
#else
|
||||
#define CAPI_ARGLIST_SETITEM(idx, value) PyTuple_SetItem((PyObject *)capi_arglist, idx, value)
|
||||
#endif
|
||||
#pyobjfrom#
|
||||
#undef CAPI_ARGLIST_SETITEM
|
||||
#ifdef PYPY_VERSION
|
||||
CFUNCSMESSPY(\"cb:capi_arglist=\",capi_arglist_list);
|
||||
#else
|
||||
CFUNCSMESSPY(\"cb:capi_arglist=\",capi_arglist);
|
||||
#endif
|
||||
CFUNCSMESS(\"cb:Call-back calling Python function #argname#.\\n\");
|
||||
#ifdef F2PY_REPORT_ATEXIT
|
||||
f2py_cb_start_call_clock();
|
||||
#endif
|
||||
#ifdef PYPY_VERSION
|
||||
capi_return = PyObject_CallObject(cb->capi,(PyObject *)capi_arglist_list);
|
||||
Py_DECREF(capi_arglist_list);
|
||||
capi_arglist_list = NULL;
|
||||
#else
|
||||
capi_return = PyObject_CallObject(cb->capi,(PyObject *)capi_arglist);
|
||||
#endif
|
||||
#ifdef F2PY_REPORT_ATEXIT
|
||||
f2py_cb_stop_call_clock();
|
||||
#endif
|
||||
CFUNCSMESSPY(\"cb:capi_return=\",capi_return);
|
||||
if (capi_return == NULL) {
|
||||
fprintf(stderr,\"capi_return is NULL\\n\");
|
||||
goto capi_fail;
|
||||
}
|
||||
if (capi_return == Py_None) {
|
||||
Py_DECREF(capi_return);
|
||||
capi_return = Py_BuildValue(\"()\");
|
||||
}
|
||||
else if (!PyTuple_Check(capi_return)) {
|
||||
capi_return = Py_BuildValue(\"(N)\",capi_return);
|
||||
}
|
||||
capi_j = PyTuple_Size(capi_return);
|
||||
capi_i = 0;
|
||||
#frompyobj#
|
||||
CFUNCSMESS(\"cb:#name#:successful\\n\");
|
||||
Py_DECREF(capi_return);
|
||||
#ifdef F2PY_REPORT_ATEXIT
|
||||
f2py_cb_stop_clock();
|
||||
#endif
|
||||
goto capi_return_pt;
|
||||
capi_fail:
|
||||
fprintf(stderr,\"Call-back #name# failed.\\n\");
|
||||
Py_XDECREF(capi_return);
|
||||
Py_XDECREF(capi_arglist_list);
|
||||
if (capi_longjmp_ok) {
|
||||
longjmp(cb->jmpbuf,-1);
|
||||
}
|
||||
capi_return_pt:
|
||||
;
|
||||
#return#
|
||||
}
|
||||
#endtitle#
|
||||
""",
|
||||
'need': ['setjmp.h', 'CFUNCSMESS', 'F2PY_THREAD_LOCAL_DECL'],
|
||||
'maxnofargs': '#maxnofargs#',
|
||||
'nofoptargs': '#nofoptargs#',
|
||||
'docstr': """\
|
||||
def #argname#(#docsignature#): return #docreturn#\\n\\
|
||||
#docstrsigns#""",
|
||||
'latexdocstr': """
|
||||
{{}\\verb@def #argname#(#latexdocsignature#): return #docreturn#@{}}
|
||||
#routnote#
|
||||
|
||||
#latexdocstrsigns#""",
|
||||
'docstrshort': 'def #argname#(#docsignature#): return #docreturn#'
|
||||
}
|
||||
cb_rout_rules = [
|
||||
{ # Init
|
||||
'separatorsfor': {'decl': '\n',
|
||||
'args': ',', 'optargs': '', 'pyobjfrom': '\n', 'freemem': '\n',
|
||||
'args_td': ',', 'optargs_td': '',
|
||||
'args_nm': ',', 'optargs_nm': '',
|
||||
'frompyobj': '\n', 'setdims': '\n',
|
||||
'docstrsigns': '\\n"\n"',
|
||||
'latexdocstrsigns': '\n',
|
||||
'latexdocstrreq': '\n', 'latexdocstropt': '\n',
|
||||
'latexdocstrout': '\n', 'latexdocstrcbs': '\n',
|
||||
},
|
||||
'decl': '/*decl*/', 'pyobjfrom': '/*pyobjfrom*/', 'frompyobj': '/*frompyobj*/',
|
||||
'args': [], 'optargs': '', 'return': '', 'strarglens': '', 'freemem': '/*freemem*/',
|
||||
'args_td': [], 'optargs_td': '', 'strarglens_td': '',
|
||||
'args_nm': [], 'optargs_nm': '', 'strarglens_nm': '',
|
||||
'noargs': '',
|
||||
'setdims': '/*setdims*/',
|
||||
'docstrsigns': '', 'latexdocstrsigns': '',
|
||||
'docstrreq': ' Required arguments:',
|
||||
'docstropt': ' Optional arguments:',
|
||||
'docstrout': ' Return objects:',
|
||||
'docstrcbs': ' Call-back functions:',
|
||||
'docreturn': '', 'docsign': '', 'docsignopt': '',
|
||||
'latexdocstrreq': '\\noindent Required arguments:',
|
||||
'latexdocstropt': '\\noindent Optional arguments:',
|
||||
'latexdocstrout': '\\noindent Return objects:',
|
||||
'latexdocstrcbs': '\\noindent Call-back functions:',
|
||||
'routnote': {hasnote: '--- #note#', l_not(hasnote): ''},
|
||||
}, { # Function
|
||||
'decl': ' #ctype# return_value = 0;',
|
||||
'frompyobj': [
|
||||
{debugcapi: ' CFUNCSMESS("cb:Getting return_value->");'},
|
||||
'''\
|
||||
if (capi_j>capi_i) {
|
||||
GETSCALARFROMPYTUPLE(capi_return,capi_i++,&return_value,#ctype#,
|
||||
"#ctype#_from_pyobj failed in converting return_value of"
|
||||
" call-back function #name# to C #ctype#\\n");
|
||||
} else {
|
||||
fprintf(stderr,"Warning: call-back function #name# did not provide"
|
||||
" return value (index=%d, type=#ctype#)\\n",capi_i);
|
||||
}''',
|
||||
{debugcapi:
|
||||
' fprintf(stderr,"#showvalueformat#.\\n",return_value);'}
|
||||
],
|
||||
'need': ['#ctype#_from_pyobj', {debugcapi: 'CFUNCSMESS'}, 'GETSCALARFROMPYTUPLE'],
|
||||
'return': ' return return_value;',
|
||||
'_check': l_and(isfunction, l_not(isstringfunction), l_not(iscomplexfunction))
|
||||
},
|
||||
{ # String function
|
||||
'pyobjfrom': {debugcapi: ' fprintf(stderr,"debug-capi:cb:#name#:%d:\\n",return_value_len);'},
|
||||
'args': '#ctype# return_value,int return_value_len',
|
||||
'args_nm': 'return_value,&return_value_len',
|
||||
'args_td': '#ctype# ,int',
|
||||
'frompyobj': [
|
||||
{debugcapi: ' CFUNCSMESS("cb:Getting return_value->\\"");'},
|
||||
"""\
|
||||
if (capi_j>capi_i) {
|
||||
GETSTRFROMPYTUPLE(capi_return,capi_i++,return_value,return_value_len);
|
||||
} else {
|
||||
fprintf(stderr,"Warning: call-back function #name# did not provide"
|
||||
" return value (index=%d, type=#ctype#)\\n",capi_i);
|
||||
}""",
|
||||
{debugcapi:
|
||||
' fprintf(stderr,"#showvalueformat#\\".\\n",return_value);'}
|
||||
],
|
||||
'need': ['#ctype#_from_pyobj', {debugcapi: 'CFUNCSMESS'},
|
||||
'string.h', 'GETSTRFROMPYTUPLE'],
|
||||
'return': 'return;',
|
||||
'_check': isstringfunction
|
||||
},
|
||||
{ # Complex function
|
||||
'optargs': """
|
||||
#ifndef F2PY_CB_RETURNCOMPLEX
|
||||
#ctype# *return_value
|
||||
#endif
|
||||
""",
|
||||
'optargs_nm': """
|
||||
#ifndef F2PY_CB_RETURNCOMPLEX
|
||||
return_value
|
||||
#endif
|
||||
""",
|
||||
'optargs_td': """
|
||||
#ifndef F2PY_CB_RETURNCOMPLEX
|
||||
#ctype# *
|
||||
#endif
|
||||
""",
|
||||
'decl': """
|
||||
#ifdef F2PY_CB_RETURNCOMPLEX
|
||||
#ctype# return_value = {0, 0};
|
||||
#endif
|
||||
""",
|
||||
'frompyobj': [
|
||||
{debugcapi: ' CFUNCSMESS("cb:Getting return_value->");'},
|
||||
"""\
|
||||
if (capi_j>capi_i) {
|
||||
#ifdef F2PY_CB_RETURNCOMPLEX
|
||||
GETSCALARFROMPYTUPLE(capi_return,capi_i++,&return_value,#ctype#,
|
||||
\"#ctype#_from_pyobj failed in converting return_value of call-back\"
|
||||
\" function #name# to C #ctype#\\n\");
|
||||
#else
|
||||
GETSCALARFROMPYTUPLE(capi_return,capi_i++,return_value,#ctype#,
|
||||
\"#ctype#_from_pyobj failed in converting return_value of call-back\"
|
||||
\" function #name# to C #ctype#\\n\");
|
||||
#endif
|
||||
} else {
|
||||
fprintf(stderr,
|
||||
\"Warning: call-back function #name# did not provide\"
|
||||
\" return value (index=%d, type=#ctype#)\\n\",capi_i);
|
||||
}""",
|
||||
{debugcapi: """\
|
||||
#ifdef F2PY_CB_RETURNCOMPLEX
|
||||
fprintf(stderr,\"#showvalueformat#.\\n\",(return_value).r,(return_value).i);
|
||||
#else
|
||||
fprintf(stderr,\"#showvalueformat#.\\n\",(*return_value).r,(*return_value).i);
|
||||
#endif
|
||||
"""}
|
||||
],
|
||||
'return': """
|
||||
#ifdef F2PY_CB_RETURNCOMPLEX
|
||||
return return_value;
|
||||
#else
|
||||
return;
|
||||
#endif
|
||||
""",
|
||||
'need': ['#ctype#_from_pyobj', {debugcapi: 'CFUNCSMESS'},
|
||||
'string.h', 'GETSCALARFROMPYTUPLE', '#ctype#'],
|
||||
'_check': iscomplexfunction
|
||||
},
|
||||
{'docstrout': ' #pydocsignout#',
|
||||
'latexdocstrout': ['\\item[]{{}\\verb@#pydocsignout#@{}}',
|
||||
{hasnote: '--- #note#'}],
|
||||
'docreturn': '#rname#,',
|
||||
'_check': isfunction},
|
||||
{'_check': issubroutine, 'return': 'return;'}
|
||||
]
|
||||
|
||||
cb_arg_rules = [
|
||||
{ # Doc
|
||||
'docstropt': {l_and(isoptional, isintent_nothide): ' #pydocsign#'},
|
||||
'docstrreq': {l_and(isrequired, isintent_nothide): ' #pydocsign#'},
|
||||
'docstrout': {isintent_out: ' #pydocsignout#'},
|
||||
'latexdocstropt': {l_and(isoptional, isintent_nothide): ['\\item[]{{}\\verb@#pydocsign#@{}}',
|
||||
{hasnote: '--- #note#'}]},
|
||||
'latexdocstrreq': {l_and(isrequired, isintent_nothide): ['\\item[]{{}\\verb@#pydocsign#@{}}',
|
||||
{hasnote: '--- #note#'}]},
|
||||
'latexdocstrout': {isintent_out: ['\\item[]{{}\\verb@#pydocsignout#@{}}',
|
||||
{l_and(hasnote, isintent_hide): '--- #note#',
|
||||
l_and(hasnote, isintent_nothide): '--- See above.'}]},
|
||||
'docsign': {l_and(isrequired, isintent_nothide): '#varname#,'},
|
||||
'docsignopt': {l_and(isoptional, isintent_nothide): '#varname#,'},
|
||||
'depend': ''
|
||||
},
|
||||
{
|
||||
'args': {
|
||||
l_and(isscalar, isintent_c): '#ctype# #varname_i#',
|
||||
l_and(isscalar, l_not(isintent_c)): '#ctype# *#varname_i#_cb_capi',
|
||||
isarray: '#ctype# *#varname_i#',
|
||||
isstring: '#ctype# #varname_i#'
|
||||
},
|
||||
'args_nm': {
|
||||
l_and(isscalar, isintent_c): '#varname_i#',
|
||||
l_and(isscalar, l_not(isintent_c)): '#varname_i#_cb_capi',
|
||||
isarray: '#varname_i#',
|
||||
isstring: '#varname_i#'
|
||||
},
|
||||
'args_td': {
|
||||
l_and(isscalar, isintent_c): '#ctype#',
|
||||
l_and(isscalar, l_not(isintent_c)): '#ctype# *',
|
||||
isarray: '#ctype# *',
|
||||
isstring: '#ctype#'
|
||||
},
|
||||
'need': {l_or(isscalar, isarray, isstring): '#ctype#'},
|
||||
# untested with multiple args
|
||||
'strarglens': {isstring: ',int #varname_i#_cb_len'},
|
||||
'strarglens_td': {isstring: ',int'}, # untested with multiple args
|
||||
# untested with multiple args
|
||||
'strarglens_nm': {isstring: ',#varname_i#_cb_len'},
|
||||
},
|
||||
{ # Scalars
|
||||
'decl': {l_not(isintent_c): ' #ctype# #varname_i#=(*#varname_i#_cb_capi);'},
|
||||
'error': {l_and(isintent_c, isintent_out,
|
||||
throw_error('intent(c,out) is forbidden for callback scalar arguments')):
|
||||
''},
|
||||
'frompyobj': [{debugcapi: ' CFUNCSMESS("cb:Getting #varname#->");'},
|
||||
{isintent_out:
|
||||
' if (capi_j>capi_i)\n GETSCALARFROMPYTUPLE(capi_return,capi_i++,#varname_i#_cb_capi,#ctype#,"#ctype#_from_pyobj failed in converting argument #varname# of call-back function #name# to C #ctype#\\n");'},
|
||||
{l_and(debugcapi, l_and(l_not(iscomplex), isintent_c)):
|
||||
' fprintf(stderr,"#showvalueformat#.\\n",#varname_i#);'},
|
||||
{l_and(debugcapi, l_and(l_not(iscomplex), l_not( isintent_c))):
|
||||
' fprintf(stderr,"#showvalueformat#.\\n",*#varname_i#_cb_capi);'},
|
||||
{l_and(debugcapi, l_and(iscomplex, isintent_c)):
|
||||
' fprintf(stderr,"#showvalueformat#.\\n",(#varname_i#).r,(#varname_i#).i);'},
|
||||
{l_and(debugcapi, l_and(iscomplex, l_not( isintent_c))):
|
||||
' fprintf(stderr,"#showvalueformat#.\\n",(*#varname_i#_cb_capi).r,(*#varname_i#_cb_capi).i);'},
|
||||
],
|
||||
'need': [{isintent_out: ['#ctype#_from_pyobj', 'GETSCALARFROMPYTUPLE']},
|
||||
{debugcapi: 'CFUNCSMESS'}],
|
||||
'_check': isscalar
|
||||
}, {
|
||||
'pyobjfrom': [{isintent_in: """\
|
||||
if (cb->nofargs>capi_i)
|
||||
if (CAPI_ARGLIST_SETITEM(capi_i++,pyobj_from_#ctype#1(#varname_i#)))
|
||||
goto capi_fail;"""},
|
||||
{isintent_inout: """\
|
||||
if (cb->nofargs>capi_i)
|
||||
if (CAPI_ARGLIST_SETITEM(capi_i++,pyarr_from_p_#ctype#1(#varname_i#_cb_capi)))
|
||||
goto capi_fail;"""}],
|
||||
'need': [{isintent_in: 'pyobj_from_#ctype#1'},
|
||||
{isintent_inout: 'pyarr_from_p_#ctype#1'},
|
||||
{iscomplex: '#ctype#'}],
|
||||
'_check': l_and(isscalar, isintent_nothide),
|
||||
'_optional': ''
|
||||
}, { # String
|
||||
'frompyobj': [{debugcapi: ' CFUNCSMESS("cb:Getting #varname#->\\"");'},
|
||||
""" if (capi_j>capi_i)
|
||||
GETSTRFROMPYTUPLE(capi_return,capi_i++,#varname_i#,#varname_i#_cb_len);""",
|
||||
{debugcapi:
|
||||
' fprintf(stderr,"#showvalueformat#\\":%d:.\\n",#varname_i#,#varname_i#_cb_len);'},
|
||||
],
|
||||
'need': ['#ctype#', 'GETSTRFROMPYTUPLE',
|
||||
{debugcapi: 'CFUNCSMESS'}, 'string.h'],
|
||||
'_check': l_and(isstring, isintent_out)
|
||||
}, {
|
||||
'pyobjfrom': [
|
||||
{debugcapi:
|
||||
(' fprintf(stderr,"debug-capi:cb:#varname#=#showvalueformat#:'
|
||||
'%d:\\n",#varname_i#,#varname_i#_cb_len);')},
|
||||
{isintent_in: """\
|
||||
if (cb->nofargs>capi_i)
|
||||
if (CAPI_ARGLIST_SETITEM(capi_i++,pyobj_from_#ctype#1size(#varname_i#,#varname_i#_cb_len)))
|
||||
goto capi_fail;"""},
|
||||
{isintent_inout: """\
|
||||
if (cb->nofargs>capi_i) {
|
||||
int #varname_i#_cb_dims[] = {#varname_i#_cb_len};
|
||||
if (CAPI_ARGLIST_SETITEM(capi_i++,pyarr_from_p_#ctype#1(#varname_i#,#varname_i#_cb_dims)))
|
||||
goto capi_fail;
|
||||
}"""}],
|
||||
'need': [{isintent_in: 'pyobj_from_#ctype#1size'},
|
||||
{isintent_inout: 'pyarr_from_p_#ctype#1'}],
|
||||
'_check': l_and(isstring, isintent_nothide),
|
||||
'_optional': ''
|
||||
},
|
||||
# Array ...
|
||||
{
|
||||
'decl': ' npy_intp #varname_i#_Dims[#rank#] = {#rank*[-1]#};',
|
||||
'setdims': ' #cbsetdims#;',
|
||||
'_check': isarray,
|
||||
'_depend': ''
|
||||
},
|
||||
{
|
||||
'pyobjfrom': [{debugcapi: ' fprintf(stderr,"debug-capi:cb:#varname#\\n");'},
|
||||
{isintent_c: """\
|
||||
if (cb->nofargs>capi_i) {
|
||||
/* tmp_arr will be inserted to capi_arglist_list that will be
|
||||
destroyed when leaving callback function wrapper together
|
||||
with tmp_arr. */
|
||||
PyArrayObject *tmp_arr = (PyArrayObject *)PyArray_New(&PyArray_Type,
|
||||
#rank#,#varname_i#_Dims,#atype#,NULL,(char*)#varname_i#,#elsize#,
|
||||
NPY_ARRAY_CARRAY,NULL);
|
||||
""",
|
||||
l_not(isintent_c): """\
|
||||
if (cb->nofargs>capi_i) {
|
||||
/* tmp_arr will be inserted to capi_arglist_list that will be
|
||||
destroyed when leaving callback function wrapper together
|
||||
with tmp_arr. */
|
||||
PyArrayObject *tmp_arr = (PyArrayObject *)PyArray_New(&PyArray_Type,
|
||||
#rank#,#varname_i#_Dims,#atype#,NULL,(char*)#varname_i#,#elsize#,
|
||||
NPY_ARRAY_FARRAY,NULL);
|
||||
""",
|
||||
},
|
||||
"""
|
||||
if (tmp_arr==NULL)
|
||||
goto capi_fail;
|
||||
if (CAPI_ARGLIST_SETITEM(capi_i++,(PyObject *)tmp_arr))
|
||||
goto capi_fail;
|
||||
}"""],
|
||||
'_check': l_and(isarray, isintent_nothide, l_or(isintent_in, isintent_inout)),
|
||||
'_optional': '',
|
||||
}, {
|
||||
'frompyobj': [{debugcapi: ' CFUNCSMESS("cb:Getting #varname#->");'},
|
||||
""" if (capi_j>capi_i) {
|
||||
PyArrayObject *rv_cb_arr = NULL;
|
||||
if ((capi_tmp = PyTuple_GetItem(capi_return,capi_i++))==NULL) goto capi_fail;
|
||||
rv_cb_arr = array_from_pyobj(#atype#,#varname_i#_Dims,#rank#,F2PY_INTENT_IN""",
|
||||
{isintent_c: '|F2PY_INTENT_C'},
|
||||
""",capi_tmp);
|
||||
if (rv_cb_arr == NULL) {
|
||||
fprintf(stderr,\"rv_cb_arr is NULL\\n\");
|
||||
goto capi_fail;
|
||||
}
|
||||
MEMCOPY(#varname_i#,PyArray_DATA(rv_cb_arr),PyArray_NBYTES(rv_cb_arr));
|
||||
if (capi_tmp != (PyObject *)rv_cb_arr) {
|
||||
Py_DECREF(rv_cb_arr);
|
||||
}
|
||||
}""",
|
||||
{debugcapi: ' fprintf(stderr,"<-.\\n");'},
|
||||
],
|
||||
'need': ['MEMCOPY', {iscomplexarray: '#ctype#'}],
|
||||
'_check': l_and(isarray, isintent_out)
|
||||
}, {
|
||||
'docreturn': '#varname#,',
|
||||
'_check': isintent_out
|
||||
}
|
||||
]
|
||||
|
||||
################## Build call-back module #############
|
||||
cb_map = {}
|
||||
|
||||
|
||||
def buildcallbacks(m):
|
||||
cb_map[m['name']] = []
|
||||
for bi in m['body']:
|
||||
if bi['block'] == 'interface':
|
||||
for b in bi['body']:
|
||||
if b:
|
||||
buildcallback(b, m['name'])
|
||||
else:
|
||||
errmess('warning: empty body for %s\n' % (m['name']))
|
||||
|
||||
|
||||
def buildcallback(rout, um):
|
||||
from . import capi_maps
|
||||
|
||||
outmess(' Constructing call-back function "cb_%s_in_%s"\n' %
|
||||
(rout['name'], um))
|
||||
args, depargs = getargs(rout)
|
||||
capi_maps.depargs = depargs
|
||||
var = rout['vars']
|
||||
vrd = capi_maps.cb_routsign2map(rout, um)
|
||||
rd = dictappend({}, vrd)
|
||||
cb_map[um].append([rout['name'], rd['name']])
|
||||
for r in cb_rout_rules:
|
||||
if ('_check' in r and r['_check'](rout)) or ('_check' not in r):
|
||||
ar = applyrules(r, vrd, rout)
|
||||
rd = dictappend(rd, ar)
|
||||
savevrd = {}
|
||||
for i, a in enumerate(args):
|
||||
vrd = capi_maps.cb_sign2map(a, var[a], index=i)
|
||||
savevrd[a] = vrd
|
||||
for r in cb_arg_rules:
|
||||
if '_depend' in r:
|
||||
continue
|
||||
if '_optional' in r and isoptional(var[a]):
|
||||
continue
|
||||
if ('_check' in r and r['_check'](var[a])) or ('_check' not in r):
|
||||
ar = applyrules(r, vrd, var[a])
|
||||
rd = dictappend(rd, ar)
|
||||
if '_break' in r:
|
||||
break
|
||||
for a in args:
|
||||
vrd = savevrd[a]
|
||||
for r in cb_arg_rules:
|
||||
if '_depend' in r:
|
||||
continue
|
||||
if ('_optional' not in r) or ('_optional' in r and isrequired(var[a])):
|
||||
continue
|
||||
if ('_check' in r and r['_check'](var[a])) or ('_check' not in r):
|
||||
ar = applyrules(r, vrd, var[a])
|
||||
rd = dictappend(rd, ar)
|
||||
if '_break' in r:
|
||||
break
|
||||
for a in depargs:
|
||||
vrd = savevrd[a]
|
||||
for r in cb_arg_rules:
|
||||
if '_depend' not in r:
|
||||
continue
|
||||
if '_optional' in r:
|
||||
continue
|
||||
if ('_check' in r and r['_check'](var[a])) or ('_check' not in r):
|
||||
ar = applyrules(r, vrd, var[a])
|
||||
rd = dictappend(rd, ar)
|
||||
if '_break' in r:
|
||||
break
|
||||
if 'args' in rd and 'optargs' in rd:
|
||||
if isinstance(rd['optargs'], list):
|
||||
rd['optargs'] = rd['optargs'] + ["""
|
||||
#ifndef F2PY_CB_RETURNCOMPLEX
|
||||
,
|
||||
#endif
|
||||
"""]
|
||||
rd['optargs_nm'] = rd['optargs_nm'] + ["""
|
||||
#ifndef F2PY_CB_RETURNCOMPLEX
|
||||
,
|
||||
#endif
|
||||
"""]
|
||||
rd['optargs_td'] = rd['optargs_td'] + ["""
|
||||
#ifndef F2PY_CB_RETURNCOMPLEX
|
||||
,
|
||||
#endif
|
||||
"""]
|
||||
if isinstance(rd['docreturn'], list):
|
||||
rd['docreturn'] = stripcomma(
|
||||
replace('#docreturn#', {'docreturn': rd['docreturn']}))
|
||||
optargs = stripcomma(replace('#docsignopt#',
|
||||
{'docsignopt': rd['docsignopt']}
|
||||
))
|
||||
if optargs == '':
|
||||
rd['docsignature'] = stripcomma(
|
||||
replace('#docsign#', {'docsign': rd['docsign']}))
|
||||
else:
|
||||
rd['docsignature'] = replace('#docsign#[#docsignopt#]',
|
||||
{'docsign': rd['docsign'],
|
||||
'docsignopt': optargs,
|
||||
})
|
||||
rd['latexdocsignature'] = rd['docsignature'].replace('_', '\\_')
|
||||
rd['latexdocsignature'] = rd['latexdocsignature'].replace(',', ', ')
|
||||
rd['docstrsigns'] = []
|
||||
rd['latexdocstrsigns'] = []
|
||||
for k in ['docstrreq', 'docstropt', 'docstrout', 'docstrcbs']:
|
||||
if k in rd and isinstance(rd[k], list):
|
||||
rd['docstrsigns'] = rd['docstrsigns'] + rd[k]
|
||||
k = 'latex' + k
|
||||
if k in rd and isinstance(rd[k], list):
|
||||
rd['latexdocstrsigns'] = rd['latexdocstrsigns'] + rd[k][0:1] +\
|
||||
['\\begin{description}'] + rd[k][1:] +\
|
||||
['\\end{description}']
|
||||
if 'args' not in rd:
|
||||
rd['args'] = ''
|
||||
rd['args_td'] = ''
|
||||
rd['args_nm'] = ''
|
||||
if not (rd.get('args') or rd.get('optargs') or rd.get('strarglens')):
|
||||
rd['noargs'] = 'void'
|
||||
|
||||
ar = applyrules(cb_routine_rules, rd)
|
||||
cfuncs.callbacks[rd['name']] = ar['body']
|
||||
if isinstance(ar['need'], str):
|
||||
ar['need'] = [ar['need']]
|
||||
|
||||
if 'need' in rd:
|
||||
for t in cfuncs.typedefs.keys():
|
||||
if t in rd['need']:
|
||||
ar['need'].append(t)
|
||||
|
||||
cfuncs.typedefs_generated[rd['name'] + '_typedef'] = ar['cbtypedefs']
|
||||
ar['need'].append(rd['name'] + '_typedef')
|
||||
cfuncs.needs[rd['name']] = ar['need']
|
||||
|
||||
capi_maps.lcb2_map[rd['name']] = {'maxnofargs': ar['maxnofargs'],
|
||||
'nofoptargs': ar['nofoptargs'],
|
||||
'docstr': ar['docstr'],
|
||||
'latexdocstr': ar['latexdocstr'],
|
||||
'argname': rd['argname']
|
||||
}
|
||||
outmess(' %s\n' % (ar['docstrshort']))
|
||||
return
|
||||
################## Build call-back function #############
|
1545
venv/lib/python3.12/site-packages/numpy/f2py/cfuncs.py
Normal file
1545
venv/lib/python3.12/site-packages/numpy/f2py/cfuncs.py
Normal file
File diff suppressed because it is too large
Load Diff
146
venv/lib/python3.12/site-packages/numpy/f2py/common_rules.py
Normal file
146
venv/lib/python3.12/site-packages/numpy/f2py/common_rules.py
Normal file
@ -0,0 +1,146 @@
|
||||
"""
|
||||
Build common block mechanism for f2py2e.
|
||||
|
||||
Copyright 1999 -- 2011 Pearu Peterson all rights reserved.
|
||||
Copyright 2011 -- present NumPy Developers.
|
||||
Permission to use, modify, and distribute this software is given under the
|
||||
terms of the NumPy License
|
||||
|
||||
NO WARRANTY IS EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
|
||||
"""
|
||||
from . import __version__
|
||||
f2py_version = __version__.version
|
||||
|
||||
from .auxfuncs import (
|
||||
hasbody, hascommon, hasnote, isintent_hide, outmess, getuseblocks
|
||||
)
|
||||
from . import capi_maps
|
||||
from . import func2subr
|
||||
from .crackfortran import rmbadname
|
||||
|
||||
|
||||
def findcommonblocks(block, top=1):
|
||||
ret = []
|
||||
if hascommon(block):
|
||||
for key, value in block['common'].items():
|
||||
vars_ = {v: block['vars'][v] for v in value}
|
||||
ret.append((key, value, vars_))
|
||||
elif hasbody(block):
|
||||
for b in block['body']:
|
||||
ret = ret + findcommonblocks(b, 0)
|
||||
if top:
|
||||
tret = []
|
||||
names = []
|
||||
for t in ret:
|
||||
if t[0] not in names:
|
||||
names.append(t[0])
|
||||
tret.append(t)
|
||||
return tret
|
||||
return ret
|
||||
|
||||
|
||||
def buildhooks(m):
|
||||
ret = {'commonhooks': [], 'initcommonhooks': [],
|
||||
'docs': ['"COMMON blocks:\\n"']}
|
||||
fwrap = ['']
|
||||
|
||||
def fadd(line, s=fwrap):
|
||||
s[0] = '%s\n %s' % (s[0], line)
|
||||
chooks = ['']
|
||||
|
||||
def cadd(line, s=chooks):
|
||||
s[0] = '%s\n%s' % (s[0], line)
|
||||
ihooks = ['']
|
||||
|
||||
def iadd(line, s=ihooks):
|
||||
s[0] = '%s\n%s' % (s[0], line)
|
||||
doc = ['']
|
||||
|
||||
def dadd(line, s=doc):
|
||||
s[0] = '%s\n%s' % (s[0], line)
|
||||
for (name, vnames, vars) in findcommonblocks(m):
|
||||
lower_name = name.lower()
|
||||
hnames, inames = [], []
|
||||
for n in vnames:
|
||||
if isintent_hide(vars[n]):
|
||||
hnames.append(n)
|
||||
else:
|
||||
inames.append(n)
|
||||
if hnames:
|
||||
outmess('\t\tConstructing COMMON block support for "%s"...\n\t\t %s\n\t\t Hidden: %s\n' % (
|
||||
name, ','.join(inames), ','.join(hnames)))
|
||||
else:
|
||||
outmess('\t\tConstructing COMMON block support for "%s"...\n\t\t %s\n' % (
|
||||
name, ','.join(inames)))
|
||||
fadd('subroutine f2pyinit%s(setupfunc)' % name)
|
||||
for usename in getuseblocks(m):
|
||||
fadd(f'use {usename}')
|
||||
fadd('external setupfunc')
|
||||
for n in vnames:
|
||||
fadd(func2subr.var2fixfortran(vars, n))
|
||||
if name == '_BLNK_':
|
||||
fadd('common %s' % (','.join(vnames)))
|
||||
else:
|
||||
fadd('common /%s/ %s' % (name, ','.join(vnames)))
|
||||
fadd('call setupfunc(%s)' % (','.join(inames)))
|
||||
fadd('end\n')
|
||||
cadd('static FortranDataDef f2py_%s_def[] = {' % (name))
|
||||
idims = []
|
||||
for n in inames:
|
||||
ct = capi_maps.getctype(vars[n])
|
||||
elsize = capi_maps.get_elsize(vars[n])
|
||||
at = capi_maps.c2capi_map[ct]
|
||||
dm = capi_maps.getarrdims(n, vars[n])
|
||||
if dm['dims']:
|
||||
idims.append('(%s)' % (dm['dims']))
|
||||
else:
|
||||
idims.append('')
|
||||
dms = dm['dims'].strip()
|
||||
if not dms:
|
||||
dms = '-1'
|
||||
cadd('\t{\"%s\",%s,{{%s}},%s, %s},'
|
||||
% (n, dm['rank'], dms, at, elsize))
|
||||
cadd('\t{NULL}\n};')
|
||||
inames1 = rmbadname(inames)
|
||||
inames1_tps = ','.join(['char *' + s for s in inames1])
|
||||
cadd('static void f2py_setup_%s(%s) {' % (name, inames1_tps))
|
||||
cadd('\tint i_f2py=0;')
|
||||
for n in inames1:
|
||||
cadd('\tf2py_%s_def[i_f2py++].data = %s;' % (name, n))
|
||||
cadd('}')
|
||||
if '_' in lower_name:
|
||||
F_FUNC = 'F_FUNC_US'
|
||||
else:
|
||||
F_FUNC = 'F_FUNC'
|
||||
cadd('extern void %s(f2pyinit%s,F2PYINIT%s)(void(*)(%s));'
|
||||
% (F_FUNC, lower_name, name.upper(),
|
||||
','.join(['char*'] * len(inames1))))
|
||||
cadd('static void f2py_init_%s(void) {' % name)
|
||||
cadd('\t%s(f2pyinit%s,F2PYINIT%s)(f2py_setup_%s);'
|
||||
% (F_FUNC, lower_name, name.upper(), name))
|
||||
cadd('}\n')
|
||||
iadd('\ttmp = PyFortranObject_New(f2py_%s_def,f2py_init_%s);' % (name, name))
|
||||
iadd('\tif (tmp == NULL) return NULL;')
|
||||
iadd('\tif (F2PyDict_SetItemString(d, \"%s\", tmp) == -1) return NULL;'
|
||||
% name)
|
||||
iadd('\tPy_DECREF(tmp);')
|
||||
tname = name.replace('_', '\\_')
|
||||
dadd('\\subsection{Common block \\texttt{%s}}\n' % (tname))
|
||||
dadd('\\begin{description}')
|
||||
for n in inames:
|
||||
dadd('\\item[]{{}\\verb@%s@{}}' %
|
||||
(capi_maps.getarrdocsign(n, vars[n])))
|
||||
if hasnote(vars[n]):
|
||||
note = vars[n]['note']
|
||||
if isinstance(note, list):
|
||||
note = '\n'.join(note)
|
||||
dadd('--- %s' % (note))
|
||||
dadd('\\end{description}')
|
||||
ret['docs'].append(
|
||||
'"\t/%s/ %s\\n"' % (name, ','.join(map(lambda v, d: v + d, inames, idims))))
|
||||
ret['commonhooks'] = chooks
|
||||
ret['initcommonhooks'] = ihooks
|
||||
ret['latexdoc'] = doc[0]
|
||||
if len(ret['docs']) <= 1:
|
||||
ret['docs'] = ''
|
||||
return ret, fwrap[0]
|
3755
venv/lib/python3.12/site-packages/numpy/f2py/crackfortran.py
Executable file
3755
venv/lib/python3.12/site-packages/numpy/f2py/crackfortran.py
Executable file
File diff suppressed because it is too large
Load Diff
154
venv/lib/python3.12/site-packages/numpy/f2py/diagnose.py
Normal file
154
venv/lib/python3.12/site-packages/numpy/f2py/diagnose.py
Normal file
@ -0,0 +1,154 @@
|
||||
#!/usr/bin/env python3
|
||||
import os
|
||||
import sys
|
||||
import tempfile
|
||||
|
||||
|
||||
def run_command(cmd):
|
||||
print('Running %r:' % (cmd))
|
||||
os.system(cmd)
|
||||
print('------')
|
||||
|
||||
|
||||
def run():
|
||||
_path = os.getcwd()
|
||||
os.chdir(tempfile.gettempdir())
|
||||
print('------')
|
||||
print('os.name=%r' % (os.name))
|
||||
print('------')
|
||||
print('sys.platform=%r' % (sys.platform))
|
||||
print('------')
|
||||
print('sys.version:')
|
||||
print(sys.version)
|
||||
print('------')
|
||||
print('sys.prefix:')
|
||||
print(sys.prefix)
|
||||
print('------')
|
||||
print('sys.path=%r' % (':'.join(sys.path)))
|
||||
print('------')
|
||||
|
||||
try:
|
||||
import numpy
|
||||
has_newnumpy = 1
|
||||
except ImportError as e:
|
||||
print('Failed to import new numpy:', e)
|
||||
has_newnumpy = 0
|
||||
|
||||
try:
|
||||
from numpy.f2py import f2py2e
|
||||
has_f2py2e = 1
|
||||
except ImportError as e:
|
||||
print('Failed to import f2py2e:', e)
|
||||
has_f2py2e = 0
|
||||
|
||||
try:
|
||||
import numpy.distutils
|
||||
has_numpy_distutils = 2
|
||||
except ImportError:
|
||||
try:
|
||||
import numpy_distutils
|
||||
has_numpy_distutils = 1
|
||||
except ImportError as e:
|
||||
print('Failed to import numpy_distutils:', e)
|
||||
has_numpy_distutils = 0
|
||||
|
||||
if has_newnumpy:
|
||||
try:
|
||||
print('Found new numpy version %r in %s' %
|
||||
(numpy.__version__, numpy.__file__))
|
||||
except Exception as msg:
|
||||
print('error:', msg)
|
||||
print('------')
|
||||
|
||||
if has_f2py2e:
|
||||
try:
|
||||
print('Found f2py2e version %r in %s' %
|
||||
(f2py2e.__version__.version, f2py2e.__file__))
|
||||
except Exception as msg:
|
||||
print('error:', msg)
|
||||
print('------')
|
||||
|
||||
if has_numpy_distutils:
|
||||
try:
|
||||
if has_numpy_distutils == 2:
|
||||
print('Found numpy.distutils version %r in %r' % (
|
||||
numpy.distutils.__version__,
|
||||
numpy.distutils.__file__))
|
||||
else:
|
||||
print('Found numpy_distutils version %r in %r' % (
|
||||
numpy_distutils.numpy_distutils_version.numpy_distutils_version,
|
||||
numpy_distutils.__file__))
|
||||
print('------')
|
||||
except Exception as msg:
|
||||
print('error:', msg)
|
||||
print('------')
|
||||
try:
|
||||
if has_numpy_distutils == 1:
|
||||
print(
|
||||
'Importing numpy_distutils.command.build_flib ...', end=' ')
|
||||
import numpy_distutils.command.build_flib as build_flib
|
||||
print('ok')
|
||||
print('------')
|
||||
try:
|
||||
print(
|
||||
'Checking availability of supported Fortran compilers:')
|
||||
for compiler_class in build_flib.all_compilers:
|
||||
compiler_class(verbose=1).is_available()
|
||||
print('------')
|
||||
except Exception as msg:
|
||||
print('error:', msg)
|
||||
print('------')
|
||||
except Exception as msg:
|
||||
print(
|
||||
'error:', msg, '(ignore it, build_flib is obsolute for numpy.distutils 0.2.2 and up)')
|
||||
print('------')
|
||||
try:
|
||||
if has_numpy_distutils == 2:
|
||||
print('Importing numpy.distutils.fcompiler ...', end=' ')
|
||||
import numpy.distutils.fcompiler as fcompiler
|
||||
else:
|
||||
print('Importing numpy_distutils.fcompiler ...', end=' ')
|
||||
import numpy_distutils.fcompiler as fcompiler
|
||||
print('ok')
|
||||
print('------')
|
||||
try:
|
||||
print('Checking availability of supported Fortran compilers:')
|
||||
fcompiler.show_fcompilers()
|
||||
print('------')
|
||||
except Exception as msg:
|
||||
print('error:', msg)
|
||||
print('------')
|
||||
except Exception as msg:
|
||||
print('error:', msg)
|
||||
print('------')
|
||||
try:
|
||||
if has_numpy_distutils == 2:
|
||||
print('Importing numpy.distutils.cpuinfo ...', end=' ')
|
||||
from numpy.distutils.cpuinfo import cpuinfo
|
||||
print('ok')
|
||||
print('------')
|
||||
else:
|
||||
try:
|
||||
print(
|
||||
'Importing numpy_distutils.command.cpuinfo ...', end=' ')
|
||||
from numpy_distutils.command.cpuinfo import cpuinfo
|
||||
print('ok')
|
||||
print('------')
|
||||
except Exception as msg:
|
||||
print('error:', msg, '(ignore it)')
|
||||
print('Importing numpy_distutils.cpuinfo ...', end=' ')
|
||||
from numpy_distutils.cpuinfo import cpuinfo
|
||||
print('ok')
|
||||
print('------')
|
||||
cpu = cpuinfo()
|
||||
print('CPU information:', end=' ')
|
||||
for name in dir(cpuinfo):
|
||||
if name[0] == '_' and name[1] != '_' and getattr(cpu, name[1:])():
|
||||
print(name[1:], end=' ')
|
||||
print('------')
|
||||
except Exception as msg:
|
||||
print('error:', msg)
|
||||
print('------')
|
||||
os.chdir(_path)
|
||||
if __name__ == "__main__":
|
||||
run()
|
787
venv/lib/python3.12/site-packages/numpy/f2py/f2py2e.py
Executable file
787
venv/lib/python3.12/site-packages/numpy/f2py/f2py2e.py
Executable file
@ -0,0 +1,787 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
|
||||
f2py2e - Fortran to Python C/API generator. 2nd Edition.
|
||||
See __usage__ below.
|
||||
|
||||
Copyright 1999 -- 2011 Pearu Peterson all rights reserved.
|
||||
Copyright 2011 -- present NumPy Developers.
|
||||
Permission to use, modify, and distribute this software is given under the
|
||||
terms of the NumPy License.
|
||||
|
||||
NO WARRANTY IS EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
|
||||
"""
|
||||
import sys
|
||||
import os
|
||||
import pprint
|
||||
import re
|
||||
from pathlib import Path
|
||||
from itertools import dropwhile
|
||||
import argparse
|
||||
import copy
|
||||
|
||||
from . import crackfortran
|
||||
from . import rules
|
||||
from . import cb_rules
|
||||
from . import auxfuncs
|
||||
from . import cfuncs
|
||||
from . import f90mod_rules
|
||||
from . import __version__
|
||||
from . import capi_maps
|
||||
from .cfuncs import errmess
|
||||
from numpy.f2py._backends import f2py_build_generator
|
||||
|
||||
f2py_version = __version__.version
|
||||
numpy_version = __version__.version
|
||||
|
||||
# outmess=sys.stdout.write
|
||||
show = pprint.pprint
|
||||
outmess = auxfuncs.outmess
|
||||
MESON_ONLY_VER = (sys.version_info >= (3, 12))
|
||||
|
||||
__usage__ =\
|
||||
f"""Usage:
|
||||
|
||||
1) To construct extension module sources:
|
||||
|
||||
f2py [<options>] <fortran files> [[[only:]||[skip:]] \\
|
||||
<fortran functions> ] \\
|
||||
[: <fortran files> ...]
|
||||
|
||||
2) To compile fortran files and build extension modules:
|
||||
|
||||
f2py -c [<options>, <build_flib options>, <extra options>] <fortran files>
|
||||
|
||||
3) To generate signature files:
|
||||
|
||||
f2py -h <filename.pyf> ...< same options as in (1) >
|
||||
|
||||
Description: This program generates a Python C/API file (<modulename>module.c)
|
||||
that contains wrappers for given fortran functions so that they
|
||||
can be called from Python. With the -c option the corresponding
|
||||
extension modules are built.
|
||||
|
||||
Options:
|
||||
|
||||
-h <filename> Write signatures of the fortran routines to file <filename>
|
||||
and exit. You can then edit <filename> and use it instead
|
||||
of <fortran files>. If <filename>==stdout then the
|
||||
signatures are printed to stdout.
|
||||
<fortran functions> Names of fortran routines for which Python C/API
|
||||
functions will be generated. Default is all that are found
|
||||
in <fortran files>.
|
||||
<fortran files> Paths to fortran/signature files that will be scanned for
|
||||
<fortran functions> in order to determine their signatures.
|
||||
skip: Ignore fortran functions that follow until `:'.
|
||||
only: Use only fortran functions that follow until `:'.
|
||||
: Get back to <fortran files> mode.
|
||||
|
||||
-m <modulename> Name of the module; f2py generates a Python/C API
|
||||
file <modulename>module.c or extension module <modulename>.
|
||||
Default is 'untitled'.
|
||||
|
||||
'-include<header>' Writes additional headers in the C wrapper, can be passed
|
||||
multiple times, generates #include <header> each time.
|
||||
|
||||
--[no-]lower Do [not] lower the cases in <fortran files>. By default,
|
||||
--lower is assumed with -h key, and --no-lower without -h key.
|
||||
|
||||
--build-dir <dirname> All f2py generated files are created in <dirname>.
|
||||
Default is tempfile.mkdtemp().
|
||||
|
||||
--overwrite-signature Overwrite existing signature file.
|
||||
|
||||
--[no-]latex-doc Create (or not) <modulename>module.tex.
|
||||
Default is --no-latex-doc.
|
||||
--short-latex Create 'incomplete' LaTeX document (without commands
|
||||
\\documentclass, \\tableofcontents, and \\begin{{document}},
|
||||
\\end{{document}}).
|
||||
|
||||
--[no-]rest-doc Create (or not) <modulename>module.rst.
|
||||
Default is --no-rest-doc.
|
||||
|
||||
--debug-capi Create C/API code that reports the state of the wrappers
|
||||
during runtime. Useful for debugging.
|
||||
|
||||
--[no-]wrap-functions Create Fortran subroutine wrappers to Fortran 77
|
||||
functions. --wrap-functions is default because it ensures
|
||||
maximum portability/compiler independence.
|
||||
|
||||
--[no-]freethreading-compatible Create a module that declares it does or
|
||||
doesn't require the GIL. The default is
|
||||
--freethreading-compatible for backward
|
||||
compatibility. Inspect the Fortran code you are wrapping for
|
||||
thread safety issues before passing
|
||||
--no-freethreading-compatible, as f2py does not analyze
|
||||
fortran code for thread safety issues.
|
||||
|
||||
--include-paths <path1>:<path2>:... Search include files from the given
|
||||
directories.
|
||||
|
||||
--help-link [..] List system resources found by system_info.py. See also
|
||||
--link-<resource> switch below. [..] is optional list
|
||||
of resources names. E.g. try 'f2py --help-link lapack_opt'.
|
||||
|
||||
--f2cmap <filename> Load Fortran-to-Python KIND specification from the given
|
||||
file. Default: .f2py_f2cmap in current directory.
|
||||
|
||||
--quiet Run quietly.
|
||||
--verbose Run with extra verbosity.
|
||||
--skip-empty-wrappers Only generate wrapper files when needed.
|
||||
-v Print f2py version ID and exit.
|
||||
|
||||
|
||||
build backend options (only effective with -c)
|
||||
[NO_MESON] is used to indicate an option not meant to be used
|
||||
with the meson backend or above Python 3.12:
|
||||
|
||||
--fcompiler= Specify Fortran compiler type by vendor [NO_MESON]
|
||||
--compiler= Specify distutils C compiler type [NO_MESON]
|
||||
|
||||
--help-fcompiler List available Fortran compilers and exit [NO_MESON]
|
||||
--f77exec= Specify the path to F77 compiler [NO_MESON]
|
||||
--f90exec= Specify the path to F90 compiler [NO_MESON]
|
||||
--f77flags= Specify F77 compiler flags
|
||||
--f90flags= Specify F90 compiler flags
|
||||
--opt= Specify optimization flags [NO_MESON]
|
||||
--arch= Specify architecture specific optimization flags [NO_MESON]
|
||||
--noopt Compile without optimization [NO_MESON]
|
||||
--noarch Compile without arch-dependent optimization [NO_MESON]
|
||||
--debug Compile with debugging information
|
||||
|
||||
--dep <dependency>
|
||||
Specify a meson dependency for the module. This may
|
||||
be passed multiple times for multiple dependencies.
|
||||
Dependencies are stored in a list for further processing.
|
||||
|
||||
Example: --dep lapack --dep scalapack
|
||||
This will identify "lapack" and "scalapack" as dependencies
|
||||
and remove them from argv, leaving a dependencies list
|
||||
containing ["lapack", "scalapack"].
|
||||
|
||||
--backend <backend_type>
|
||||
Specify the build backend for the compilation process.
|
||||
The supported backends are 'meson' and 'distutils'.
|
||||
If not specified, defaults to 'distutils'. On
|
||||
Python 3.12 or higher, the default is 'meson'.
|
||||
|
||||
Extra options (only effective with -c):
|
||||
|
||||
--link-<resource> Link extension module with <resource> as defined
|
||||
by numpy.distutils/system_info.py. E.g. to link
|
||||
with optimized LAPACK libraries (vecLib on MacOSX,
|
||||
ATLAS elsewhere), use --link-lapack_opt.
|
||||
See also --help-link switch. [NO_MESON]
|
||||
|
||||
-L/path/to/lib/ -l<libname>
|
||||
-D<define> -U<name>
|
||||
-I/path/to/include/
|
||||
<filename>.o <filename>.so <filename>.a
|
||||
|
||||
Using the following macros may be required with non-gcc Fortran
|
||||
compilers:
|
||||
-DPREPEND_FORTRAN -DNO_APPEND_FORTRAN -DUPPERCASE_FORTRAN
|
||||
|
||||
When using -DF2PY_REPORT_ATEXIT, a performance report of F2PY
|
||||
interface is printed out at exit (platforms: Linux).
|
||||
|
||||
When using -DF2PY_REPORT_ON_ARRAY_COPY=<int>, a message is
|
||||
sent to stderr whenever F2PY interface makes a copy of an
|
||||
array. Integer <int> sets the threshold for array sizes when
|
||||
a message should be shown.
|
||||
|
||||
Version: {f2py_version}
|
||||
numpy Version: {numpy_version}
|
||||
License: NumPy license (see LICENSE.txt in the NumPy source code)
|
||||
Copyright 1999 -- 2011 Pearu Peterson all rights reserved.
|
||||
Copyright 2011 -- present NumPy Developers.
|
||||
https://numpy.org/doc/stable/f2py/index.html\n"""
|
||||
|
||||
|
||||
def scaninputline(inputline):
|
||||
files, skipfuncs, onlyfuncs, debug = [], [], [], []
|
||||
f, f2, f3, f5, f6, f8, f9, f10 = 1, 0, 0, 0, 0, 0, 0, 0
|
||||
verbose = 1
|
||||
emptygen = True
|
||||
dolc = -1
|
||||
dolatexdoc = 0
|
||||
dorestdoc = 0
|
||||
wrapfuncs = 1
|
||||
buildpath = '.'
|
||||
include_paths, freethreading_compatible, inputline = get_newer_options(inputline)
|
||||
signsfile, modulename = None, None
|
||||
options = {'buildpath': buildpath,
|
||||
'coutput': None,
|
||||
'f2py_wrapper_output': None}
|
||||
for l in inputline:
|
||||
if l == '':
|
||||
pass
|
||||
elif l == 'only:':
|
||||
f = 0
|
||||
elif l == 'skip:':
|
||||
f = -1
|
||||
elif l == ':':
|
||||
f = 1
|
||||
elif l[:8] == '--debug-':
|
||||
debug.append(l[8:])
|
||||
elif l == '--lower':
|
||||
dolc = 1
|
||||
elif l == '--build-dir':
|
||||
f6 = 1
|
||||
elif l == '--no-lower':
|
||||
dolc = 0
|
||||
elif l == '--quiet':
|
||||
verbose = 0
|
||||
elif l == '--verbose':
|
||||
verbose += 1
|
||||
elif l == '--latex-doc':
|
||||
dolatexdoc = 1
|
||||
elif l == '--no-latex-doc':
|
||||
dolatexdoc = 0
|
||||
elif l == '--rest-doc':
|
||||
dorestdoc = 1
|
||||
elif l == '--no-rest-doc':
|
||||
dorestdoc = 0
|
||||
elif l == '--wrap-functions':
|
||||
wrapfuncs = 1
|
||||
elif l == '--no-wrap-functions':
|
||||
wrapfuncs = 0
|
||||
elif l == '--short-latex':
|
||||
options['shortlatex'] = 1
|
||||
elif l == '--coutput':
|
||||
f8 = 1
|
||||
elif l == '--f2py-wrapper-output':
|
||||
f9 = 1
|
||||
elif l == '--f2cmap':
|
||||
f10 = 1
|
||||
elif l == '--overwrite-signature':
|
||||
options['h-overwrite'] = 1
|
||||
elif l == '-h':
|
||||
f2 = 1
|
||||
elif l == '-m':
|
||||
f3 = 1
|
||||
elif l[:2] == '-v':
|
||||
print(f2py_version)
|
||||
sys.exit()
|
||||
elif l == '--show-compilers':
|
||||
f5 = 1
|
||||
elif l[:8] == '-include':
|
||||
cfuncs.outneeds['userincludes'].append(l[9:-1])
|
||||
cfuncs.userincludes[l[9:-1]] = '#include ' + l[8:]
|
||||
elif l == '--skip-empty-wrappers':
|
||||
emptygen = False
|
||||
elif l[0] == '-':
|
||||
errmess('Unknown option %s\n' % repr(l))
|
||||
sys.exit()
|
||||
elif f2:
|
||||
f2 = 0
|
||||
signsfile = l
|
||||
elif f3:
|
||||
f3 = 0
|
||||
modulename = l
|
||||
elif f6:
|
||||
f6 = 0
|
||||
buildpath = l
|
||||
elif f8:
|
||||
f8 = 0
|
||||
options["coutput"] = l
|
||||
elif f9:
|
||||
f9 = 0
|
||||
options["f2py_wrapper_output"] = l
|
||||
elif f10:
|
||||
f10 = 0
|
||||
options["f2cmap_file"] = l
|
||||
elif f == 1:
|
||||
try:
|
||||
with open(l):
|
||||
pass
|
||||
files.append(l)
|
||||
except OSError as detail:
|
||||
errmess(f'OSError: {detail!s}. Skipping file "{l!s}".\n')
|
||||
elif f == -1:
|
||||
skipfuncs.append(l)
|
||||
elif f == 0:
|
||||
onlyfuncs.append(l)
|
||||
if not f5 and not files and not modulename:
|
||||
print(__usage__)
|
||||
sys.exit()
|
||||
if not os.path.isdir(buildpath):
|
||||
if not verbose:
|
||||
outmess('Creating build directory %s\n' % (buildpath))
|
||||
os.mkdir(buildpath)
|
||||
if signsfile:
|
||||
signsfile = os.path.join(buildpath, signsfile)
|
||||
if signsfile and os.path.isfile(signsfile) and 'h-overwrite' not in options:
|
||||
errmess(
|
||||
'Signature file "%s" exists!!! Use --overwrite-signature to overwrite.\n' % (signsfile))
|
||||
sys.exit()
|
||||
|
||||
options['emptygen'] = emptygen
|
||||
options['debug'] = debug
|
||||
options['verbose'] = verbose
|
||||
if dolc == -1 and not signsfile:
|
||||
options['do-lower'] = 0
|
||||
else:
|
||||
options['do-lower'] = dolc
|
||||
if modulename:
|
||||
options['module'] = modulename
|
||||
if signsfile:
|
||||
options['signsfile'] = signsfile
|
||||
if onlyfuncs:
|
||||
options['onlyfuncs'] = onlyfuncs
|
||||
if skipfuncs:
|
||||
options['skipfuncs'] = skipfuncs
|
||||
options['dolatexdoc'] = dolatexdoc
|
||||
options['dorestdoc'] = dorestdoc
|
||||
options['wrapfuncs'] = wrapfuncs
|
||||
options['buildpath'] = buildpath
|
||||
options['include_paths'] = include_paths
|
||||
options['requires_gil'] = not freethreading_compatible
|
||||
options.setdefault('f2cmap_file', None)
|
||||
return files, options
|
||||
|
||||
|
||||
def callcrackfortran(files, options):
|
||||
rules.options = options
|
||||
crackfortran.debug = options['debug']
|
||||
crackfortran.verbose = options['verbose']
|
||||
if 'module' in options:
|
||||
crackfortran.f77modulename = options['module']
|
||||
if 'skipfuncs' in options:
|
||||
crackfortran.skipfuncs = options['skipfuncs']
|
||||
if 'onlyfuncs' in options:
|
||||
crackfortran.onlyfuncs = options['onlyfuncs']
|
||||
crackfortran.include_paths[:] = options['include_paths']
|
||||
crackfortran.dolowercase = options['do-lower']
|
||||
postlist = crackfortran.crackfortran(files)
|
||||
if 'signsfile' in options:
|
||||
outmess('Saving signatures to file "%s"\n' % (options['signsfile']))
|
||||
pyf = crackfortran.crack2fortran(postlist)
|
||||
if options['signsfile'][-6:] == 'stdout':
|
||||
sys.stdout.write(pyf)
|
||||
else:
|
||||
with open(options['signsfile'], 'w') as f:
|
||||
f.write(pyf)
|
||||
if options["coutput"] is None:
|
||||
for mod in postlist:
|
||||
mod["coutput"] = "%smodule.c" % mod["name"]
|
||||
else:
|
||||
for mod in postlist:
|
||||
mod["coutput"] = options["coutput"]
|
||||
if options["f2py_wrapper_output"] is None:
|
||||
for mod in postlist:
|
||||
mod["f2py_wrapper_output"] = "%s-f2pywrappers.f" % mod["name"]
|
||||
else:
|
||||
for mod in postlist:
|
||||
mod["f2py_wrapper_output"] = options["f2py_wrapper_output"]
|
||||
for mod in postlist:
|
||||
if options["requires_gil"]:
|
||||
mod['gil_used'] = 'Py_MOD_GIL_USED'
|
||||
else:
|
||||
mod['gil_used'] = 'Py_MOD_GIL_NOT_USED'
|
||||
return postlist
|
||||
|
||||
|
||||
def buildmodules(lst):
|
||||
cfuncs.buildcfuncs()
|
||||
outmess('Building modules...\n')
|
||||
modules, mnames, isusedby = [], [], {}
|
||||
for item in lst:
|
||||
if '__user__' in item['name']:
|
||||
cb_rules.buildcallbacks(item)
|
||||
else:
|
||||
if 'use' in item:
|
||||
for u in item['use'].keys():
|
||||
if u not in isusedby:
|
||||
isusedby[u] = []
|
||||
isusedby[u].append(item['name'])
|
||||
modules.append(item)
|
||||
mnames.append(item['name'])
|
||||
ret = {}
|
||||
for module, name in zip(modules, mnames):
|
||||
if name in isusedby:
|
||||
outmess('\tSkipping module "%s" which is used by %s.\n' % (
|
||||
name, ','.join('"%s"' % s for s in isusedby[name])))
|
||||
else:
|
||||
um = []
|
||||
if 'use' in module:
|
||||
for u in module['use'].keys():
|
||||
if u in isusedby and u in mnames:
|
||||
um.append(modules[mnames.index(u)])
|
||||
else:
|
||||
outmess(
|
||||
f'\tModule "{name}" uses nonexisting "{u}" '
|
||||
'which will be ignored.\n')
|
||||
ret[name] = {}
|
||||
dict_append(ret[name], rules.buildmodule(module, um))
|
||||
return ret
|
||||
|
||||
|
||||
def dict_append(d_out, d_in):
|
||||
for (k, v) in d_in.items():
|
||||
if k not in d_out:
|
||||
d_out[k] = []
|
||||
if isinstance(v, list):
|
||||
d_out[k] = d_out[k] + v
|
||||
else:
|
||||
d_out[k].append(v)
|
||||
|
||||
|
||||
def run_main(comline_list):
|
||||
"""
|
||||
Equivalent to running::
|
||||
|
||||
f2py <args>
|
||||
|
||||
where ``<args>=string.join(<list>,' ')``, but in Python. Unless
|
||||
``-h`` is used, this function returns a dictionary containing
|
||||
information on generated modules and their dependencies on source
|
||||
files.
|
||||
|
||||
You cannot build extension modules with this function, that is,
|
||||
using ``-c`` is not allowed. Use the ``compile`` command instead.
|
||||
|
||||
Examples
|
||||
--------
|
||||
The command ``f2py -m scalar scalar.f`` can be executed from Python as
|
||||
follows.
|
||||
|
||||
.. literalinclude:: ../../source/f2py/code/results/run_main_session.dat
|
||||
:language: python
|
||||
|
||||
"""
|
||||
crackfortran.reset_global_f2py_vars()
|
||||
f2pydir = os.path.dirname(os.path.abspath(cfuncs.__file__))
|
||||
fobjhsrc = os.path.join(f2pydir, 'src', 'fortranobject.h')
|
||||
fobjcsrc = os.path.join(f2pydir, 'src', 'fortranobject.c')
|
||||
# gh-22819 -- begin
|
||||
parser = make_f2py_compile_parser()
|
||||
args, comline_list = parser.parse_known_args(comline_list)
|
||||
pyf_files, _ = filter_files("", "[.]pyf([.]src|)", comline_list)
|
||||
# Checks that no existing modulename is defined in a pyf file
|
||||
# TODO: Remove all this when scaninputline is replaced
|
||||
if args.module_name:
|
||||
if "-h" in comline_list:
|
||||
modname = (
|
||||
args.module_name
|
||||
) # Directly use from args when -h is present
|
||||
else:
|
||||
modname = validate_modulename(
|
||||
pyf_files, args.module_name
|
||||
) # Validate modname when -h is not present
|
||||
comline_list += ['-m', modname] # needed for the rest of scaninputline
|
||||
# gh-22819 -- end
|
||||
files, options = scaninputline(comline_list)
|
||||
auxfuncs.options = options
|
||||
capi_maps.load_f2cmap_file(options['f2cmap_file'])
|
||||
postlist = callcrackfortran(files, options)
|
||||
isusedby = {}
|
||||
for plist in postlist:
|
||||
if 'use' in plist:
|
||||
for u in plist['use'].keys():
|
||||
if u not in isusedby:
|
||||
isusedby[u] = []
|
||||
isusedby[u].append(plist['name'])
|
||||
for plist in postlist:
|
||||
if plist['block'] == 'python module' and '__user__' in plist['name']:
|
||||
if plist['name'] in isusedby:
|
||||
# if not quiet:
|
||||
outmess(
|
||||
f'Skipping Makefile build for module "{plist["name"]}" '
|
||||
'which is used by {}\n'.format(
|
||||
','.join(f'"{s}"' for s in isusedby[plist['name']])))
|
||||
if 'signsfile' in options:
|
||||
if options['verbose'] > 1:
|
||||
outmess(
|
||||
'Stopping. Edit the signature file and then run f2py on the signature file: ')
|
||||
outmess('%s %s\n' %
|
||||
(os.path.basename(sys.argv[0]), options['signsfile']))
|
||||
return
|
||||
for plist in postlist:
|
||||
if plist['block'] != 'python module':
|
||||
if 'python module' not in options:
|
||||
errmess(
|
||||
'Tip: If your original code is Fortran source then you must use -m option.\n')
|
||||
raise TypeError('All blocks must be python module blocks but got %s' % (
|
||||
repr(plist['block'])))
|
||||
auxfuncs.debugoptions = options['debug']
|
||||
f90mod_rules.options = options
|
||||
auxfuncs.wrapfuncs = options['wrapfuncs']
|
||||
|
||||
ret = buildmodules(postlist)
|
||||
|
||||
for mn in ret.keys():
|
||||
dict_append(ret[mn], {'csrc': fobjcsrc, 'h': fobjhsrc})
|
||||
return ret
|
||||
|
||||
|
||||
def filter_files(prefix, suffix, files, remove_prefix=None):
|
||||
"""
|
||||
Filter files by prefix and suffix.
|
||||
"""
|
||||
filtered, rest = [], []
|
||||
match = re.compile(prefix + r'.*' + suffix + r'\Z').match
|
||||
if remove_prefix:
|
||||
ind = len(prefix)
|
||||
else:
|
||||
ind = 0
|
||||
for file in [x.strip() for x in files]:
|
||||
if match(file):
|
||||
filtered.append(file[ind:])
|
||||
else:
|
||||
rest.append(file)
|
||||
return filtered, rest
|
||||
|
||||
|
||||
def get_prefix(module):
|
||||
p = os.path.dirname(os.path.dirname(module.__file__))
|
||||
return p
|
||||
|
||||
|
||||
class CombineIncludePaths(argparse.Action):
|
||||
def __call__(self, parser, namespace, values, option_string=None):
|
||||
include_paths_set = set(getattr(namespace, 'include_paths', []) or [])
|
||||
if option_string == "--include_paths":
|
||||
outmess("Use --include-paths or -I instead of --include_paths which will be removed")
|
||||
if option_string == "--include-paths" or option_string == "--include_paths":
|
||||
include_paths_set.update(values.split(':'))
|
||||
else:
|
||||
include_paths_set.add(values)
|
||||
setattr(namespace, 'include_paths', list(include_paths_set))
|
||||
|
||||
def f2py_parser():
|
||||
parser = argparse.ArgumentParser(add_help=False)
|
||||
parser.add_argument("-I", dest="include_paths", action=CombineIncludePaths)
|
||||
parser.add_argument("--include-paths", dest="include_paths", action=CombineIncludePaths)
|
||||
parser.add_argument("--include_paths", dest="include_paths", action=CombineIncludePaths)
|
||||
parser.add_argument("--freethreading-compatible", dest="ftcompat", action=argparse.BooleanOptionalAction)
|
||||
return parser
|
||||
|
||||
def get_newer_options(iline):
|
||||
iline = (' '.join(iline)).split()
|
||||
parser = f2py_parser()
|
||||
args, remain = parser.parse_known_args(iline)
|
||||
ipaths = args.include_paths
|
||||
if args.include_paths is None:
|
||||
ipaths = []
|
||||
return ipaths, args.ftcompat, remain
|
||||
|
||||
def make_f2py_compile_parser():
|
||||
parser = argparse.ArgumentParser(add_help=False)
|
||||
parser.add_argument("--dep", action="append", dest="dependencies")
|
||||
parser.add_argument("--backend", choices=['meson', 'distutils'], default='distutils')
|
||||
parser.add_argument("-m", dest="module_name")
|
||||
return parser
|
||||
|
||||
def preparse_sysargv():
|
||||
# To keep backwards bug compatibility, newer flags are handled by argparse,
|
||||
# and `sys.argv` is passed to the rest of `f2py` as is.
|
||||
parser = make_f2py_compile_parser()
|
||||
|
||||
args, remaining_argv = parser.parse_known_args()
|
||||
sys.argv = [sys.argv[0]] + remaining_argv
|
||||
|
||||
backend_key = args.backend
|
||||
if MESON_ONLY_VER and backend_key == 'distutils':
|
||||
outmess("Cannot use distutils backend with Python>=3.12,"
|
||||
" using meson backend instead.\n")
|
||||
backend_key = "meson"
|
||||
|
||||
return {
|
||||
"dependencies": args.dependencies or [],
|
||||
"backend": backend_key,
|
||||
"modulename": args.module_name,
|
||||
}
|
||||
|
||||
def run_compile():
|
||||
"""
|
||||
Do it all in one call!
|
||||
"""
|
||||
import tempfile
|
||||
|
||||
# Collect dependency flags, preprocess sys.argv
|
||||
argy = preparse_sysargv()
|
||||
modulename = argy["modulename"]
|
||||
if modulename is None:
|
||||
modulename = 'untitled'
|
||||
dependencies = argy["dependencies"]
|
||||
backend_key = argy["backend"]
|
||||
build_backend = f2py_build_generator(backend_key)
|
||||
|
||||
i = sys.argv.index('-c')
|
||||
del sys.argv[i]
|
||||
|
||||
remove_build_dir = 0
|
||||
try:
|
||||
i = sys.argv.index('--build-dir')
|
||||
except ValueError:
|
||||
i = None
|
||||
if i is not None:
|
||||
build_dir = sys.argv[i + 1]
|
||||
del sys.argv[i + 1]
|
||||
del sys.argv[i]
|
||||
else:
|
||||
remove_build_dir = 1
|
||||
build_dir = tempfile.mkdtemp()
|
||||
|
||||
_reg1 = re.compile(r'--link-')
|
||||
sysinfo_flags = [_m for _m in sys.argv[1:] if _reg1.match(_m)]
|
||||
sys.argv = [_m for _m in sys.argv if _m not in sysinfo_flags]
|
||||
if sysinfo_flags:
|
||||
sysinfo_flags = [f[7:] for f in sysinfo_flags]
|
||||
|
||||
_reg2 = re.compile(
|
||||
r'--((no-|)(wrap-functions|lower|freethreading-compatible)|debug-capi|quiet|skip-empty-wrappers)|-include')
|
||||
f2py_flags = [_m for _m in sys.argv[1:] if _reg2.match(_m)]
|
||||
sys.argv = [_m for _m in sys.argv if _m not in f2py_flags]
|
||||
f2py_flags2 = []
|
||||
fl = 0
|
||||
for a in sys.argv[1:]:
|
||||
if a in ['only:', 'skip:']:
|
||||
fl = 1
|
||||
elif a == ':':
|
||||
fl = 0
|
||||
if fl or a == ':':
|
||||
f2py_flags2.append(a)
|
||||
if f2py_flags2 and f2py_flags2[-1] != ':':
|
||||
f2py_flags2.append(':')
|
||||
f2py_flags.extend(f2py_flags2)
|
||||
sys.argv = [_m for _m in sys.argv if _m not in f2py_flags2]
|
||||
_reg3 = re.compile(
|
||||
r'--((f(90)?compiler(-exec|)|compiler)=|help-compiler)')
|
||||
flib_flags = [_m for _m in sys.argv[1:] if _reg3.match(_m)]
|
||||
sys.argv = [_m for _m in sys.argv if _m not in flib_flags]
|
||||
# TODO: Once distutils is dropped completely, i.e. min_ver >= 3.12, unify into --fflags
|
||||
reg_f77_f90_flags = re.compile(r'--f(77|90)flags=')
|
||||
reg_distutils_flags = re.compile(r'--((f(77|90)exec|opt|arch)=|(debug|noopt|noarch|help-fcompiler))')
|
||||
fc_flags = [_m for _m in sys.argv[1:] if reg_f77_f90_flags.match(_m)]
|
||||
distutils_flags = [_m for _m in sys.argv[1:] if reg_distutils_flags.match(_m)]
|
||||
if not (MESON_ONLY_VER or backend_key == 'meson'):
|
||||
fc_flags.extend(distutils_flags)
|
||||
sys.argv = [_m for _m in sys.argv if _m not in (fc_flags + distutils_flags)]
|
||||
|
||||
del_list = []
|
||||
for s in flib_flags:
|
||||
v = '--fcompiler='
|
||||
if s[:len(v)] == v:
|
||||
if MESON_ONLY_VER or backend_key == 'meson':
|
||||
outmess(
|
||||
"--fcompiler cannot be used with meson,"
|
||||
"set compiler with the FC environment variable\n"
|
||||
)
|
||||
else:
|
||||
from numpy.distutils import fcompiler
|
||||
fcompiler.load_all_fcompiler_classes()
|
||||
allowed_keys = list(fcompiler.fcompiler_class.keys())
|
||||
nv = ov = s[len(v):].lower()
|
||||
if ov not in allowed_keys:
|
||||
vmap = {} # XXX
|
||||
try:
|
||||
nv = vmap[ov]
|
||||
except KeyError:
|
||||
if ov not in vmap.values():
|
||||
print('Unknown vendor: "%s"' % (s[len(v):]))
|
||||
nv = ov
|
||||
i = flib_flags.index(s)
|
||||
flib_flags[i] = '--fcompiler=' + nv
|
||||
continue
|
||||
for s in del_list:
|
||||
i = flib_flags.index(s)
|
||||
del flib_flags[i]
|
||||
assert len(flib_flags) <= 2, repr(flib_flags)
|
||||
|
||||
_reg5 = re.compile(r'--(verbose)')
|
||||
setup_flags = [_m for _m in sys.argv[1:] if _reg5.match(_m)]
|
||||
sys.argv = [_m for _m in sys.argv if _m not in setup_flags]
|
||||
|
||||
if '--quiet' in f2py_flags:
|
||||
setup_flags.append('--quiet')
|
||||
|
||||
# Ugly filter to remove everything but sources
|
||||
sources = sys.argv[1:]
|
||||
f2cmapopt = '--f2cmap'
|
||||
if f2cmapopt in sys.argv:
|
||||
i = sys.argv.index(f2cmapopt)
|
||||
f2py_flags.extend(sys.argv[i:i + 2])
|
||||
del sys.argv[i + 1], sys.argv[i]
|
||||
sources = sys.argv[1:]
|
||||
|
||||
pyf_files, _sources = filter_files("", "[.]pyf([.]src|)", sources)
|
||||
sources = pyf_files + _sources
|
||||
modulename = validate_modulename(pyf_files, modulename)
|
||||
extra_objects, sources = filter_files('', '[.](o|a|so|dylib)', sources)
|
||||
library_dirs, sources = filter_files('-L', '', sources, remove_prefix=1)
|
||||
libraries, sources = filter_files('-l', '', sources, remove_prefix=1)
|
||||
undef_macros, sources = filter_files('-U', '', sources, remove_prefix=1)
|
||||
define_macros, sources = filter_files('-D', '', sources, remove_prefix=1)
|
||||
for i in range(len(define_macros)):
|
||||
name_value = define_macros[i].split('=', 1)
|
||||
if len(name_value) == 1:
|
||||
name_value.append(None)
|
||||
if len(name_value) == 2:
|
||||
define_macros[i] = tuple(name_value)
|
||||
else:
|
||||
print('Invalid use of -D:', name_value)
|
||||
|
||||
# Construct wrappers / signatures / things
|
||||
if backend_key == 'meson':
|
||||
if not pyf_files:
|
||||
outmess('Using meson backend\nWill pass --lower to f2py\nSee https://numpy.org/doc/stable/f2py/buildtools/meson.html\n')
|
||||
f2py_flags.append('--lower')
|
||||
run_main(f" {' '.join(f2py_flags)} -m {modulename} {' '.join(sources)}".split())
|
||||
else:
|
||||
run_main(f" {' '.join(f2py_flags)} {' '.join(pyf_files)}".split())
|
||||
|
||||
# Order matters here, includes are needed for run_main above
|
||||
include_dirs, _, sources = get_newer_options(sources)
|
||||
# Now use the builder
|
||||
builder = build_backend(
|
||||
modulename,
|
||||
sources,
|
||||
extra_objects,
|
||||
build_dir,
|
||||
include_dirs,
|
||||
library_dirs,
|
||||
libraries,
|
||||
define_macros,
|
||||
undef_macros,
|
||||
f2py_flags,
|
||||
sysinfo_flags,
|
||||
fc_flags,
|
||||
flib_flags,
|
||||
setup_flags,
|
||||
remove_build_dir,
|
||||
{"dependencies": dependencies},
|
||||
)
|
||||
|
||||
builder.compile()
|
||||
|
||||
|
||||
def validate_modulename(pyf_files, modulename='untitled'):
|
||||
if len(pyf_files) > 1:
|
||||
raise ValueError("Only one .pyf file per call")
|
||||
if pyf_files:
|
||||
pyff = pyf_files[0]
|
||||
pyf_modname = auxfuncs.get_f2py_modulename(pyff)
|
||||
if modulename != pyf_modname:
|
||||
outmess(
|
||||
f"Ignoring -m {modulename}.\n"
|
||||
f"{pyff} defines {pyf_modname} to be the modulename.\n"
|
||||
)
|
||||
modulename = pyf_modname
|
||||
return modulename
|
||||
|
||||
def main():
|
||||
if '--help-link' in sys.argv[1:]:
|
||||
sys.argv.remove('--help-link')
|
||||
if MESON_ONLY_VER:
|
||||
outmess("Use --dep for meson builds\n")
|
||||
else:
|
||||
from numpy.distutils.system_info import show_all
|
||||
show_all()
|
||||
return
|
||||
|
||||
if '-c' in sys.argv[1:]:
|
||||
run_compile()
|
||||
else:
|
||||
run_main(sys.argv[1:])
|
272
venv/lib/python3.12/site-packages/numpy/f2py/f90mod_rules.py
Normal file
272
venv/lib/python3.12/site-packages/numpy/f2py/f90mod_rules.py
Normal file
@ -0,0 +1,272 @@
|
||||
"""
|
||||
Build F90 module support for f2py2e.
|
||||
|
||||
Copyright 1999 -- 2011 Pearu Peterson all rights reserved.
|
||||
Copyright 2011 -- present NumPy Developers.
|
||||
Permission to use, modify, and distribute this software is given under the
|
||||
terms of the NumPy License.
|
||||
|
||||
NO WARRANTY IS EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
|
||||
"""
|
||||
__version__ = "$Revision: 1.27 $"[10:-1]
|
||||
|
||||
f2py_version = 'See `f2py -v`'
|
||||
|
||||
import numpy as np
|
||||
|
||||
from . import capi_maps
|
||||
from . import func2subr
|
||||
from .crackfortran import undo_rmbadname, undo_rmbadname1
|
||||
|
||||
# The environment provided by auxfuncs.py is needed for some calls to eval.
|
||||
# As the needed functions cannot be determined by static inspection of the
|
||||
# code, it is safest to use import * pending a major refactoring of f2py.
|
||||
from .auxfuncs import *
|
||||
|
||||
options = {}
|
||||
|
||||
|
||||
def findf90modules(m):
|
||||
if ismodule(m):
|
||||
return [m]
|
||||
if not hasbody(m):
|
||||
return []
|
||||
ret = []
|
||||
for b in m['body']:
|
||||
if ismodule(b):
|
||||
ret.append(b)
|
||||
else:
|
||||
ret = ret + findf90modules(b)
|
||||
return ret
|
||||
|
||||
fgetdims1 = """\
|
||||
external f2pysetdata
|
||||
logical ns
|
||||
integer r,i
|
||||
integer(%d) s(*)
|
||||
ns = .FALSE.
|
||||
if (allocated(d)) then
|
||||
do i=1,r
|
||||
if ((size(d,i).ne.s(i)).and.(s(i).ge.0)) then
|
||||
ns = .TRUE.
|
||||
end if
|
||||
end do
|
||||
if (ns) then
|
||||
deallocate(d)
|
||||
end if
|
||||
end if
|
||||
if ((.not.allocated(d)).and.(s(1).ge.1)) then""" % np.intp().itemsize
|
||||
|
||||
fgetdims2 = """\
|
||||
end if
|
||||
if (allocated(d)) then
|
||||
do i=1,r
|
||||
s(i) = size(d,i)
|
||||
end do
|
||||
end if
|
||||
flag = 1
|
||||
call f2pysetdata(d,allocated(d))"""
|
||||
|
||||
fgetdims2_sa = """\
|
||||
end if
|
||||
if (allocated(d)) then
|
||||
do i=1,r
|
||||
s(i) = size(d,i)
|
||||
end do
|
||||
!s(r) must be equal to len(d(1))
|
||||
end if
|
||||
flag = 2
|
||||
call f2pysetdata(d,allocated(d))"""
|
||||
|
||||
|
||||
def buildhooks(pymod):
|
||||
from . import rules
|
||||
ret = {'f90modhooks': [], 'initf90modhooks': [], 'body': [],
|
||||
'need': ['F_FUNC', 'arrayobject.h'],
|
||||
'separatorsfor': {'includes0': '\n', 'includes': '\n'},
|
||||
'docs': ['"Fortran 90/95 modules:\\n"'],
|
||||
'latexdoc': []}
|
||||
fhooks = ['']
|
||||
|
||||
def fadd(line, s=fhooks):
|
||||
s[0] = '%s\n %s' % (s[0], line)
|
||||
doc = ['']
|
||||
|
||||
def dadd(line, s=doc):
|
||||
s[0] = '%s\n%s' % (s[0], line)
|
||||
|
||||
usenames = getuseblocks(pymod)
|
||||
for m in findf90modules(pymod):
|
||||
contains_functions_or_subroutines = any(
|
||||
item for item in m["body"] if item["block"] in ["function", "subroutine"]
|
||||
)
|
||||
sargs, fargs, efargs, modobjs, notvars, onlyvars = [], [], [], [], [
|
||||
m['name']], []
|
||||
sargsp = []
|
||||
ifargs = []
|
||||
mfargs = []
|
||||
if hasbody(m):
|
||||
for b in m['body']:
|
||||
notvars.append(b['name'])
|
||||
for n in m['vars'].keys():
|
||||
var = m['vars'][n]
|
||||
|
||||
if (n not in notvars and isvariable(var)) and (not l_or(isintent_hide, isprivate)(var)):
|
||||
onlyvars.append(n)
|
||||
mfargs.append(n)
|
||||
outmess('\t\tConstructing F90 module support for "%s"...\n' %
|
||||
(m['name']))
|
||||
if len(onlyvars) == 0 and len(notvars) == 1 and m['name'] in notvars:
|
||||
outmess(f"\t\t\tSkipping {m['name']} since there are no public vars/func in this module...\n")
|
||||
continue
|
||||
|
||||
if m['name'] in usenames and not contains_functions_or_subroutines:
|
||||
outmess(f"\t\t\tSkipping {m['name']} since it is in 'use'...\n")
|
||||
continue
|
||||
if onlyvars:
|
||||
outmess('\t\t Variables: %s\n' % (' '.join(onlyvars)))
|
||||
chooks = ['']
|
||||
|
||||
def cadd(line, s=chooks):
|
||||
s[0] = '%s\n%s' % (s[0], line)
|
||||
ihooks = ['']
|
||||
|
||||
def iadd(line, s=ihooks):
|
||||
s[0] = '%s\n%s' % (s[0], line)
|
||||
|
||||
vrd = capi_maps.modsign2map(m)
|
||||
cadd('static FortranDataDef f2py_%s_def[] = {' % (m['name']))
|
||||
dadd('\\subsection{Fortran 90/95 module \\texttt{%s}}\n' % (m['name']))
|
||||
if hasnote(m):
|
||||
note = m['note']
|
||||
if isinstance(note, list):
|
||||
note = '\n'.join(note)
|
||||
dadd(note)
|
||||
if onlyvars:
|
||||
dadd('\\begin{description}')
|
||||
for n in onlyvars:
|
||||
var = m['vars'][n]
|
||||
modobjs.append(n)
|
||||
ct = capi_maps.getctype(var)
|
||||
at = capi_maps.c2capi_map[ct]
|
||||
dm = capi_maps.getarrdims(n, var)
|
||||
dms = dm['dims'].replace('*', '-1').strip()
|
||||
dms = dms.replace(':', '-1').strip()
|
||||
if not dms:
|
||||
dms = '-1'
|
||||
use_fgetdims2 = fgetdims2
|
||||
cadd('\t{"%s",%s,{{%s}},%s, %s},' %
|
||||
(undo_rmbadname1(n), dm['rank'], dms, at,
|
||||
capi_maps.get_elsize(var)))
|
||||
dadd('\\item[]{{}\\verb@%s@{}}' %
|
||||
(capi_maps.getarrdocsign(n, var)))
|
||||
if hasnote(var):
|
||||
note = var['note']
|
||||
if isinstance(note, list):
|
||||
note = '\n'.join(note)
|
||||
dadd('--- %s' % (note))
|
||||
if isallocatable(var):
|
||||
fargs.append('f2py_%s_getdims_%s' % (m['name'], n))
|
||||
efargs.append(fargs[-1])
|
||||
sargs.append(
|
||||
'void (*%s)(int*,npy_intp*,void(*)(char*,npy_intp*),int*)' % (n))
|
||||
sargsp.append('void (*)(int*,npy_intp*,void(*)(char*,npy_intp*),int*)')
|
||||
iadd('\tf2py_%s_def[i_f2py++].func = %s;' % (m['name'], n))
|
||||
fadd('subroutine %s(r,s,f2pysetdata,flag)' % (fargs[-1]))
|
||||
fadd('use %s, only: d => %s\n' %
|
||||
(m['name'], undo_rmbadname1(n)))
|
||||
fadd('integer flag\n')
|
||||
fhooks[0] = fhooks[0] + fgetdims1
|
||||
dms = range(1, int(dm['rank']) + 1)
|
||||
fadd(' allocate(d(%s))\n' %
|
||||
(','.join(['s(%s)' % i for i in dms])))
|
||||
fhooks[0] = fhooks[0] + use_fgetdims2
|
||||
fadd('end subroutine %s' % (fargs[-1]))
|
||||
else:
|
||||
fargs.append(n)
|
||||
sargs.append('char *%s' % (n))
|
||||
sargsp.append('char*')
|
||||
iadd('\tf2py_%s_def[i_f2py++].data = %s;' % (m['name'], n))
|
||||
if onlyvars:
|
||||
dadd('\\end{description}')
|
||||
if hasbody(m):
|
||||
for b in m['body']:
|
||||
if not isroutine(b):
|
||||
outmess("f90mod_rules.buildhooks:"
|
||||
f" skipping {b['block']} {b['name']}\n")
|
||||
continue
|
||||
modobjs.append('%s()' % (b['name']))
|
||||
b['modulename'] = m['name']
|
||||
api, wrap = rules.buildapi(b)
|
||||
if isfunction(b):
|
||||
fhooks[0] = fhooks[0] + wrap
|
||||
fargs.append('f2pywrap_%s_%s' % (m['name'], b['name']))
|
||||
ifargs.append(func2subr.createfuncwrapper(b, signature=1))
|
||||
else:
|
||||
if wrap:
|
||||
fhooks[0] = fhooks[0] + wrap
|
||||
fargs.append('f2pywrap_%s_%s' % (m['name'], b['name']))
|
||||
ifargs.append(
|
||||
func2subr.createsubrwrapper(b, signature=1))
|
||||
else:
|
||||
fargs.append(b['name'])
|
||||
mfargs.append(fargs[-1])
|
||||
api['externroutines'] = []
|
||||
ar = applyrules(api, vrd)
|
||||
ar['docs'] = []
|
||||
ar['docshort'] = []
|
||||
ret = dictappend(ret, ar)
|
||||
cadd(('\t{"%s",-1,{{-1}},0,0,NULL,(void *)'
|
||||
'f2py_rout_#modulename#_%s_%s,'
|
||||
'doc_f2py_rout_#modulename#_%s_%s},')
|
||||
% (b['name'], m['name'], b['name'], m['name'], b['name']))
|
||||
sargs.append('char *%s' % (b['name']))
|
||||
sargsp.append('char *')
|
||||
iadd('\tf2py_%s_def[i_f2py++].data = %s;' %
|
||||
(m['name'], b['name']))
|
||||
cadd('\t{NULL}\n};\n')
|
||||
iadd('}')
|
||||
ihooks[0] = 'static void f2py_setup_%s(%s) {\n\tint i_f2py=0;%s' % (
|
||||
m['name'], ','.join(sargs), ihooks[0])
|
||||
if '_' in m['name']:
|
||||
F_FUNC = 'F_FUNC_US'
|
||||
else:
|
||||
F_FUNC = 'F_FUNC'
|
||||
iadd('extern void %s(f2pyinit%s,F2PYINIT%s)(void (*)(%s));'
|
||||
% (F_FUNC, m['name'], m['name'].upper(), ','.join(sargsp)))
|
||||
iadd('static void f2py_init_%s(void) {' % (m['name']))
|
||||
iadd('\t%s(f2pyinit%s,F2PYINIT%s)(f2py_setup_%s);'
|
||||
% (F_FUNC, m['name'], m['name'].upper(), m['name']))
|
||||
iadd('}\n')
|
||||
ret['f90modhooks'] = ret['f90modhooks'] + chooks + ihooks
|
||||
ret['initf90modhooks'] = ['\tPyDict_SetItemString(d, "%s", PyFortranObject_New(f2py_%s_def,f2py_init_%s));' % (
|
||||
m['name'], m['name'], m['name'])] + ret['initf90modhooks']
|
||||
fadd('')
|
||||
fadd('subroutine f2pyinit%s(f2pysetupfunc)' % (m['name']))
|
||||
if mfargs:
|
||||
for a in undo_rmbadname(mfargs):
|
||||
fadd('use %s, only : %s' % (m['name'], a))
|
||||
if ifargs:
|
||||
fadd(' '.join(['interface'] + ifargs))
|
||||
fadd('end interface')
|
||||
fadd('external f2pysetupfunc')
|
||||
if efargs:
|
||||
for a in undo_rmbadname(efargs):
|
||||
fadd('external %s' % (a))
|
||||
fadd('call f2pysetupfunc(%s)' % (','.join(undo_rmbadname(fargs))))
|
||||
fadd('end subroutine f2pyinit%s\n' % (m['name']))
|
||||
|
||||
dadd('\n'.join(ret['latexdoc']).replace(
|
||||
r'\subsection{', r'\subsubsection{'))
|
||||
|
||||
ret['latexdoc'] = []
|
||||
ret['docs'].append('"\t%s --- %s"' % (m['name'],
|
||||
','.join(undo_rmbadname(modobjs))))
|
||||
|
||||
ret['routine_defs'] = ''
|
||||
ret['doc'] = []
|
||||
ret['docshort'] = []
|
||||
ret['latexdoc'] = doc[0]
|
||||
if len(ret['docs']) <= 1:
|
||||
ret['docs'] = ''
|
||||
return ret, fhooks[0]
|
323
venv/lib/python3.12/site-packages/numpy/f2py/func2subr.py
Normal file
323
venv/lib/python3.12/site-packages/numpy/f2py/func2subr.py
Normal file
@ -0,0 +1,323 @@
|
||||
"""
|
||||
|
||||
Rules for building C/API module with f2py2e.
|
||||
|
||||
Copyright 1999 -- 2011 Pearu Peterson all rights reserved.
|
||||
Copyright 2011 -- present NumPy Developers.
|
||||
Permission to use, modify, and distribute this software is given under the
|
||||
terms of the NumPy License.
|
||||
|
||||
NO WARRANTY IS EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
|
||||
"""
|
||||
import copy
|
||||
|
||||
from .auxfuncs import (
|
||||
getfortranname, isexternal, isfunction, isfunction_wrap, isintent_in,
|
||||
isintent_out, islogicalfunction, ismoduleroutine, isscalar,
|
||||
issubroutine, issubroutine_wrap, outmess, show
|
||||
)
|
||||
|
||||
from ._isocbind import isoc_kindmap
|
||||
|
||||
def var2fixfortran(vars, a, fa=None, f90mode=None):
|
||||
if fa is None:
|
||||
fa = a
|
||||
if a not in vars:
|
||||
show(vars)
|
||||
outmess('var2fixfortran: No definition for argument "%s".\n' % a)
|
||||
return ''
|
||||
if 'typespec' not in vars[a]:
|
||||
show(vars[a])
|
||||
outmess('var2fixfortran: No typespec for argument "%s".\n' % a)
|
||||
return ''
|
||||
vardef = vars[a]['typespec']
|
||||
if vardef == 'type' and 'typename' in vars[a]:
|
||||
vardef = '%s(%s)' % (vardef, vars[a]['typename'])
|
||||
selector = {}
|
||||
lk = ''
|
||||
if 'kindselector' in vars[a]:
|
||||
selector = vars[a]['kindselector']
|
||||
lk = 'kind'
|
||||
elif 'charselector' in vars[a]:
|
||||
selector = vars[a]['charselector']
|
||||
lk = 'len'
|
||||
if '*' in selector:
|
||||
if f90mode:
|
||||
if selector['*'] in ['*', ':', '(*)']:
|
||||
vardef = '%s(len=*)' % (vardef)
|
||||
else:
|
||||
vardef = '%s(%s=%s)' % (vardef, lk, selector['*'])
|
||||
else:
|
||||
if selector['*'] in ['*', ':']:
|
||||
vardef = '%s*(%s)' % (vardef, selector['*'])
|
||||
else:
|
||||
vardef = '%s*%s' % (vardef, selector['*'])
|
||||
else:
|
||||
if 'len' in selector:
|
||||
vardef = '%s(len=%s' % (vardef, selector['len'])
|
||||
if 'kind' in selector:
|
||||
vardef = '%s,kind=%s)' % (vardef, selector['kind'])
|
||||
else:
|
||||
vardef = '%s)' % (vardef)
|
||||
elif 'kind' in selector:
|
||||
vardef = '%s(kind=%s)' % (vardef, selector['kind'])
|
||||
|
||||
vardef = '%s %s' % (vardef, fa)
|
||||
if 'dimension' in vars[a]:
|
||||
vardef = '%s(%s)' % (vardef, ','.join(vars[a]['dimension']))
|
||||
return vardef
|
||||
|
||||
def useiso_c_binding(rout):
|
||||
useisoc = False
|
||||
for key, value in rout['vars'].items():
|
||||
kind_value = value.get('kindselector', {}).get('kind')
|
||||
if kind_value in isoc_kindmap:
|
||||
return True
|
||||
return useisoc
|
||||
|
||||
def createfuncwrapper(rout, signature=0):
|
||||
assert isfunction(rout)
|
||||
|
||||
extra_args = []
|
||||
vars = rout['vars']
|
||||
for a in rout['args']:
|
||||
v = rout['vars'][a]
|
||||
for i, d in enumerate(v.get('dimension', [])):
|
||||
if d == ':':
|
||||
dn = 'f2py_%s_d%s' % (a, i)
|
||||
dv = dict(typespec='integer', intent=['hide'])
|
||||
dv['='] = 'shape(%s, %s)' % (a, i)
|
||||
extra_args.append(dn)
|
||||
vars[dn] = dv
|
||||
v['dimension'][i] = dn
|
||||
rout['args'].extend(extra_args)
|
||||
need_interface = bool(extra_args)
|
||||
|
||||
ret = ['']
|
||||
|
||||
def add(line, ret=ret):
|
||||
ret[0] = '%s\n %s' % (ret[0], line)
|
||||
name = rout['name']
|
||||
fortranname = getfortranname(rout)
|
||||
f90mode = ismoduleroutine(rout)
|
||||
newname = '%sf2pywrap' % (name)
|
||||
|
||||
if newname not in vars:
|
||||
vars[newname] = vars[name]
|
||||
args = [newname] + rout['args'][1:]
|
||||
else:
|
||||
args = [newname] + rout['args']
|
||||
|
||||
l_tmpl = var2fixfortran(vars, name, '@@@NAME@@@', f90mode)
|
||||
if l_tmpl[:13] == 'character*(*)':
|
||||
if f90mode:
|
||||
l_tmpl = 'character(len=10)' + l_tmpl[13:]
|
||||
else:
|
||||
l_tmpl = 'character*10' + l_tmpl[13:]
|
||||
charselect = vars[name]['charselector']
|
||||
if charselect.get('*', '') == '(*)':
|
||||
charselect['*'] = '10'
|
||||
|
||||
l1 = l_tmpl.replace('@@@NAME@@@', newname)
|
||||
rl = None
|
||||
|
||||
useisoc = useiso_c_binding(rout)
|
||||
sargs = ', '.join(args)
|
||||
if f90mode:
|
||||
# gh-23598 fix warning
|
||||
# Essentially, this gets called again with modules where the name of the
|
||||
# function is added to the arguments, which is not required, and removed
|
||||
sargs = sargs.replace(f"{name}, ", '')
|
||||
args = [arg for arg in args if arg != name]
|
||||
rout['args'] = args
|
||||
add('subroutine f2pywrap_%s_%s (%s)' %
|
||||
(rout['modulename'], name, sargs))
|
||||
if not signature:
|
||||
add('use %s, only : %s' % (rout['modulename'], fortranname))
|
||||
if useisoc:
|
||||
add('use iso_c_binding')
|
||||
else:
|
||||
add('subroutine f2pywrap%s (%s)' % (name, sargs))
|
||||
if useisoc:
|
||||
add('use iso_c_binding')
|
||||
if not need_interface:
|
||||
add('external %s' % (fortranname))
|
||||
rl = l_tmpl.replace('@@@NAME@@@', '') + ' ' + fortranname
|
||||
|
||||
if need_interface:
|
||||
for line in rout['saved_interface'].split('\n'):
|
||||
if line.lstrip().startswith('use ') and '__user__' not in line:
|
||||
add(line)
|
||||
|
||||
args = args[1:]
|
||||
dumped_args = []
|
||||
for a in args:
|
||||
if isexternal(vars[a]):
|
||||
add('external %s' % (a))
|
||||
dumped_args.append(a)
|
||||
for a in args:
|
||||
if a in dumped_args:
|
||||
continue
|
||||
if isscalar(vars[a]):
|
||||
add(var2fixfortran(vars, a, f90mode=f90mode))
|
||||
dumped_args.append(a)
|
||||
for a in args:
|
||||
if a in dumped_args:
|
||||
continue
|
||||
if isintent_in(vars[a]):
|
||||
add(var2fixfortran(vars, a, f90mode=f90mode))
|
||||
dumped_args.append(a)
|
||||
for a in args:
|
||||
if a in dumped_args:
|
||||
continue
|
||||
add(var2fixfortran(vars, a, f90mode=f90mode))
|
||||
|
||||
add(l1)
|
||||
if rl is not None:
|
||||
add(rl)
|
||||
|
||||
if need_interface:
|
||||
if f90mode:
|
||||
# f90 module already defines needed interface
|
||||
pass
|
||||
else:
|
||||
add('interface')
|
||||
add(rout['saved_interface'].lstrip())
|
||||
add('end interface')
|
||||
|
||||
sargs = ', '.join([a for a in args if a not in extra_args])
|
||||
|
||||
if not signature:
|
||||
if islogicalfunction(rout):
|
||||
add('%s = .not.(.not.%s(%s))' % (newname, fortranname, sargs))
|
||||
else:
|
||||
add('%s = %s(%s)' % (newname, fortranname, sargs))
|
||||
if f90mode:
|
||||
add('end subroutine f2pywrap_%s_%s' % (rout['modulename'], name))
|
||||
else:
|
||||
add('end')
|
||||
return ret[0]
|
||||
|
||||
|
||||
def createsubrwrapper(rout, signature=0):
|
||||
assert issubroutine(rout)
|
||||
|
||||
extra_args = []
|
||||
vars = rout['vars']
|
||||
for a in rout['args']:
|
||||
v = rout['vars'][a]
|
||||
for i, d in enumerate(v.get('dimension', [])):
|
||||
if d == ':':
|
||||
dn = 'f2py_%s_d%s' % (a, i)
|
||||
dv = dict(typespec='integer', intent=['hide'])
|
||||
dv['='] = 'shape(%s, %s)' % (a, i)
|
||||
extra_args.append(dn)
|
||||
vars[dn] = dv
|
||||
v['dimension'][i] = dn
|
||||
rout['args'].extend(extra_args)
|
||||
need_interface = bool(extra_args)
|
||||
|
||||
ret = ['']
|
||||
|
||||
def add(line, ret=ret):
|
||||
ret[0] = '%s\n %s' % (ret[0], line)
|
||||
name = rout['name']
|
||||
fortranname = getfortranname(rout)
|
||||
f90mode = ismoduleroutine(rout)
|
||||
|
||||
args = rout['args']
|
||||
|
||||
useisoc = useiso_c_binding(rout)
|
||||
sargs = ', '.join(args)
|
||||
if f90mode:
|
||||
add('subroutine f2pywrap_%s_%s (%s)' %
|
||||
(rout['modulename'], name, sargs))
|
||||
if useisoc:
|
||||
add('use iso_c_binding')
|
||||
if not signature:
|
||||
add('use %s, only : %s' % (rout['modulename'], fortranname))
|
||||
else:
|
||||
add('subroutine f2pywrap%s (%s)' % (name, sargs))
|
||||
if useisoc:
|
||||
add('use iso_c_binding')
|
||||
if not need_interface:
|
||||
add('external %s' % (fortranname))
|
||||
|
||||
if need_interface:
|
||||
for line in rout['saved_interface'].split('\n'):
|
||||
if line.lstrip().startswith('use ') and '__user__' not in line:
|
||||
add(line)
|
||||
|
||||
dumped_args = []
|
||||
for a in args:
|
||||
if isexternal(vars[a]):
|
||||
add('external %s' % (a))
|
||||
dumped_args.append(a)
|
||||
for a in args:
|
||||
if a in dumped_args:
|
||||
continue
|
||||
if isscalar(vars[a]):
|
||||
add(var2fixfortran(vars, a, f90mode=f90mode))
|
||||
dumped_args.append(a)
|
||||
for a in args:
|
||||
if a in dumped_args:
|
||||
continue
|
||||
add(var2fixfortran(vars, a, f90mode=f90mode))
|
||||
|
||||
if need_interface:
|
||||
if f90mode:
|
||||
# f90 module already defines needed interface
|
||||
pass
|
||||
else:
|
||||
add('interface')
|
||||
for line in rout['saved_interface'].split('\n'):
|
||||
if line.lstrip().startswith('use ') and '__user__' in line:
|
||||
continue
|
||||
add(line)
|
||||
add('end interface')
|
||||
|
||||
sargs = ', '.join([a for a in args if a not in extra_args])
|
||||
|
||||
if not signature:
|
||||
add('call %s(%s)' % (fortranname, sargs))
|
||||
if f90mode:
|
||||
add('end subroutine f2pywrap_%s_%s' % (rout['modulename'], name))
|
||||
else:
|
||||
add('end')
|
||||
return ret[0]
|
||||
|
||||
|
||||
def assubr(rout):
|
||||
if isfunction_wrap(rout):
|
||||
fortranname = getfortranname(rout)
|
||||
name = rout['name']
|
||||
outmess('\t\tCreating wrapper for Fortran function "%s"("%s")...\n' % (
|
||||
name, fortranname))
|
||||
rout = copy.copy(rout)
|
||||
fname = name
|
||||
rname = fname
|
||||
if 'result' in rout:
|
||||
rname = rout['result']
|
||||
rout['vars'][fname] = rout['vars'][rname]
|
||||
fvar = rout['vars'][fname]
|
||||
if not isintent_out(fvar):
|
||||
if 'intent' not in fvar:
|
||||
fvar['intent'] = []
|
||||
fvar['intent'].append('out')
|
||||
flag = 1
|
||||
for i in fvar['intent']:
|
||||
if i.startswith('out='):
|
||||
flag = 0
|
||||
break
|
||||
if flag:
|
||||
fvar['intent'].append('out=%s' % (rname))
|
||||
rout['args'][:] = [fname] + rout['args']
|
||||
return rout, createfuncwrapper(rout)
|
||||
if issubroutine_wrap(rout):
|
||||
fortranname = getfortranname(rout)
|
||||
name = rout['name']
|
||||
outmess('\t\tCreating wrapper for Fortran subroutine "%s"("%s")...\n'
|
||||
% (name, fortranname))
|
||||
rout = copy.copy(rout)
|
||||
return rout, createsubrwrapper(rout)
|
||||
return rout, ''
|
1573
venv/lib/python3.12/site-packages/numpy/f2py/rules.py
Executable file
1573
venv/lib/python3.12/site-packages/numpy/f2py/rules.py
Executable file
File diff suppressed because it is too large
Load Diff
3
venv/lib/python3.12/site-packages/numpy/f2py/setup.cfg
Normal file
3
venv/lib/python3.12/site-packages/numpy/f2py/setup.cfg
Normal file
@ -0,0 +1,3 @@
|
||||
[bdist_rpm]
|
||||
doc_files = docs/
|
||||
tests/
|
1423
venv/lib/python3.12/site-packages/numpy/f2py/src/fortranobject.c
Normal file
1423
venv/lib/python3.12/site-packages/numpy/f2py/src/fortranobject.c
Normal file
File diff suppressed because it is too large
Load Diff
173
venv/lib/python3.12/site-packages/numpy/f2py/src/fortranobject.h
Normal file
173
venv/lib/python3.12/site-packages/numpy/f2py/src/fortranobject.h
Normal file
@ -0,0 +1,173 @@
|
||||
#ifndef Py_FORTRANOBJECT_H
|
||||
#define Py_FORTRANOBJECT_H
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <Python.h>
|
||||
|
||||
#ifndef NPY_NO_DEPRECATED_API
|
||||
#define NPY_NO_DEPRECATED_API NPY_API_VERSION
|
||||
#endif
|
||||
#ifdef FORTRANOBJECT_C
|
||||
#define NO_IMPORT_ARRAY
|
||||
#endif
|
||||
#define PY_ARRAY_UNIQUE_SYMBOL _npy_f2py_ARRAY_API
|
||||
#include "numpy/arrayobject.h"
|
||||
#include "numpy/npy_3kcompat.h"
|
||||
|
||||
#ifdef F2PY_REPORT_ATEXIT
|
||||
#include <sys/timeb.h>
|
||||
// clang-format off
|
||||
extern void f2py_start_clock(void);
|
||||
extern void f2py_stop_clock(void);
|
||||
extern void f2py_start_call_clock(void);
|
||||
extern void f2py_stop_call_clock(void);
|
||||
extern void f2py_cb_start_clock(void);
|
||||
extern void f2py_cb_stop_clock(void);
|
||||
extern void f2py_cb_start_call_clock(void);
|
||||
extern void f2py_cb_stop_call_clock(void);
|
||||
extern void f2py_report_on_exit(int, void *);
|
||||
// clang-format on
|
||||
#endif
|
||||
|
||||
#ifdef DMALLOC
|
||||
#include "dmalloc.h"
|
||||
#endif
|
||||
|
||||
/* Fortran object interface */
|
||||
|
||||
/*
|
||||
123456789-123456789-123456789-123456789-123456789-123456789-123456789-12
|
||||
|
||||
PyFortranObject represents various Fortran objects:
|
||||
Fortran (module) routines, COMMON blocks, module data.
|
||||
|
||||
Author: Pearu Peterson <pearu@cens.ioc.ee>
|
||||
*/
|
||||
|
||||
#define F2PY_MAX_DIMS 40
|
||||
#define F2PY_MESSAGE_BUFFER_SIZE 300 // Increase on "stack smashing detected"
|
||||
|
||||
typedef void (*f2py_set_data_func)(char *, npy_intp *);
|
||||
typedef void (*f2py_void_func)(void);
|
||||
typedef void (*f2py_init_func)(int *, npy_intp *, f2py_set_data_func, int *);
|
||||
|
||||
/*typedef void* (*f2py_c_func)(void*,...);*/
|
||||
|
||||
typedef void *(*f2pycfunc)(void);
|
||||
|
||||
typedef struct {
|
||||
char *name; /* attribute (array||routine) name */
|
||||
int rank; /* array rank, 0 for scalar, max is F2PY_MAX_DIMS,
|
||||
|| rank=-1 for Fortran routine */
|
||||
struct {
|
||||
npy_intp d[F2PY_MAX_DIMS];
|
||||
} dims; /* dimensions of the array, || not used */
|
||||
int type; /* PyArray_<type> || not used */
|
||||
int elsize; /* Element size || not used */
|
||||
char *data; /* pointer to array || Fortran routine */
|
||||
f2py_init_func func; /* initialization function for
|
||||
allocatable arrays:
|
||||
func(&rank,dims,set_ptr_func,name,len(name))
|
||||
|| C/API wrapper for Fortran routine */
|
||||
char *doc; /* documentation string; only recommended
|
||||
for routines. */
|
||||
} FortranDataDef;
|
||||
|
||||
typedef struct {
|
||||
PyObject_HEAD
|
||||
int len; /* Number of attributes */
|
||||
FortranDataDef *defs; /* An array of FortranDataDef's */
|
||||
PyObject *dict; /* Fortran object attribute dictionary */
|
||||
} PyFortranObject;
|
||||
|
||||
#define PyFortran_Check(op) (Py_TYPE(op) == &PyFortran_Type)
|
||||
#define PyFortran_Check1(op) (0 == strcmp(Py_TYPE(op)->tp_name, "fortran"))
|
||||
|
||||
extern PyTypeObject PyFortran_Type;
|
||||
extern int
|
||||
F2PyDict_SetItemString(PyObject *dict, char *name, PyObject *obj);
|
||||
extern PyObject *
|
||||
PyFortranObject_New(FortranDataDef *defs, f2py_void_func init);
|
||||
extern PyObject *
|
||||
PyFortranObject_NewAsAttr(FortranDataDef *defs);
|
||||
|
||||
PyObject *
|
||||
F2PyCapsule_FromVoidPtr(void *ptr, void (*dtor)(PyObject *));
|
||||
void *
|
||||
F2PyCapsule_AsVoidPtr(PyObject *obj);
|
||||
int
|
||||
F2PyCapsule_Check(PyObject *ptr);
|
||||
|
||||
extern void *
|
||||
F2PySwapThreadLocalCallbackPtr(char *key, void *ptr);
|
||||
extern void *
|
||||
F2PyGetThreadLocalCallbackPtr(char *key);
|
||||
|
||||
#define ISCONTIGUOUS(m) (PyArray_FLAGS(m) & NPY_ARRAY_C_CONTIGUOUS)
|
||||
#define F2PY_INTENT_IN 1
|
||||
#define F2PY_INTENT_INOUT 2
|
||||
#define F2PY_INTENT_OUT 4
|
||||
#define F2PY_INTENT_HIDE 8
|
||||
#define F2PY_INTENT_CACHE 16
|
||||
#define F2PY_INTENT_COPY 32
|
||||
#define F2PY_INTENT_C 64
|
||||
#define F2PY_OPTIONAL 128
|
||||
#define F2PY_INTENT_INPLACE 256
|
||||
#define F2PY_INTENT_ALIGNED4 512
|
||||
#define F2PY_INTENT_ALIGNED8 1024
|
||||
#define F2PY_INTENT_ALIGNED16 2048
|
||||
|
||||
#define ARRAY_ISALIGNED(ARR, SIZE) ((size_t)(PyArray_DATA(ARR)) % (SIZE) == 0)
|
||||
#define F2PY_ALIGN4(intent) (intent & F2PY_INTENT_ALIGNED4)
|
||||
#define F2PY_ALIGN8(intent) (intent & F2PY_INTENT_ALIGNED8)
|
||||
#define F2PY_ALIGN16(intent) (intent & F2PY_INTENT_ALIGNED16)
|
||||
|
||||
#define F2PY_GET_ALIGNMENT(intent) \
|
||||
(F2PY_ALIGN4(intent) \
|
||||
? 4 \
|
||||
: (F2PY_ALIGN8(intent) ? 8 : (F2PY_ALIGN16(intent) ? 16 : 1)))
|
||||
#define F2PY_CHECK_ALIGNMENT(arr, intent) \
|
||||
ARRAY_ISALIGNED(arr, F2PY_GET_ALIGNMENT(intent))
|
||||
#define F2PY_ARRAY_IS_CHARACTER_COMPATIBLE(arr) ((PyArray_DESCR(arr)->type_num == NPY_STRING && PyArray_ITEMSIZE(arr) >= 1) \
|
||||
|| PyArray_DESCR(arr)->type_num == NPY_UINT8)
|
||||
#define F2PY_IS_UNICODE_ARRAY(arr) (PyArray_DESCR(arr)->type_num == NPY_UNICODE)
|
||||
|
||||
extern PyArrayObject *
|
||||
ndarray_from_pyobj(const int type_num, const int elsize_, npy_intp *dims,
|
||||
const int rank, const int intent, PyObject *obj,
|
||||
const char *errmess);
|
||||
|
||||
extern PyArrayObject *
|
||||
array_from_pyobj(const int type_num, npy_intp *dims, const int rank,
|
||||
const int intent, PyObject *obj);
|
||||
extern int
|
||||
copy_ND_array(const PyArrayObject *in, PyArrayObject *out);
|
||||
|
||||
#ifdef DEBUG_COPY_ND_ARRAY
|
||||
extern void
|
||||
dump_attrs(const PyArrayObject *arr);
|
||||
#endif
|
||||
|
||||
extern int f2py_describe(PyObject *obj, char *buf);
|
||||
|
||||
/* Utility CPP macros and functions that can be used in signature file
|
||||
expressions. See signature-file.rst for documentation.
|
||||
*/
|
||||
|
||||
#define f2py_itemsize(var) (PyArray_ITEMSIZE(capi_ ## var ## _as_array))
|
||||
#define f2py_size(var, ...) f2py_size_impl((PyArrayObject *)(capi_ ## var ## _as_array), ## __VA_ARGS__, -1)
|
||||
#define f2py_rank(var) var ## _Rank
|
||||
#define f2py_shape(var,dim) var ## _Dims[dim]
|
||||
#define f2py_len(var) f2py_shape(var,0)
|
||||
#define f2py_fshape(var,dim) f2py_shape(var,rank(var)-dim-1)
|
||||
#define f2py_flen(var) f2py_fshape(var,0)
|
||||
#define f2py_slen(var) capi_ ## var ## _len
|
||||
|
||||
extern npy_intp f2py_size_impl(PyArrayObject* var, ...);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* !Py_FORTRANOBJECT_H */
|
1517
venv/lib/python3.12/site-packages/numpy/f2py/symbolic.py
Normal file
1517
venv/lib/python3.12/site-packages/numpy/f2py/symbolic.py
Normal file
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,15 @@
|
||||
from numpy.testing import IS_WASM, IS_EDITABLE
|
||||
import pytest
|
||||
|
||||
if IS_WASM:
|
||||
pytest.skip(
|
||||
"WASM/Pyodide does not use or support Fortran",
|
||||
allow_module_level=True
|
||||
)
|
||||
|
||||
|
||||
if IS_EDITABLE:
|
||||
pytest.skip(
|
||||
"Editable install doesn't support tests with a compile step",
|
||||
allow_module_level=True
|
||||
)
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -0,0 +1,34 @@
|
||||
module ops_module
|
||||
|
||||
abstract interface
|
||||
subroutine op(x, y, z)
|
||||
integer, intent(in) :: x, y
|
||||
integer, intent(out) :: z
|
||||
end subroutine
|
||||
end interface
|
||||
|
||||
contains
|
||||
|
||||
subroutine foo(x, y, r1, r2)
|
||||
integer, intent(in) :: x, y
|
||||
integer, intent(out) :: r1, r2
|
||||
procedure (op) add1, add2
|
||||
procedure (op), pointer::p
|
||||
p=>add1
|
||||
call p(x, y, r1)
|
||||
p=>add2
|
||||
call p(x, y, r2)
|
||||
end subroutine
|
||||
end module
|
||||
|
||||
subroutine add1(x, y, z)
|
||||
integer, intent(in) :: x, y
|
||||
integer, intent(out) :: z
|
||||
z = x + y
|
||||
end subroutine
|
||||
|
||||
subroutine add2(x, y, z)
|
||||
integer, intent(in) :: x, y
|
||||
integer, intent(out) :: z
|
||||
z = x + 2 * y
|
||||
end subroutine
|
@ -0,0 +1,6 @@
|
||||
module test
|
||||
abstract interface
|
||||
subroutine foo()
|
||||
end subroutine
|
||||
end interface
|
||||
end module test
|
@ -0,0 +1,235 @@
|
||||
/*
|
||||
* This file was auto-generated with f2py (version:2_1330) and hand edited by
|
||||
* Pearu for testing purposes. Do not edit this file unless you know what you
|
||||
* are doing!!!
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************** See f2py2e/cfuncs.py: includes ***********************/
|
||||
|
||||
#define PY_SSIZE_T_CLEAN
|
||||
#include <Python.h>
|
||||
#include "fortranobject.h"
|
||||
#include <math.h>
|
||||
|
||||
static PyObject *wrap_error;
|
||||
static PyObject *wrap_module;
|
||||
|
||||
/************************************ call ************************************/
|
||||
static char doc_f2py_rout_wrap_call[] = "\
|
||||
Function signature:\n\
|
||||
arr = call(type_num,dims,intent,obj)\n\
|
||||
Required arguments:\n"
|
||||
" type_num : input int\n"
|
||||
" dims : input int-sequence\n"
|
||||
" intent : input int\n"
|
||||
" obj : input python object\n"
|
||||
"Return objects:\n"
|
||||
" arr : array";
|
||||
static PyObject *f2py_rout_wrap_call(PyObject *capi_self,
|
||||
PyObject *capi_args) {
|
||||
PyObject * volatile capi_buildvalue = NULL;
|
||||
int type_num = 0;
|
||||
int elsize = 0;
|
||||
npy_intp *dims = NULL;
|
||||
PyObject *dims_capi = Py_None;
|
||||
int rank = 0;
|
||||
int intent = 0;
|
||||
PyArrayObject *capi_arr_tmp = NULL;
|
||||
PyObject *arr_capi = Py_None;
|
||||
int i;
|
||||
|
||||
if (!PyArg_ParseTuple(capi_args,"iiOiO|:wrap.call",\
|
||||
&type_num,&elsize,&dims_capi,&intent,&arr_capi))
|
||||
return NULL;
|
||||
rank = PySequence_Length(dims_capi);
|
||||
dims = malloc(rank*sizeof(npy_intp));
|
||||
for (i=0;i<rank;++i) {
|
||||
PyObject *tmp;
|
||||
tmp = PySequence_GetItem(dims_capi, i);
|
||||
if (tmp == NULL) {
|
||||
goto fail;
|
||||
}
|
||||
dims[i] = (npy_intp)PyLong_AsLong(tmp);
|
||||
Py_DECREF(tmp);
|
||||
if (dims[i] == -1 && PyErr_Occurred()) {
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
capi_arr_tmp = ndarray_from_pyobj(type_num,elsize,dims,rank,intent|F2PY_INTENT_OUT,arr_capi,"wrap.call failed");
|
||||
if (capi_arr_tmp == NULL) {
|
||||
free(dims);
|
||||
return NULL;
|
||||
}
|
||||
capi_buildvalue = Py_BuildValue("N",capi_arr_tmp);
|
||||
free(dims);
|
||||
return capi_buildvalue;
|
||||
|
||||
fail:
|
||||
free(dims);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static char doc_f2py_rout_wrap_attrs[] = "\
|
||||
Function signature:\n\
|
||||
arr = array_attrs(arr)\n\
|
||||
Required arguments:\n"
|
||||
" arr : input array object\n"
|
||||
"Return objects:\n"
|
||||
" data : data address in hex\n"
|
||||
" nd : int\n"
|
||||
" dimensions : tuple\n"
|
||||
" strides : tuple\n"
|
||||
" base : python object\n"
|
||||
" (kind,type,type_num,elsize,alignment) : 4-tuple\n"
|
||||
" flags : int\n"
|
||||
" itemsize : int\n"
|
||||
;
|
||||
static PyObject *f2py_rout_wrap_attrs(PyObject *capi_self,
|
||||
PyObject *capi_args) {
|
||||
PyObject *arr_capi = Py_None;
|
||||
PyArrayObject *arr = NULL;
|
||||
PyObject *dimensions = NULL;
|
||||
PyObject *strides = NULL;
|
||||
char s[100];
|
||||
int i;
|
||||
memset(s,0,100);
|
||||
if (!PyArg_ParseTuple(capi_args,"O!|:wrap.attrs",
|
||||
&PyArray_Type,&arr_capi))
|
||||
return NULL;
|
||||
arr = (PyArrayObject *)arr_capi;
|
||||
sprintf(s,"%p",PyArray_DATA(arr));
|
||||
dimensions = PyTuple_New(PyArray_NDIM(arr));
|
||||
strides = PyTuple_New(PyArray_NDIM(arr));
|
||||
for (i=0;i<PyArray_NDIM(arr);++i) {
|
||||
PyTuple_SetItem(dimensions,i,PyLong_FromLong(PyArray_DIM(arr,i)));
|
||||
PyTuple_SetItem(strides,i,PyLong_FromLong(PyArray_STRIDE(arr,i)));
|
||||
}
|
||||
return Py_BuildValue("siNNO(cciii)ii",s,PyArray_NDIM(arr),
|
||||
dimensions,strides,
|
||||
(PyArray_BASE(arr)==NULL?Py_None:PyArray_BASE(arr)),
|
||||
PyArray_DESCR(arr)->kind,
|
||||
PyArray_DESCR(arr)->type,
|
||||
PyArray_TYPE(arr),
|
||||
PyArray_ITEMSIZE(arr),
|
||||
PyDataType_ALIGNMENT(PyArray_DESCR(arr)),
|
||||
PyArray_FLAGS(arr),
|
||||
PyArray_ITEMSIZE(arr));
|
||||
}
|
||||
|
||||
static PyMethodDef f2py_module_methods[] = {
|
||||
|
||||
{"call",f2py_rout_wrap_call,METH_VARARGS,doc_f2py_rout_wrap_call},
|
||||
{"array_attrs",f2py_rout_wrap_attrs,METH_VARARGS,doc_f2py_rout_wrap_attrs},
|
||||
{NULL,NULL}
|
||||
};
|
||||
|
||||
static struct PyModuleDef moduledef = {
|
||||
PyModuleDef_HEAD_INIT,
|
||||
"test_array_from_pyobj_ext",
|
||||
NULL,
|
||||
-1,
|
||||
f2py_module_methods,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
PyMODINIT_FUNC PyInit_test_array_from_pyobj_ext(void) {
|
||||
PyObject *m,*d, *s;
|
||||
m = wrap_module = PyModule_Create(&moduledef);
|
||||
Py_SET_TYPE(&PyFortran_Type, &PyType_Type);
|
||||
import_array();
|
||||
if (PyErr_Occurred())
|
||||
Py_FatalError("can't initialize module wrap (failed to import numpy)");
|
||||
d = PyModule_GetDict(m);
|
||||
s = PyUnicode_FromString("This module 'wrap' is auto-generated with f2py (version:2_1330).\nFunctions:\n"
|
||||
" arr = call(type_num,dims,intent,obj)\n"
|
||||
".");
|
||||
PyDict_SetItemString(d, "__doc__", s);
|
||||
wrap_error = PyErr_NewException ("wrap.error", NULL, NULL);
|
||||
Py_DECREF(s);
|
||||
|
||||
#define ADDCONST(NAME, CONST) \
|
||||
s = PyLong_FromLong(CONST); \
|
||||
PyDict_SetItemString(d, NAME, s); \
|
||||
Py_DECREF(s)
|
||||
|
||||
ADDCONST("F2PY_INTENT_IN", F2PY_INTENT_IN);
|
||||
ADDCONST("F2PY_INTENT_INOUT", F2PY_INTENT_INOUT);
|
||||
ADDCONST("F2PY_INTENT_OUT", F2PY_INTENT_OUT);
|
||||
ADDCONST("F2PY_INTENT_HIDE", F2PY_INTENT_HIDE);
|
||||
ADDCONST("F2PY_INTENT_CACHE", F2PY_INTENT_CACHE);
|
||||
ADDCONST("F2PY_INTENT_COPY", F2PY_INTENT_COPY);
|
||||
ADDCONST("F2PY_INTENT_C", F2PY_INTENT_C);
|
||||
ADDCONST("F2PY_OPTIONAL", F2PY_OPTIONAL);
|
||||
ADDCONST("F2PY_INTENT_INPLACE", F2PY_INTENT_INPLACE);
|
||||
ADDCONST("NPY_BOOL", NPY_BOOL);
|
||||
ADDCONST("NPY_BYTE", NPY_BYTE);
|
||||
ADDCONST("NPY_UBYTE", NPY_UBYTE);
|
||||
ADDCONST("NPY_SHORT", NPY_SHORT);
|
||||
ADDCONST("NPY_USHORT", NPY_USHORT);
|
||||
ADDCONST("NPY_INT", NPY_INT);
|
||||
ADDCONST("NPY_UINT", NPY_UINT);
|
||||
ADDCONST("NPY_INTP", NPY_INTP);
|
||||
ADDCONST("NPY_UINTP", NPY_UINTP);
|
||||
ADDCONST("NPY_LONG", NPY_LONG);
|
||||
ADDCONST("NPY_ULONG", NPY_ULONG);
|
||||
ADDCONST("NPY_LONGLONG", NPY_LONGLONG);
|
||||
ADDCONST("NPY_ULONGLONG", NPY_ULONGLONG);
|
||||
ADDCONST("NPY_FLOAT", NPY_FLOAT);
|
||||
ADDCONST("NPY_DOUBLE", NPY_DOUBLE);
|
||||
ADDCONST("NPY_LONGDOUBLE", NPY_LONGDOUBLE);
|
||||
ADDCONST("NPY_CFLOAT", NPY_CFLOAT);
|
||||
ADDCONST("NPY_CDOUBLE", NPY_CDOUBLE);
|
||||
ADDCONST("NPY_CLONGDOUBLE", NPY_CLONGDOUBLE);
|
||||
ADDCONST("NPY_OBJECT", NPY_OBJECT);
|
||||
ADDCONST("NPY_STRING", NPY_STRING);
|
||||
ADDCONST("NPY_UNICODE", NPY_UNICODE);
|
||||
ADDCONST("NPY_VOID", NPY_VOID);
|
||||
ADDCONST("NPY_NTYPES_LEGACY", NPY_NTYPES_LEGACY);
|
||||
ADDCONST("NPY_NOTYPE", NPY_NOTYPE);
|
||||
ADDCONST("NPY_USERDEF", NPY_USERDEF);
|
||||
|
||||
ADDCONST("CONTIGUOUS", NPY_ARRAY_C_CONTIGUOUS);
|
||||
ADDCONST("FORTRAN", NPY_ARRAY_F_CONTIGUOUS);
|
||||
ADDCONST("OWNDATA", NPY_ARRAY_OWNDATA);
|
||||
ADDCONST("FORCECAST", NPY_ARRAY_FORCECAST);
|
||||
ADDCONST("ENSURECOPY", NPY_ARRAY_ENSURECOPY);
|
||||
ADDCONST("ENSUREARRAY", NPY_ARRAY_ENSUREARRAY);
|
||||
ADDCONST("ALIGNED", NPY_ARRAY_ALIGNED);
|
||||
ADDCONST("WRITEABLE", NPY_ARRAY_WRITEABLE);
|
||||
ADDCONST("WRITEBACKIFCOPY", NPY_ARRAY_WRITEBACKIFCOPY);
|
||||
|
||||
ADDCONST("BEHAVED", NPY_ARRAY_BEHAVED);
|
||||
ADDCONST("BEHAVED_NS", NPY_ARRAY_BEHAVED_NS);
|
||||
ADDCONST("CARRAY", NPY_ARRAY_CARRAY);
|
||||
ADDCONST("FARRAY", NPY_ARRAY_FARRAY);
|
||||
ADDCONST("CARRAY_RO", NPY_ARRAY_CARRAY_RO);
|
||||
ADDCONST("FARRAY_RO", NPY_ARRAY_FARRAY_RO);
|
||||
ADDCONST("DEFAULT", NPY_ARRAY_DEFAULT);
|
||||
ADDCONST("UPDATE_ALL", NPY_ARRAY_UPDATE_ALL);
|
||||
|
||||
#undef ADDCONST
|
||||
|
||||
if (PyErr_Occurred())
|
||||
Py_FatalError("can't initialize module wrap");
|
||||
|
||||
#ifdef F2PY_REPORT_ATEXIT
|
||||
on_exit(f2py_report_on_exit,(void*)"array_from_pyobj.wrap.call");
|
||||
#endif
|
||||
|
||||
#if Py_GIL_DISABLED
|
||||
// signal whether this module supports running with the GIL disabled
|
||||
PyUnstable_Module_SetGIL(m, Py_MOD_GIL_NOT_USED);
|
||||
#endif
|
||||
|
||||
return m;
|
||||
}
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@ -0,0 +1 @@
|
||||
dict(real=dict(rk="double"))
|
@ -0,0 +1,34 @@
|
||||
|
||||
subroutine sum(x, res)
|
||||
implicit none
|
||||
real, intent(in) :: x(:)
|
||||
real, intent(out) :: res
|
||||
|
||||
integer :: i
|
||||
|
||||
!print *, "sum: size(x) = ", size(x)
|
||||
|
||||
res = 0.0
|
||||
|
||||
do i = 1, size(x)
|
||||
res = res + x(i)
|
||||
enddo
|
||||
|
||||
end subroutine sum
|
||||
|
||||
function fsum(x) result (res)
|
||||
implicit none
|
||||
real, intent(in) :: x(:)
|
||||
real :: res
|
||||
|
||||
integer :: i
|
||||
|
||||
!print *, "fsum: size(x) = ", size(x)
|
||||
|
||||
res = 0.0
|
||||
|
||||
do i = 1, size(x)
|
||||
res = res + x(i)
|
||||
enddo
|
||||
|
||||
end function fsum
|
@ -0,0 +1,41 @@
|
||||
|
||||
module mod
|
||||
|
||||
contains
|
||||
|
||||
subroutine sum(x, res)
|
||||
implicit none
|
||||
real, intent(in) :: x(:)
|
||||
real, intent(out) :: res
|
||||
|
||||
integer :: i
|
||||
|
||||
!print *, "sum: size(x) = ", size(x)
|
||||
|
||||
res = 0.0
|
||||
|
||||
do i = 1, size(x)
|
||||
res = res + x(i)
|
||||
enddo
|
||||
|
||||
end subroutine sum
|
||||
|
||||
function fsum(x) result (res)
|
||||
implicit none
|
||||
real, intent(in) :: x(:)
|
||||
real :: res
|
||||
|
||||
integer :: i
|
||||
|
||||
!print *, "fsum: size(x) = ", size(x)
|
||||
|
||||
res = 0.0
|
||||
|
||||
do i = 1, size(x)
|
||||
res = res + x(i)
|
||||
enddo
|
||||
|
||||
end function fsum
|
||||
|
||||
|
||||
end module mod
|
@ -0,0 +1,19 @@
|
||||
subroutine sum_with_use(x, res)
|
||||
use precision
|
||||
|
||||
implicit none
|
||||
|
||||
real(kind=rk), intent(in) :: x(:)
|
||||
real(kind=rk), intent(out) :: res
|
||||
|
||||
integer :: i
|
||||
|
||||
!print *, "size(x) = ", size(x)
|
||||
|
||||
res = 0.0
|
||||
|
||||
do i = 1, size(x)
|
||||
res = res + x(i)
|
||||
enddo
|
||||
|
||||
end subroutine
|
@ -0,0 +1,4 @@
|
||||
module precision
|
||||
integer, parameter :: rk = selected_real_kind(8)
|
||||
integer, parameter :: ik = selected_real_kind(4)
|
||||
end module
|
@ -0,0 +1,6 @@
|
||||
SUBROUTINE FOO()
|
||||
INTEGER BAR(2, 3)
|
||||
|
||||
COMMON /BLOCK/ BAR
|
||||
RETURN
|
||||
END
|
@ -0,0 +1,62 @@
|
||||
subroutine t(fun,a)
|
||||
integer a
|
||||
cf2py intent(out) a
|
||||
external fun
|
||||
call fun(a)
|
||||
end
|
||||
|
||||
subroutine func(a)
|
||||
cf2py intent(in,out) a
|
||||
integer a
|
||||
a = a + 11
|
||||
end
|
||||
|
||||
subroutine func0(a)
|
||||
cf2py intent(out) a
|
||||
integer a
|
||||
a = 11
|
||||
end
|
||||
|
||||
subroutine t2(a)
|
||||
cf2py intent(callback) fun
|
||||
integer a
|
||||
cf2py intent(out) a
|
||||
external fun
|
||||
call fun(a)
|
||||
end
|
||||
|
||||
subroutine string_callback(callback, a)
|
||||
external callback
|
||||
double precision callback
|
||||
double precision a
|
||||
character*1 r
|
||||
cf2py intent(out) a
|
||||
r = 'r'
|
||||
a = callback(r)
|
||||
end
|
||||
|
||||
subroutine string_callback_array(callback, cu, lencu, a)
|
||||
external callback
|
||||
integer callback
|
||||
integer lencu
|
||||
character*8 cu(lencu)
|
||||
integer a
|
||||
cf2py intent(out) a
|
||||
|
||||
a = callback(cu, lencu)
|
||||
end
|
||||
|
||||
subroutine hidden_callback(a, r)
|
||||
external global_f
|
||||
cf2py intent(callback, hide) global_f
|
||||
integer a, r, global_f
|
||||
cf2py intent(out) r
|
||||
r = global_f(a)
|
||||
end
|
||||
|
||||
subroutine hidden_callback2(a, r)
|
||||
external global_f
|
||||
integer a, r, global_f
|
||||
cf2py intent(out) r
|
||||
r = global_f(a)
|
||||
end
|
@ -0,0 +1,7 @@
|
||||
function gh17797(f, y) result(r)
|
||||
external f
|
||||
integer(8) :: r, f
|
||||
integer(8), dimension(:) :: y
|
||||
r = f(0)
|
||||
r = r + sum(y)
|
||||
end function gh17797
|
@ -0,0 +1,17 @@
|
||||
! When gh18335_workaround is defined as an extension,
|
||||
! the issue cannot be reproduced.
|
||||
!subroutine gh18335_workaround(f, y)
|
||||
! implicit none
|
||||
! external f
|
||||
! integer(kind=1) :: y(1)
|
||||
! call f(y)
|
||||
!end subroutine gh18335_workaround
|
||||
|
||||
function gh18335(f) result (r)
|
||||
implicit none
|
||||
external f
|
||||
integer(kind=1) :: y(1), r
|
||||
y(1) = 123
|
||||
call f(y)
|
||||
r = y(1)
|
||||
end function gh18335
|
@ -0,0 +1,10 @@
|
||||
SUBROUTINE FOO(FUN,R)
|
||||
EXTERNAL FUN
|
||||
INTEGER I
|
||||
REAL*8 R, FUN
|
||||
Cf2py intent(out) r
|
||||
R = 0D0
|
||||
DO I=-5,5
|
||||
R = R + FUN(I)
|
||||
ENDDO
|
||||
END
|
@ -0,0 +1,18 @@
|
||||
python module __user__routines
|
||||
interface
|
||||
function fun(i) result (r)
|
||||
integer :: i
|
||||
real*8 :: r
|
||||
end function fun
|
||||
end interface
|
||||
end python module __user__routines
|
||||
|
||||
python module callback2
|
||||
interface
|
||||
subroutine foo(f,r)
|
||||
use __user__routines, f=>fun
|
||||
external f
|
||||
real*8 intent(out) :: r
|
||||
end subroutine foo
|
||||
end interface
|
||||
end python module callback2
|
@ -0,0 +1,6 @@
|
||||
python module test_22819
|
||||
interface
|
||||
subroutine hello()
|
||||
end subroutine hello
|
||||
end interface
|
||||
end python module test_22819
|
@ -0,0 +1,3 @@
|
||||
SUBROUTINE HI
|
||||
PRINT*, "HELLO WORLD"
|
||||
END SUBROUTINE
|
@ -0,0 +1,3 @@
|
||||
function hi()
|
||||
print*, "Hello World"
|
||||
end function
|
@ -0,0 +1,11 @@
|
||||
SUBROUTINE INITCB
|
||||
DOUBLE PRECISION LONG
|
||||
CHARACTER STRING
|
||||
INTEGER OK
|
||||
|
||||
COMMON /BLOCK/ LONG, STRING, OK
|
||||
LONG = 1.0
|
||||
STRING = '2'
|
||||
OK = 3
|
||||
RETURN
|
||||
END
|
@ -0,0 +1,10 @@
|
||||
module typedefmod
|
||||
use iso_fortran_env, only: real32
|
||||
end module typedefmod
|
||||
|
||||
module data
|
||||
use typedefmod, only: real32
|
||||
implicit none
|
||||
real(kind=real32) :: x
|
||||
common/test/x
|
||||
end module data
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user