chrisimcevoy / pyoda-time

A better date and time API for Python
https://pyodatime.org/
Apache License 2.0
1 stars 0 forks source link

Consider PEP 702 style decorators for types with no public constructor #163

Open chrisimcevoy opened 1 month ago

chrisimcevoy commented 1 month ago

A fair number of Noda Time types have no public constructor. Python doesn't have constructors in quite the same way, but __new__ and __init__ are always present.

We have the rather hacky, poorly-named _private decorator which enforces that trying to instantiate such classes raises an error at runtime.

Generally this sort of heavy-handed approach is frowned upon in Python, but I really do want to discourage reliance on unintentional/implicit facets of this port where possible, in order to save pain down the line if/when the mother project's API changes. With that said, I think we can try to do better UX than runtime exceptions.

PyCharm has a nice feature that, if you have the relevant deprecation inspection enabled (which it is by default), it displays strikethrough text and the message of the DeprecationWarning when you hover over the symbol.

image

The problem is, this doesn't seem to work with dunder methods like __init__ and __new__, unless you call them directly.

(Ideally the foo = Foo() would show strikethrough text on the right hand of the assignment)

image

There are a bunch of open enhancement tickets around this. See PY-25798 (and click through to the related/similar tickets). Some of them mention supporting existing third-party packages; while that support may come some day in PyCharm, I personally have no appetite to take another dependency just for this purpose.

Besides which, none of this works in VS Code as far as I am aware. (Maybe via extensions, but I haven't looked.)

image

More interestingly, there is https://youtrack.jetbrains.com/issue/PY-61651/Deprecation-highlighting-with-PEP-702-deprecated-decorator which requests support for PEP 702 deprecation decorators.

Those decorators are available in 3.12 as backports in typing.extensions, and while they don't currently affect PyCharm's UI, I would expect support for something in the stdlib to be much more likely to materialise than support for third-party packages.

To add even more credibility to that, it looks like this is already supported in pyright. For example:

At time of writing, PyCharm doesn't understand what these decorators are.

image

In VS Code however, it looks exacly as I would like it to; The class itself is not deprecated, but individual methods can be marked deprecated, including magic methods:

image