5 ms·
I fully agree with the description. What worries me, though, is that the features that make Python quite good at prototyping make it rather bad at auditing for
by Yoric 4y ago
I fully agree with the description.
What worries me, though, is that the features that make Python quite good at prototyping make it rather bad at auditing for safety and security. And we live in a world in which production code is prototyping code, which means that Python code that should have remained a quick experiment – and more often than not, written by people who are not that good at Python or don't care about code quality – ends up powering safety/security-critical infrastructures. Cue in the thousands of developer-hours debugging or attempting to scale code that is hostile to the task.
I would claim that the same applies to JavaScript/Node, btw.
- awkward 4y agoWe still live in a world where many outward facing networked applications are written in C. Dynamic languages with safe strings are far from the floor for securable tools.
- Yoric 4y agoThat is true. However, I hope that these C applications are written by people who are really good at C. I know that some of these Python applications are written by people who discovered the language as they deployed into production.
- KyeRussell 4y agoThat’s a measure of programming prowess, not the actual security concern at hand. If the masterful C developer still insists on using a language that has so many footguns and a weird culture of developers pretending that they’re more capable than they are, then their C mastery could very well’ve not been worth much against someone throwing something together in Python, which will at the very least immediately bypass the vast majority of vulnerabilities found in C code. Plus, my experience with such software is that the sort of higher level vulnerabilities that you’d still see in Python code aren’t ones that the C developer has necessarily dealt with.
- deleted 4y ago[deleted]
- Yoric 4y agoThat's entirely possible. How could we check?
- osigurdson 4y agoHey, it is better than programs written as Excel functions.
- crispyambulance 4y agoIt is. But I fear that the same folks that decried the use of excel by "the masses" are now just as horrified by the widespread usage of Python! :-)
- di456 4y ago> the features that make Python quite good at prototyping make it rather bad at auditing for safety and security What's an example that makes it bad? Is it a case of the wrong tool for the job? For example I understand that garbage collection languages shouldn't be used with real time systems like flight controllers.
- syntheweave 4y agoWhat audits need most is some ability to analyze the system discretely and really "take it apart" into pieces that they can apply metrics of success or failure to(e.g. pass/fail for a coding style, numbers of branches and loops, when memory is allocated and released). Python is designed to be highly dynamic and to allow more code paths to be taken at runtime, through interpreting and reacting to the live data - "late binding" in the lingo, as opposed to the "early binding" of a Rust or Haskell, where you specify as much as you can up front and have the compiler test that specification at build time. Late binding creates an explosion of potential complexity and catastrophic failures because it tends to kick the can down the road - the program fails in one place, but the bug shows up somewhere else because the interpreter is very permissive and assumes what you meant was whatever allows the program to continue running, even if it leads to a crash or bad output later. Late binding is very useful - we need to assume some of it to have a live, interactive system instead of a punchcard batch process. And writing text and drawing pictures is "late binding" in the sense of the information being parsed by your eyes rather than a machine. But late binding also creates a large surface area where "anything can happen" and you don't know if you're staying in your specification or not.
- di456 4y agoInteresting. What kinds of software get this level of audit scrutiny?
- Yoric 4y agoThere are many examples, but let's speak for instance of the fact that Python has privacy by convention and not by semantics. This is very useful when you're writing unit tests or when you want to monkey-patch a behavior and don't have time for the refactoring that this would deserve. On the other hand, this means that a module or class, no matter how well tested and documented and annotated with types, could be entirely broken because another piece of code is monkey-patching that class, possibly from another library. Is it the case? Probably not. But how can you be sure? Another (related) example: PyTorch. Extremely useful library, as we have all witnessed for a few years. But that model you just downloaded (dynamically?) from Hugging Face (or anywhere else) can actually run arbitrary code, possibly monkey-patching your classes (see above). Is it the case? Probably not. But how can you be sure? Cue in supply chain attacks. That's what I mean by auditing for safety and security. With Python, you can get quite quickly to the result you're aiming for, or something close. But it's really, really, really hard to be sure that your code is actually safe and secure. And while I believe that Python is an excellent tool for many tasks, I am also something of an expert in safety, with some experience in security, and I consider that Python is a risky foundation to develop any safety- or security-critical application or service.
- dkarl 4y agoI sometimes think about what Python would be like if it were written today, with the hindsight of the last thirty years. Immutability would be the default, but mutability would be allowed, marked in some concise way so that it was easy to calculate things using imperative-style loops. Pervasive use of immutable instances would make it impossible for libraries to rely on mutating objects a la SQLAlchemy. The language would be statically type-checked, with optional type annotations and magic support for duck typing (magic because I don't know how that would work.) The type system would prioritize helpful, legible feedback, and it would not support powerful type-level programming, to keep the ecosystem accessible to beginners. It would still have a REPL, but not everything allowed in the REPL would be allowed when running code from a file. There would be a strong module system that deterred libraries from relying on global state. Support for at least one fairly accessible concurrency paradigm would be built in. I suspect that the error system would be exception-based, so that beginners and busy people could write happy path code without being nagged to handle error values and without worrying that errors could be invisibly suppressed, but there might be another way.
- deleted 4y ago[deleted]
- deleted 4y ago[deleted]
- jezzamon 4y agoI think free mutability and not really needing to know about types are two things that make the language easier for beginners. If someone who's not familiar with programming runs into an error like "why can't I change the value of X" that might take them multiple hours to figure out, or they may never figure it out. Even if the error message is clear, total beginners often just don't know how to read them and use them. They provide longer term advantages once your program becomes larger but the short term advantages are more important as a scripting language imo
- dkarl 4y agoThe type system I want would just be a type system that tells you that your code will fail, and why. Pretty much the same errors you get at runtime. Hence the need for my hypothetical type system to handle duck typing. I don't think mutability by default is necessary for beginners. They just need obvious ways of getting things done. There are two places beginners use mutability a lot. The first is gradual transformation of a value: line = "The best of times, the worst " line = line.trim() line = line[:line.find(' ')] This is easily handled by using a different name for each value. The second is in loops: word_count = 0 for line in lines(): word_count += num_words(line) I think in a lot of cases beginners will have no problem using a map or list comprehension idiom if they've seen examples: word_counts = [num_words(line) for line in lines] # or word_counts = map(num_words, line) word_count = sum(word_counts) But for cases where the immutable idiom is a bit tricker (like a complicated fold) they could use a mutable variable using the mutability marker I mentioned. Let's make the mutability marker @ since it tells you that the value can be different "at" different times, and let's require it everywhere the variable is used: word_count @= 0 for line in lines(): word_count @= word_count + num_words(line) Voila. The important thing is not to mandate immutability, but to ensure that mutability is the exception, and immutability the norm. That ensures that library writers won't assume mutability and rely on it (cough SQLAlchemy cough), and the language will provide good ergonomic support for immutability. It's a common claim that immutability only pays off in larger programs, but I think the mental tax of mutability starts pretty immediately for beginners. We're just used to it. Consider this example: dog_name = Name(first='Rusty', last='Licks') dog1.name = favorite_name dog_name.last = 'Barksalot' dog2.name = favorite_name print(dog1.name) # It's not Rusty Licks! Beginners shouldn't have to constantly wrestle with the difference between value semantics and reference semantics! This is the simplest possible example, and it's already a mind-bender for beginners. In slightly more complicated guises, it even trips up professionals programmers. I inherited a Jupyter notebook from a poor data scientist who printed out the same expression over and over again in different places in the notebook trying to pinpoint where and why the value changed. (Lesson learned: never try to use application code in a data science calculation... lol.) Reserving mutability for special cases protects beginners from wrestling with strange behavior from mistakes like these.
- wongarsu 4y agoA popular opinion in game development is that you should write a prototype first to figure out what works and is fun, and once you reach a good solution throw away that prototype code and write a proper solution with the insigts gained. The challenge is that many projects just extend the prototype code to make the final product, and end up with a mess. Regular sofware development is a lot like that as well. But you can kind of get around that by having Python as the "prototyping language", and anything that's proven to be useful gets converted to a language that's more useful for production.
- stevofolife 4y agoPython code can be production code. There are many people and companies shipping Python production code and generating substantial value.
- Yoric 4y agoYou are correct, there are absolutely huge companies shipping Python production code and generating substantial value. Do we agree that this somewhat orthogonal to what I'm writing, though?
- deleted 4y ago[deleted]