C++ header (and source) parser for Python using Clang plugins.
-
Get the required tools:
-
You'll need to have clang-11 and the required dev tools installed.
To install using
apt
on Debian / Ubuntu see LLVM Debian/Ubuntu nightly packages page. -
Note that pyheaders requires Python>=3.8.
-
-
Clone pyheaders:
Change the directory to where you want the pyheaders installer directory placed.
git clone https://github.com/Roynecro97/pyheaders.git
-
Build the plugins:
cd pyheaders ./update-plugin.sh
-
Install pyheaders:
From the pyheaders directory run:
python setup.py install
Or to install in develop mode:
python setup.py develop
-
You can now safely erase the git clone (unless pyheaders is installed in develop mode).
pyheaders can be imported and used as a module.
It provides 3 main functions: load_path
, load
and loads
.
All 3 functions return a pyheaders.SrcData
object that has 2 properties:
scope
- The C++ global scope that was parsed from the provided code.macros
- A dictionary with all non-function macros that were generated.
Both load
and loads
behave similarly to the similarly named functions in the json
and pickle
modules.
Using load
:
Assuming source.cpp contains the line
static constexpr int x = 100;
import pyheaders
with open('source.cpp') as f:
data = pyheaders.load(f)
print(data.scope['x'])
Output:
100
Using loads
:
import pyheaders
cpp_code = '''\
namespace constants {
inline constexpr auto greeting = "Hello World!";
}
'''
scope, macros = pyheaders.loads(cpp_code, ['-std=c++17'])
print(scope['constants::greeting'])
Output:
Hello World!
Using load_path
:
load_path
provides a useful alternative when working with big projects as it accepts the path to a C++ file or a directory that contains C++ source code and loads it.
Using this method allows pyheaders to find your project's compile_commands.json if it exists and read the compilation flags from there implicitly.
Assuming src/ contains a file with:
class MyClass { // code ... static constexpr int magic = 0x10; // code ... };
import pyheaders
scope = pyheaders.load_path('src/').scope
print(scope['MyClass::magic'])
Output:
16
NOTE: When using load
or loads
pyheaders will look for a compile_commands.json file from the current working directory.
NOTE: When using load
or loads
and when a file processed by load_path
is missing from the compile_commands.json, but the compile commands were successfully loaded, pyheaders will attempt to find a close match in the compile commands and use flags that are common among all commands.
This mechanism allows pyheaders to find the include path (for example) for a header file (that is not compiled on its own).
pyheaders can also be used as an executable by running python -m pyheaders
or simply pyheaders
.
Example usage:
$ cat << EOF > a.cpp
namespace project
{
static constexpr auto greeting = "Hello from pyheaders!";
}
EOF
$ pyheaders get a.cpp --const project::greeting --hide-names
'Hello from pyheaders!'