However I have one base object and multiple cutters. I first tried just passing one brep as the first argument, but it told me it expected an IEnumerable[brep]. So I tried just making a list from the one brep, certain it was going to fail, but it actually worked (more or less).
I think the code you wrote is the correct approach (first input in a list).
What probably happens is that CreateBooleanSplit method splits the first input iteratively. So it takes the first cutter, split the first input into two/more pieces. Then checks if the second cutter intersects the any of the two/more pieces. If it does, it deletes that one (already split) piece and creates new pieces from it. And so on. All these deleted pieces are returned as ‘None’.
My thought is similar to Djordje’s but I think the brep is split with the first and then the resulting breps are split with the second, of which one gives a None result. Since there is no awareness of where the objects are located I assume this is just done brute force.
Splitting a closed object. It should return a closed object as well, that is the purpose. If you are splitting a closed object with a curved surface then Cap will not work to close the object as the opening is not planar. Hence the use of BooleanSplit, which works similarly to the native Rhino command.
Otherwise, just like you would do with native Rhino commands, it’s necessary to code with just Brep.Split() which leaves the object open, then get the splitting surface, split that as well, figure out which part of the surface you want to keep and then join that to the rest. That’s just a lot more coding.