Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/python.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,4 @@ jobs:
- name: Type checks
run: uv run ty check .
- name: Tests
run: uv run python -m unittest discover --verbose .
run: uv run pytest
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
The MIT License (MIT)

Copyright (c) 2016 The py_cppmodel Authors. All Rights Reserved.
Copyright (c) 2016 The py-cppmodel Authors. All Rights Reserved.

Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ uv sync
To run the tests, run:

```sh
uv run python -m unittest discover --verbose .
uv run pytest
```

To run type checking:
Expand Down
6 changes: 5 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,15 @@ Repository = "https://github.com/jbcoe/py_cppmodel"
dev = [
"ipython>=8.12.3",
"jupyter>=1.1.1",
"parameterized>=0.9.0",
"pre-commit>=4.5.1",
"pytest>=9.0.2",
"pytest-xdist>=3.8.0",
"ty>=0.0.14",
]

[tool.pytest.ini_options]
addopts = "-n auto -v"
Copy link

Copilot AI Jan 31, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Setting addopts = "-n auto -v" makes pytest-xdist effectively mandatory for any pytest invocation (otherwise -n is an unknown option). Consider moving -n auto to CI/scripts (or using required_plugins to fail with a clearer message) so local/packaging workflows that install only pytest don’t break.

Suggested change
addopts = "-n auto -v"
addopts = "-v"

Copilot uses AI. Check for mistakes.

[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"
Expand Down
2 changes: 1 addition & 1 deletion test.macos.sh
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,4 @@ uv sync
uv run ty check .

# Unit tests
uv run python -m unittest discover --verbose .
uv run pytest
85 changes: 37 additions & 48 deletions test_parse_standard_library_includes.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
import unittest

import pytest
from clang.cindex import TranslationUnit
from parameterized import parameterized

import py_cppmodel

Expand All @@ -14,50 +12,41 @@
]


def _custom_name_func(testcase_func, _, param):
return "%s_%s" % (testcase_func.__name__, parameterized.to_safe_name(param.args[0]))


class TestStandardLibraryIncludes(unittest.TestCase):
@parameterized.expand(
[
"algorithm",
"any",
"array",
"deque",
"forward_list",
"functional",
"iterator",
"list",
"map",
"memory",
"numeric",
"optional",
"queue",
"set",
"stack",
"string",
"tuple",
"type_traits",
"unordered_map",
"unordered_set",
"utility",
"variant",
"vector",
],
name_func=_custom_name_func,
@pytest.mark.parametrize(
"include",
[
"algorithm",
"any",
"array",
"deque",
"forward_list",
"functional",
"iterator",
"list",
"map",
"memory",
"numeric",
"optional",
"queue",
"set",
"stack",
"string",
"tuple",
"type_traits",
"unordered_map",
"unordered_set",
"utility",
"variant",
"vector",
],
)
def test_include(include):
source = f"#include <{include}>"
tu = TranslationUnit.from_source(
"t.cc",
COMPILER_ARGS,
unsaved_files=[("t.cc", source)],
)
def test_include(self, include):
source = f"#include <{include}>"
tu = TranslationUnit.from_source(
"t.cc",
COMPILER_ARGS,
unsaved_files=[("t.cc", source)],
)

# This should not raise an exception.
self.model = py_cppmodel.Model(tu)


if __name__ == "__main__":
unittest.main()
# This should not raise an exception.
py_cppmodel.Model(tu)
109 changes: 51 additions & 58 deletions test_py_cppmodel.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import unittest

import pytest
from clang.cindex import TranslationUnit

import py_cppmodel
Expand Down Expand Up @@ -35,59 +34,53 @@ class B {
"""


class TestCppModel(unittest.TestCase):
def setUp(self):
tu = TranslationUnit.from_source(
"sample.cc",
COMPILER_ARGS,
unsaved_files=[("sample.cc", SOURCE)],
)
self.model = py_cppmodel.Model(tu)

def test_filename(self):
self.assertEqual(self.model.filename, "sample.cc")

def test_functions(self):
self.assertEqual(len(self.model.functions), 2)
self.assertEqual(str(self.model.functions[0]), "<py_cppmodel.Function double bar(double)>")
self.assertEqual(str(self.model.functions[1]), "<py_cppmodel.Function int main()>")

def test_classes(self):
self.assertEqual(len(self.model.classes), 1)
self.assertEqual(str(self.model.classes[0]), "<py_cppmodel.Class A>")

self.assertEqual(len(self.model.classes[0].annotations), 1)
self.assertEqual(self.model.classes[0].annotations[0], "A")

self.assertEqual(len(self.model.classes[0].members), 3)
self.assertEqual(
str(self.model.classes[0].members[0]),
"<py_cppmodel.Member <py_cppmodel.Type int> a>",
)
self.assertEqual(
str(self.model.classes[0].members[1]),
"<py_cppmodel.Member <py_cppmodel.Type double> b>",
)
self.assertEqual(
str(self.model.classes[0].members[2]),
"<py_cppmodel.Member <py_cppmodel.Type char[8]> c>",
)

self.assertEqual(len(self.model.classes[0].methods), 1)
self.assertEqual(str(self.model.classes[0].methods[0]), "<py_cppmodel.Method int foo(int)>")
self.assertEqual(len(self.model.classes[0].methods[0].annotations), 1)
self.assertEqual(self.model.classes[0].methods[0].annotations[0], "foo")

self.assertEqual(len(self.model.unmodelled_nodes), 2)
self.assertEqual(
str(self.model.unmodelled_nodes[0]),
"<py_cppmodel.Unmodelled z <SourceLocation file 'sample.cc', line 1, column 5>>",
)
self.assertEqual(
str(self.model.unmodelled_nodes[1]),
"<py_cppmodel.Unmodelled B<T> <SourceLocation file 'sample.cc', line 12, column 7>>",
)


if __name__ == "__main__":
unittest.main()
@pytest.fixture
def model():
tu = TranslationUnit.from_source(
"sample.cc",
COMPILER_ARGS,
unsaved_files=[("sample.cc", SOURCE)],
)
return py_cppmodel.Model(tu)


def test_filename(model):
assert model.filename == "sample.cc"


def test_functions(model):
assert len(model.functions) == 2
assert str(model.functions[0]) == "<py_cppmodel.Function double bar(double)>"
assert str(model.functions[1]) == "<py_cppmodel.Function int main()>"


def test_classes(model):
assert len(model.classes) == 1
assert str(model.classes[0]) == "<py_cppmodel.Class A>"

assert len(model.classes[0].annotations) == 1
assert model.classes[0].annotations[0] == "A"


def test_class_members(model):
assert len(model.classes[0].members) == 3
assert str(model.classes[0].members[0]) == "<py_cppmodel.Member <py_cppmodel.Type int> a>"
assert str(model.classes[0].members[1]) == "<py_cppmodel.Member <py_cppmodel.Type double> b>"
assert str(model.classes[0].members[2]) == "<py_cppmodel.Member <py_cppmodel.Type char[8]> c>"

assert len(model.classes[0].methods) == 1
assert str(model.classes[0].methods[0]) == "<py_cppmodel.Method int foo(int)>"
assert len(model.classes[0].methods[0].annotations) == 1
assert model.classes[0].methods[0].annotations[0] == "foo"


def test_unmodelled_nodes(model):
assert len(model.unmodelled_nodes) == 2
assert (
str(model.unmodelled_nodes[0])
== "<py_cppmodel.Unmodelled z <SourceLocation file 'sample.cc', line 1, column 5>>"
)
assert (
str(model.unmodelled_nodes[1])
== "<py_cppmodel.Unmodelled B<T> <SourceLocation file 'sample.cc', line 12, column 7>>"
)
62 changes: 62 additions & 0 deletions uv.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.