Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
509 views
in Technique[技术] by (71.8m points)

python - Is it possible to create a regex-constrained type hint?

I have a helper function that converts a %Y-%m-%d %H:%M:%S-formatted string to a datetime.datetime:

def ymdt_to_datetime(ymdt: str) -> datetime.datetime:
    return datetime.datetime.strptime(ymdt, '%Y-%m-%d %H:%M:%S')

I can validate the ymdt format in the function itself, but it'd be more useful to have a custom object to use as a type hint for the argument, something like

from typing import NewType, Pattern

ymdt_pattern = '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9]'
YmdString = NewType('YmdString', Pattern[ymdt_pattern])

def ymdt_to_datetime(ymdt: YmdString)...

Am I going down the wrong rabbit hole? Should this be an issue in mypy or someplace? Or can this be accomplished with the current type hint implementation (3.61)?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

There currently is no way for types to statically verify that your string matches a precise format, unfortunately. This is partially because checking at compile time the exact values a given variable can hold is exceedingly difficult to implement (and in fact, is NP-hard in some cases), and partially because the problem becomes impossible in the face of things like user input. As a result, it's unlikely that this feature will be added to either mypy or the Python typing ecosystem in the near future, if at all.

One potential workaround would be to leverage NewType, and carefully control when exactly you construct a string of that format. That is, you could do:

from typing import NewType
YmdString = NewType('YmdString', str)

def datetime_to_ymd(d: datetime) -> YmdString:
    # Do conversion here
    return YmdStr(s)

def verify_is_ymd(s: str) -> YmdString:
    # Runtime validation checks here
    return YmdString(s)

If you use only functions like these to introduce values of type YmdString and do testing to confirm that your 'constructor functions' are working perfectly, you can more or less safely distinguish between strings and YmdString at compile time. You'd then want to design your program to minimize how frequently you call these functions to avoid incurring unnecessary overhead, but hopefully, that won't be too onerous to do.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...