Registry / serialization / pycparser

pycparser

JSON →
library3.0pypypi✓ verified 27d ago

pycparser is a complete, standards-compliant C99 parser written in pure Python, producing an Abstract Syntax Tree (AST) that can be traversed, modified, and re-emitted as C code. Current version is 3.0, released January 2026, which replaced the bundled PLY (Lex/Yacc) backend with a hand-written lexer and recursive-descent parser—eliminating all external dependencies and improving parse speed by ~30%. Release cadence is irregular; major versions are rare (2.x spanned 2012–2025).

pip install pycparser
INSTALL
IMPORT
SIG · PYCPARSER
P
pycparser
serializationpythonv3.0
Install
1.8s avg
Import
73ms
Disk
17MB
Pass rate
10/ 10
Env Coverage10 / 10
glibc
3.93.13
musl
3.93.13
Install & Compatibility
Where this runs
tested against v3.0 · pip install
no network on importno background threads
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
musl
py 3.103.910 runs
installs and imports cleanly · install 0.0s · import 0.076s · 18.9MB
glibc
py 3.103.910 runs
installs and imports cleanly · install 1.8s · import 0.070s · 19MB
17MB installed
● package 17MB
Code
Verified usage

Verified import paths — ran on the pinned version, not inferred.

CParser
from pycparser import c_parser parser = c_parser.CParser()
from pycparser import CParser
CParser lives in the c_parser submodule; top-level pycparser does not re-export it directly.
parse_file
from pycparser import parse_file
parse_file IS exported from the top-level package and invokes cpp/gcc-E automatically.
c_generator.CGenerator
from pycparser import c_generator gen = c_generator.CGenerator()
Used to emit C source from a pycparser AST; must be imported from the submodule.
c_ast / NodeVisitor
from pycparser import c_ast class MyVisitor(c_ast.NodeVisitor): ...
All AST node types and the NodeVisitor base class live in pycparser.c_ast.

Parse a tiny C snippet directly with CParser (no preprocessor needed for self-contained code), then walk the AST with a visitor.

from pycparser import c_parser, c_ast, c_generator # Direct in-memory parse — only works for preprocessor-free, self-contained C parser = c_parser.CParser() src = r""" int add(int a, int b) { return a + b; } """ ast = parser.parse(src, filename='<none>') ast.show(attrnames=True, nodenames=True) # Regenerate C source from AST gen = c_generator.CGenerator() print(gen.visit(ast)) # Visitor pattern: collect all function names class FuncDefVisitor(c_ast.NodeVisitor): def visit_FuncDef(self, node): print('Function:', node.decl.name) v = FuncDefVisitor() v.visit(ast)
Debug
Known issues
breakingv3.0 dropped PLY entirely and rewrote the lexer/parser from scratch. CParser.__init__ kwargs lex_optimize, yacc_optimize, yacc_debug, lextab, yacctab are no longer accepted — passing them raises TypeError.
fix
Remove all PLY-related kwargs from CParser() calls. The public AST API is unchanged; only internal constructor arguments differ.
affects: <3.0
breakingPython 3.8 support was dropped in v3.0. Requires Python >=3.10.
fix
Upgrade to Python 3.10+. Pin pycparser<3 if you must support Python 3.8 or 3.9.
affects: 3.0+
gotchapycparser cannot parse raw C files that contain #include or macros — it requires preprocessed input. Passing unpreprocessed C to parser.parse() will produce parse errors for any non-trivial real-world file.
fix
Use parse_file(..., use_cpp=True) which calls cpp/gcc-E automatically, or manually preprocess with subprocess before calling parser.parse().
affects: all
gotchafake_libc_include headers are NOT included in the PyPI pip wheel. Code that assumes pycparser.__file__ contains a utils/fake_libc_include directory will fail at runtime.
fix
Install the companion package `pip install pycparser-fake-libc` and use `import pycparser_fake_libc; cpp_args='-I' + pycparser_fake_libc.directory`, or vendor the headers from the GitHub source tree.
affects: all
gotchaThe fake_libc_include headers target C11 and will cause errors if the preprocessor is invoked with -std=c99 or older standards.
fix
Omit -std=c99 from cpp_args when using fake_libc_include, or use a preprocessor invocation that defaults to C11 or later.
affects: 2.22+
gotchapycparser supports C99 and a subset of C11, but does NOT support GCC/Clang extensions (__attribute__, __extension__, __builtin_*, etc.) out of the box. Passing GCC-extended code will raise ParseError.
fix
Pass cpp_args=['-D__attribute__(x)=', '-D__extension__=', ...] to strip extensions before parsing, as shown in the project FAQ.
affects: all
gotchaFrozen-app packagers (cx_Freeze, PyInstaller) may fail to import pycparser 3.0 due to internal relative-import restructuring introduced when PLY was removed, raising ImportError on 'c_parser'.
fix
Check for updated hooks in your freezer tool. As a workaround, pin pycparser<3 until the packager adds support.
affects: 3.0
Errors
Common errors & fixes
ModuleNotFoundError: No module named 'pycparser'
The `pycparser` package is not installed in the Python environment being used.
fix
Install the package using pip: `pip install pycparser`
ModuleNotFoundError: No module named 'pycparser.plyparser'
In `pycparser` version 3.0, the internal `plyparser` module was removed as part of replacing the PLY backend with a hand-written parser. Code attempting to import this module will fail.
fix
Update your code to remove any direct imports of `pycparser.plyparser`. If a dependency requires it, ensure that dependency is compatible with `pycparser` 3.0 or downgrade `pycparser` to a 2.x version if necessary.
pycparser.ParseError: <file>:<line>:<column>: before: <token>
`pycparser` encountered C code it could not parse, often due to non-standard C extensions (like GCC built-ins), complex macros, or if the input C code was not fully preprocessed before being passed to `pycparser`.
fix
Ensure the C code is fully preprocessed (e.g., using `gcc -E` or `clang -E`) before parsing with `pycparser`. If using standard library headers, provide `pycparser` with its bundled `fake_libc_include` directory (e.g., `parse_file('file.c', parse_headers=True, cpp_args=['-Iutils/fake_libc_include'])`). Simplify or remove non-standard C constructs if `pycparser` doesn't support them.
ImportError: cannot import name 'c_parser' from partially initialized module 'pycparser'
This issue typically arises with `pycparser` 3.0, particularly in frozen applications (e.g., those built with `cx_Freeze`), indicating a potential circular import or an initialization problem specific to the packaging process.
fix
Downgrade `pycparser` to a version prior to 3.0 (e.g., `pip install pycparser<3`). Alternatively, check for updates to `pycparser` or the freezing tool that address this specific compatibility problem.
Upgrade
Version history
3.0latest on PyPI · released Jan 21, 2026
Audit
Dependencies

No dependency data recorded yet.

Agent activity
13 hits · last 30 days
node
10
Bingbot
1
Resources
pycparser — pip install pycparser · libregistry