edit: I don't mean this as a knock on py3. All I'm saying is that my situation and uses for python allow me to be apathetic towards 2 vs. 3.
I would have made UTF-8 the internal representation, and generated an array of subscript indices only when someone random-accessed a string. If the string is being processed sequentially, as with
for c in s :
...
you don't need an index array. You don't need them for list comprehensions or regular expressions. One could even have opaque string indices, returned by search methods, which don't require an index array unless forcibly converted to an integer. Some special cases, such as "s[-1]", don't really need an index array either.Indexing a string in Python 3 returns glyphs (which are strings), not bytes. Not graphemes; if you index through a Python 3 string with emoji that have skin color modifications, you'll get the emoji glyph and the skin color modifier as separate items.
Python 3 also has a type "bytes", which can't quite decide whether it's a string type or an array of integers. Print a "bytes" type, and it's printed as a string, with a 'b" in front of it, not as an array of integers. But an element of a "bytes" array is an int, not a bytes type. This is for backwards compatibility; it's roughly compatible with legacy "str" from Python 2.
Rust struggles with this. Rust tries to prevent you from getting a invalid UTF-8 string. The solution used involves re-checking for UTF-8 validity a lot, or bypassing it with unsafe code. This gets messy.
You only need to check once, at the boundary of when you're converting from something that may or may not be UTF-8 to a UTF-8 string.
I am pretty much in the same situation and in hindsight I kinda wish I upgraded a little sooner. Fixing print brackets was the biggest (not that big) task, and from there on it was all python3 sugar for me :)
If you are maintaining a large or important codebase rather than working as a hobbyist or independent contractor, then there is nothing wrong with using older languages/platforms, especially if they are stable and well tested. Avoiding surprises or breakage is generally a lot more important to you than getting a cool new list comprehension facility. Actually, stability of the language is something to be desired, as there is a cognitive cost to having different portions of the project use different language constructs.
In terms of python 2 not being supported in the future, if we are forced to stop using python 2, we'll probably need to switch the project over to Java. Not something I'm looking forward to, but at least the java community doesn't force developers to rewrite their source code when a new JVM comes out. There were some examples of older bytecode not working in newer JVMs, but as long as you had the original sources you could always compile to the newer bytecode. Personally, I've grabbed jars from 2005 and used them without any issue. My employer is mostly a java shop, and I already have to occasionally answer questions from other devs about why this project is in python. My answer has always been that python is a more productive language for this use case, and their retort is that it's not really enterprise ready -- meaning things like stability and support, so that while the language may be faster to initially develop in, the long term maintenance cost will be higher. The lack of respect for backwards compatibility as well as the hostility of the community to basic things like don't break working code is causing me to lose some conviction in my side of this argument. I imagine the same discussion is happening in businesses all over the country.
The question is not python 2 or python 3, but python 2 or move away from the language to one that understands my needs. This transition has created a real black eye for python and its role in the commercial space -- at least that's my impression.
This is just silly. It will take at least 100x more effort to rewrite the project in Java than it would to upgrade to Python 3.
> at least the java community doesn't force developers to rewrite their source code when a new JVM comes out
Yes, that was an unfortunate, one-time thing for Python that happened almost a decade ago.
> My employer is mostly a java shop ... and their retort is that [python is] not really enterprise ready
Yep. That sounds like the kind of nonsense people say in a Java shop.
Yes, but in return it will bring a 10x performance improvement in lots of areas, and the option of a whole lot more sturdy statically checked code.
mypy is a much better type system than Java, btw, if that's what you're after.
There are downsides though: type stubs are of... varying... quality, there are ugly hacks needed to resolve cyclic imports and the type annotation syntax gets yucky in places, even in 3.6.
I'm using mypy seriously for about a year and it's progressing very well. I see very good ROI even with the uglification of the code.
Haven't checked, but I find it absolutely possible that there's one (or more).
You say it as if that would be a strange position to be it, but it's a common situation. A lot of time you start with the faster to prototype / more familiar language, and outgrow it.
That's what companies do after they grow so much that a language such as Python/Ruby/PHP is not doing it for them anymore or wont be doing it soon with their growth trajectory.
And you don't have to be Twitter scale either.
Even if you have moderate growth, you might find that with a different language, you can use 1/10 the servers, and thus drastically lower your operating expenses.
So, when some of those companies face the jump to Python 3, and the required rewriting, they often decide to bite the bullet, and do a fuller rewriting in another language (like Java, but Golang is also getting many Python converts, including e.g. Dropbox IIRC), that will give them much more bang for their buck.
I know that a sibling mentions the ridiculousness of the situation, but a forced depreciation of the Python 2 runtime (see also, Windows) is a billable, justifiable, reason to do the work of refactoring parts of the system. I do not expect those billable hours to happen in the next decade, however.
Maybe one way of thinking about it is to take a hard drive full of data and randomly flip a few bits. Then ask what the effort is to find and fix all the errors, and whether this effort is a function of the number of bits flipped or the size of the drive. The people who don't understand/have sympathy with my concerns are saying -- it will only introduce a few breaking changes -- but I'm looking at the size of the project.
But this condescending attitude coming from some in the python community really isn't helping the language any. I am not saying that everyone has to share my concerns, but they certainly aren't "nonsense" or "ridiculous".
If your code base is a big pile with no tests.. well you dug that grave.
I'm sorry to be the one to break this to you friend, but you must be suffering from the Java shop version of Stockholm Syndrome.
Java contains a lot of ugly legacy bullshit because of that.
Joel Spolsky talks about this desire for artistic purity over useful backwards compatible cruft in a couple of nice essays:
https://www.joelonsoftware.com/2000/04/06/things-you-should-...
https://www.joelonsoftware.com/2004/06/13/how-microsoft-lost...
I hear some people really really prefer `print as statement`, but I've never seem them in real life.
I really hope someone makes this work. I literally laughed and thought that it was a troll the first time I saw the future print import and that being used as a compelling reason that I should switch to Py3.
print "Text",
For those not familiar with Python 2's syntax: that trailing comma is significant. And it's pure syntax; it's not the creation of a tuple either… print >>sys.stderr, "Spam"
Whereas in the new print function it's a keyword argument: print("Spam", file=sys.stderr) print(“Text”, end=“”)
is verbose. Not too verbose, but considering how often I write prints as temporary throwaway code, every little bit hurts…* I work a lot with low level data and I prefer strings to be an array of bytes. The forced unicode support is stupid for all my use cases. Also Unicode in 3.x support is rather flawed: http://www.cmlenz.net/archives/2008/07/the-truth-about-unico...
* Major APIs now return iterators or views instead of simple lists. This is rarely justified introduces unnecessary complication in many cases. Everybody knows list, why not keep it simple. I can't count how often I list() all the things just to get things going and because I didn't bother to look up the API to check what types are returned.
* I have to convert a lot of clear text data formats and needing to use 'print(x, end=" ")' instead of a simple 'print x,' is really cumbersome. I think printing something is absolutely substantial and it is justified for "print" be a statement.
* There is a distinct performance loss if you directly compare 3.x to 2.x at least for all my use cases.
* The sudden harsh break of backwards compatibility was completely unnecessary and stupid. Why not introduce new features slow and mark old features as deprecated or allow to specify the version in the header. There are a lot of ways one could handle this better.
* Python 3.x may be a marginally better (e.g more consitent) language than 2.x. For me it only introduces inconveniences. It takes a huge amount of effort to port code from 2.x to 3.x (if you want to keep it clean and readable). The practical benefits are close to zero (and you even loose performance). This is why the community seems to agree to stay with 2.x for a very long time.
bytes and bytearray are still there … if you don't want to work with unicode data in a proper Unicode type, you don't have to. But it doesn't follow that the rest of us that do want a good type for text shouldn't be able to have a good type / tooling for that.
(If you mean that functions that take text require text as input now, well, yeah.)
> Also Unicode in 3.x support is rather flawed
The entirety of "Internal Representation" is out of date, and no longer correct. For just about every other section, I believe libraries readily exist in PyPI to solve those problems. I do agree that it would be nice to have some of that closer to the standard library.
> I have to convert a lot of clear text data formats
I find it strange that you work with text formats, but you dislike having a proper text type? Even if you data were mostly or all ASCII, Python's text handling would still be mostly transparent, just silently doing the right thing if non-ASCII ever were encountered.
> I think printing something is absolutely substantial and it is justified for "print" be a statement.
I'm going to disagree. Python 2's print statements special syntax just adds cognitive load to reading, and to newcomers encountering such syntax, that just doesn't need to be there. Further, the trailing comma for "no EOL" is too subtle from a readability perspective.
> Major APIs now return iterators or views instead of simple lists. This is rarely justified introduces unnecessary complication in many cases.
The old APIs forced materialization of an iterable to a list, and there are plenty of circumstances where this just isn't required. This results in higher memory usage, for that list. The list() also makes it explicit where such materialization happen.
You can always get a list from an API/function that uses generators. You can't go the other way.
In my experience, the most you are doing is shifting around imports (urllib, for instance), declaring classes slightly differently, handling string encoding differently, or printing, format-ing, and raising exceptions slightly differently (and in a more sensible syntax for all, imo).
On the contrary, there are new modules that you are missing out on and you will regularly run into "it's in the stdlib" answers that are not applicable to you.
Anaconda Python really should be more popular on OS X and Linux than it is. Homebrew is okay, but a little bit wonky for Python packages.
I just tried again and saw an error similar to what I get when I try with pip+brew - ModuleNotFoundError: No module named 'PyQt4'.
Note, this is after spending quite a while installing/removing/upgrading various qt packages and dependencies to try to resolve this. The system might be in a weird state because of that - but I originally started from scratch and only followed the instructions I found on the matplotlib site...