20 comments

[ 2.9 ms ] story [ 56.8 ms ] thread
This will add some overhead for every single call to such wrapped function. If you use that extensively for many classes, won't that be a huge performance degradation?

It would maybe be nice to have a flag so that these wrappings apply only in test or debug mode.

Also, it works e.g. by using `inspect.currentframe().f_back.f_back`. I'm not sure if that is such a clean and stable solution. (See e.g. here: https://github.com/amitassaraf/lang/blob/master/src/lang/acc...) E.g. when you add other wrappers around your function, I'm quite sure that this would break.

This is an impressive library, but I don't really see the usefulness. That is either because I'm a Python programmer, and Java semantics aren't useful in Python, or because I'm a Python programmer, and I haven't used Java semantics, so I wouldn't know.

I can say, though, that I've never had problems with something accessing private variables that it shouldn't have. The meaning of private variables in Python isn't "don't access anything that starts with an underscore", rather it's "you're accessing these variables at your own risk".

This "we're all adults" model has worked out very well for my use cases. Can anyone share a few cases where hard constraints here would be beneficial?

It feels like it might work better used as a test/verify step, but doesn't have the mechanics to be toggled on and off easily.

I can see the value in quickly knowing if new code is mucking with private/protected properties.

> I can see the value in quickly knowing if new code is mucking with private/protected properties.

Would this do it?

    re.findall(r'(?<!self)\._\w+', sourcelines)
Anytime you're using ``obj._foo`` and it's not ``self._foo`` that suggests you're mucking about with the internals of an object that the author didn't expect you to use.
That would miss some things, like iteration of all properties without a direct reference, subclasses accessing _Parent__private stuff, etc.

I'm not actively looking for a solution, just noting this might be more well received if you could easily turn it off and on.

Edit: Again, not looking for solutions. I thought the feedback of being able to turn it on/off might be useful for the OP.

Well, for your future reference, Pylint (https://www.pylint.org/) checks for that and many other common pitfalls. I'm sure its competitors PyChecker and Pyflakes do so as well.
I feel like this is the most anti-pythonic thing I've ever seen.
This _is_ the most anti-pythonic thing I've ever seen.
"After all, we're all consenting adults here."
This makes me a little sad. So, a few observations:

- The use of metaclasses for (almost?) every feature in this library makes it prone to metaclass conflicts. What if I want to inherit from two classes that use two different features from the library?

    >>> class MetaOne(type):
    ...     pass
    ...
    >>> class MetaTwo(type):
    ...     pass
    ...
    >>> class One(metaclass=MetaOne):
    ...     pass
    ...
    >>> class Two(metaclass=MetaTwo):
    ...     pass
    ...
    >>> class Both(One, Two):
    ...     pass
    ...
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    TypeError: metaclass conflict: the metaclass of a derived class must be a (non-strict) subclass of the metaclasses of all its bases
- I've never had a problem with other programmers accidentally changing my "constants" (eg. THE_THINGS_IN_ALL_CAPS) and I've never had a problem with other programmers accidentally changing my "private" attributes (eg. _prepended_with_underscore). Naming conventions are good enough for those purposes, in my experience.

- And when they're not, there's __name_mangling, which is sufficient to avoid the need for a 'final'. Compilers can make use of 'final', which is why final exists in Cython. I'm not sure the purpose in pure Python.

- There's no need for the distinction between an Abstract class and and Interface. Python already supports multiple inheritance of abstract classes.

A little off topic, but it's possible to automatically resolve metaclass conflicts in cases like this (e.g. construct a minimal suitable metaclass on the fly) :)
That's OK if the programmer who caused the conflict is the same person who decided to use this lib. If not, that'll be frustrating for one of the two.
An impressive effort. Nonetheless, I feel like it would be better to warn about these things via static analysis rather than enforcing at run time.
I agree - enforcing some of these best practices as a lint step would be more useful than crashing at run time. The benefit of these features in Java/C++ is that they catch problems at compile time.
I appreciate the work that went into this. But as a Python guy, this really seems like a solution in search of a problem--a problem that was already identified by the language and addressed.
"We're all consenting adults here" or at least that's what I like to believe...

So yeah, props for the effort, but I don't see it being actually used.

??? Go write Java if you want to write Java. Don't try to write Java with Python syntax. Use Python to write Python.

Trying to force the idioms of the programming language you just left onto the programming language you just learned is the classic sign of not having put any effort whatsoever into learning the idioms of the new programming language.

You lost me at the second sentence:

> Lang was built using a Java like mindset

I don't really understand why people want to make Python something which is not. Python is not Java, if you want to use Java constructs, use Java! That simple.

No, just no.

Being more like Java is about the last thing in the world python needs.

OP:

FYI This was just a fun thing to experiment with, never claimed this would be useful or is the right thing to use :)