PySCIPOpt icon indicating copy to clipboard operation
PySCIPOpt copied to clipboard

Distributing type stubs

Open jonathanberthias opened this issue 3 months ago • 9 comments

Is your feature request related to a problem? Please describe.

Since this library is packaged as an extension module, type checkers and LSPs are not able to inspect the source code to extract type information. This makes it harder to discover available functions and methods as the IDEs cannot help.

Image

A few months ago, I started working on type stubs for pyscipopt: https://github.com/jonathanberthias/scip-stubs. I haven't caught up with the latest changes yet but it shouldn't be too much work to update. If I install this stub package in the environment, then I get:

Image

Describe the solution you'd like

There are 2 ways to distribute the stub files: they can either be part of the package itself as additional files, or they can be distributed in a separate package, conventionally named pkg-stubs.

The main difference between the 2 approaches is the development flow. If the stubs are part of the package, then users don't need to install an additional package and they get completion, docstrings in the IDE, type checking, etc. for free. However, it puts more burden on the contributors and maintainers as for each change, one has to ensure the stubs reflect the implementation by modifying both the source files and the stub files. It also means a new version of the library must be released for changes to stubs to be available.

If the stubs are packaged separately, there is more freedom to release on a separate schedule. For instance, the type stubs package for pyscipopt 5.6.0 could be versioned 5.6.0.0, and if a fix is needed, then 5.6.0.1 can be released. The downside is that the stubs are not in the same repo as the source, increasing the chances that they are out of sync. As an example, to test the stubs, I had to copy most of the tutorials from this repo to have some reference code. If the stubs were in this repo, the code would test the stubs automatically.

I don't have a clear preference for either model. I think it is up to you to decide which model suits your workflow best. In any case, I will gladly share the stubs I have already written and those I will add in the future, either by contributing to this repo or by publishing a separate package.

For reference, scipy have a separate repo for stubs: https://github.com/scipy/scipy-stubs, whereas gurobipy ship the type stubs with the package directly.

Happy to discuss this further if you need additional information!

jonathanberthias avatar Sep 15 '25 21:09 jonathanberthias

Would join in on this request! This would be amazing, since I stumbled across this as well and started to set up my own stub files yesterday (because I wouldn't find any existing ones). So thank you a lot for your contribution @jonathanberthias!:)

I do agree, that having an official source would be a great addition to pyscipopt.

justuskilianwolff avatar Sep 16 '25 20:09 justuskilianwolff

Hey @jonathanberthias . Holy moly, is this useful!!

As I shared on the repo recently, unfortunately I won't be able to follow this very closely, but it's a great great great addition to pyscipopt.

My only concern is having to manually update every time a new function is added. Is there really not a proper way to do this automatically that is compatible with us? If not, I guess a script that scraps the files wouldn't be too bad...

Regarding your question, I'm all in favor of adding it to the package directly! The loss of flexibility is just relevant if the stubs need to be manually updated, right?

Joao-Dionisio avatar Sep 17 '25 08:09 Joao-Dionisio

That's great to read @Joao-Dionisio, thanks a lot for your support! I guess I'll try to break things down into small focused PRs so that it's easy to follow, though it might take some time to get all the stubs clean and useful.

Regarding automation, there are some tools such as stubtest that check the stubs define the same functions and arguments as the runtime package. It's really good to get a broad coverage though it doesn't ensure the type annotations are correct. But it'll definitely be part of the setup for stubs, such that it will warn if a function is added to the implementation but not to the stubs. I also had a script to copy over the docstrings so that they show up in the editor, so that part can be fully automated.

jonathanberthias avatar Sep 20 '25 21:09 jonathanberthias

Music to my ears, @jonathanberthias :)

Maybe a good initial PR would contain the most basic modeling methods (adding a variable/constraint, etc. etc.), as I guess inexperienced people would benefit the most from this.

Joao-Dionisio avatar Sep 22 '25 09:09 Joao-Dionisio

@jonathanberthias (and @justuskilianwolff :) ), can you please give me a sort of work plan for what is coming next, to have an overview?

Joao-Dionisio avatar Oct 06 '25 10:10 Joao-Dionisio

Here is a high-level task list:

  1. complete the type annotations for all "easy" things (float, bool, int parameters and return types)
  2. manage the enums (they aren't really enums, but I think typing them as enums is more useful than being faithful to the runtime)
  3. type the Expr operations
  4. rank-typing for the matrix API? (not sure this is possible)
  5. add docstrings to all methods
  6. add default values when they are simple
  7. enforce complete stubs in CI (stubtest)
  8. enforce up-to-date docstrings in CI
  9. type the plugins

Sorry if this list is a bit raw, I might polish it a little as I get through the items. I think doing the first 3 steps is important to reach a state where the type annotations bring a lot of value to users, the following steps are more focused on maintainability.

If the question is whether we should wait for some of these before cutting a release, I think we shouldn't. This process can be done in parallel to new features, and it won't be done before a long time. And type annotations can't break user code, they should just help the dev experience for the time being - though at some point there might be type errors in user code, but that's the goal 😉

jonathanberthias avatar Oct 07 '25 21:10 jonathanberthias

Happy to support where support is needed! :)

justuskilianwolff avatar Oct 08 '25 07:10 justuskilianwolff

Hey @jonathanberthias, just letting you know that a new minor SCIP will release in about a week or so, meaning that a new PySCIPOpt release will come hopefully soon after. Just letting you know, in case there's something related to this that you feel would be nice to have in this release.

Joao-Dionisio avatar Oct 23 '25 12:10 Joao-Dionisio

Thanks for the heads up @Joao-Dionisio! I'll probably just check again that all methods exist in the stubs since a lot of PRs have been merged recently, but other than that I think actually filling in the stubs with useful information can wait for the next releases.

jonathanberthias avatar Oct 24 '25 14:10 jonathanberthias