New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Language specifications for strings #1370
Comments
There are currently two ways that this could be implemented. Using from typing import NewType, cast
HTMLString = NewType("HTMLString", str)
def print_html(html: HTMLString) -> None: ...
html = cast(HTMLString, "<div>Hi!</div>")
print_html(html) # works
print_html("<script ...>") # error Using from typing import Annotated
def print_html(html: str) -> None: ...
html: Annotated[str, "html"] = "<div>Hi!</div>"
print_html(html) In both cases, the hard part is finding common ground for tool manufacturers to support this notation. |
Sorry for the ping-pong -- this issue really belongs over at the |
100% agreed. It's clearly a "build it and they will come" kind of thing. It has to be built first, and people need to start pushing implementations for it all over the place. I can certainly write lots of PRs, but if the basic architecture isn't there, then I can't :P |
There has been some discussion of this topic in the pylance discussion forum. |
@srittau Looking again at your example code I think you must have misunderstood the idea. Changing your example to what I want: def print_html(html: HTMLString) -> None: ...
html = cast(HTMLString, "<div>Hi!</div>")
print_html(html) # works
print_html("<script ...>") # ALSO WORKS The proposal here is that the second case ( For |
A discussion at microsoft/pylance-release#3952 lead to the concrete suggestion of a |
I don't think The other suggestions above, including |
@erictraut I don't understand the distinction. Why can't Anyway, I think my point was more about using the word "language" somewhere. |
I really like the class MyModel:
template: Html # aka Annotated[str, Html(flavor=?)] or similar
regex: Regex # aka Annotated[str, Regex(flags=0)] or similar And have that be available both for static type checking and runtime type checking so that |
A related discussion for PyCharm: https://youtrack.jetbrains.com/issue/PY-53278/Cant-inject-template-language-into-Python-string |
In PyCharm you can set the programming/markup language of strings like this:
I find this extremely useful and use it all over the place. A pattern I noticed is that a large proportion of such uses are in fact more like:
In this case the format_html function doesn’t take any random string as the first argument, it takes a string that is supposed to be html. Reading through my usage of # language= I see that I have CSS, HTML, and JavaScript.
There are many places in my codebases that also have very different types of “languages” that unfortunately isn’t supported as a language injection in PyCharm. Some examples:
fully qualified name (module.module.symbol, for example view functions in Django)
module names (module.module, for example app names in Django)
There are probably more, but I think this gets the point across.
PyCharm has some (presumably hardcoded) rules about some of these strings, for example in settings.py it knows that strings in the list INSTALLED_APPS are module names, so you can jump to the definitions of those modules, and PyCharm will resolve and check them for you. But this is a closed system where any introduced variables I create myself can’t be validated in this way.
I think it would be good if python typing could have a facility for this type of thing. When this gets some traction we could see support for it in Python language servers, PyCharm, static analysis tools, etc.
What do you guys think?
(originally posted at https://discuss.python.org/t/language-specifications-for-strings/21826/1 where it was suggested that this is the right place for this discussion)
The text was updated successfully, but these errors were encountered: