Skip to content

Write an architecture plugin (Python)

When Understand's built-in and shipped architectures don't group your project the way you need, write an automatic-architecture plugin. It appears in the New Automatic Architecture list, and — unlike a manual architecture — it rebuilds on every analysis, so it stays current as the code changes. An architecture plugin is one of Understand's five plugin types; this page covers the architecture-specific contract.

Python only

Architecture plugins are Python scripts (.upy). You add entities to the architecture through the Understand API in a build function.

The plugin contract

Understand classifies a .upy file as an architecture plugin because it defines a top-level build function. Unlike other plugins, one architecture plugin can produce many architectures: name() is the entry in the New Automatic Architecture list, and the user names each instance they create from it.

Function Required Purpose
name() yes The plugin's name in the New Automatic Architecture list.
build(arch, db) yes Builds the architecture — adds entities to arch.
description() no HTML shown in the Plugin Manager and the New Automatic Architecture dialog.
tags() no List of tags shown in the Plugin Manager.
test_global(db) no Return True if the plugin applies to this database (assumed True).
define_options(arch) no Define options here; read them in build with arch.options().

In build(arch, db), arch is an AutomaticArchContext and db is the understand.Db being analyzed.

Building with the architecture API

Inside build and define_options, the arch context is how you populate the architecture. For the full class reference and the API's own plugin-writing narrative, see the Python API architectures guide:

Call Does
arch.add(ent, name="") Add an entity under a /-separated path; an empty name adds it to the root. This is the heart of the plugin.
arch.options() Define options (in define_options) and read them (.lookup(...)).
arch.is_aborted() Return True if the user cancelled generation — bail out of long loops.
arch.set_progress_range(min, max) / set_progress_value(v) Report progress (default range 1–100).

(arch.map(...) is a deprecated alias of arch.add(...).)

Example: group entities by long name

def name():
    return "Long Name"

def define_options(arch):
    arch.options().text("kinds", "Kind String", "class ~unresolved ~member")
    arch.options().text("sep", "Separator", "::")

def build(arch, db):
    sep = arch.options().lookup("sep")
    for ent in db.ents(arch.options().lookup("kinds")):
        parts = ent.longname().split(sep)
        if len(parts) > 1:
            # A '/'-separated name creates sub-architectures; an empty name
            # would add the entity directly to the root.
            arch.add(ent, "/".join(parts[:-1]))

The shipped plugins/Arch/longname.upy is this example in full (with a description and tags). It groups entities by their long name, splitting on a configurable separator — :: for C++, . for C#, and so on.

Start from a template

The shipped plugins/Arch/ library is the easiest starting point. In the Plugin Manager, filter by the Sample Template tag, pick one, and Customize it to drop an editable copy into your plugin folder.

Install & run

Install an architecture plugin like any other — drag the .upy onto the main window, or add it from the Plugin Manager. Understand recognizes it as an architecture (it defines build) and files it under your per-user Arch plugin folder.

Then create an architecture from it: Architectures → New Automatic Architecture → [name], or the Add New Automatic Architecture button in the Architecture Browser. Name the instance, set any options, and it rebuilds on each analysis. See Build, browse & enable architectures for the GUI workflow, and Write a plugin for the plugin model and common gotchas (broken plugins, reloading, the per-interpreter GIL).

Headless: the Python API's db.automatic_arch(...) creates a temporary architecture that lasts only until the project closes. To create and save a permanent one from the command line, use und archund arch -generate "<name>" (and und arch -list shows the available names).