
Lang: Python module for enforcing programming language constraints - amitassaraf
https://github.com/amitassaraf/lang
======
StavrosK
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?

~~~
tyingq
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.

~~~
msellout
> 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.

~~~
tyingq
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.

~~~
msellout
Well, for your future reference, Pylint
([https://www.pylint.org/](https://www.pylint.org/)) checks for that and many
other common pitfalls. I'm sure its competitors PyChecker and Pyflakes do so
as well.

------
msellout
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.

~~~
aldanor
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) :)

~~~
msellout
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.

------
luchadorvader
I feel like this is the most anti-pythonic thing I've ever seen.

~~~
czardoz
This _is_ the most anti-pythonic thing I've ever seen.

------
albertzeyer
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...](https://github.com/amitassaraf/lang/blob/master/src/lang/access.py))
E.g. when you add other wrappers around your function, I'm quite sure that
this would break.

------
ianamartin
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.

------
michaelhoffman
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.

~~~
rzimmerman
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.

------
dbcurtis
??? 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.

------
Walkman
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.

------
frnhr
"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.

------
amitassaraf
OP:

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

------
deeviant
No, just no.

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

