Skip to main content

OpenUnderstand

OpenUnderstand Logo

An open-source implementation of the SciTools Understand Python API, for Java.

Understand reads a codebase and lets you ask questions about it -- which methods call this one, what does this class contain, how complex is this function. The API is good. The analysis is closed: the database format is proprietary, the API source is not published, and it needs a licence.

OpenUnderstand reimplements that API on top of an ANTLR4 Java parser and a SQLite database, so the same scripts run without one.

import openunderstand.ounderstand as und

db = und.open("myproject.udb")

for cls in db.ents("Class"):
    print(cls.longname())
    for ref in cls.refs("Define", "Method"):
        print("   ", ref.ent().name(), "at line", ref.line())

That is Understand's API, unchanged. Same class names, same method signatures, same kind names.

Install

pip install openunderstand

Python 3.9+. On Linux x86_64 that wheel carries the C++ parse accelerator, which is 7.8x faster at parsing and takes about 17% off a full analysis. Everywhere else the pure-Python ANTLR runtime is used instead and everything works the same, just slower -- both engines produce byte-identical databases.

Optional extras:

Extra For
openunderstand[speedy] tools to build the C++ parser accelerator from source
openunderstand[mcp] the MCP server, so an assistant can query your code

From a checkout instead:

git clone https://github.com/m-zakeri/OpenUnderstand
cd OpenUnderstand
python -m venv .venv && . .venv/bin/activate
pip install -e ".[dev]"

Build a database

Point it at a directory of Java source:

python openunderstand/ounderstand/openunderstand.py \
    -r /path/to/java/project \
    -dba /path/for/database \
    -dbn myproject.udb \
    -l /path/for/app.log
Flag Meaning
-r source directory to analyse
-dba directory to write the database into
-dbn database filename
-e C++ (fast) or Python parser backend
-l log file

Or from Python:

from openunderstand.ounderstand.openunderstand import start_parsing

start_parsing(
    repo_address="/path/to/java/project",
    db_address="/path/for/database",
    db_name="myproject.udb",
    engine_core="C++",
    log_address="/path/for/app.log",
)

The result is a .udb file. Despite the name it is plain SQLite -- open it with any SQLite tool if you want to poke at the rows directly.

How correct is it?

Honestly measured, not claimed. Every release is compared against a licensed SciTools Understand install on the same source, entity by entity, reference by reference, metric by metric.

Current agreement, over eleven Java systems and 174,260 Understand entities:

pooled range across subjects
Entities recovered -- recall 0.935 0.49 -- 1.00
-- precision 0.943 0.84 -- 0.97
References at the exact position -- recall 0.90 -- 0.98
-- precision 0.62 -- 0.88

Three of the subjects, for comparison with earlier releases:

calculator_app org.json TheAlgorithms
Java files 8 85 228
Reference recall / precision 0.98 / 0.86 0.97 / 0.84 0.96 / 0.83

Both sides are scoped the same way: Understand indexes the whole Java library whether or not a JDK is added to the project, and its dump keeps only entities declared under the fixture root, so this project's placeholders for those same names -- java.lang.String, java.util.ArrayList -- are excluded too. Counting ours while its counterparts were dropped understated entity precision by 5 to 14 points depending on the subject.

docs/parity.md has the per-kind breakdown.

The comparison is the specification: what the real tool outputs is what decides whether a reference is right. Understand must be installed and licensed, so it is not part of this repository -- ask if you want to run it.

tests/ holds unit tests for the pass rules that comparison established. They need no database and run in about a second each:

for t in tests/test_*.py; do .venv/bin/python -W ignore "$t"; done

Use it from an assistant

An MCP server ships with the package:

pip install "openunderstand[mcp]"
{"mcpServers": {"openunderstand": {"command": "openunderstand-mcp"}}}

Six tools (analyze, open_database, list_entities, entity_references, entity_metrics, list_kinds), four resources exposing the kind vocabulary and metric names, and three prompts (review_class, complexity_hotspots, trace_callers) -- so an assistant can analyse a Java project and ask what calls what, without knowing the schema. See docs/mcp.md.

Use it from IntelliJ IDEA

idea-plugin/ builds a Java Metrics tool window: analyse the open project, sort by any metric, double-click to jump to the declaration, export CSV. It runs the analysis in a Python subprocess and offers to install the package into a private virtualenv when it cannot find one.

cd idea-plugin && gradle buildPlugin    # then install the zip from disk

See docs/idea-plugin.md.

What it does not do

  • Java 8 only. The grammar predates records, sealed types, var, text blocks and yield.
  • No external resolution. The JDK and third-party jars are not analysed, so java.lang.String exists but has no members.
  • Partial coverage. 90 to 98% of Understand's references are reproduced at the exact position, at 62 to 88% precision. 46 of the 49 public API methods are implemented.
  • Silence, not refusal, on what is missing. The three unimplemented methods -- Db.close, Db.lookup_uniquename, Violation.add_fixit_hint -- return None. Querying a reference kind no pass emits returns an empty list, which reads exactly like an entity that has none. NotImplementedError is not raised anywhere in the query API, whatever this file used to say.

Documentation

Getting started install, build, query
API reference every class and method, and what is missing
Kinds the 237 entity and 106 reference kinds
Architecture how a file becomes rows; how to add a pass
Parity measured agreement with Understand
MCP server query your code from an assistant
IntelliJ IDEA plugin metrics in a tool window

Published at m-zakeri.github.io/OpenUnderstand.

Contributing

Read docs/architecture.md first -- particularly the rule that kind ids are positions and must always be resolved by name.

Changes to the analysis are judged against Understand, not against opinion. If you can run the comparison, report recall and precision before and after -- a change that raises recall by tanking precision is not an improvement. If you cannot, say what you expect to change and it will be measured for you.

Pull requests target the dev branch.

Credits

Started at the IUST Reverse Engineering Research Laboratory. Uses ANTLR4, peewee, and a labelled fork of the grammars-v4 Java grammar.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

openunderstand-0.3.0.tar.gz (464.3 kB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

openunderstand-0.3.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl (3.3 MB view details)

Uploaded CPython 3.13manylinux: glibc 2.27+ x86-64manylinux: glibc 2.28+ x86-64

openunderstand-0.3.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl (3.3 MB view details)

Uploaded CPython 3.12manylinux: glibc 2.27+ x86-64manylinux: glibc 2.28+ x86-64

openunderstand-0.3.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl (3.3 MB view details)

Uploaded CPython 3.11manylinux: glibc 2.27+ x86-64manylinux: glibc 2.28+ x86-64

openunderstand-0.3.0-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl (3.3 MB view details)

Uploaded CPython 3.10manylinux: glibc 2.27+ x86-64manylinux: glibc 2.28+ x86-64

openunderstand-0.3.0-cp39-cp39-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl (3.3 MB view details)

Uploaded CPython 3.9manylinux: glibc 2.27+ x86-64manylinux: glibc 2.28+ x86-64

File details

Details for the file openunderstand-0.3.0.tar.gz.

File metadata

  • Download URL: openunderstand-0.3.0.tar.gz
  • Upload date:
  • Size: 464.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for openunderstand-0.3.0.tar.gz
Algorithm Hash digest
SHA256 f41730806be489ed78e66d46934ed5bea616047ea88407c8df25312270743bb5
MD5 5973b0551cb8155df92b69a78154cd31
BLAKE2b-256 d11a9826faa736c59c7f7165a1ccbafce00663b0a2c0581e51db1965045ee6bd

See more details on using hashes here.

Provenance

The following attestation bundles were made for openunderstand-0.3.0.tar.gz:

Publisher: release.yml on m-zakeri/OpenUnderstand

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file openunderstand-0.3.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for openunderstand-0.3.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 ccb369cf325a3876eecda5b851f8589bbb6fdd88ac4be0fe1a187f526b2afd62
MD5 6702d6d5d254a6d7dd642eb553681c66
BLAKE2b-256 8c0f148c5c1b3932b1e7136c2bb73a0a2bab43863f1d72de59d98353fed9fff3

See more details on using hashes here.

Provenance

The following attestation bundles were made for openunderstand-0.3.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl:

Publisher: release.yml on m-zakeri/OpenUnderstand

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file openunderstand-0.3.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for openunderstand-0.3.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 4ff225ebad4823cd7d59f6acde19ab41ac86096dbeb1c9db5ad72f5edb4fad85
MD5 a3d9e3ead5e48c93f2ad0eb829b931f7
BLAKE2b-256 4a114fd6c6eaa0986b9d27391e7db92c989078bb4d8b789c840c064177d0c1b1

See more details on using hashes here.

Provenance

The following attestation bundles were made for openunderstand-0.3.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl:

Publisher: release.yml on m-zakeri/OpenUnderstand

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file openunderstand-0.3.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for openunderstand-0.3.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 53255503c06abfb9500188c74a94e1c5c2965bc1cf15c4f41a696e39610f14d1
MD5 d19a7b9483822465e633b4d3070a0b94
BLAKE2b-256 f29c2360ca9f7529e9d3b9af54736949b7070a2e9aa2a40d7b06a42a36892455

See more details on using hashes here.

Provenance

The following attestation bundles were made for openunderstand-0.3.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl:

Publisher: release.yml on m-zakeri/OpenUnderstand

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file openunderstand-0.3.0-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for openunderstand-0.3.0-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 b62612a691d2343408d35e9428b630611ae5571ab95323d7f80f8665bfebdebf
MD5 72112cda022bfdbd519893f639ae2762
BLAKE2b-256 7854d2771aee68f0a77648e82e41cf40585be167a4f3359e7eba128981a4810b

See more details on using hashes here.

Provenance

The following attestation bundles were made for openunderstand-0.3.0-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl:

Publisher: release.yml on m-zakeri/OpenUnderstand

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file openunderstand-0.3.0-cp39-cp39-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for openunderstand-0.3.0-cp39-cp39-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 e57d549aa85008eda5f51863885b9f11a6093d70c9cc73d3ed00ac939d8f82f7
MD5 0dfa492c6ec7326550c6752daca4fde9
BLAKE2b-256 6139c9662309711c71e17a19c3e4edd24def20ac77a724dcb8dc5c12bba2e4ac

See more details on using hashes here.

Provenance

The following attestation bundles were made for openunderstand-0.3.0-cp39-cp39-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl:

Publisher: release.yml on m-zakeri/OpenUnderstand

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

0.4.0

19 files

0.3.1

16 files

This release

0.3.0 This release

6 files

0.2.4

2 files

0.2.3

2 files

0.2.2

2 files

0.2.1

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page