Skip to content
Open
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
71 changes: 71 additions & 0 deletions .github/workflows/stubs.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
name: Check type stubs
env:
version: 10.0.0

on:
push:
branches:
- "master"
pull_request:
types: [opened, synchronize, reopened, ready_for_review]
branches:
- "master"
workflow_dispatch:

defaults:
run:
shell: bash

jobs:
stubtest:
if: (github.event_name != 'pull_request') || (github.event.pull_request.draft == false)
runs-on: ubuntu-24.04
env:
PYTHON_VERSION: "3.14"

steps:
- uses: actions/checkout@v6

- name: Install dependencies (SCIPOptSuite)
run: |
wget --quiet --no-check-certificate "https://github.com/scipopt/scip/releases/download/v${{ env.version }}/scipoptsuite_${{ env.version }}-1+jammy_amd64.deb"
sudo apt-get update && sudo apt install -y ./scipoptsuite_${{ env.version }}-1+jammy_amd64.deb

- name: Setup python ${{ env.PYTHON_VERSION }}
uses: actions/setup-python@v4
with:
python-version: ${{ env.PYTHON_VERSION }}

- name: Install mypy
run: |
python -m pip install mypy

- name: Install PySCIPOpt
run: |
export CFLAGS="-O0 -ggdb -Wall -Wextra -Werror -Wno-error=deprecated-declarations" # Debug mode. More warnings. Warnings as errors, but allow deprecated declarations.
python -m pip install . -v 2>&1 | tee build.log

- name: Run MyPy
run: python -m mypy --package pyscipopt

- name: Run stubtest
run: stubs/test.sh

lint:
runs-on: ubuntu-latest
env:
FILES: src/pyscipopt/scip.pyi

steps:
- uses: actions/checkout@v6

- name: Install Ruff
uses: astral-sh/ruff-action@v3
with:
args: "--version"

- name: Lint type stubs
run: ruff check ${{ env.FILES }} --extend-select PYI

- name: Format type stubs
run: ruff format ${{ env.FILES }}
2 changes: 1 addition & 1 deletion src/pyscipopt/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import os
if hasattr(os, 'add_dll_directory'):
if os.getenv('SCIPOPTDIR'):
os.add_dll_directory(os.path.join(os.getenv('SCIPOPTDIR').strip('"'), 'bin'))
os.add_dll_directory(os.path.join(os.environ['SCIPOPTDIR'].strip('"'), 'bin'))

# export user-relevant objects:
from pyscipopt.Multidict import multidict as multidict
Expand Down
2 changes: 1 addition & 1 deletion src/pyscipopt/recipes/getLocalConss.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ def getLocalConss(model: Model, node = None) -> List[List[Constraint]]:
else:
cur_node = node

added_conss = []
added_conss: List[Constraint] = []
while cur_node is not None:
added_conss = cur_node.getAddedConss() + added_conss
cur_node = cur_node.getParent()
Expand Down
22 changes: 11 additions & 11 deletions src/pyscipopt/scip.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -379,9 +379,9 @@ class MatrixExpr(numpy.ndarray):
def sum(self, *args, **kwargs): ...
def __add__(self, other): ...
def __eq__(self, other: object) -> bool: ...
def __ge__(self, other: object) -> bool: ...
def __ge__(self, other: object) -> MatrixExprCons: ...
def __iadd__(self, other): ...
def __le__(self, other: object) -> bool: ...
def __le__(self, other: object) -> MatrixExprCons: ...
def __matmul__(self, *args, **kwargs): ...
def __mul__(self, other): ...
def __pow__(self, other): ...
Expand All @@ -394,8 +394,8 @@ class MatrixExpr(numpy.ndarray):

class MatrixExprCons(numpy.ndarray):
def __eq__(self, other: object) -> bool: ...
def __ge__(self, other: object) -> bool: ...
def __le__(self, other: object) -> bool: ...
def __ge__(self, other: object) -> MatrixExprCons: ...
def __le__(self, other: object) -> MatrixExprCons: ...

class MatrixGenExpr(MatrixExpr): ...

Expand Down Expand Up @@ -1300,14 +1300,14 @@ class Statistics:
copying_time: float
problem_name: str
presolved_problem_name: str
n_runs: int = None
n_nodes: int = None
n_runs: int | None = None
n_nodes: int | None = None
n_solutions_found: int = -1
first_solution: float = None
primal_bound: float = None
dual_bound: float = None
gap: float = None
primal_dual_integral: float = None
first_solution: float | None = None
primal_bound: float | None = None
dual_bound: float | None = None
gap: float | None = None
primal_dual_integral: float | None = None
@property
def n_binary_vars(self): ...
@property
Expand Down
3 changes: 3 additions & 0 deletions stubs/allowlist
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.*.__reduce_cython__
.*.__setstate_cython__
pyscipopt.scip.__test__
10 changes: 10 additions & 0 deletions stubs/test.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#!/bin/bash -e

# Test the stubs for pyscipopt using stubtest
# This checks that the type hints in the stubs are consistent with the actual implementation
# Prerequisite: install mypy (which provides stubtest) in the same environment as pyscipopt
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
python -m mypy.stubtest \
--allowlist "$SCRIPT_DIR/allowlist" \
--allowlist "$SCRIPT_DIR/todo" \
pyscipopt
Loading
Loading