This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: re.sub appears not to check count optional argument for integerness
Type: behavior Stage: resolved
Components: Library (Lib) Versions: Python 3.4
process
Status: closed Resolution: duplicate
Dependencies: Superseder: re: convert re flags to (much friendlier) IntFlag constants
View: 28082
Assigned To: Nosy List: Danny Yoo, r.david.murray
Priority: normal Keywords:

Created on 2016-12-08 17:02 by Danny Yoo, last changed 2022-04-11 14:58 by admin. This issue is now closed.

Messages (4)
msg282719 - (view) Author: Danny Yoo (Danny Yoo) Date: 2016-12-08 17:02
This comes from diagnosing a beginner's question on Python-tutor.

https://mail.python.org/pipermail/tutor/2016-December/110066.html

It appears that re.sub is not checking whether the count argument is integer or not, and silently accepts a nonsensical argument.  For example:


>>> import re
>>> s = "AAAcBBB\nAAAdBBB"
>>> print(re.sub(r'^AAA', "aaa", s, re.MULTILINE))
aaacBBB
AAAdBBB


Of course, the user intended to pass re.MULTILINE to flags, not to count, but the fact that this isn't raising a TypeError is error-prone.
msg282721 - (view) Author: Danny Yoo (Danny Yoo) Date: 2016-12-08 17:11
Ugh.  I suddenly realize that this is complicated by the fact that flag values are themselves represented as integers, and Python's type system isn't rich enough to label flag values as a distinct type for the purposes.

It may be worthwhile to add a warning in the documentation about this, as it is an easy mistake to make.
msg282722 - (view) Author: Danny Yoo (Danny Yoo) Date: 2016-12-08 17:32
Alternatively, change the representation of flag values from integers to some class extension that supports the common bitwise operators.

As a very rough sketch:

>>> class FlagInt(int):
...     def __or__(self, other):
...         return FlagInt(int(self) | int(other))
... 
>>> f1 = FlagInt(1)
>>> f2 = FlagInt(2)
>>> f1 | f2
3
>>> isinstance(3, FlagInt)
False
>>> isinstance(f1 | f2, FlagInt)
True


That way, flag arguments can be determined at runtime to have derived from the proper flag values.

This kind of approach may have some backwards-incompatibility, unfortunately, since other folks have been hardcoding integers rather than use the flag constants.  Other concerns might include serialization, in case someone tries to save a FlagInt somewhere and pull it out at some other time.
msg282726 - (view) Author: R. David Murray (r.david.murray) * (Python committer) Date: 2016-12-08 18:37
See issue 28082.
History
Date User Action Args
2022-04-11 14:58:40adminsetgithub: 73091
2016-12-08 18:37:08r.david.murraysetstatus: open -> closed

superseder: re: convert re flags to (much friendlier) IntFlag constants

nosy: + r.david.murray
messages: + msg282726
resolution: duplicate
stage: resolved
2016-12-08 17:32:51Danny Yoosetmessages: + msg282722
2016-12-08 17:11:37Danny Yoosetmessages: + msg282721
2016-12-08 17:02:58Danny Yoocreate