You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Type "def func1() -> Unknown | def func2() -> Unknown" is not callable #406
Type "def func1() -> Unknown | def func2() -> Unknown" is not callable
Ideally the type checker could see that both branches of the optional type are themselves callable, and avoid a warning here.
This is using starpls v0.1.21, along with --experimental_infer_ctx_attributes, --experimental_use_code_flow_analysis, and --experimental_enable_label_completions.
@jschear If you still want to help out, take a look at #443 for some inspiration. I think there's 2 paths we can take:
We strip the func1 and func2 pieces and do something similar to my PR, where we special case the unioning of two functions with the same signature. So def func1() -> Unknown | def func2() -> Unknown would become def () -> Unknown (a nameless function type). It may make sense to stack the change on top of my branch.
Special case the union type so that it is callable iff all of its members are callable.
I could see some arguments for 2, since we don't lose information, but 1 produces a simpler type and the fix should be simpler.
FYI, the author is quite busy with $dayjob and hasn't been able to look at the repo in a while. I've been maintaining a fork here https://github.com/modular/starpls, happy to cherry pick fixes or if you want to submit a PR there I'm happy to merge it. (I'll be cherry picking my own PR there in the next few days.)
Hi @Ahajha, thanks for the info. I'm no longer at the $dayjob that motivated this issue, so no longer in any real rush to fix it.
My more complete example looked something like this, where the functions didn't have the exact same type signature, so option 1 wouldn't have fixed my particular issue.
# in defs.bzldeffunc1(use_foo_feature=False):
passdeffunc2(**kwargs):
passmy_func=func1ifTrueelsefunc2# in BUILDmy_func(
name="MyTarget",
use_foo_feature=True,
)
But in general it makes sense to me that the union type A | A should be treated as A, so even if that wouldn't have fixed my issue, it might still be a good change? I'll dig in a bit.
Activity
jschear commentedon Dec 17, 2025
I'd like to try to contribute a fix here, especially if I can get a pointer to relevant code. I'm guessing this falls under "code flow analysis"?
Ahajha commentedon Oct 17, 2026
@jschear If you still want to help out, take a look at #443 for some inspiration. I think there's 2 paths we can take:
func1andfunc2pieces and do something similar to my PR, where we special case the unioning of two functions with the same signature. Sodef func1() -> Unknown | def func2() -> Unknownwould becomedef () -> Unknown(a nameless function type). It may make sense to stack the change on top of my branch.I could see some arguments for 2, since we don't lose information, but 1 produces a simpler type and the fix should be simpler.
FYI, the author is quite busy with $dayjob and hasn't been able to look at the repo in a while. I've been maintaining a fork here https://github.com/modular/starpls, happy to cherry pick fixes or if you want to submit a PR there I'm happy to merge it. (I'll be cherry picking my own PR there in the next few days.)
jschear commentedon Oct 23, 2026
Hi @Ahajha, thanks for the info. I'm no longer at the $dayjob that motivated this issue, so no longer in any real rush to fix it.
My more complete example looked something like this, where the functions didn't have the exact same type signature, so option 1 wouldn't have fixed my particular issue.
But in general it makes sense to me that the union type
A | Ashould be treated asA, so even if that wouldn't have fixed my issue, it might still be a good change? I'll dig in a bit.