{
  "__type": "IngestedDoc",
  "__tag": 4010,
  "_content": {},
  "_ordered_sections": [],
  "item_file": null,
  "item_line": null,
  "item_type": null,
  "aliases": [],
  "example_section_data": {
    "__type": "Section",
    "__tag": 4015,
    "children": [],
    "title": [],
    "level": 0,
    "target": null
  },
  "see_also": [],
  "signature": null,
  "references": null,
  "qa": "f2py:advanced:boilerplating",
  "arbitrary": [
    {
      "__type": "Section",
      "__tag": 4015,
      "children": [],
      "title": [
        {
          "__type": "Text",
          "__tag": 4046,
          "value": "Boilerplate reduction and templating"
        }
      ],
      "level": 0,
      "target": "f2py-boilerplating"
    },
    {
      "__type": "Section",
      "__tag": 4015,
      "children": [
        {
          "__type": "Paragraph",
          "__tag": 4045,
          "children": [
            {
              "__type": "InlineCode",
              "__tag": 4051,
              "value": "f2py"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " doesn't currently support binding interface blocks. However, there are workarounds in use. Perhaps the best known is the usage of "
            },
            {
              "__type": "InlineCode",
              "__tag": 4051,
              "value": "tempita"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " for using "
            },
            {
              "__type": "InlineCode",
              "__tag": 4051,
              "value": ".pyf.src"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " files as is done in the bindings which "
            },
            {
              "__type": "Link",
              "__tag": 4049,
              "children": [
                {
                  "__type": "Text",
                  "__tag": 4046,
                  "value": "are part of scipy"
                }
              ],
              "url": "https://github.com/scipy/scipy/blob/c93da6f46dbed8b3cc0ccd2495b5678f7b740a03/scipy/linalg/clapack.pyf.src",
              "title": ""
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": ". "
            },
            {
              "__type": "InlineRole",
              "__tag": 4003,
              "value": "tempita",
              "domain": null,
              "role": null,
              "inventory": null
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " support has been removed and is no longer recommended in any case."
            }
          ]
        },
        {
          "__type": "Admonition",
          "__tag": 4056,
          "kind": "note",
          "base_type": "note",
          "children": [
            {
              "__type": "AdmonitionTitle",
              "__tag": 4055,
              "children": [
                {
                  "__type": "Text",
                  "__tag": 4046,
                  "value": "note "
                }
              ]
            },
            {
              "__type": "Paragraph",
              "__tag": 4045,
              "children": [
                {
                  "__type": "Text",
                  "__tag": 4046,
                  "value": "The reason interfaces cannot be supported within "
                },
                {
                  "__type": "InlineCode",
                  "__tag": 4051,
                  "value": "f2py"
                },
                {
                  "__type": "Text",
                  "__tag": 4046,
                  "value": " itself is because they don't correspond to exported symbols in compiled libraries."
                }
              ]
            },
            {
              "__type": "Code",
              "__tag": 4050,
              "value": "❯ nm gen.o\n 0000000000000078 T __add_mod_MOD_add_complex\n 0000000000000000 T __add_mod_MOD_add_complex_dp\n 0000000000000150 T __add_mod_MOD_add_integer\n 0000000000000124 T __add_mod_MOD_add_real\n 00000000000000ee T __add_mod_MOD_add_real_dp",
              "execution_status": null
            }
          ]
        },
        {
          "__type": "Paragraph",
          "__tag": 4045,
          "children": [
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "Here we will discuss a few techniques to leverage "
            },
            {
              "__type": "InlineCode",
              "__tag": 4051,
              "value": "f2py"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " in conjunction with "
            },
            {
              "__type": "Link",
              "__tag": 4049,
              "children": [
                {
                  "__type": "Text",
                  "__tag": 4046,
                  "value": "fypp"
                }
              ],
              "url": "https://fypp.readthedocs.io/en/stable/fypp.html",
              "title": ""
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " to emulate generic interfaces and to ease the binding of multiple (similar) functions."
            }
          ]
        }
      ],
      "title": [
        {
          "__type": "Text",
          "__tag": 4046,
          "value": "Using FYPP for binding generic interfaces"
        }
      ],
      "level": 1,
      "target": null
    },
    {
      "__type": "Section",
      "__tag": 4015,
      "children": [
        {
          "__type": "Paragraph",
          "__tag": 4045,
          "children": [
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "Let us build on the example (from the user guide, "
            },
            {
              "__type": "CrossRef",
              "__tag": 4002,
              "value": "f2py-examples",
              "reference": {
                "__type": "LocalRef",
                "__tag": 4022,
                "kind": "docs",
                "path": "f2py:f2py-examples"
              },
              "kind": "exists"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": ") of a subroutine which takes in two arrays and returns its sum."
            }
          ]
        },
        {
          "__type": "Paragraph",
          "__tag": 4045,
          "children": [
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "We will recast this into modern fortran:"
            }
          ]
        },
        {
          "__type": "Paragraph",
          "__tag": 4045,
          "children": [
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "We could go on as in the original example, adding intents by hand among other things, however in production often there are other concerns. For one, we can template via FYPP the construction of similar functions:"
            }
          ]
        },
        {
          "__type": "Paragraph",
          "__tag": 4045,
          "children": [
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "This can be pre-processed to generate the full fortran code:"
            }
          ]
        },
        {
          "__type": "Code",
          "__tag": 4050,
          "value": "❯ fypp gen_adder.f90.fypp > adder.f90",
          "execution_status": null
        },
        {
          "__type": "Paragraph",
          "__tag": 4045,
          "children": [
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "As to be expected, this can be wrapped by "
            },
            {
              "__type": "InlineCode",
              "__tag": 4051,
              "value": "f2py"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " subsequently."
            }
          ]
        },
        {
          "__type": "Paragraph",
          "__tag": 4045,
          "children": [
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "Now we will consider maintaining the bindings in a separate file. Note the following basic "
            },
            {
              "__type": "InlineCode",
              "__tag": 4051,
              "value": ".pyf"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " which can be generated for a single subroutine via "
            },
            {
              "__type": "InlineCode",
              "__tag": 4051,
              "value": "f2py -m adder adder_base.f90 -h adder.pyf"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": ":"
            }
          ]
        },
        {
          "__type": "Paragraph",
          "__tag": 4045,
          "children": [
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "With the docstring:"
            }
          ]
        },
        {
          "__type": "Paragraph",
          "__tag": 4045,
          "children": [
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "Which is already pretty good. However, "
            },
            {
              "__type": "InlineCode",
              "__tag": 4051,
              "value": "n"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " should never be passed in the first place so we will make some minor adjustments."
            }
          ]
        },
        {
          "__type": "Paragraph",
          "__tag": 4045,
          "children": [
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "Which corresponds to:"
            }
          ]
        },
        {
          "__type": "Paragraph",
          "__tag": 4045,
          "children": [
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "Finally, we can template over this in a similar manner, to attain the original goal of having bindings which make use of "
            },
            {
              "__type": "InlineCode",
              "__tag": 4051,
              "value": "f2py"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " directives and have minimal spurious repetition."
            }
          ]
        },
        {
          "__type": "Paragraph",
          "__tag": 4045,
          "children": [
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "Usage boils down to:"
            }
          ]
        },
        {
          "__type": "Code",
          "__tag": 4050,
          "value": "fypp gen_adder.f90.fypp > adder.f90\nfypp adder.pyf.fypp > adder.pyf\nf2py -m adder -c adder.pyf adder.f90 --backend meson",
          "execution_status": null
        },
        {
          "__type": "Target",
          "__tag": 4061,
          "label": "fypp"
        },
        {
          "__type": "Target",
          "__tag": 4061,
          "label": "are part of scipy"
        }
      ],
      "title": [
        {
          "__type": "Text",
          "__tag": 4046,
          "value": "Basic example: Addition module"
        }
      ],
      "level": 2,
      "target": null
    }
  ],
  "local_refs": []
}