24 ms·
5% of 666 Python repos had comma typo bugs (inc V8, TensorFlow and PyTorch)
- TonyRobbins 5y ago
- einpoklum 5y agoI wonder how many of those 666 have syntax bugs which are _difficult_ to locate using code analysis tools, because they are legit in themselves and you need to know what the author meant to make the call.
- jiveturkey 5y agonice ad!
- asow92 5y agoI'm sure the devil is in the details on this bug.
- routerl 5y agotl;dr: Python concatenates space separated strings, so ['foo' 'bar'] becomes ['foobar'], leading to silent bugs due to typos. I've been bitten by this one at work, and can't help but think it is an insane behaviour, given that ['foo' + 'bar'] explicitly concatenates the strings, and ['foo', 'bar'] is the much more common desired result. edit: This also applies to un-separated strings, so ['foo''bar'] also becomes ['foobar']
- Palomides 5y agoI assume it's based on the C behavior, where it can be handy with macros I don't think it fits well in python
- pletnes 5y agoI assumed it was borrowed from shell, where everything can just be put next to eachother since it’s all text.
- pmontra 5y agoMaybe. We must remember that Python was designed at the very end of the 80s so what was normal for developers back then could be unexpected nowadays. An example: the self in Python's OO is a C pointer to struct of data and function pointers. It should be perfectly clear to anybody writing OO code in plain C at the time (rising hand.) Five years later new OO languages (Java, Ruby) kept self inside the classes but hide it in method definitions.
- wartijn_ 5y agoBut Python 3 was designed in the 2000s and had many breaking changes. Seems like they could have changed this behavior with that version.
- idealmedtech 5y agoIt's a holdover from C, where implicit string literal concatenation is very useful in the preprocessor.
- thrdbndndn 5y agoI luckily never accidently used this space-concatenation thing, but I've been bitten by the fact a=(1) doesn't create 1-element tuple multiple times in my early days learning Python.
- onphonenow 5y agoI still don't understand why it doesn't! So I still get bit from time to time.
- voussoir 5y agoIf a person decides to add parentheses to some booleans or arithmetic, (4 + 5) * (8 + 2) (this and that) or (theother) These elements should not become 1-tuples after the interior contents are evaluated. I sometimes add parentheses even around single variables just for visual clarity. Also, this allows you to do dot-access on int / float literals, if you want to # doesn't work 4.to_bytes(8, 'little') # works (4).to_bytes(8, 'little')
- int_19h 5y agoIn principle, a 1-tuple shouldn't even be a thing - any single value is a 1-tuple by itself already. However, in a dynamically typed language, this approach complicates things elsewhere - e.g. if you have a value / 1-tuple that is a list, you'd expect iteration over it to give you list elements, not the single element that is a list. But if you have a value that is a tuple of unknown size, you don't want to special-case iteration for when that size is 1.
- housecarpenter 5y agoIt depends what you mean by tuple. In Python, tuples are basically just immutable lists. Just as lists with 1 element are useful, so are tuples with 1 element. You might be dealing with a tuple of unknown length, where the length could be 1. In other contexts, the word "tuple" often carries the connotation of "having a known fixed length", in which case the notion of a 1-tuple as distinct from the value itself is less useful.
- prepend 5y agoThis seems like not a big deal. It’s a common mistake and is in 5% of repos but it’s not causing major damage. And there’s no evaluation of importance as to whether these instances are in test files or non-critical code. Packages are big and can have hundreds or thousands of files. It could be that if these mattered, they would have been detected and fixed. A good example for unit tests and perhaps checking to see if these bugs are covered or not covered. I like these kinds of analyses but don’t like the presented like it’s some significant failure.
- jollybean 5y ago5% of 'released' software is quite a lot, more importantly it's a class of errors that definitely should not exist. This is a 'bug' in the language effectively there just isn't any real upside. Python has a few of these things, which is really sad.
- bcrl 5y agoIt's a class of error that would be caught by even the most basic testing. A better title for the article is that 5% of 666 Python repos have typos that demonstrate the code in them that is completely untested. It doesn't matter which language it is: untested code is untested code in any language.
- rikatee 5y agounfortunately like 10% of the bugs were in the tests themselves. e.g., the sentry one https://codereviewdoctor.medium.com/5-of-666-python-repos-had-comma-typos-including-tensorflow-and-pytorch-sentry-and-v8-7bc3ad9a1bb7#15b3 https://codereviewdoctor.medium.com/5-of-666-python-repos-ha... the tests are only as good as the code they're written with, and as good as the code review process they were merged under.
- bcrl 5y agoOne of the habits I have when writing kernel code is to intentionally break code in the kernel to verify that my test is checking what I think it's checking. That's because of a lesson I learned a long, long time ago after someone reviewed my code and caught a problem: when your code has security implications, you need to make sure the boundary conditions that your tests are supposed to cover actually get tested. Having implemented a number of syscalls exposted to untrusted userland over the years, this habit has saved my bacon several times and avoided CVEs.
- karolkozub 5y agoI really like the idea of automated code review tools that point out unusual or suspicious solutions and code patterns. Kind of like an advanced linter that looks deeper into the code structure. With emerging AI tools like Github Copilot, it seems like the inevitable future. Programming is very pattern-oriented and even though these kinds of tools might not necessarily be able to point out architectural flaws in a codebase, there might be lots of low-hanging fruits in this area and opportunities to add automated value.
- lumost 5y agoConsider that you may be describing a compiler. Typos are not generally a problem in statically typed languages with notable exceptions such as dictionary key lookups etc. Even without static typing, argument length verification etc. can be done with a suitable compiler. In python we are left chasing 100% code coverage in unit tests as it's the only way to be certain that the code doesn't include a silly mistake.
- samhw 5y agoI think 100% code coverage is folly. Spreading tests so widely near-inevitably means they're also going to be thin. In any codebase I'm working on, I would focus my attention on testing functions which are either (a) crucially important or (b) significantly complex (and I mean real complexity, not just the cyclomatic complexity of the control flow inside the function itself).
- lumost 5y agoFully agree, but I never want to see a missed function argument programming error in customer facing code. In python you really do need code coverage to achieve this goal - static languages have some additional flexibility.
- lanstin 5y agoOr a rich suite of linters religiously applied. Never save a file with red lines in flymake or the equivalent. Ed: actually, I am unsure if my current suite would miss required parameters. I tend to have defaults for all but the first parameter or two, so not a big issue for me I guess. I do like a compile time check on stuff tho, one of the reasons I am doing more and more tools in Go.
- tyingq 5y agoSeems expected, as linters can't be sure when it's not intentional. Like this request to pylint: https://github.com/PyCQA/pylint/issues/1589 https://github.com/PyCQA/pylint/issues/1589 Is there usually enough context for a linter to make an educated guess?
- mikepurvis 5y agoI would have thought it would be a no-brainer to just ban it and insist on an explicit + operator. I'm pretty surprised that issue was so flippantly closed.
- thaumasiotes 5y ago> I would have thought it would be a no-brainer to just ban it and insist on an explicit + operator. Maybe as a matter of linting. As a matter of language design, I think + for string concatenation is a big mistake; using different symbols for numeric addition and string concatenation is something Perl got right.
- mikepurvis 5y agoYes, I meant as a matter of linting. I can understand the arguments being different for the language as a whole, particularly when legacy compatibility is a consideration. But my impression using pylint is that its default settings are wildly opinionated, hence the surprise that this wouldn't have fallen under that umbrella.
- ReleaseCandidat 5y agoThe PR has been merged (for lists and tuples and sets only). https://github.com/PyCQA/pylint/pull/1655 https://github.com/PyCQA/pylint/pull/1655
- rikatee 5y agocan do a good job at allowing long urls for example, but would be whack a mole trying to cater for "all" purposeful implicit string concatenations
- arusahni 5y agoThe removal of implicit string concatenation was proposed for Py3k[1], but was rejected. [1] https://www.python.org/dev/peps/pep-3126/ https://www.python.org/dev/peps/pep-3126/
- wodenokoto 5y agoThe rejection notice seems completely counter intuitive to me. How is adding a plus "harder" compared to removing a foot gun? > This PEP is rejected. There wasn't enough support in favor, the feature to be removed isn't all that harmful, and there are some use cases that would become harder.
- oa2022 5y agoThis change would break a lot of legacy code for no good reason The most common way to split a string in lines is using this concatenation formula.
- benesch 5y ago> This change would break a lot of legacy code for no good reason Preventing a bug that occurs in 5% of observed codebases (and anecdotally, happens to me during development all the time) seems like about as good as reasons get. Swapping a perfectly fine print statement for a function, on the other hand… that’s the breaking change in Py3k that’s never seemed worth it to me.
- aflag 5y agoI've never heard from Guido on this, but I've always felt that he created the print keyword in the very early days, just because it was easy and he always thought the language would be a niche small language. But, as the popularity of the language increased, the print keyword just stand out as a sore thumb and he just had to fix that.
- wodenokoto 5y agoBut wasn't this proposal part of the move to python 3? strings where broken left and right anyway.
- Forge36 5y agoI wonder if any of the found issues will turn out to be important issues.
- usrbinbash 5y agoLiterally the second item in the "Zen of Python" (https://www.python.org/dev/peps/pep-0020/ https://www.python.org/dev/peps/pep-0020/): Explicit is better than implicit. And yet, s = ["one", "two" "three"] will implicitly and silently do something, that is probably wrong most of the time.
- rat9988 5y agoThis is not what implicit is about.
- ianbicking 5y agoImplicit concatenation sure seems implicit to me
- jstx1 5y agoI mean the zen being wrong is kind of a meme at this point. The whole “only one obvious way to do it” isn’t just false but the exact opposite is true. Python is one of the most flexible languages with many many ways to do the same thing; more than any other language I can think of.
- fault1 5y agothe zen of python was written in the 90s. from that context it makes sense, because the only goal of python in the 1990s was to be more popular than perl, which was notorious in having many ways of doing the same thing. but yeah, python had had significant feature creep over the years, it's nowhere near the small clear lang it used to be.
- oaiey 5y agoI am a bit in shock. Accidental string concatenation. Python just lost a lot of reputation in my brain.
- ErikCorry 5y agoMisspelling a variable on the lhs of an assignment just causes a new variable to be created with the new name. That's a lot worse in my book.
- ReleaseCandidat 5y agoI'd say unexpected behavior is always worse than expected one. Yes, you'll certainly find somebody who doesn't know what 'not statically typed' means, but ... And yes, there are also C(++) users, that expect strings to be concatenated like that.
- obua 5y agoYou seem to also not know what "not statically typed" means. It certainly does not mean "not properly scoped".
- ReleaseCandidat 5y agoYes, of course. But you see that no scope keywords exist in Python. But there exists `+` to concatenate strings (too).
- fragmede 5y agoKeywords like namespace, no; but functions and classes and modules provide for a lot of scoping opportunities.
- ReleaseCandidat 5y agoThe problem is `fop` should be `foo`: foo = 5 fop = 6 Keywords like `let` solve this problem: let foo = 5 fop = 6 # error
- pmontra 5y agoAs a comparison, in Ruby puts "a" "b" == "ab" # true and puts "a" "b" == "ab" prints "a" with "b" == "ab" evaluated to false and discarded. This could create bugs as with Python. However ["a" "b"] == ["ab"] is syntax error at the beginning of the second line. The parser expects a ] It would evaluate to true if it were on one line.
- grey-area 5y agoIn Ruby one too many commas can also cause problems: # list list = "a","b", # function def foobar end => ["a", "b", :foobar]
- int_19h 5y agoI actually prefer Python approach here in that within () [] {} newlines are simply whitespace with no special meaning - this allows for very flexible formatting of expressions which is still unambiguous. The implicit concat of string literals is the culprit here. It really should require "+".
- kazinator 5y agoNot in Lisp! ("foo" "bar") and ("foobar") are lists of length 2 and 1, respectively. (Python copies some bad ideas from C. Another one is having to import everything you use. It seems that since Python is written in C, its designer took it for granted that there will be something analogous to #include for using libraries, even standard ones that come with the language.) Implicit string literal catenation is tempting to implement because it solves problems like: printf("long %s string" "nicely breaks up" "with indentation and all", arg, arg, ...) and if you're working in a language which has comma separation everywhere, you can get away with it easily. There are other ways to solve it. In TXR Lisp, I allow string literals to go across multiple lines with a backslash newline sequence. All contiguous unescaped whitespace adjacent to the backslash is eaten: This is the TXR Lisp interactive listener of TXR 273. Quit with :quit or Ctrl-D on an empty line. Ctrl-X ? for cheatsheet. TXR needs money, so even abnormal exits now go through the gift shop. 1> "abcd \ efg" "abcdefg" If you want a significant space, you can backslash escape it; the exact placement is up to you: 2> "abcd\ \ efg" "abcd efg" 3> "abcd \ \ efg" "abcd efg" 4> "abcd \ \ efg" "abcd efg" 5> "abcd \ \ \ efg" "abcd efg"
- lanstin 5y agoHaving everything be imported is what makes the language be useable. Especially if you never import * you can easily find the definition and meaning of everything you read on the screen. A prime example of explicit is better than implicit. And backslash doesn’t let you have the literal obey the proper indenting. Might as well use “””
- kazinator 5y ago> you can easily find the definition and meaning of everything you read on the screen I don't want to be finding definitions of things that the language provides in the code. Languages that don't work this way have IDE's, editor plug-ins or other tools for easily finding the definitions of things that are in the language, without hunting for them through intermediate definition steps in the same file. "I've spent all my life in and out of jails, so I expect bars on doors and windows ..."
- titzer 5y agoJust to be clear, the V8 "bug" was in the test runner code and caused mis-parsing of command line options for testing for non-SSE hardware. Not exactly a critical bug.
- jeffbee 5y agoThe way the bug arrived in that test runner is interesting. It sneaked in mid-review. Possibly bugs added in the middles of code reviews are more likely to get through. https://chromium-review.googlesource.com/c/v8/v8/+/2629465/3..5/tools/testrunner/base_runner.py https://chromium-review.googlesource.com/c/v8/v8/+/2629465/3... Personally, I prefer uniform lists with leading commas, because it's easier to add and remove lines for later, inevitable refactoring. For example, I prefer: things = [ 'foo' , 'bar' , 'baz' ] This drives some people crazy, but I think it's the One True Way.
- aflag 5y agoIsn't things = [ 'foo', 'bar', 'baz', ] even better? In your case, if you want to add something to the beginning of the list you'll have to modify two lines.
- jeffbee 5y agoDepending on the context, yes. But sometimes you are not allowed the last comma. ETA: Let me expand on why it's important to put the comma first. Which list is more clear to you: a , dog , weather , banana , b , car or a, dog, weather, banana, b, car With the leading commas, they all line up, and you can see them in a neat little row. I really prefer it especially in contexts where the trailing comma is not permitted, such as a SQL query: SELECT name , date , operation FROM stuff
- micimize 5y agoFor those looking to avoid this specific problem, there is a flake8 rule: https://pypi.org/project/flake8-no-implicit-concat https://pypi.org/project/flake8-no-implicit-concat. More broadly, the https://codereview.doctors https://codereview.doctors makers are making the point that their tool caught an easy-to-miss issue that most wouldn't think to add a rule for. A bit of an open question to me how many of those there really are at the language level, but still seems like a neat project.
- rikatee 5y agothere is also https://pypi.org/project/flake8-tuple/ https://pypi.org/project/flake8-tuple/ typo in the url (or in HN's markup) btw: it's https://codereview.doctor https://codereview.doctor
- oblvious-earth 5y agoAlso all but 1 of the issues they found relates to test code, it seems people are a little less careful compared to functional code. Also in terms of mistakes codereviewdoctor twice linked to the same issue in their blog https://github.com/tensorflow/tensorflow/issues/53636 https://github.com/tensorflow/tensorflow/issues/53636 and raised the PR to the wrong project https://github.com/tensorflow/tensorflow/pull/53637 https://github.com/tensorflow/tensorflow/pull/53637 (I guess Tensorflow vendors Keras, easy mistake)
- sundarurfriend 5y ago> all but 1 of the issues they found relates to test code, it seems people are a little less careful compared to functional code. Also a factor that bugs in functional code are more visible, both during development and to users once shipped. So there may have been an equal number or more such bugs in the non-test code, that just didn't remain in the code base for this long.
- thrdbndndn 5y agohttps://github.com/tensorflow/tensorflow/tree/0d8705c82c64dfb39c49e346de1a66182e5eabd1/tensorflow/python/keras#readme https://github.com/tensorflow/tensorflow/tree/0d8705c82c64df... STOP! This folder contains the legacy Keras code which is stale and about to be deleted. The current Keras code lives in github/keras-team/keras. Please do not use the code from this folder. Yeah, not the most obvious notice. The fact they didn't find the same mistake(s) in keras-team/keras (I assume they scanned, it's one of the most popular Python repo) makes me believe these issues have been fixed/removed in up-to-date karas repo.
- bilalq 5y agoThe whole "666" thing really threw me off. I thought it was some Python specific term or something at first glance. They open with a sentence that mentions "5% of the 666 Python open source GitHub repositories" as though there were only 666 total open source Python GH repos. Picking a number with other fun connotations or whatever to use as a sample is fine, but without setting that context, it was kind of distracting from their main content.
- deathanatos 5y agoDid you figure out what the context is, and if you did, would you mind spelling it out for me? I still haven't figured out what correction to make to that sentence to get it to make sense.
- rikatee 5y agoin a blog post about the evils of typos there was a typo! classic https://en.wikipedia.org/wiki/Muphry%27s_law https://en.wikipedia.org/wiki/Muphry%27s_law ;)
- ffhhj 5y agoAlso this classic: > Apple I was the first product ever announced by the company in 1976. The computer was put on sale for $666.66 at the time. https://9to5mac.com/2021/11/25/steve-woz-signs-rare-1976-apple-i-motherboard-in-dubai/ https://9to5mac.com/2021/11/25/steve-woz-signs-rare-1976-app...
- bilalq 5y agoThey ran their static analyzer over a sample of GH repos. They chose 666 as the number for their sample size. That's all.
- dudeinjapan 5y agoIt's further evidence that the Illuminati intentionally put these typo bugs there to destabilize the global order.
- aeturnum 5y agoThe high-level goals of python end up creating these little syntactic landmines that can get even experienced coders. My personal nomination for the worst one of these is that having a comma after a single value often (depending on the surrounding syntax) creates a tuple. It's easy to miss and creates maddening errors where nothing works how you expect. I've moved away from working in Python in general, but I think the #1 feature I want in the core of the language is the ability to make violating type hints an exception[1]. The core team has been slowly integrating type information, but it feels like they have really struggled to articulate a vision about what type information is "for" in the core ecosystem. I think a little more opinion from them would go a long way to ecosystem health. [1] I know there are libraries that do this, I am not seeking recommendations.
- macNchz 5y agoI’ve been writing Python professional full time for 8 years and still occasionally make the trailing-comma-tuple mistake. These days at least I’ll recognize and be able to find it quickly rather than wasting time. Can be caught with a linter, but not every codebase is readily linted.
- aylmao 5y agoThe lack of a static type-system is IMO what makes these one-character mistakes very annoying. The compiler can't tell you something is wrong, so you're just left to figure out why things are broken, just to realize it was the smallest of typos.
- aeturnum 5y agoI love how simple and forgiving Python is for small projects. The "trailing comma creates a tuple" situation comes out of, as far as I can tell, a desire to create maximally convenient syntax in the scenarios where tuples are intended. I think that's great for small code! I just wish that the core team would take that same zeal for a "pythonic" experience with small code and use it to develop more scaled-up systems for dealing with larger code bases. My idea is to enforce strong pre-conditions on function calls using type hints, but I am sure there are other ways to do it.
- wartijn_ 5y agoI like this. It's clearly meant as marketing for their product, but imo the best kind of marketing. They don't just run their tool and automatically make tickets, but check for false positive and (offer to) make pr's. It's both good for those projects and for the company that does the marketing since they reach there exact target group. Plus it gets them on the front page of HN.
- ehsankia 5y agoA great addition to prune a ton of false-positives is to check the length of the strings. Almost always, the intentional implicit concats will have a very long string that reaches the max line length, whereas the accidental ones are almost always very short strings.
- tus666 5y agoAlternative title: 5% of Python repos has inadequate test coverage.
- _dain_ 5y agoMost of the errors were in the tests themselves.
- wirthjason 5y agoIronic to see this today. I spent an hour debugging this very same issue this morning. I was just doing some simple refactoring, changing a hard coded sting into a parameterized list of f-strings that’s filtered and joined back into a string. I’m glad that I had unit tests that caught the problem! I couldn’t figure out why it was breaking, that comma is very devilish to spot with the naked eye. I’m surprised my linters didn’t catch it either. Maybe time to revisit them.
- shoyer 5y agoMost of the "bugs" caught here (including in TensorFlow and in my own project, Xarray) seems to actually be typos in the test suite. This is certainly a good catch (and yes, linters should check for this!), but seems a little oversold to me.
- chillee 5y agoSame :P I'm actually responsible for one of these (https://github.com/pytorch/pytorch/issues/70607 https://github.com/pytorch/pytorch/issues/70607), but it's a typo in a list of tests to skip.
- hvdijk 5y agoA typo in a list of tests to skip means tests are run that are not intended to be run. This can lead to unexpected failures, so in my opinion is not the same as the errors in test suites where tests run with other test data than intended but should still pass.
- ehsankia 5y agoNice! Internally we have a PCRE support on our code search and I regularly run a regex to find and fix these. I've also found a ton on opensource project which I've been trying to fix: https://github.com/YosysHQ/prjtrellis/pull/176 https://github.com/YosysHQ/prjtrellis/pull/176 https://github.com/UWQuickstep/quickstep/pull/9 https://github.com/UWQuickstep/quickstep/pull/9 https://github.com/tensorflow/tensorflow/pull/51578 https://github.com/tensorflow/tensorflow/pull/51578 https://github.com/mono/mono/pull/21197 https://github.com/mono/mono/pull/21197 https://github.com/llvm/llvm-project/pull/335 https://github.com/llvm/llvm-project/pull/335 https://github.com/PyCQA/baron/pull/156 https://github.com/PyCQA/baron/pull/156 https://github.com/dagwieers/pygments/pull/1 https://github.com/dagwieers/pygments/pull/1 https://github.com/zhuyifei1999/guppy3/pull/12 https://github.com/zhuyifei1999/guppy3/pull/12 https://github.com/pyusb/pyusb/pull/277 https://github.com/pyusb/pyusb/pull/277 https://github.com/KhronosGroup/Vulkan-ValidationLayers/pull/1293 https://github.com/KhronosGroup/Vulkan-ValidationLayers/pull... It is indeed a very common mistake in Python, and can be very hard to debug. It bit me once and wasted a whole day for me, so I've been finding/fixing them ever since trying to save others the same pain I went through. EDIT: I will point out that I've found this error in other non-Python code too, such as c++ (see the 2nd PR for example). Here's the regex for anyone curious: [([{]\s*\n?(\s*['"](\w)+['"],\n)+(\s*['"]\w+['"]\n)(\s*['"]\w+['"],\n)*
- ficklepickle 5y agoIronically there are a variety of typos in the article. A paragraph is repeated and the markdown links at the end are broken because there is a space between ] and (.
- Pensacola 5y agoWhy 666?
- aflag 5y agoIt's a biblical number. No deeper meaning.
- codeptualize 5y agoAnd then people make fun of JavaScript! (Just joking, I like Python, also JS, I guess everything has its quirks, it's a good thing we have linters)
- dannymi 5y agoI can see the value of a lint (if there's a newline without a comma, warn), but concatenating strings by multiplication is the correct thing to do (since it's also used this way in mathematics of parsers). Using the plus operator to concatenate strings is just weird. Think of the usual algebraic properties these operators are supposed to have. "+" always is supposed to be commutative--so "a"+"b" = "b"+"a", if those mean alternatives (they usually do mean that in mathematics), is just fine. On the other hand, multiplication is often not commutative--also not here. "a" "b" != "b" "a". So string concatenation should be the latter. And indeed that's how it's in regular expression mathematics for example.
- hayd 5y agoWhich invertible commutative string operation would you choose for + ? This might be nice from a math point of view, but I think users are going to be confused using "string"^3 for repetitions (instead of "string"*3). + and * make too much sense to the unwashed masses. At any rate, explicit is better than implicit.
- dragonwriter 5y agoThere is no reason you couldn't use str * str for concatenation and str * integer (or even string * real) repetition. Well, except if you wanted to support user classes that could duck type as both strings and numbers, which it would make awkward.
- int_19h 5y agoJuxtaposition is not multiplication in this context - you can't write (2 3), for example, it has to be (2 * 3). Furthermore, Python already uses * for strings to indicate repetition: ("foo" * 2 == "foofoo"). String concatenation really just needs its own separate operator. & is an obvious candidate, if only it wasn't so commonly appropriated for bitwise AND - which is a very poor use of a single-char operator as it's not something that you need often, especially in a language like Python. On the other hand, D uses binary ~ for concatenation. That has a neat mnemonic: it's a "rope" that "ties strings together".
- Subsentient 5y agoInteresting. I've hit this bug before, but not often in Python as far as I can remember. I guess if I need a huge list of something, I'm more likely to look to a dict than use a list with normal indexes.
- gumby 5y agoClearly bugs by programmers who don’t adhere to the Oxford comma.
- xvilka 5y agoPython was never supposed to be a language for anything more complex than basic scripting and prototyping. Use proper languages with static typing (and better speed) for anything serious. And no, JavaScript isn't a good language either.
- hesdeadjim 5y agoYea, but TDD! :eyeroll:
- the_gigi 5y agoI often use split(). Instead of: s = ['a', 'b', 'c'] I'll type: s = 'a b c'.split() For multiline lists where I want to get rid of leading whitespace I'll add lstrip(): lines = """line 1 line 2 line 3 """.split('\n') lines = [line.lstrip() for line in lines]
- timzaman 5y agoHaha the bug in Tensorflow is in "tensorflow/tensorflow/python/keras/engine/training_generator_test.py". clickbait.
- anonymousiam 5y agoHeh. "cromulent" again. ..."there are perfectly cromulent reasons a developer would do implicit string concatenation spanning multiple lines"... https://www.merriam-webster.com/words-at-play/what-does-cromulent-mean https://www.merriam-webster.com/words-at-play/what-does-crom...
- LAC-Tech 5y agoA lot of people are criticising dynamic typing for this. It doesn't seem to have anything to do with typing discipline. words = ( 'yes', 'correct', 'affirmative' 'agreed', ) Would be a tuple (immutable list) of strings, while words = ( 'yes', 'correct', 'affirmative', 'agreed', ) would also be a tuple of strings. If haskell had for some reason decided to have the same syntax sugar, it also would have caused an issue.
- motles 5y agoYou got me for a second there.
- pxeger1 5y agoThe first one, the implicit concatenation, I can see. But the rest of the things seem like most of the time they're intentional. { 'key': ( 'long string long string long string' ) } Using parentheses like this to put long strings on their own line is standard practice. title = 'Hello world', I, for one, have often used this deliberately.
- deleted 5y ago[deleted]
- delgaudm 5y agoWhen I used to write code, especially SQL statements I would: "put" , "Commas" , "first" , "to" avoid these kinds of things.
- dragonwriter 5y agov8 may be a repo that includes some Python, but there is no reasonable standard by which it is a “Python repo”.