Proposed solution fits needs for pure-Python code. How about CPython parts, written in C? Or C extension modules? I’m pretty sure there is a zoo of poor-man replacements for this. E.g. the reduce() function uses NULL as default for the initial argument. perm() uses k=None.
Maybe it was discussed in the looong thread somewhere, but I would appreciate if that use case will be mentioned in the PEP text.
It wasn’t really discussed. I think it makes sense to provide a PySentinel_New(name, module) C API function. I’m not sure it’s needed for the cases you mention (C functions where NULL or None is acceptable), but it would make sense for replacing e.g. typing.NoDefault.
What should the interface look like? I’m leaning towards PySentinel_New(const char *name, const char *module).
In the typing case, the module object is for the _typing module, but we want the object to pretend it is in typing. The same would go for functools.Placeholder, which is actually created in the _functools module.
I think the same thing will happen commonly in third-party code. For example, many numpy classes say they are in the numpy module, but in fact are presumably defined in some internal helper module.
It is very contrived but wouldn’t be surprised if this pattern could emerge in very long modules. Is this a redefinition of MISSING that is allowed? Or should this raise an error? Or should each type checker be allowed to choose the behaviour/strictness they want?
I don’t remember this being discussed in this thread, but I think we can all agree that at this point it is quite hard to remember all the various discussions we have had in it