Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Fortran support may be broken #214

Open
principis opened this issue Jan 26, 2024 · 3 comments
Open

Fortran support may be broken #214

principis opened this issue Jan 26, 2024 · 3 comments
Labels

Comments

@principis
Copy link

On Fedora 39 the CPPFortranMixed.test_hierarchies test fails:

FAILED testing/tests/cpp_fortran_mixed.py::CPPFortranMixed::test_hierarchies - RuntimeError: Matching child for [function] 'conversions::degrees_to_radians_s' with signature 'real(c_float) function conversions::degrees_to_radians_s(degrees_s)' not found!

Complete test results: test_output.txt

Version info:
Doxygen version: 1.9.7
Breathe version: 4.35.0
Sphinx version: 6.2.1
Python version: 3.12.1

@svenevs
Copy link
Owner

svenevs commented Jan 27, 2024

Thanks for reporting @principis!

It seems like either the gfortran version or [email protected] are at play here. The underlying problem is the testing framework is dumb / very picky, and wanted to find real(c_float) function conversions::degrees_to_radians_s(real(c_float), intent(in)) (note: the difference is the parameters degrees_s)

I will need to fiddle with things, if this is for a packaging build it might be appropriate to disable the test. I will see what I can dig up, I've had this change behavior in the past too and IIRC it was because doxygen changed how the xml worked.

@principis
Copy link
Author

Thanks for your swift response! I'm packaging exhale for Fedora, I'll disable the test for now. 🙂

@svenevs svenevs changed the title CPPFortranMixed.test_hierarchies fails Fortran support may be broken Jan 28, 2024
@svenevs svenevs added the bug label Jan 28, 2024
@svenevs
Copy link
Owner

svenevs commented Jan 28, 2024

I'll disable the test for now.

TL;DR: I'd say that's probably the right call, not much has changed code-wise for a couple of years, the latest release was really just to fix packaging mistakes that were starting to prevent people from installing the project on RTD using PyPI.


image

Hmmmmm... so after some digging around, it seems like at some point the fortran support broke. Possibly for quite some time. The next thing to check for me / anybody interested would be looking at different combinations of sphinx and breathe versions to see if there is a known point where the function signatures exhale was generating actually worked.

# See tox.ini hack, the variable needs the leadding '=='
# change X.Y.Z / A.B.C to try
SPHINX_VERSION='==X.Y.Z' BREATHE_VERSION='==A.B.C' tox -e py -- -k cpp_fortran_mixed --pdb -s

In this edge case, tests don't actually necessarily fail, it will just render the warning. To keep all of the builds around (warning: -k cpp_fortran_mixed is useful here, actually builds and renders the html for all projects if you run just tox -e py...):

diff --git a/testing/base.py b/testing/base.py
index 3360c81..96a8219 100644
--- a/testing/base.py
+++ b/testing/base.py
@@ -122,7 +122,7 @@ class ExhaleTestCaseMetaclass(type):
                 yield  # the test runs
                 # @no_cleanup sets self.testroot to [self.testroot] as a flag that
                 # cleanup should not transpire
-                if isinstance(self.testroot, six.string_types):
+                if False and isinstance(self.testroot, six.string_types):
                     # This cleanup happens between each test case, do not delete docs/
                     # until all tests for this class are done!
                     containmentFolder = self.getAbsContainmentFolder()
@@ -207,7 +207,7 @@ class ExhaleTestCaseMetaclass(type):
                 # perform cleanup by deleting the docs dir
                 # @no_cleanup sets self.testroot to [self.testroot] as a flag that
                 # cleanup should not transpire
-                if isinstance(self.testroot, six.string_types) and os.path.isdir(self.testroot):
+                if False and isinstance(self.testroot, six.string_types) and os.path.isdir(self.testroot):
                     shutil.rmtree(self.testroot)
 
                 self.testroot = None
@@ -225,6 +225,9 @@ class ExhaleTestCaseMetaclass(type):
                     self.checkAllFilesGenerated()
                     self.checkAllFilesIncluded()
 
+                    print("{{{{{ imma building }}}}}")
+                    self.app.build()
+
             attrs["test_common"] = test_common
 
             # Import the default hierarchy dictionaries from the testing/projects folder

And the place where you can fiddle with the parsing of things is here

diff --git a/exhale/graph.py b/exhale/graph.py
index c0d8e86..99d57ad 100644
--- a/exhale/graph.py
+++ b/exhale/graph.py
@@ -2196,7 +2196,16 @@ class ExhaleRoot(object):
                 # 2. The function parameter list.
                 parameters = []
                 for param in memberdef.find_all("param", recursive=False):
-                    parameters.append(param.type.text)
+                    # if param.type.text is not None and 'real(c_float), intent(in)' == param.type.text:
+                    if func_refid == "namespaceconversions_1af3f7e870092b4986419a4c8c56aaff63":
+                        # import pdb
+                        # pdb.set_trace()
+                        # (pdb) p param <<< that'll show you the function parameters
+                        #         these are the beautiful soup (xml) nodes getting parsed
+                        #         as we're building the {hacky} exhale representation
+                        parameters.append(param.defname.text)
+                    else:
+                        parameters.append(param.type.text)
                 func.parameters = utils.sanitize_all(parameters)
                 # 3. The template parameter list.
                 templateparamlist = memberdef.templateparamlist

Noting that modifying this method directly is also an easy way to hack

def breathe_identifier(self):

There's other known problems even with C++ functions (overloads specifically, some work, some don't) 😶 While I'd love to be able to fix these things, they're usually in a corner case of "no known solution without making significant changes here and in breathe"...


When running tests against later versions of sphinx and breathe all kinds of other things broke, so it's not clear if this will get solved anytime soon 😞

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants