classification
Title: re.RegexFlag is not included in __all__, makes type inference less useful
Type: Stage:
Components: Regular Expressions Versions: Python 3.8, Python 3.7
process
Status: open Resolution:
Dependencies: Superseder:
Assigned To: Nosy List: PJB3005, cheryl.sabella, docs@python, ethan.furman, ezio.melotti, gvanrossum, levkivskyi, mrabarnett, r.david.murray, serhiy.storchaka
Priority: normal Keywords:

Created on 2017-09-06 20:40 by PJB3005, last changed 2020-09-13 18:12 by gvanrossum.

Messages (10)
msg301516 - (view) Author: Pieter-Jan Briers (PJB3005) Date: 2017-09-06 20:40
It exists and its flags are exported, but not the direct classes itself. This seems inconsistent to me and fixing it would make things like using static typing on it just a little bit easier.
msg301529 - (view) Author: R. David Murray (r.david.murray) * (Python committer) Date: 2017-09-06 22:24
I think RegexFlag is an implementation detail, but it is true that it isn't prefixed with a _ so putting it in __all__ is not obviously wrong.  However, if we do that we should also document it (currently it is mentioned only in a versionchanged line, which isn't technically documenting it).

I find it curious that static typing is affected by __all___, but I don't really know anything about typing.
msg301532 - (view) Author: Pieter-Jan Briers (PJB3005) Date: 2017-09-06 22:43
I suppose it may be an implementation detail, though I wouldn't be amazed that had enum existed when re was written it'd have been used instead of constant integers at the time. Though I do suppose exposing it fully would add two ways to get the flags which I can see how it would be considered bad.

It's still useful for type checking though, and while I did make a PR to add it to typeshed, that still leaves it in an iffy state and I probably would not be the last person to be confused by it initially.
msg301536 - (view) Author: R. David Murray (r.david.murray) * (Python committer) Date: 2017-09-06 22:53
Well, I consider that they really should be named constants and not an enum, which is why I consider it an implementation detail :)
msg338567 - (view) Author: Cheryl Sabella (cheryl.sabella) * (Python committer) Date: 2019-03-21 22:55
@ethan.furman, since you had originally added RegexFlag in #28082, do have an opinion on this?  Thanks.
msg338583 - (view) Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) Date: 2019-03-22 03:28
I concur with David. This is an imlementation detail. No need to prefix it with a _ if the module uses __all__for public names.
msg338815 - (view) Author: Ethan Furman (ethan.furman) * (Python committer) Date: 2019-03-25 18:05
I see no reason no prefix `RegexFlag` with an `_`.

As far as adding it to `__all__` -- I didn't originally because I was trying to mirror the original implementation, but I am not against it.  I would defer that decision to those that work on typing.
msg339545 - (view) Author: Ivan Levkivskyi (levkivskyi) * (Python committer) Date: 2019-04-06 21:30
I am totally fine with making RegexFlag public (this may be indeed useful for static typing purposes).
msg376815 - (view) Author: Ethan Furman (ethan.furman) * (Python committer) Date: 2020-09-13 00:18
Guido, do you have an opinion on adding `RegexFlag` to the `re` module's `__all__` and documenting it?

There is also some discussion on making these types of int-to-Enum conversions use a `module.name` repr instead of `class.name`:

used to be:

    >>> re.I
    <RegexFlag.I: 2>

is now:

    >>> re.I
    re.IGNORECASE

I of course have no idea if that matters to typing one way or the other.
msg376841 - (view) Author: Guido van Rossum (gvanrossum) * (Python committer) Date: 2020-09-13 18:12
What it prints is irrelevant to static checking.

Currently the typeshed stub for the code already exports RegexFlag, so that the following passes mypy but fails at runtime:
```
from re import *

def foo(flag: RegexFlag):
    return match("[a-z]+", "ABC", flag)

print(foo(IGNORECASE))
print(foo(VERBOSE))
```
I think it's good to add it to `__all__` so this code will not put the type checker to shame, and it would be good to document it.

One thing I discovered when developing this example: there doesn't seem to be a flag to represent 0 (zero), i.e. "no flags".  And foo(0) is a type error (even though it works fine at runtime).
History
Date User Action Args
2020-09-13 18:12:58gvanrossumsetmessages: + msg376841
2020-09-13 00:18:21ethan.furmansetmessages: + msg376815
2019-04-06 21:30:18levkivskyisetmessages: + msg339545
2019-03-25 18:05:39ethan.furmansettitle: re.RegexFlag is not included in __all__ -> re.RegexFlag is not included in __all__, makes type inference less useful
nosy: + gvanrossum, levkivskyi

messages: + msg338815

assignee: docs@python ->
components: - Documentation
2019-03-22 03:28:12serhiy.storchakasetnosy: + serhiy.storchaka
messages: + msg338583
2019-03-21 22:55:58cheryl.sabellasetnosy: + ethan.furman, cheryl.sabella

messages: + msg338567
versions: + Python 3.8, - Python 3.6
2017-09-06 22:53:45r.david.murraysetmessages: + msg301536
2017-09-06 22:43:21PJB3005setmessages: + msg301532
2017-09-06 22:24:23r.david.murraysetversions: + Python 3.7
nosy: + r.david.murray, docs@python

messages: + msg301529

assignee: docs@python
components: + Documentation
2017-09-06 20:40:02PJB3005create