NewYour coding agent can read the release notes before it upgrades.Set up the MCP server →
PyPI · #3573 most downloaded on PyPI
A code analyzer without caring the C/C++ header files. It works with Java, C/C++, JavaScript, Python, Ruby, Swift, Objective C. Metrics includes cyclomatic complexity number etc.
Last release 1 months ago
19 Aug 2026
Release timing varies
gaps range from 8 days to 4 months
Most releases are documented
notes for 46 of the last 60 stable releases
Nothing withdrawn
no release was ever pulled
13 years old
129 releases · first in 2013
Halstead metrics ( -Ehalstead ) — per-function Halstead volume, difficulty, and effort (issue #464 , PR #485 )
-Ehalstead) — per-function Halstead volume, difficulty, and effort (issue #464, PR #485)--no-gitignore — analyze all discovered source files even when a .gitignore would exclude them (PR #488)record as a contextual keyword in field initializers and method declarations[...] type parameters (PR #484)FUNCTION_INFO fields (PR #486)# comment continuing past a trailing backslash (issue #317, PR #482)Published to PyPI via GitHub Actions (release.yml).
One column per quarter.
Python — structural pattern matching ( match / case , PEP 634, Python 3.10+) is now counted correctly for cyclomatic complexity (including --modified
match/case, PEP 634, Python 3.10+) is now counted correctly for cyclomatic complexity (including --modified mode)R"(…)") from swallowing following code in the tokenizer (issue #478, PR #479)Published to PyPI via GitHub Actions (release.yml).
match/case, PEP 634, Python 3.10+) is now counted correctly:
case arm adds +1 to cyclomatic complexity (like an if/elif branch)case guards (case x if cond:) count the if as a normal conditioncase and match used as plain variable names (assignments, attribute access, function calls, subscripts, tuple unpacking, annotated assignments) are not counted — soft-keyword disambiguation via lookahead in preprocess--modified: an entire match/case block counts as 1, consistent with switch/case in C-family languagesR"(…)") from swallowing following code in the tokenizer (issue #478, PR #479)Co-authored-by: Cursor cursoragent@cursor.com
Co-authored-by: Cursor cursoragent@cursor.com
index.py): enable debug only when FLASK_DEBUG is set, not by default (PR #475)TypeScript: fix IndexError on nested template literals ( #471 , #472 ). See CHANGELOG.md.
IndexError when parsing nested template literals (issue #471, PR #472)Release 1.22.0: TypeScript, TSX, and JSX parser improvements (PRs #46 …
Release 1.22.0: TypeScript, TSX, and JSX parser improvements (PRs #46…
TypeScriptStates path as .ts (tokenizer-only layer for JSX), so class methods and CCN are no longer wrong or double-counted.interface { … } method signatures, type … = value types, abstract method declarations without bodies; ES2022 private names #foo in tokenization; smarter parameters (type keyword noise, commas inside Map<…>, etc.).handleClick = () => {}) are reported under the field name instead of (anonymous); better call vs definition and class-body cases (typed fields, static / async fields, LWC-style async x => fields, field = CONST.PROP;, JSX attribute expressions).Java parser: contextual record keyword and class-body brace depth (issue #470 ).
Java parser: contextual record keyword and class-body brace depth (issue #470).
Made-with: Cursor
record as a contextual keyword (field and method name record are no longer parsed as a record class); track brace depth for field array/object initializers so = { } does not end the class body before a static block (issue #470)Release workflow: clarify how PyPI matches trusted publishers (repository owner id, workflow file, environment); add optional PYPI_API_TOKEN secret fo
PYPI_API_TOKEN secret for token-based upload when OIDC is not usedNew GitHub Actions workflow builds sdist/wheel on semver tags and publishes via PyPI trusted publishing (pypi environment).
Made-with: Cursor
@Transactional(rollbackFor = Exception.class)) being parsed as methods and corrupting complexity (issue #463)Fix nesting depth calculation for C++ else if chains (issue #418)
else if chains (issue #418)
else if () {} is now treated as same nesting level as if, not as nestedFix Ruby parser hang on %i[] and %I[] symbol array literals (issue #457)
Add selective metric forgiveness (issue #455)
#lizard forgives(length) to forgive only specific metrics#lizard forgives(length, parameter_count) for multiple metrics#lizard forgives without parentheses continues to forgive all metrics (backward compatible)record keyword and variables named "record"Fix IndexError crash when parsing C++ raw string literals containing braces
R"delimiter(content)delimiter")Full Changelog: https://github.com/terryyin/lizard/compare/1.19.0...1.20.0
Add PL/SQL language support with comprehensive parsing for procedures, functions, and triggers
Add R language support with comprehensive function parsing
Nothing published for this version
Fix TypeScript function detection issue.
Fix TypeScript function detection issue.
Fix modern PHP issues.
Fix modern PHP issues.
Fix Java function count issue.
Fix Java function count issue.
Fix Java function count issue.
Fix Java function count issue.
Bug fixes. "lizard forgive" for python
Bug fixes. "lizard forgive" for python
Added support for #lizard forgive global to suppress warnings for all code outside of functions, for languages like Python, Perl, etc, that allow glob
Added support for #lizard forgive global to suppress warnings for all code outside of functions, for languages like Python, Perl, etc, that allow global code.
#lizard forgive at the global level will suppress warnings for all code after it.
Bug fixes.
Bug fixes.
Add Complete Perl support.
Add Complete Perl support.
Add Perl support.
Add Perl support.
Nothing published for this version
Bug fixes.
Bug fixes.
Bug fixes.
Bug fixes.
Bug fixes.
Bug fixes.
Add support for gitignore files. A few bug fixes.
Add support for gitignore files. A few bug fixes.
Add VueJS support.
Add VueJS support.
Add TSX support.
Add TSX support.
Bug fix: Replace re.NOFLAG with 0 to make it compatible with Python 3.10+
Bug fix: Replace re.NOFLAG with 0 to make it compatible with Python 3.10+
Bug fix: Fortran support for ELSEIF
Bug fix: Fortran support for ELSEIF
Nothing published for this version
Bug fix: Java generic like List<? extends String> JSX file extension
Bug fix: Java generic like List<? extends String> JSX file extension
Add Fortran to the language supported
Add Fortran to the language supported
Bug fixing. typedef being read properly.
Bug fixing. typedef being read properly.
Bug fixing. .mm file was not recognized as object-c(++) file.
Bug fixing. .mm file was not recognized as object-c(++) file.
Nothing published for this version
Bug fixing in Lua and Scala support
Bug fixing in Lua and Scala support
Fix missing file when install
Fix missing file when install
Fix HTML Output template problem.
Fix HTML Output template problem.
Support JavaScript with ES6 and JSX. Support Rust
Support JavaScript with ES6 and JSX. Support Rust
'for' keyword in Swift label should not be counted as ccn.
Bug fixes:
'for' keyword in Swift label should not be counted as ccn.
'guard' keyword should be counted.
'-o' or '--output_file' parameter added.
Nothing published for this version
Fix the performance issue
Fix the performance issue
Nothing published for this version
Add Lua to the languages.
Add Lua to the languages.
Fix a bug in MSVS format output.
Fix a bug in MSVS format output.
Minor fix for the average NCSS (lines of code) in the XML output. Previously, the average NCSS per function included code outside any function. Now th
Minor fix for the average NCSS (lines of code) in the XML output. Previously, the average NCSS per function included code outside any function. Now this is fixed.
Nothing published for this version
Nothing published for this version
An important new feature -- duplicate detector -- in the form of an extension.
An important new feature -- duplicate detector -- in the form of an extension.
Usage:
lizard -Eduplicate
The current version hasn't had any performance optimization yet. Yet, it can scan 1000 cpp files in less than 2 minutes.
Code after comments containing "GENERATED CODE" will be ignored.
Nothing published for this version
Class<?>[] testClasses = {String.class};
in
Class<?>[] testClasses = {String.class};
The ? wouldn't be counted as CC.
A minor fix for the --version option
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Your coding agent can read these notes before it upgrades. Set up the MCP server →