Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
8ac8850
Add Meson build system
czgdp1807 Jul 26, 2025
583d35d
Add spin config and install Python sources
czgdp1807 Jul 26, 2025
30359b3
Use spin build system and update CI
czgdp1807 Jul 26, 2025
8eabb3d
Remove _extensions.py dummy installation
czgdp1807 Jul 26, 2025
0bdc710
disabled py3.8 checks and fixed nodes issue
Oct 1, 2025
4036995
bug fix
Oct 1, 2025
24b1394
bug fix
Oct 1, 2025
2bcc3fd
bug fix
Oct 1, 2025
6f35472
bug fix
Oct 1, 2025
ee430b9
bug fix
Oct 1, 2025
3da3f9c
bug fix
Oct 1, 2025
7d6733c
bug fix
Oct 1, 2025
8e4fb88
bug fix
Oct 1, 2025
3e7278e
bug fix
Oct 1, 2025
25e3f60
bug fix
Oct 1, 2025
fd28eb5
bug fix
Oct 1, 2025
2b26b75
bug fix
Oct 1, 2025
a4f1572
bug fix
Oct 1, 2025
2db7fe3
bug fix
Oct 1, 2025
251c1d8
bug fix
Oct 1, 2025
2c2cf64
bug fix
Oct 1, 2025
cb285b9
bug fix
Oct 1, 2025
01cfaff
bug fix
Oct 1, 2025
531b7ed
bug fix
Oct 1, 2025
b02653f
bug fix
Oct 2, 2025
4d47e18
bug fix
Oct 2, 2025
9ae7049
bug fix
Oct 2, 2025
c1ea567
bug fix
Oct 2, 2025
8d9e45a
bug fix
Oct 4, 2025
cc1f9c7
bug fix
Oct 4, 2025
e60a234
bug fix
Oct 4, 2025
3c185c5
bug fix
Oct 4, 2025
1353b41
bug fix
Oct 4, 2025
0146fef
bug fix
Oct 5, 2025
a583e0c
bug fix
Oct 5, 2025
01c71f0
upgraded python versions
Oct 10, 2025
33ad75d
bug fix
Oct 10, 2025
b901ed2
bug fix
Oct 10, 2025
421702a
bug fix
Oct 10, 2025
ea3ffda
bug fix
Oct 10, 2025
4bc3aec
bug fix
Oct 10, 2025
6727aba
bug fix
Oct 10, 2025
5a9240c
bug fix
Oct 11, 2025
30c6493
bug fix
Oct 11, 2025
798b1ba
bug fix
Oct 11, 2025
a2804e0
bug fix
Oct 11, 2025
c2a7111
bug fix
Oct 11, 2025
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
129 changes: 61 additions & 68 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,23 +7,17 @@ on:
branches: [main]

jobs:
test-ubuntu-py38:
runs-on: ${{matrix.os}}
test-ubuntu-py39-coverage:
runs-on: ubuntu-latest
timeout-minutes: 20
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest]
python-version:
- "3.8"

steps:
- uses: actions/checkout@v3

- name: Set up Python ${{ matrix.python-version }}
- name: Set up Python 3.9
uses: actions/setup-python@v4
with:
python-version: ${{ matrix.python-version }}
python-version: "3.9"

- name: Upgrade pip version
run: |
Expand All @@ -33,19 +27,23 @@ jobs:
run: |
python -m pip install -r requirements.txt
python -m pip install -r docs/requirements.txt
python -m pip install spin

- name: Install lcov
run: |
sudo apt-get update
sudo apt-get install -y lcov

- name: Build package
env:
CXXFLAGS: "-std=c++17 --coverage"
CFLAGS: "--coverage"
run: |
CXXFLAGS="-std=c++17 --coverage" CFLAGS="--coverage" python scripts/build/install.py
# coverage tests
spin build -v

- name: Run tests
run: |
python -m pytest --doctest-modules --cov=./ --cov-report=xml -s
spin test -v

- name: Capture Coverage Data with lcov
run: |
Expand All @@ -72,7 +70,7 @@ jobs:
run: |
sphinx-build -b html docs/source/ docs/build/html

test-ubuntu-py39-py310:
test-ubuntu-py39-py310-py311:
runs-on: ${{matrix.os}}
timeout-minutes: 20
strategy:
Expand All @@ -82,6 +80,7 @@ jobs:
python-version:
- "3.9"
- "3.10"
- "3.11"

steps:
- uses: actions/checkout@v3
Expand All @@ -99,14 +98,17 @@ jobs:
run: |
python -m pip install -r requirements.txt
python -m pip install -r docs/requirements.txt
python -m pip install spin

- name: Build package
env:
CXXFLAGS: "-std=c++17"
run: |
CXXFLAGS="-std=c++17" python scripts/build/install.py
spin build -v

- name: Run tests
run: |
python -c "import pydatastructs; pydatastructs.test(only_benchmarks=True)"
spin test -v

- name: Build Documentation
run: |
Expand All @@ -120,9 +122,9 @@ jobs:
matrix:
os: [macos-latest]
python-version:
- "3.8"
- "3.9"
- "3.10"
- "3.11"

steps:
- uses: actions/checkout@v3
Expand All @@ -140,66 +142,57 @@ jobs:
run: |
python -m pip install -r requirements.txt
python -m pip install -r docs/requirements.txt
python -m pip install spin

- name: Build package
env:
MACOSX_DEPLOYMENT_TARGET: 11.0
CXXFLAGS: "-std=c++17"
run: |
CXXFLAGS="-std=c++17" python scripts/build/install.py
spin build -v

- name: Run tests
run: |
python -c "import pydatastructs; pydatastructs.test()"
spin test -v

- name: Build Documentation
run: |
sphinx-build -b html docs/source/ docs/build/html

# test-windows:
# runs-on: ${{matrix.os}}
# timeout-minutes: 20
# strategy:
# fail-fast: false
# matrix:
# os: [windows-latest]
# python-version:
# - "3.8"

# steps:
# - uses: actions/checkout@v3

# - name: Set up Python ${{ matrix.python-version }}
# uses: actions/setup-python@v4
# with:
# python-version: ${{ matrix.python-version }}

# - name: Setup conda
# uses: s-weigand/setup-conda@v1
# with:
# update-conda: true
# python-version: ${{ matrix.python-version }}
# conda-channels: anaconda, conda-forge
# # - run: conda --version # This fails due to unknown reasons
# - run: which python

# - name: Upgrade pip version
# run: |
# python -m pip install --upgrade pip

# - name: Install requirements
# run: |
# python -m pip install -r requirements.txt
# python -m pip install -r docs/requirements.txt

# - name: Build package
# env:
# CL: "/std:c++17"
# run: |
# python scripts/build/install.py

# - name: Run tests
# run: |
# python -c "import pydatastructs; pydatastructs.test()"

# - name: Build Documentation
# run: |
# sphinx-build -b html docs/source/ docs/build/html
test-windows:
runs-on: windows-latest
strategy:
fail-fast: false
matrix:
python-version: ["3.9", "3.10", "3.11"]

steps:
- uses: actions/checkout@v3

- uses: actions/setup-python@v4
with:
python-version: ${{ matrix.python-version }}

- uses: ilammy/msvc-dev-cmd@v1

- name: Upgrade pip
run: python -m pip install --upgrade pip

- name: Install requirements
run: |
python -m pip install -r requirements.txt
python -m pip install -r docs/requirements.txt
python -m pip install spin

- name: Build package
env:
CFLAGS: "/MD"
CXXFLAGS: "/std:c++17 /MD /Zc:strictStrings-"
CL: "/std:c++17 /MD /Zc:strictStrings-"
run: spin build -v

- name: Run tests
run: spin test -v

- name: Build Documentation
run: sphinx-build -b html docs/source/ docs/build/html
2 changes: 2 additions & 0 deletions environment.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ dependencies:
- pip:
- codecov
- pytest-cov
- spin
- meson
- sphinx==5.0
- sphinx-readable-theme==1.3.0
- myst_nb==0.17.2
Expand Down
8 changes: 8 additions & 0 deletions meson.build
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
project('pydatastructs', 'cpp',
version : '1.0.1-dev',
default_options : ['cpp_std=c++17'])


python = import('python').find_installation(pure: false)

subdir('pydatastructs')
1 change: 0 additions & 1 deletion pydatastructs/graphs/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
from . import algorithms
from . import adjacency_list
from . import adjacency_matrix
from . import _extensions

from .algorithms import (
breadth_first_search,
Expand Down
52 changes: 32 additions & 20 deletions pydatastructs/graphs/_backend/cpp/graph.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,59 +4,71 @@
#include "AdjacencyMatrix.hpp"
#include "AdjacencyListGraphNode.hpp"
#include "AdjacencyMatrixGraphNode.hpp"
#include "GraphEdge.hpp"
#include "GraphNode.hpp"
#include "graph_bindings.hpp"
#include "Algorithms.hpp"

#ifdef __cplusplus
extern "C" {
#endif

PyMODINIT_FUNC PyInit__graph(void);

#ifdef __cplusplus
}
#endif
static PyMethodDef GraphMethods[] = {
{"bfs_adjacency_list", (PyCFunction)breadth_first_search_adjacency_list, METH_VARARGS | METH_KEYWORDS, "Run BFS on adjacency list with callback"},
{"bfs_adjacency_matrix", (PyCFunction)breadth_first_search_adjacency_matrix, METH_VARARGS | METH_KEYWORDS, "Run BFS on adjacency matrix with callback"},
{"minimum_spanning_tree_prim_adjacency_list", (PyCFunction)minimum_spanning_tree_prim_adjacency_list, METH_VARARGS | METH_KEYWORDS, "Run Prim's algorithm on adjacency list"},
{"shortest_paths_dijkstra_adjacency_list", (PyCFunction)shortest_paths_dijkstra_adjacency_list, METH_VARARGS | METH_KEYWORDS, "Dijkstra's algorithm for adjacency list graphs"},
{NULL, NULL, 0, NULL}
};

static struct PyModuleDef graph_module = {
PyModuleDef_HEAD_INIT,
"_graph",
"C++ module for graphs",
-1,
NULL,
GraphMethods,
};

PyMODINIT_FUNC PyInit__graph(void) {
PyObject* m;

if (PyType_Ready(&AdjacencyListGraphType) < 0)
if (PyType_Ready(&GraphNodeType) < 0)
return NULL;

if (PyType_Ready(&AdjacencyListGraphNodeType) < 0)
return NULL;

if (PyType_Ready(&AdjacencyMatrixGraphType) < 0)
if (PyType_Ready(&AdjacencyMatrixGraphNodeType) < 0)
return NULL;

if (PyType_Ready(&AdjacencyMatrixGraphNodeType) < 0)
if (PyType_Ready(&GraphEdgeType) < 0)
return NULL;

if (PyType_Ready(&AdjacencyListGraphType) < 0)
return NULL;

if (PyType_Ready(&AdjacencyMatrixGraphType) < 0)
return NULL;

m = PyModule_Create(&graph_module);
if (m == NULL)
return NULL;

Py_INCREF(&GraphNodeType);
PyModule_AddObject(m, "GraphNode", (PyObject*)&GraphNodeType);

Py_INCREF(&AdjacencyListGraphNodeType);
PyModule_AddObject(m, "AdjacencyListGraphNode", (PyObject*)&AdjacencyListGraphNodeType);

Py_INCREF(&AdjacencyMatrixGraphNodeType);
PyModule_AddObject(m, "AdjacencyMatrixGraphNode", (PyObject*)&AdjacencyMatrixGraphNodeType);

Py_INCREF(&GraphEdgeType);
PyModule_AddObject(m, "GraphEdge", (PyObject*)&GraphEdgeType);

Py_INCREF(&AdjacencyListGraphType);
if (PyModule_AddObject(m, "AdjacencyListGraph", (PyObject*)&AdjacencyListGraphType) < 0) {
Py_DECREF(&AdjacencyListGraphType);
Py_DECREF(m);
return NULL;
}

Py_INCREF(&AdjacencyListGraphNodeType);
if (PyModule_AddObject(m, "AdjacencyListGraphNode", (PyObject*)&AdjacencyListGraphNodeType) < 0) {
Py_DECREF(&AdjacencyListGraphNodeType);
Py_DECREF(m);
return NULL;
}

Py_INCREF(&AdjacencyMatrixGraphType);
if (PyModule_AddObject(m, "AdjacencyMatrixGraph", (PyObject*)&AdjacencyMatrixGraphType) < 0) {
Py_DECREF(&AdjacencyMatrixGraphType);
Expand Down
6 changes: 3 additions & 3 deletions pydatastructs/graphs/algorithms.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ def breadth_first_search(
return getattr(algorithms, func)(
graph, source_node, operation, *args, **kwargs)
else:
from pydatastructs.graphs._backend.cpp._algorithms import bfs_adjacency_list, bfs_adjacency_matrix
from pydatastructs.graphs._backend.cpp._graph import bfs_adjacency_list, bfs_adjacency_matrix
if (graph._impl == "adjacency_list"):
extra_args = args if args else ()
return bfs_adjacency_list(graph, source_node, operation, extra_args)
Expand Down Expand Up @@ -349,7 +349,7 @@ def minimum_spanning_tree(graph, algorithm, **kwargs):
%(algorithm, graph._impl))
return getattr(algorithms, func)(graph)
else:
from pydatastructs.graphs._backend.cpp._algorithms import minimum_spanning_tree_prim_adjacency_list
from pydatastructs.graphs._backend.cpp._graph import minimum_spanning_tree_prim_adjacency_list
if graph._impl == "adjacency_list" and algorithm == 'prim':
return minimum_spanning_tree_prim_adjacency_list(graph)

Expand Down Expand Up @@ -814,7 +814,7 @@ def shortest_paths(graph: Graph, algorithm: str,
"finding shortest paths in graphs."%(algorithm))
return getattr(algorithms, func)(graph, source, target)
else:
from pydatastructs.graphs._backend.cpp._algorithms import shortest_paths_dijkstra_adjacency_list
from pydatastructs.graphs._backend.cpp._graph import shortest_paths_dijkstra_adjacency_list
if graph._impl == "adjacency_list" and algorithm == 'dijkstra':
return shortest_paths_dijkstra_adjacency_list(graph, source, target)

Expand Down
34 changes: 34 additions & 0 deletions pydatastructs/graphs/meson.build
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
python = import('python').find_installation(pure: false)

python.install_sources(
[
'__init__.py',
'adjacency_list.py',
'adjacency_matrix.py',
'algorithms.py',
'graph.py'
],
subdir: 'pydatastructs/graphs'
)

python.install_sources(
['_backend/__init__.py', '_backend/cpp/__init__.py'],
subdir: 'pydatastructs/graphs/_backend'
)

py_include = include_directories('../utils/_backend/cpp')

python.extension_module(
'_graph',
[
'_backend/cpp/graph.cpp',
'_backend/cpp/algorithms.cpp',
'../utils/_backend/cpp/graph_utils.cpp',
],
include_directories: py_include,
install: true,
subdir: 'pydatastructs/graphs/_backend/cpp'
)


subdir('tests')
Loading
Loading