Yes. Complexity is always exponential.
> Because simple linear scaleup suggests 6 days of work, not 30-40 days of work.
Well, again your project is particularly hard: c extension + Python 2 / 3 compatible code base. That's not the common case.
You can always find somebody with a particular situation. And we hear those persons more, and not the hundred ons with just a few scripts or a website.
> I also pointed out that just the test suite, which not much bigger than 20KLOC, required hours of work to tweak all of the b"" strings correctly.
That's Python 2 / 3 compatible code base for you. This tweak is almost a no brainer in pure python 3.
> many submodules with print statements which needed to turned into print functions.
2to3 does that automatically, and many other things, that you can even cherry-pick. If you don't use the provided tooling, you make your life harder.
> These are mostly the usual iteritems()->items(), zip()->list(zip()), itertools.izip()->zip(), a compatibility shim for isinstance(obj, basestring), open(name, "U") vs. open(name, "r", newline=None), etc.
python-future provide all the helpers for that: normalized builtins, import aliases, wrappers, etc. It has existed since 2013. People need to spread the word about the proverbial wheel on this one.
It's like using
> Some of the trickier ones were: how to read bytes from stdin (sys.stdin.buffer); explicit flushes on sys.stderr (not needed for Python 2.x); a StringIO-like wrapper around BytesIO so I could write() both bytes and Unicode strings containing only ASCII (which is what cStringIO.StringIO did); and a few workarounds for changes in argparse behavior.
Yeah, that's the hard part. You can't automate that. But it's what, 3% of your code ? Unless you hate DRY.
It's quite fair that bumping an entire project to an non compatible version of your plateform requires you do this.
> The trickiest is that I allow the user to pass in an eval-able mathematical expression on the command-line. My code first compiles the expression and checks that all of the global variables are known, in order to generate a more detailed error message than Python itself would.
Quite a cool project :)
> This is about twice as long as your estimate would suggest. (I'm excluding the auto-generated data table and the third-party package from my LOC count.)
Granted. Still, 4 days of porting for an entire project one time in a 25 years old language feels ok in my book.
Don't forget that since 2000:
- Perl 6 has been late for a decade.
- PHP failed its V6 and jumped to V7.
- NodeJS forked and merged twice.
From this point of view, what Python did is an amazing accomplishment.
> This tweak is almost a no brainer in pure python 3.
The timing estimate I made assumed 4 changes per minute. That's already pretty no-brainer. Are you suggesting it should have been faster than that? I don't know how. Not all of the strings needed to be converted to byte strings.
> python-future provide all the helpers for that
First time I heard of it. I thought we were supposed to be using 'six', which is where I got the shims from.
If I understand correctly, that package should not be used for Python libraries which want to maintain Python 2 compatibility. That is, if I have library X, and some of my users are on Python 2, then I shouldn't use python-future because the 'standard_library.install_aliases()' call modifies builtins, which may change how Python 2 works for those users.
> 4 days of porting for an entire project one time in a 25 years old language feels ok in my book.
Yes. My point is that I think your original numbers are optimistic, not that they are fundamentally flawed.