增加环绕侦察场景适配
This commit is contained in:
@@ -1,5 +1,4 @@
|
||||
from .f2py2e import main as main
|
||||
from .f2py2e import run_main
|
||||
from .f2py2e import main as main, run_main
|
||||
|
||||
__all__ = ["get_include", "run_main"]
|
||||
|
||||
|
||||
@@ -50,6 +50,7 @@ class MesonTemplate:
|
||||
self.pipeline = [
|
||||
self.initialize_template,
|
||||
self.sources_substitution,
|
||||
self.objects_substitution,
|
||||
self.deps_substitution,
|
||||
self.include_substitution,
|
||||
self.libraries_substitution,
|
||||
@@ -79,6 +80,11 @@ class MesonTemplate:
|
||||
[f"{self.indent}'''{source}'''," for source in self.sources]
|
||||
)
|
||||
|
||||
def objects_substitution(self) -> None:
|
||||
self.substitutions["obj_list"] = ",\n".join(
|
||||
[f"{self.indent}'''{obj}'''," for obj in self.objects]
|
||||
)
|
||||
|
||||
def deps_substitution(self) -> None:
|
||||
self.substitutions["dep_list"] = f",\n{self.indent}".join(
|
||||
[f"{self.indent}dependency('{dep}')," for dep in self.deps]
|
||||
@@ -186,6 +192,7 @@ class MesonBackend(Backend):
|
||||
|
||||
def compile(self) -> None:
|
||||
self.sources = _prepare_sources(self.modulename, self.sources, self.build_dir)
|
||||
_prepare_objects(self.modulename, self.extra_objects, self.build_dir)
|
||||
self.write_meson_build(self.build_dir)
|
||||
self.run_meson(self.build_dir)
|
||||
self._move_exec_to_root(self.build_dir)
|
||||
@@ -216,6 +223,12 @@ def _prepare_sources(mname, sources, bdir):
|
||||
]
|
||||
return extended_sources
|
||||
|
||||
def _prepare_objects(mname, objects, bdir):
|
||||
Path(bdir).mkdir(parents=True, exist_ok=True)
|
||||
# Copy objects
|
||||
for obj in objects:
|
||||
if Path(obj).exists() and Path(obj).is_file():
|
||||
shutil.copy(obj, bdir)
|
||||
|
||||
def _get_flags(fc_flags):
|
||||
flag_values = []
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
from collections.abc import Callable
|
||||
from pathlib import Path
|
||||
from typing import Final
|
||||
from typing import Literal as L
|
||||
|
||||
from typing import Final, Literal as L
|
||||
from typing_extensions import override
|
||||
|
||||
from ._backend import Backend
|
||||
@@ -42,6 +40,7 @@ class MesonTemplate:
|
||||
#
|
||||
def initialize_template(self) -> None: ...
|
||||
def sources_substitution(self) -> None: ...
|
||||
def objects_substitution(self) -> None: ...
|
||||
def deps_substitution(self) -> None: ...
|
||||
def libraries_substitution(self) -> None: ...
|
||||
def include_substitution(self) -> None: ...
|
||||
|
||||
@@ -43,6 +43,9 @@ ${source_list},
|
||||
include_directories: [
|
||||
inc_np,
|
||||
${inc_list}
|
||||
],
|
||||
objects: [
|
||||
${obj_list}
|
||||
],
|
||||
dependencies : [
|
||||
py_dep,
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
import re
|
||||
from _typeshed import StrOrBytesPath
|
||||
from collections.abc import Mapping
|
||||
from typing import Final
|
||||
|
||||
from _typeshed import StrOrBytesPath
|
||||
|
||||
routine_start_re: Final[re.Pattern[str]] = ...
|
||||
routine_end_re: Final[re.Pattern[str]] = ...
|
||||
function_start_re: Final[re.Pattern[str]] = ...
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
from _typeshed import FileDescriptorOrPath
|
||||
from collections.abc import Callable, Mapping
|
||||
from pprint import pprint as show
|
||||
from typing import Any, Final, Never, TypeAlias, TypeVar, overload
|
||||
from typing import Literal as L
|
||||
|
||||
from _typeshed import FileDescriptorOrPath
|
||||
from typing import Any, Final, Literal as L, Never, TypeAlias, TypeVar, overload
|
||||
|
||||
from .cfuncs import errmess
|
||||
|
||||
|
||||
@@ -1,9 +1,17 @@
|
||||
import re
|
||||
from collections.abc import Callable, Iterable, Mapping
|
||||
from typing import IO, Any, Concatenate, Final, Never, ParamSpec, TypeAlias, overload
|
||||
from typing import Literal as L
|
||||
|
||||
from _typeshed import StrOrBytesPath, StrPath
|
||||
from collections.abc import Callable, Iterable, Mapping
|
||||
from typing import (
|
||||
IO,
|
||||
Any,
|
||||
Concatenate,
|
||||
Final,
|
||||
Literal as L,
|
||||
Never,
|
||||
ParamSpec,
|
||||
TypeAlias,
|
||||
overload,
|
||||
)
|
||||
|
||||
from .__version__ import version
|
||||
from .auxfuncs import isintent_dict as isintent_dict
|
||||
|
||||
@@ -378,6 +378,8 @@ def callcrackfortran(files, options):
|
||||
mod['gil_used'] = 'Py_MOD_GIL_USED'
|
||||
else:
|
||||
mod['gil_used'] = 'Py_MOD_GIL_NOT_USED'
|
||||
# gh-26718 Reset global
|
||||
crackfortran.f77modulename = ''
|
||||
return postlist
|
||||
|
||||
|
||||
|
||||
@@ -3,12 +3,10 @@ import pprint
|
||||
from collections.abc import Hashable, Iterable, Mapping, MutableMapping, Sequence
|
||||
from types import ModuleType
|
||||
from typing import Any, Final, NotRequired, TypedDict, type_check_only
|
||||
|
||||
from typing_extensions import TypeVar, override
|
||||
|
||||
from .__version__ import version
|
||||
from .auxfuncs import _Bool
|
||||
from .auxfuncs import outmess as outmess
|
||||
from .auxfuncs import _Bool, outmess as outmess
|
||||
|
||||
###
|
||||
|
||||
|
||||
@@ -77,7 +77,7 @@ def var2fixfortran(vars, a, fa=None, f90mode=None):
|
||||
|
||||
def useiso_c_binding(rout):
|
||||
useisoc = False
|
||||
for key, value in rout['vars'].items():
|
||||
for value in rout['vars'].values():
|
||||
kind_value = value.get('kindselector', {}).get('kind')
|
||||
if kind_value in isoc_kindmap:
|
||||
return True
|
||||
|
||||
@@ -286,7 +286,7 @@ PyMODINIT_FUNC PyInit_#modulename#(void) {
|
||||
#initcommonhooks#
|
||||
#interface_usercode#
|
||||
|
||||
#if Py_GIL_DISABLED
|
||||
#ifdef Py_GIL_DISABLED
|
||||
// signal whether this module supports running with the GIL disabled
|
||||
PyUnstable_Module_SetGIL(m , #gil_used#);
|
||||
#endif
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
from collections.abc import Callable, Iterable, Mapping
|
||||
from typing import Any, Final, TypeAlias
|
||||
from typing import Literal as L
|
||||
|
||||
from typing import Any, Final, Literal as L, TypeAlias
|
||||
from typing_extensions import TypeVar
|
||||
|
||||
from .__version__ import version
|
||||
|
||||
@@ -47,7 +47,7 @@ F2PySwapThreadLocalCallbackPtr(char *key, void *ptr)
|
||||
"failed");
|
||||
}
|
||||
|
||||
value = PyDict_GetItemString(local_dict, key);
|
||||
value = PyDict_GetItemString(local_dict, key); // noqa: borrowed-ref OK
|
||||
if (value != NULL) {
|
||||
prev = PyLong_AsVoidPtr(value);
|
||||
if (PyErr_Occurred()) {
|
||||
@@ -87,7 +87,7 @@ F2PyGetThreadLocalCallbackPtr(char *key)
|
||||
"F2PyGetThreadLocalCallbackPtr: PyThreadState_GetDict failed");
|
||||
}
|
||||
|
||||
value = PyDict_GetItemString(local_dict, key);
|
||||
value = PyDict_GetItemString(local_dict, key); // noqa: borrowed-ref OK
|
||||
if (value != NULL) {
|
||||
prev = PyLong_AsVoidPtr(value);
|
||||
if (PyErr_Occurred()) {
|
||||
@@ -365,7 +365,7 @@ fortran_getattr(PyFortranObject *fp, char *name)
|
||||
if (fp->dict != NULL) {
|
||||
// python 3.13 added PyDict_GetItemRef
|
||||
#if PY_VERSION_HEX < 0x030D0000
|
||||
PyObject *v = _PyDict_GetItemStringWithError(fp->dict, name);
|
||||
PyObject *v = _PyDict_GetItemStringWithError(fp->dict, name); // noqa: borrowed-ref OK
|
||||
if (v == NULL && PyErr_Occurred()) {
|
||||
return NULL;
|
||||
}
|
||||
@@ -822,7 +822,7 @@ get_elsize(PyObject *obj) {
|
||||
} else if (PyUnicode_Check(obj)) {
|
||||
return PyUnicode_GET_LENGTH(obj);
|
||||
} else if (PySequence_Check(obj)) {
|
||||
PyObject* fast = PySequence_Fast(obj, "f2py:fortranobject.c:get_elsize");
|
||||
PyObject* fast = PySequence_Fast(obj, "f2py:fortranobject.c:get_elsize"); // noqa: borrowed-ref OK
|
||||
if (fast != NULL) {
|
||||
Py_ssize_t i, n = PySequence_Fast_GET_SIZE(fast);
|
||||
int sz, elsize = 0;
|
||||
|
||||
@@ -155,14 +155,14 @@ def ewarn(message):
|
||||
|
||||
|
||||
class Expr:
|
||||
"""Represents a Fortran expression as a op-data pair.
|
||||
"""Represents a Fortran expression as an op-data pair.
|
||||
|
||||
Expr instances are hashable and sortable.
|
||||
"""
|
||||
|
||||
@staticmethod
|
||||
def parse(s, language=Language.C):
|
||||
"""Parse a Fortran expression to a Expr.
|
||||
"""Parse a Fortran expression to an Expr.
|
||||
"""
|
||||
return fromstring(s, language=language)
|
||||
|
||||
@@ -1236,6 +1236,8 @@ def replace_parenthesis(s):
|
||||
|
||||
i = mn_i
|
||||
j = s.find(right, i)
|
||||
if j == -1:
|
||||
raise ValueError(f'Mismatch of {left + right} parenthesis in {s!r}')
|
||||
|
||||
while s.count(left, i + 1, j) != s.count(right, i + 1, j):
|
||||
j = s.find(right, j + 1)
|
||||
@@ -1478,7 +1480,7 @@ class _FromStringWorker:
|
||||
if isinstance(items, Expr):
|
||||
return items
|
||||
if paren in ['ROUNDDIV', 'SQUARE']:
|
||||
# Expression is a array constructor
|
||||
# Expression is an array constructor
|
||||
if isinstance(items, Expr):
|
||||
items = (items,)
|
||||
return as_array(items)
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
from collections.abc import Callable, Mapping
|
||||
from enum import Enum
|
||||
from typing import Any, Generic, ParamSpec, Self, TypeAlias, overload
|
||||
from typing import Literal as L
|
||||
|
||||
from typing import Any, Generic, Literal as L, ParamSpec, Self, TypeAlias, overload
|
||||
from typing_extensions import TypeVar
|
||||
|
||||
__all__ = ["Expr"]
|
||||
|
||||
@@ -223,7 +223,7 @@ PyMODINIT_FUNC PyInit_test_array_from_pyobj_ext(void) {
|
||||
on_exit(f2py_report_on_exit,(void*)"array_from_pyobj.wrap.call");
|
||||
#endif
|
||||
|
||||
#if Py_GIL_DISABLED
|
||||
#ifdef Py_GIL_DISABLED
|
||||
// signal whether this module supports running with the GIL disabled
|
||||
PyUnstable_Module_SetGIL(m, Py_MOD_GIL_NOT_USED);
|
||||
#endif
|
||||
|
||||
@@ -147,9 +147,9 @@ _cast_dict['CHARACTER'] = ['CHARACTER']
|
||||
# and several tests fail as the alignment flag can be randomly true or false
|
||||
# when numpy gains an aligned allocator the tests could be enabled again
|
||||
#
|
||||
# Furthermore, on macOS ARM64, LONGDOUBLE is an alias for DOUBLE.
|
||||
# Furthermore, on macOS ARM64 and AIX, LONGDOUBLE is an alias for DOUBLE.
|
||||
if ((np.intp().dtype.itemsize != 4 or np.clongdouble().dtype.alignment <= 8)
|
||||
and sys.platform != "win32"
|
||||
and sys.platform not in ["win32", "aix"]
|
||||
and (platform.system(), platform.processor()) != ("Darwin", "arm")):
|
||||
_type_names.extend(["LONGDOUBLE", "CDOUBLE", "CLONGDOUBLE"])
|
||||
_cast_dict["LONGDOUBLE"] = _cast_dict["LONG"] + [
|
||||
|
||||
@@ -60,5 +60,7 @@ class TestDocAdvanced(util.F2PyTest):
|
||||
ftype.data.x[1] = 45
|
||||
assert_array_equal(ftype.data.x,
|
||||
np.array([1, 45, 3], dtype=np.float32))
|
||||
# gh-26718 Cleanup for repeated test runs
|
||||
ftype.data.a = 0
|
||||
|
||||
# TODO: implement test methods for other example Fortran codes
|
||||
|
||||
@@ -673,6 +673,25 @@ def test_inclheader(capfd, hello_world_f90, monkeypatch):
|
||||
assert "#include <stdbool.h>" in ocmr
|
||||
assert "#include <stdio.h>" in ocmr
|
||||
|
||||
@pytest.mark.skipif((platform.system() != 'Linux'), reason='Compiler required')
|
||||
def test_cli_obj(capfd, hello_world_f90, monkeypatch):
|
||||
"""Ensures that the extra object can be specified when using meson backend
|
||||
"""
|
||||
ipath = Path(hello_world_f90)
|
||||
mname = "blah"
|
||||
odir = "tttmp"
|
||||
obj = "extra.o"
|
||||
monkeypatch.setattr(sys, "argv",
|
||||
f'f2py --backend meson --build-dir {odir} -m {mname} -c {obj} {ipath}'.split())
|
||||
|
||||
with util.switchdir(ipath.parent):
|
||||
Path(obj).touch()
|
||||
compiler_check_f2pycli()
|
||||
with Path(f"{odir}/meson.build").open() as mesonbuild:
|
||||
mbld = mesonbuild.read()
|
||||
assert "objects:" in mbld
|
||||
assert f"'''{obj}'''" in mbld
|
||||
|
||||
|
||||
def test_inclpath():
|
||||
"""Add to the include directories
|
||||
|
||||
@@ -5,13 +5,12 @@ import pytest
|
||||
|
||||
from numpy.f2py.crackfortran import (
|
||||
_selected_int_kind_func as selected_int_kind,
|
||||
)
|
||||
from numpy.f2py.crackfortran import (
|
||||
_selected_real_kind_func as selected_real_kind,
|
||||
)
|
||||
|
||||
from . import util
|
||||
|
||||
IS_PPC_OR_AIX = platform.machine().lower().startswith("ppc") or platform.system() == 'AIX'
|
||||
|
||||
class TestKind(util.F2PyTest):
|
||||
sources = [util.getpath("tests", "src", "kind", "foo.f90")]
|
||||
@@ -39,7 +38,7 @@ class TestKind(util.F2PyTest):
|
||||
i
|
||||
), f"selectedrealkind({i}): expected {selected_real_kind(i)!r} but got {selectedrealkind(i)!r}"
|
||||
|
||||
@pytest.mark.xfail(platform.machine().lower().startswith("ppc"),
|
||||
@pytest.mark.xfail(IS_PPC_OR_AIX,
|
||||
reason="Some PowerPC may not support full IEEE 754 precision")
|
||||
def test_quad_precision(self):
|
||||
"""
|
||||
|
||||
@@ -158,7 +158,7 @@ def test_gh26623():
|
||||
|
||||
|
||||
@pytest.mark.slow
|
||||
@pytest.mark.skipif(platform.system() not in ['Linux', 'Darwin'], reason='Unsupported on this platform for now')
|
||||
@pytest.mark.skipif(platform.system() == "Windows", reason='Unsupported on this platform for now')
|
||||
def test_gh25784():
|
||||
# Compile dubious file using passed flags
|
||||
try:
|
||||
@@ -167,7 +167,7 @@ def test_gh25784():
|
||||
options=[
|
||||
# Meson will collect and dedup these to pass to fortran_args:
|
||||
"--f77flags='-ffixed-form -O2'",
|
||||
"--f90flags=\"-ffixed-form -Og\"",
|
||||
"--f90flags=\"-ffixed-form -g\"",
|
||||
],
|
||||
module_name="Blah",
|
||||
)
|
||||
|
||||
@@ -29,8 +29,8 @@ class TestReturnInteger(util.F2PyTest):
|
||||
pytest.raises(IndexError, t, [])
|
||||
pytest.raises(IndexError, t, ())
|
||||
|
||||
pytest.raises(Exception, t, t)
|
||||
pytest.raises(Exception, t, {})
|
||||
pytest.raises(TypeError, t, t)
|
||||
pytest.raises(TypeError, t, {})
|
||||
|
||||
if tname in ["t8", "s8"]:
|
||||
pytest.raises(OverflowError, t, 100000000000000000000000)
|
||||
|
||||
@@ -39,8 +39,8 @@ class TestReturnReal(util.F2PyTest):
|
||||
pytest.raises(IndexError, t, [])
|
||||
pytest.raises(IndexError, t, ())
|
||||
|
||||
pytest.raises(Exception, t, t)
|
||||
pytest.raises(Exception, t, {})
|
||||
pytest.raises(TypeError, t, t)
|
||||
pytest.raises(TypeError, t, {})
|
||||
|
||||
try:
|
||||
r = t(10**400)
|
||||
|
||||
@@ -493,3 +493,8 @@ class TestSymbolic(util.F2PyTest):
|
||||
assert (y(x) + x).polynomial_atoms() == {y(x), x}
|
||||
assert (y(x) * x[y]).polynomial_atoms() == {y(x), x[y]}
|
||||
assert (y(x)**x).polynomial_atoms() == {y(x)}
|
||||
|
||||
def test_unmatched_parenthesis_gh30268(self):
|
||||
#gh - 30268
|
||||
with pytest.raises(ValueError, match=r"Mismatch of \(\) parenthesis"):
|
||||
Expr.parse("DATA (A, I=1, N", language=Language.Fortran)
|
||||
|
||||
Reference in New Issue
Block a user