I wouldn't call it 'traps'. I would call it 'read and understand documentation before writing code' like: what is 'is' operator, or how floats behave in EVERY programming language, or why you should sanitize EVERY user input. So, basically, I can write such a list for every language I know.
which is great and you totally should. not everyone knows about those things.
A bite of Python
21–30 of 168 posts
Re: A bite of Python
#22The feature is just some syntactic sugar.
When within a class, private fields such as:
class Foo:
def __init__(self):
self.__bar
are accessible from within other methods of class Foo as `self.__bar`. But that's just syntactic sugar, the real name of `self.__bar` is `self._Foo__bar`.So from the outside "world", including `hasattr()`, you can still access `self.__bar` as `Foo()._Foo__bar`.
>>> class Foo():
... def __init__(self):
... self.__bar = 'hello'
... def show(self):
... print(1, self.__bar)
... print(2, getattr(self, '__bar'))
...
>>> foo = Foo()
>>> foo._Foo__bar
True
>>> foo.show()
1 hello
Traceback (most recent call last):
File "", line 1, in
File "", line 6, in show
AttributeError: 'Foo' object has no attribute '__bar'
>>> foo.__bar = 'world'
>>> foo.show()
1 hello
2 world
In the end, when `x.__private` is setup outside of the class definition, obviously, it's a new member as its name differs from the internal name `__private` (which really is `_X__private`).From within the code doing `getattr('X', '__private')` will return the `__private` setup from outside the class, and `getattr('X', '_X__private')` the one defined from within the class.
The whole point of that feature is to ensure that members defined within a class that are not part of the public API are left untouched when that class get subclassed, to avoid unexpected behaviours.
Here's an example of why this has been designed:
>>> class A:
... def __init__(self):
... self.__internal = "this is a"
... def show(self):
... print(1, "A", self.__internal)
...
>>> class B(A):
... def __init__(self):
... super(B, self).__init__()
... self.__internal = "this is b"
... def show(self):
... super(B, self).show()
... print(2, "B", self._A__internal)
... print(3, "B", self.__internal)
...
>>> B().show()
1 A this is a
2 B this is a
3 B this is b
>>>
There's nothing that should be surprising or asymmetrical to anybody who've read the python documentation, and use that feature appropriately. It's maybe a weird feature, but it's still a coherent and homogeneous behaviour and actually adding more safety to codes.Documentation references:
* https://docs.python.org/3/faq/programming.html#i-try-to-use-spam-and-i-get-an-error-about-someclassname-spam
* https://docs.python.org/3/reference/expressions.html#atom-identifiersRe: A bite of Python
#23The part of the article about an issue with name mangling of private fields is somehow misleading. The feature is just some syntactic sugar. When within a class, private fields such as: class Foo: def __init__(self): self.__bar are accessible from within other methods of class Foo as `self.__bar`. But that's just syntactic sugar, the real name of `self.__bar` is `self._Foo__bar`. So from the outside "world", includin…
Re: A bite of Python
#24Earlier quoted context omitted.
> Assert is primarily meant to be documentation of constraints in code Real or imagined constraints? AFAICT, an assert only tells me what you wish your program did, but that has absolutely no bearing on what it will actually do.
Neither "real" nor "imagined". An asserts checks DESIRED constraints. > AFAICT, an assert only tells me what you wish your program did, but that has absolutely no bearing on what it will actually do. Depending on the implementation, an assert can either merely log or absolutely stop a program that doesn't pass its test, so it very much has a bearing on what the program will actually do.
Then imagined it is. Your desires are totally a part of your imagination, unless you make them become real.
> Depending on the implementation, an assert can either merely log or absolutely stop a program that doesn't pass its test, so it very much has a bearing on what the program will actually do.
Point taken. Unfortunately, logging errors or aborting the program won't make assertions magically become true, though.
Re: A bite of Python
#25I wouldn't call it 'traps'. I would call it 'read and understand documentation before writing code' like: what is 'is' operator, or how floats behave in EVERY programming language, or why you should sanitize EVERY user input. So, basically, I can write such a list for every language I know.
Relying on developers to read and remember every bit of documentation for every bit of code is more likely to end up with insecure code compared to introducing sane defaults with an explicit, expressive API.
This can be said for every industry involving people.
Re: A bite of Python
#26The part of the article about an issue with name mangling of private fields is somehow misleading. The feature is just some syntactic sugar. When within a class, private fields such as: class Foo: def __init__(self): self.__bar are accessible from within other methods of class Foo as `self.__bar`. But that's just syntactic sugar, the real name of `self.__bar` is `self._Foo__bar`. So from the outside "world", includin…
Two spaces indentation will give you the proper rendering for code snippets.
Re: A bite of Python
#27The part of the article about an issue with name mangling of private fields is somehow misleading. The feature is just some syntactic sugar. When within a class, private fields such as: class Foo: def __init__(self): self.__bar are accessible from within other methods of class Foo as `self.__bar`. But that's just syntactic sugar, the real name of `self.__bar` is `self._Foo__bar`. So from the outside "world", includin…
Re: A bite of Python
#28The behavior of 'assert' is not an anomaly. It comes from 'design by contract.' Assert is primarily meant to be documentation of constraints in code and secondarily a way of catching errors during development. "Contract conditions should never be violated during execution of a bug-free program. Contracts are therefore typically only checked in debug mode during software development. Later at release, the contract che…
It's not an anomaly, but it can be a surprise for people who don't understand what it does. For example, they use asserts for validation and then the validation doesn't work in production. It's absolutely right the way it works, but it's still a gotcha for the audience this blog post is aimed at.
Would be nice if they had a pointer to the reason, however.
Re: A bite of Python
#29Some points are valid, but come on, if an attacker has write access to your code, you can't recover from that, ever.
Why is this relevant for this article? The article doesn't say anything about attackers having write access to the source.