Releases: marcoeilers/nagini
Releases · marcoeilers/nagini
Release list
v1.3.1: Initial support for ViperServer, LSP and MCP servers (#307)
v1.3.1 (July 2026)
New features
- MCP and LSP servers: Nagini now ships a Model Context Protocol (MCP) server and a Language Server Protocol (LSP) server. The MCP server exposes verification to AI agents and MCP-capable editors (e.g. Claude Code, Claude Desktop, Cursor) over stdio, allowing whole files, individual methods, or inline snippets to be verified with structured diagnostics. The LSP server provides editor integration with live diagnostics and per-method verification. Install with
pip install "nagini[mcp]"/pip install "nagini[lsp]". - ViperServer backend: Verification can now run through an in-process ViperServer instance instead of invoking Silicon/Carbon directly. This enables result caching across requests, precise cancellation of running verifications, and concurrent verification of independent requests.
- Improved
--servermode: The verification server now accepts and can reconfigure command-line options between requests, prints a startup message once it is ready, and the client (nagini_client) accepts a--selectargument to verify only specific methods or classes on a per-request basis. - Correctly formatted translation errors in
--ide-mode: Translation errors (invalid program, unsupported feature, and type errors) are now emitted in the samefile:line:col:end_line:end_col: error: messageformat as verification errors, so IDE/LSP frontends can parse them uniformly. Type errors now carry a real source range (start and end) rather than only a line. (#308) - Chained comparisons: Comparison chains such as
a < b < care now supported. enumerate()with a start argument:enumerate(xs, start)is now supported.range()with a step argument:range(start, stop, step)is now supported.- Set and dict comprehensions: Set comprehensions (
{x for x in xs}) and dict comprehensions ({k: v for ... in ...}) are now supported, including comprehensions with filters and multiple generators. (#305)
Infrastructure and dependencies
- Single bundled Viper backend: The separate
silicon.jarandcarbon.jarbackends have been replaced by a single bundledviperserver.jar, which contains Silicon, Carbon, and Silver and serves both the direct and ViperServer-based backends. Extraneous backend log output (e.g. logback traces) is now suppressed so it cannot interfere with the CLI output, the test framework, or the LSP/MCP JSON-RPC stream. - Added optional dependency extras
server,lsp, andmcpfor the respective server modes. - Added CI test workflows for the LSP/MCP servers and a test suite that runs verification through ViperServer.
v1.3.0 (June 2026)
New features
- Python 3.12–3.14 support: Nagini now targets Python 3.12 and newer (3.13 and 3.14 are also supported). Python versions older than 3.12 are no longer supported. (#300)
matchstatement support:match/casestatements are now supported in both impure and pure functions. Most pattern types (value, OR, sequence, mapping, class, wildcard, capture) are handled, with class patterns with keyword arguments currently unsupported. (#301, #302)- Branch condition reporting: When using the Silicon backend, error messages now include the branch conditions that led to the error — the set of conditions along the execution path that the verifier was exploring when it found the failure. (#298)
- Bytearray and PByteSeq: Added support for
bytearrayand a corresponding pure ghost typePByteSeq. (#299) IntEnumsupport: Classes subclassingIntEnumare now supported. (#299)- Bit shift operators: Left (
<<) and right (>>) shift operators are now supported for integers. (#299) int.bit_length(): Added support for theint.bit_length()method. (#299)- String format expressions: Basic support for string format operations. (#299)
- Relative imports:
from .module import Xstyle relative imports are now supported. (#280) - Constructor calls with type arguments: Calls like
ParseResult[bool](True)(generic constructor with explicit type argument) are now supported. (#264) - Subclassing
int: Soundly supports subclasses ofint. Subclassing other builtin types remains unsupported. (#262) - Better quantifier triggers for collections: Improved trigger selection for
Forallquantifiers over lists, sequences, and similar collection types, reducing incompleteness issues. (#289)
Fixes
- Fixed imprecise ADT type information in certain cases. (#288)
- Fixed several crashes and translation errors. (#265, #267, #268, #272, #274, #277, #279, #283, #291)
- Fixed
Reveal()annotations being incorrectly attached to type conversion wrappers rather than the actual function call. (#303)
Infrastructure and dependencies
- Migrated packaging from
setup.pytopyproject.toml. (#300) - Updated
jpype1from 1.5.0 to 1.7.0. (#300) - Updated
mypyfrom 0.900 to 1.5.0. (#300) - Updated
toposortfrom 1.5 to 1.10. (#300) - Updated
z3-solverto 4.16.0.0 on ARM. (#300) - Updated
pytestfrom 7.0.0 to 9.0.3. (#300) - Removed
astunparseandtyped-astdependencies. (#300)
Version 1.2.0
v1.2.0 (November 2025)
New features
- Python 3.9–3.12 multi-version support: Nagini now supports Python 3.9, 3.10, 3.11, and 3.12 (previously only 3.9 was officially supported). CI tests run against multiple Python versions. (#256)
- Opaque pure functions: Pure functions can now be marked
@Opaque. Callers only learn the function's postcondition by default; they must wrap the call inReveal(...)to unfold the function's definition. (#240) AssertandUnfoldin pure functions: TheAssert(e)andUnfold(P(...))contract statements can now be used inside pure functions, translating to Viper'sassertingandunfoldingexpressions. (#248)- Postconditions with lambdas:
Ensures(T, lambda r: P(r))is now accepted as an alternative toEnsures(P(Result())). This form is fully type-checkable by mypy and executable without runtime errors. (#228) @Inlinedecorator: Methods and functions can be marked@Inlineto request that Nagini inline their bodies at call sites rather than treating them modularly. (#215)- Proper string encoding: Strings are now encoded as sequences of characters in Viper, enabling stronger reasoning about string contents. (#225)
- Optional obligation encoding: The obligation encoding (for reasoning about threads, locks, and IO operations) is now only activated when the program actually uses these features. A
--force-obligationsflag is available to override this. (#230) - Using Viper's Chopper for dependency analysis: Nagini's custom dependency tracking between methods and functions has been replaced by Viper's built-in Chopper, which is more precise. (#250)
- Power operator (
**): The**operator is now supported for integers, with special-case handling for constant exponents to improve SMT automation. (#213, #217) - Ellipsis (
...): The...literal is now accepted. (#257) - Longer tuple support: Tuples up to length 9 are now supported (previously limited to length 4). A clear error is given for longer tuples. (#259)
- Resource bounds with Silicon: Verification is now run with resource bounds instead of timeouts by default when using the Silicon's backend. (#251)
- Viper 25.02: Updated to the Viper 25.02 release. (#226)
Fixes
- Fixed crash on dynamically indexed tuples. (#227)
- Fixed crash when calling an unsupported method or function. (#233)
- Fixed statically-bound calls to interface methods being incorrectly treated as dynamic dispatch. (#243)
- Fixed global constant functions not being marked as terminating. (#244)
- Fixed incorrect field vs. property ordering that could cause crashes. (#236)
- Fixed
MayCreateand built-in predicates being usable in impure positions. (#239)
Version 1.1.1
v1.1.1 (October 2024)
Fixes
- Updated
jpype1to version 1.2.1 which has pre-built wheels for Python 3.9 on Windows and avoids compilation issues on that platform. (#210) - Added basic Windows CI tests and fixed automatic Z3 executable path detection on Windows. (#211)
v1.1.0 (October 2024)
This release includes a large number of features and fixes accumulated since v0.9.0, as well as the first official support for Python 3.9.
Language and verification features
- Python 3.9 support: Nagini now supports Python 3.9 (as well as the previously supported Python 3.8). (#167)
- Abstract predicates: Predicates can now be declared abstract (without a body), allowing callers to use them without Nagini knowing their definition. (#163)
- Bitwise operators:
&,|, and^are now supported for both booleans and bounded integers. The encoding uses the SMT bitvector theory and requires a declared bit-width bound. (#208) - Reflected arithmetic magic methods:
__radd__,__rsub__,__rmul__, etc. are now supported, enabling custom right-hand-side operator overloading. (#183) - Unary operator magic methods:
__neg__,__pos__,__abs__etc. are now supported, also fixing a bug with negative float literals. (#184) - Inplace arithmetic magic methods:
__iadd__,__isub__, etc. are now supported. (#188) - Float encoding options: A new
--float-encodingcommand-line flag acceptsreal(model floats as mathematical reals) orieee32(use SMT IEEE floating point theory). The default remains uninterpreted floats. (#160) - Float model extended: The real-number float model now handles
float('inf'),float('-inf'), andfloat('nan'). A newisNaN()contract function is available. (#192) ResultT(t)contract function:ResultT(T)is a typed alternative toResult()in postconditions, allowing mypy to type-check postconditions that mention the return value without usingAny. (#205)- New dict encoding: Dictionaries are now encoded using Viper's native map type, improving completeness and counterexample quality. (#154)
- Counterexamples for generic classes: Counterexample extraction now works correctly for generic classes. (#154)
RefuteandDecreasescontract functions: AddedRefute(e)(assert thateis not provable) andDecreases(e)(termination measure). (#154)ToMSandForall_ncontract functions: AddedToMS(convert to multiset) andForall_n(quantifier overnvariables). (#154)viper_argsupport: Arguments can be passed directly to the Viper backend viaviper_arg. (#154)sorted()andsum()builtins: Added support for thesorted()andsum()builtin functions. (#172)range()with one argument:range(n)is now supported in addition torange(start, stop). (#171)- Correct exit codes: Nagini now exits with an appropriate non-zero exit code when verification fails. (#178)
- Better error messages for built-in functions: Precondition violation messages for built-in functions include source location information via Viper annotations. (#174)
- Better tuple equality: Tuple equality is now defined in terms of component-wise object equality, and object equality is axiomatized to be transitive and symmetric. (#165, #173, #179)
- Tracking static field assignments: Static field and global variable assignments are now correctly tracked, fixing incorrect
Finaldetection. (#162) - Fix
__truediv__: Fixed inconsistent use of__div__vs__truediv__(Python 3 uses the latter for/). (#190) - Fix union subtype axiom: Fixed an unsoundness where union subtype checking was incorrect for union types on the left-hand side. (#197)
- Viper data collection: Added a
--submit-for-evaluationoption to submit programs to the Viper data collection server. (#180) - Viper 24.01 update: Updated the bundled Viper backends. (#154, #166)
Version 0.9
Extensive support for information flow verification
- Verification of ordinary non-interference for sequential programs
- Verification of possibilistic and probabilistic non-interference for concurrent programs
- Counterexamples for non-interference proofs
Version 0.8.6
Major updates
- Updated dependency versions, particularly of mypy
- Compatibility with Python 3.8
- Experimental support for counterexamples
Minor changes
- Updated used Viper version to 20.07
- Improved performance for verifying top-level statements and order of declarations
nagini_contractsis marked for mypy as containing type stubs- Several smaller bug fixes