-
Notifications
You must be signed in to change notification settings - Fork 275
Auto regenerate stubs #1152
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Auto regenerate stubs #1152
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This PR adds automation for regenerating type stubs in the CI/CD pipeline and wraps the isObjIntegral() SCIP function with corresponding tests. The stub generation script will automatically regenerate type stubs during PR checks if they are out of date, and commit the updated stubs back to the PR.
Changes:
- Added
isObjIntegral()wrapper method to query whether the objective function is integral - Added test cases for
isObjIntegral()to verify the method works correctly - Modified the stubs workflow to automatically regenerate and commit type stubs when they're out of date during PR checks
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| src/pyscipopt/scip.pxd | Added C function declaration for SCIPisObjIntegral |
| src/pyscipopt/scip.pxi | Implemented Python wrapper method isObjIntegral() with documentation |
| tests/test_model.py | Added test function to verify isObjIntegral() behavior in two scenarios |
| .github/workflows/stubs.yml | Added automated stub regeneration, commit, and PR comment steps |
| CHANGELOG.md | Documented the new features in the unreleased section |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This stub version is a regression from before, we lost all the names of parameters from #1145. We can try to automate the stubs for newly added functions, but we shouldn't overwrite what's already there
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah yeah, this is still being adapted. But on the overall approach, assuming things work out, how do you feel? Regarding the script being called automatically by the pipelines whenever the stub tests fails
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #1152 +/- ##
==========================================
+ Coverage 55.07% 55.12% +0.05%
==========================================
Files 24 24
Lines 5420 5440 +20
==========================================
+ Hits 2985 2999 +14
- Misses 2435 2441 +6 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
🤖 Type stubs automatically regeneratedThe type stubs were out of date and have been automatically regenerated. A new commit has been pushed to this PR. Changes summaryDetailed diff (first 100 lines)diff --git a/src/pyscipopt/scip.pyi b/src/pyscipopt/scip.pyi
index e06e718..db52edc 100644
--- a/src/pyscipopt/scip.pyi
+++ b/src/pyscipopt/scip.pyi
@@ -156,7 +156,7 @@ class Conshdlr:
@disjoint_base
class Constant(GenExpr):
number: Incomplete
- def __init__(self, number: Incomplete) -> None: ...
+ def __init__(self, *args: Incomplete, **kwargs: Incomplete) -> None: ...
@disjoint_base
class Constraint:
@@ -259,7 +259,7 @@ class Expr:
def __ne__(self, other: object) -> bool: ...
def __neg__(self) -> Incomplete: ...
def __next__(self) -> Incomplete: ...
- def __pow__(self, other: Incomplete, mod: Incomplete = ...) -> Incomplete: ...
+ def __pow__(self, other: Incomplete, modulo: Incomplete = ...) -> Incomplete: ...
def __radd__(self, other: Incomplete) -> Incomplete: ...
def __rmul__(self, other: Incomplete) -> Incomplete: ...
def __rpow__(self, other: Incomplete) -> Incomplete: ...
@@ -300,7 +300,7 @@ class GenExpr:
def __mul__(self, other: Incomplete) -> Incomplete: ...
def __ne__(self, other: object) -> bool: ...
def __neg__(self) -> Incomplete: ...
- def __pow__(self, other: Incomplete, mod: Incomplete = ...) -> Incomplete: ...
+ def __pow__(self, other: Incomplete, modulo: Incomplete = ...) -> Incomplete: ...
def __radd__(self, other: Incomplete) -> Incomplete: ...
def __rmul__(self, other: Incomplete) -> Incomplete: ...
def __rpow__(self, other: Incomplete) -> Incomplete: ...
@@ -406,7 +406,7 @@ class MatrixExpr(numpy.ndarray):
def __le__(self, other: object) -> bool: ... # type: ignore[override]
def __matmul__(self, other: Incomplete) -> Incomplete: ...
def __mul__(self, other: Incomplete) -> Incomplete: ...
- def __pow__(self, other: Incomplete, mod: Incomplete = ...) -> Incomplete: ...
+ def __pow__(self, other: Incomplete) -> Incomplete: ... # type: ignore[override]
def __radd__(self, other: Incomplete) -> Incomplete: ...
def __rmul__(self, other: Incomplete) -> Incomplete: ...
def __rsub__(self, other: Incomplete) -> Incomplete: ...
@@ -467,13 +467,13 @@ class Model:
def addConsSOS2(self, vars: Incomplete, weights: Incomplete = ..., name: Incomplete = ..., initial: Incomplete = ..., separate: Incomplete = ..., enforce: Incomplete = ..., check: Incomplete = ..., propagate: Incomplete = ..., local: Incomplete = ..., dynamic: Incomplete = ..., removable: Incomplete = ..., stickingatnode: Incomplete = ...) -> Incomplete: ...
def addConsXor(self, vars: Incomplete, rhsvar: Incomplete, name: Incomplete = ..., initial: Incomplete = ..., separate: Incomplete = ..., enforce: Incomplete = ..., check: Incomplete = ..., propagate: Incomplete = ..., local: Incomplete = ..., modifiable: Incomplete = ..., dynamic: Incomplete = ..., removable: Incomplete = ..., stickingatnode: Incomplete = ...) -> Incomplete: ...
def addConss(self, conss: Incomplete, name: Incomplete = ..., initial: Incomplete = ..., separate: Incomplete = ..., enforce: Incomplete = ..., check: Incomplete = ..., propagate: Incomplete = ..., local: Incomplete = ..., modifiable: Incomplete = ..., dynamic: Incomplete = ..., removable: Incomplete = ..., stickingatnode: Incomplete = ...) -> Incomplete: ...
- def addCut(self, forcecut: Incomplete = ...) -> Incomplete: ...
+ def addCut(self, cut: Incomplete, forcecut: Incomplete = ...) -> Incomplete: ...
def addExprNonlinear(self, cons: Incomplete, expr: Incomplete, coef: Incomplete) -> Incomplete: ...
def addMatrixCons(self, cons: Incomplete, name: Incomplete = ..., initial: Incomplete = ..., separate: Incomplete = ..., enforce: Incomplete = ..., check: Incomplete = ..., propagate: Incomplete = ..., local: Incomplete = ..., modifiable: Incomplete = ..., dynamic: Incomplete = ..., removable: Incomplete = ..., stickingatnode: Incomplete = ...) -> Incomplete: ...
def addMatrixConsIndicator(self, cons: Incomplete, binvar: Incomplete = ..., activeone: Incomplete = ..., name: Incomplete = ..., initial: Incomplete = ..., separate: Incomplete = ..., enforce: Incomplete = ..., check: Incomplete = ..., propagate: Incomplete = ..., local: Incomplete = ..., dynamic: Incomplete = ..., removable: Incomplete = ..., stickingatnode: Incomplete = ...) -> Incomplete: ...
def addMatrixVar(self, shape: Incomplete, name: Incomplete = ..., vtype: Incomplete = ..., lb: Incomplete = ..., ub: Incomplete = ..., obj: Incomplete = ..., pricedVar: Incomplete = ..., pricedVarScore: Incomplete = ...) -> Incomplete: ...
def addObjoffset(self, offset: Incomplete, solutions: Incomplete = ...) -> Incomplete: ...
- def addPoolCut(self) -> Incomplete: ...
+ def addPoolCut(self, row: Incomplete) -> Incomplete: ...
def addPyCons(self, cons: Incomplete) -> Incomplete: ...
def addRowDive(self, row: Incomplete) -> Incomplete: ...
def addRowExact(self, rowexact: Incomplete) -> Incomplete: ...
@@ -483,7 +483,7 @@ class Model:
def addVarLocksType(self, var: Incomplete, locktype: Incomplete, nlocksdown: Incomplete, nlocksup: Incomplete) -> Incomplete: ...
def addVarSOS1(self, cons: Incomplete, var: Incomplete, weight: Incomplete) -> Incomplete: ...
def addVarSOS2(self, cons: Incomplete, var: Incomplete, weight: Incomplete) -> Incomplete: ...
- def addVarToRow(self, value: Incomplete) -> Incomplete: ...
+ def addVarToRow(self, row: Incomplete, var: Incomplete, value: Incomplete) -> Incomplete: ...
def allColsInLP(self) -> Incomplete: ...
def allowNegSlackExact(self) -> Incomplete: ...
def appendVarSOS1(self, cons: Incomplete, var: Incomplete) -> Incomplete: ...
@@ -494,7 +494,7 @@ class Model:
def branchLPExact(self) -> Incomplete: ...
def branchVar(self, variable: Incomplete) -> Incomplete: ...
def branchVarVal(self, variable: Incomplete, value: Incomplete) -> Incomplete: ...
- def cacheRowExtensions(self) -> Incomplete: ...
+ def cacheRowExtensions(self, row: Incomplete) -> Incomplete: ...
def calcChildEstimate(self, variable: Incomplete, targetvalue: Incomplete) -> Incomplete: ...
def calcNodeselPriority(self, variable: Incomplete, branchdir: Incomplete, targetvalue: Incomplete) -> Incomplete: ...
def catchEvent(self, eventtype: Incomplete, eventhdlr: Incomplete) -> Incomplete: ...
@@ -562,7 +562,7 @@ class Model:
def feastol(self) -> Incomplete: ...
def fixVar(self, var: Incomplete, val: Incomplete) -> Incomplete: ...
def fixVarProbing(self, var: Incomplete, fixedval: Incomplete) -> Incomplete: ...
- def flushRowExtensions(self) -> Incomplete: ...
+ def flushRowExtensions(self, row: Incomplete) -> Incomplete: ...
def frac(self, value: Incomplete) -> Incomplete: ...
def freeBendersSubproblems(self) -> Incomplete: ...
def freeProb(self) -> Incomplete: ...
@@ -593,8 +593,8 @@ class Model:
def getConsVars(self, constraint: Incomplete) -> Incomplete: ...
def getConss(self, transformed: Incomplete = ...) -> Incomplete: ...
def getCurrentNode(self) -> Incomplete: ...
- def getCutEfficacy(self, sol: Incomplete = ...) -> Incomplete: ...
- def getCutLPSolCutoffDistance(self) -> Incomplete: ...
+ def getCutEfficacy(self, cut: Incomplete, sol: Incomplete = ...) -> Incomplete: ...
+ def getCutLPSolCutoffDistance(self, cut: Incomplete, sol: Incomplete) -> Incomplete: ...
def getCutoffbound(self) -> Incomplete: ...
def getDepth(self) -> Incomplete: ...
def getDualMultiplier(self, cons: Incomplete) -> Incomplete: ...
@@ -743,7 +743,7 @@ class Model:
def initBendersDefault(self, subproblems: Incomplete) -> Incomplete: ...
def interruptSolve(self) -> Incomplete: ...
def isAndConsSorted(self, and_cons: Incomplete) -> Incomplete: ...
- def isCutEfficacious(self, sol: Incomplete = ...) -> Incomplete: ...
+ def isCutEfficacious(self, cut: Incomplete, sol: Incomplete = ...) -> Incomplete: ... |
|
Heck yeah! |
@jonathanberthias how do you feel about this? I'm a bit more concerned since, now that the script would be running automatically, we should be more comfortable that it's actually correct.
Added
isObjIntegral()to test that the pipelines do what they're supposed to.