Skip to content

Commit d8468f7

Browse files
Merge branch 'master' into getTermsQuadractic
2 parents 6ab6c2c + a03b00e commit d8468f7

35 files changed

Lines changed: 5099 additions & 1211 deletions

.github/workflows/stubs.yml

Lines changed: 186 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,186 @@
1+
name: Check type stubs
2+
env:
3+
version: 10.0.0
4+
5+
on:
6+
push:
7+
branches:
8+
- "master"
9+
pull_request:
10+
types: [opened, synchronize, reopened, ready_for_review]
11+
branches:
12+
- "master"
13+
workflow_dispatch:
14+
15+
defaults:
16+
run:
17+
shell: bash
18+
19+
jobs:
20+
stubtest:
21+
if: (github.event_name != 'pull_request') || (github.event.pull_request.draft == false)
22+
runs-on: ubuntu-24.04
23+
env:
24+
PYTHON_VERSION: "3.14"
25+
26+
steps:
27+
- uses: actions/checkout@v6
28+
29+
- name: Install dependencies (SCIPOptSuite)
30+
run: |
31+
wget --quiet --no-check-certificate "https://github.com/scipopt/scip/releases/download/v${{ env.version }}/scipoptsuite_${{ env.version }}-1+jammy_amd64.deb"
32+
sudo apt-get update && sudo apt install -y ./scipoptsuite_${{ env.version }}-1+jammy_amd64.deb
33+
34+
- name: Setup python ${{ env.PYTHON_VERSION }}
35+
uses: actions/setup-python@v4
36+
with:
37+
python-version: ${{ env.PYTHON_VERSION }}
38+
39+
- name: Install mypy
40+
run: |
41+
python -m pip install mypy
42+
43+
- name: Install PySCIPOpt
44+
run: |
45+
export CFLAGS="-O0 -ggdb -Wall -Wextra -Werror -Wno-error=deprecated-declarations" # Debug mode. More warnings. Warnings as errors, but allow deprecated declarations.
46+
python -m pip install . -v 2>&1 | tee build.log
47+
48+
- name: Run MyPy
49+
run: python -m mypy --package pyscipopt
50+
51+
- name: Run stubtest
52+
id: stubtest
53+
run: stubs/test.sh
54+
55+
- name: Stub regeneration hint
56+
if: failure() && steps.stubtest.outcome == 'failure'
57+
run: |
58+
echo "Type stubs are out of date. Please regenerate them locally:"
59+
echo ""
60+
echo " python scripts/generate_stubs.py"
61+
echo " pip install ruff"
62+
echo " ruff check src/pyscipopt/scip.pyi --extend-select ANN,I,PYI,RUF100 --fix"
63+
echo " ruff format src/pyscipopt/scip.pyi"
64+
echo ""
65+
echo "Then commit the updated scip.pyi file."
66+
echo ""
67+
echo "Tip: You can set up a pre-commit hook to do this automatically."
68+
echo "See .pre-commit-config.yaml in the repository root."
69+
70+
lint:
71+
runs-on: ubuntu-latest
72+
env:
73+
FILES: src/pyscipopt/scip.pyi
74+
75+
steps:
76+
- uses: actions/checkout@v6
77+
78+
- name: Install Ruff
79+
uses: astral-sh/ruff-action@v3
80+
with:
81+
args: "--version"
82+
83+
- name: Lint type stubs
84+
run: ruff check ${{ env.FILES }} --extend-select ANN,I,PYI,RUF100
85+
86+
- name: Format check type stubs
87+
run: ruff format --check ${{ env.FILES }}
88+
89+
# =============================================================================
90+
# AUTO-REGENERATION STEPS (disabled)
91+
# =============================================================================
92+
# TODO: To enable automatic stub regeneration in CI, uncomment the code below
93+
# and add the following to the stubtest job:
94+
# - Add these permissions to stubtest job:
95+
# permissions:
96+
# contents: write
97+
# pull-requests: write
98+
# - Add these to the checkout step:
99+
# with:
100+
# ref: ${{ github.head_ref || github.ref }}
101+
# repository: ${{ github.event.pull_request.head.repo.full_name || github.repository }}
102+
# token: ${{ secrets.GITHUB_TOKEN }}
103+
# fetch-depth: 0
104+
# - Change "Run MyPy" and "Run stubtest" to have continue-on-error: true
105+
# and rename to "Run MyPy (before regeneration)" / "Run stubtest (before regeneration)"
106+
# - Add "needs: stubtest" to the lint job
107+
# - Remove the "Stub regeneration hint" step
108+
#
109+
# Then uncomment these steps:
110+
#
111+
# - name: Check if safe to run generate_stubs.py
112+
# id: check_script
113+
# run: |
114+
# # For same-repo PRs, always allow running the script
115+
# if [[ "${{ github.event.pull_request.head.repo.full_name }}" == "${{ github.repository }}" ]] || [[ "${{ github.event_name }}" != "pull_request" ]]; then
116+
# echo "allowed=true" >> $GITHUB_OUTPUT
117+
# echo "Same-repo PR or push - allowing regeneration"
118+
# else
119+
# # For fork PRs, only allow if script is unchanged from master
120+
# git fetch origin master
121+
# if git diff --quiet origin/master -- scripts/generate_stubs.py; then
122+
# echo "allowed=true" >> $GITHUB_OUTPUT
123+
# echo "Fork PR with unchanged script - allowing regeneration"
124+
# else
125+
# echo "allowed=false" >> $GITHUB_OUTPUT
126+
# echo "::warning::Fork PR with modified scripts/generate_stubs.py - skipping auto-regeneration for security"
127+
# fi
128+
# fi
129+
#
130+
# - name: Regenerate stubs
131+
# if: steps.stubtest_before.outcome == 'failure' && steps.check_script.outputs.allowed == 'true'
132+
# run: |
133+
# python scripts/generate_stubs.py
134+
# pip install ruff
135+
# ruff check src/pyscipopt/scip.pyi --extend-select ANN,I,PYI,RUF100 --fix
136+
# ruff format src/pyscipopt/scip.pyi
137+
# cp src/pyscipopt/scip.pyi "$(python -c 'import pyscipopt; print(pyscipopt.__path__[0])')/scip.pyi"
138+
#
139+
# - name: Run MyPy (after regeneration)
140+
# if: steps.stubtest_before.outcome == 'failure' && steps.check_script.outputs.allowed == 'true'
141+
# run: python -m mypy --package pyscipopt
142+
#
143+
# - name: Run stubtest (after regeneration)
144+
# if: steps.stubtest_before.outcome == 'failure' && steps.check_script.outputs.allowed == 'true'
145+
# run: stubs/test.sh
146+
#
147+
# - name: Commit and push updated stubs
148+
# id: commit
149+
# if: steps.stubtest_before.outcome == 'failure' && github.event_name == 'pull_request' && steps.check_script.outputs.allowed == 'true' && github.event.pull_request.head.repo.full_name == github.repository
150+
# run: |
151+
# git config user.name "github-actions[bot]"
152+
# git config user.email "github-actions[bot]@users.noreply.github.com"
153+
# git add src/pyscipopt/scip.pyi
154+
# DIFF=$(git diff --cached --stat)
155+
# echo "diff<<EOF" >> $GITHUB_OUTPUT
156+
# echo "$DIFF" >> $GITHUB_OUTPUT
157+
# echo "EOF" >> $GITHUB_OUTPUT
158+
# DETAILED_DIFF=$(git diff --cached src/pyscipopt/scip.pyi | head -100 || true)
159+
# echo "detailed_diff<<EOF" >> $GITHUB_OUTPUT
160+
# echo "$DETAILED_DIFF" >> $GITHUB_OUTPUT
161+
# echo "EOF" >> $GITHUB_OUTPUT
162+
# if git diff --cached --quiet; then
163+
# echo "committed=false" >> $GITHUB_OUTPUT
164+
# else
165+
# git commit -m "Auto-regenerate type stubs"
166+
# git push
167+
# echo "committed=true" >> $GITHUB_OUTPUT
168+
# fi
169+
#
170+
# - name: Comment on PR
171+
# if: steps.commit.outputs.committed == 'true'
172+
# env:
173+
# GH_TOKEN: ${{ github.token }}
174+
# run: |
175+
# gh pr comment ${{ github.event.pull_request.number }} --body "## 🤖 Type stubs automatically regenerated
176+
#
177+
# The type stubs were out of date and have been automatically regenerated.
178+
#
179+
# <details>
180+
# <summary>Changes summary</summary>
181+
#
182+
# \`\`\`
183+
# ${{ steps.commit.outputs.diff }}
184+
# \`\`\`
185+
#
186+
# </details>"

.pre-commit-config.yaml

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# Pre-commit hooks for PySCIPOpt
2+
# Install with: pip install pre-commit && pre-commit install
3+
#
4+
# Note: The stub generation hook requires pyscipopt to be installed.
5+
# If you haven't built pyscipopt yet, run: pip install -e .
6+
7+
repos:
8+
- repo: local
9+
hooks:
10+
- id: regenerate-stubs
11+
name: Regenerate type stubs
12+
entry: bash -c 'python scripts/generate_stubs.py && pip install ruff -q && ruff check src/pyscipopt/scip.pyi --extend-select ANN,I,PYI,RUF100 --fix --quiet && ruff format src/pyscipopt/scip.pyi --quiet'
13+
language: system
14+
files: ^src/pyscipopt/.*\.(pxi|pxd|pyx)$
15+
pass_filenames: false
16+
stages: [pre-commit]

CHANGELOG.md

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,38 @@
33
## Unreleased
44
### Added
55
- Added getVarFarkasCoef() (untested)
6+
- Added automated script for generating type stubs
7+
- Include parameter names in type stubs
8+
- Added pre-commit hook for automatic stub regeneration (see .pre-commit-config.yaml)
9+
- Wrapped isObjIntegral() and test
10+
- Added structured_optimization_trace recipe for structured optimization progress tracking
11+
- Added methods: getPrimalDualIntegral()
612
### Fixed
13+
- getBestSol() now returns None for infeasible problems instead of a Solution with NULL pointer
714
- all fundamental callbacks now raise an error if not implemented
15+
- Fixed the type of MatrixExpr.sum(axis=...) result from MatrixVariable to MatrixExpr.
16+
- Updated IIS result in PyiisfinderExec()
17+
- Model.getVal now supports GenExpr type
18+
- Fixed lotsizing_lazy example
19+
- Fixed incorrect getVal() result when _bestSol.sol was outdated
20+
- Fixed segmentation fault when using Variable or Constraint objects after freeTransform() or Model destruction
821
- getTermsQuadratic() now correctly returns all linear terms
922
### Changed
23+
- changed default value of enablepricing flag to True
24+
- Speed up MatrixExpr.sum(axis=...) via quicksum
25+
- Speed up MatrixExpr.add.reduce via quicksum
26+
- Speed up np.ndarray(..., dtype=np.float64) @ MatrixExpr
27+
- Speed up Expr * Expr via C-level API and Term * Term
28+
- Speed up Term * Term via a $O(n)$ sort algorithm instead of Python $O(n\log(n))$ sorted function. `Term.__mul__` requires that Term.vartuple is sorted.
29+
- Rename from `Term.__add__` to `Term.__mul__`, due to this method only working with Expr * Expr.
30+
- MatrixExpr and MatrixExprCons use `__array_ufunc__` protocol to control all numpy.ufunc inputs and outputs
31+
- Set `__array_priority__` for MatrixExpr and MatrixExprCons
32+
- changed addConsNode() and addConsLocal() to mirror addCons() and accept ExprCons instead of Constraint
33+
- Improved `chgReoptObjective()` performance
34+
- Return itself for abs to UnaryExpr(Operator.fabs)
1035
### Removed
1136

12-
## 6.0.0 - 2025.xx.yy
37+
## 6.0.0 - 2025.11.28
1338
### Added
1439
- Support for SCIP 10.0.0
1540
- Added support for IIS - Irreducible Inconsistent Subsystems
@@ -62,6 +87,10 @@
6287
- Added enableDebugSol() and disableDebugSol() for controlling the debug solution mechanism if DEBUGSOL=true
6388
- Added getVarPseudocostScore() and getVarPseudocost()
6489
- Added getNBranchings() and getNBranchingsCurrentRun()
90+
- Added isActive() which wraps SCIPvarIsActive() and test
91+
- Added aggregateVars() and tests
92+
- Added example shiftbound.py
93+
- Added a tutorial in ./docs on the presolver plugin
6594
### Fixed
6695
- Raised an error when an expression is used when a variable is required
6796
- Fixed some compile warnings

0 commit comments

Comments
 (0)