On Mon, 24 Feb 2020 at 20:13, Alex Hall <alex.mojaki@gmail.com> wrote:
Conversely, I can't remember a case where I've ever accidentally iterated over a string when I meant not to.
Do you ever return a string from a function where you should have returned a list containing one string? Or similarly passed a string to a function? Forgotten to put a trailing comma in a singleton tuple? Forgotten to add .items() to `for key, value in kwargs:`?
Not that I remember - that's what I said, basically. No, I'm not perfect (far from it!) but I don't recall ever hitting this issue.
compelling arguments are typically around demonstrating how much code would be demonstrably better with the new behaviour
That represents a misunderstanding of my position. I think I'm an outlier among the advocates in this thread, but I do not believe that implementing any of the ideas in this proposal would significantly affect code that lives in the long term. Some code would become slightly better, some slightly worse.
I beg to differ. * Code that chooses to use `.chars()` would fail to work on versions of Python before whatever version implemented this (3.9? 3.10?). That makes it effectively unusable in libraries for years to come. * If you make iterating over strings produce a warning before `.chars()` is available as an option for any code that would be affected, you're inflicting a warning on all of that code. * A warning that will never become an error is (IMO) unacceptable. It's making it annoying to use a particular construct, but with no intention of ever doing anything beyond annoying people into doing what you want them to do. * A warning that *will* become an error just delays the problem - let's assume we're discussing the point when it becomes an error. As a maintainer of pip, which currently still supports Python 2.7, and which will support versions of Python earlier than 3.9 for years yet, I'd appreciate it if you would explain what pip should do about this proposed change. (Note: if you suggest just suppressing the warning, I'll counter by asking you why we'd ever remove the code to suppress the warning, and in that case what's the point of it?) And pip is an application, so easier. What about the `packaging` library? What should that do? In that case, modifying global state (the warning config) when the library is imported is generally considered bad form, so how do we protect our users from this warning being triggered by our code? Again, we won't be able to use `.chars()` for years. Boilerplate like if sys.version_info >= (3, 9): def chars(s): return s.chars() else: def chars(s): return s would be an option, but that's a lot of clutter for every project to add for something that *isn't a problem* - remember, long-running, well-maintained libraries with a broad user base will likely have already flushed out any bugs that might result from accidentally iterating over strings. And these days, projects often use mypy which will catch such errors as well. So this is literally useless boilerplate for them.
My concern surrounds the user experience when debugging code that accidentally iterates over a string. So it's impossible for me to show you code that becomes significantly better because that's not what I'm arguing about, and it's unfair to say that quoting people who have struggled with these bugs is not evidence for the problem.
OK. That's a fair point. But why can't we find other approaches? Type checking with mypy would catch returning a string when it should be a list of strings. Same with all of your other examples above. How was your experience suggesting mypy for this type of problem? I suspect that, as you are talking about beginners, you didn't inflict anything that advanced on them - is there anything that could be done to make mypy more useful in a beginner context?
I would like to reiterate a point that I think is very important and many people seem to be brushing aside. We don't have to *break* existing code. We can get a lot of value, at least in terms of aiding debugging, just by adding a warning.
Years of experience maintaining libraries and applications have convinced me that warnings can cause as much "breakage" as any other change. Just saying "you can suppress them" doesn't make the problem go away. And warnings that are suppressed by default are basically pointless, as people just ignore them. That's not to say that warnings are useless - just that introducing *new* warnings needs to be treated just as seriously as any other change. Paul