[Python-ideas] Re: Add support for private variables, methods and functions in Python

2021-05-05 Thread Serhiy Storchaka
05.05.21 17:18, Shreyan Avigyan пише:
> I don't know if it's worth adding private to python modules but what about 
> classes? Private in class is an important feature in OOP that Python lacks 
> (Most OOP languages have private like Java, C++, etc.). I don't know why it 
> was introduced in the first place but it's kind of a convention to have that 
> feature in OOP.

Private fields in Python are no less private than in C++. In C++ you can
read private fields:

class User {
  public:
string name;
  private:
string password;
};

class HackedUser {
  public:
string name;
string password;
};

password = ((HackedUser*)&user)->password;

Of course it is a bad practice. You should not write this in your code,
and if your code allows executing arbitrary code in the same address
space, your security is already gone.

And the same is in Python. You can access private attributes, but
usually you should not (except for debugging purpose).

> Moreover why does private exist in the first place? If there's a reason then 
> shouldn't it apply to Python as well.

Private exists as a mean of self-limitation. It allows you to separate
your data and code on these which are purposed to be used outside of the
module or the class, and these which aren't. For your own good you must
follow this convention. The same reasons are applied to both C++ and
Python. It is more complicated in Java, but its security model is not
perfect in any case, and Python prefers the convenience of debugging and
simplicity of implementation.

___
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at 
https://mail.python.org/archives/list/python-ideas@python.org/message/6ITKZ45ZCUCWJVMPGVJJSDEXQ4TFZWQK/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: Support more conversions in format string

2021-05-05 Thread Cameron Simpson
On 06May2021 03:43, Dennis Sweeney  wrote:
>Maybe I'm missing something, but why do you need the SimpleNamespace at all? 
>Why not make your own mapping as in
>
>class StringMapper:
>...
>def __getitem__(self, s):
># Whatever arbitrary behavior you want
># Process suffixes, etc here, for example:
>if s.endswith(".lc"):
>return self.wrapped[s.removesuffix(".lc")].lower()
>return self.wrapped[s]
>
>   format_string.format_map(StringMapper(whatever))
>
>Maybe then the data can just be data and this wrapper can handle all 
>the formatting conversions.

All this is somewhat orthoganal to adding more !foo things.

If we're not talking about extending the conversions, we should probably 
take this over to python-list, because the ":foo" stuff is just 
implementation.

That said, because my tags can have dots in their names and I want to be 
able to write:

{tag.name.with.dot}

and this is accomplished with an elaborate SimpleNamespace subclass to 
make the .name.with.dot stuff work as attributes.  Just don't ask :-( 
Oh, you did :-)

Anyway, I may be shifting sideways per my recent ":foo" post, using a 
new class which is a magic view of the TagSet and a Formatter subclass 
which parses the field_names itself (thus grabbing the dotted 
identifier). Still a work in progress.

Cheers,
Cameron Simpson 
___
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at 
https://mail.python.org/archives/list/python-ideas@python.org/message/WTCYMJAHIRDGPJCS4UDZRBCIHOWKDTJ7/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: Support more conversions in format string

2021-05-05 Thread Dennis Sweeney
Maybe I'm missing something, but why do you need the SimpleNamespace at all? 
Why not make your own mapping as in

class StringMapper:
...
def __getitem__(self, s):
# Whatever arbitrary behavior you want
# Process suffixes, etc here, for example:
if s.endswith(".lc"):
return self.wrapped[s.removesuffix(".lc")].lower()
return self.wrapped[s]
 
   format_string.format_map(StringMapper(whatever))


Maybe then the data can just be data and this wrapper can handle all the 
formatting conversions.
___
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at 
https://mail.python.org/archives/list/python-ideas@python.org/message/RDS4KL7SUAP4AAA2XVBZTM5SZE4NUU46/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: Support more conversions in format string

2021-05-05 Thread Cameron Simpson
On 25Apr2021 10:54, Cameron Simpson  wrote:
>On 24Apr2021 22:35, Stephen J. Turnbull  
>wrote:
>[...]
>> > My use case is presupplied strings, eg a command line supplied
>> > format string.
>>
>>In that case the format string is user input, and x is a variable in
>>the program that the user can have substituted into their string?
>>
>>Assuming that *exact* use case, wouldn't
>>
>>>>> class LowerableStr(str):
>>...  def __format__(self, fmt):
>>...   if fmt == 'lc':
>>...return self.lower()
>>...   else:
>>...return str.__format__(self, fmt)
>>...
>>>>> "{x} is {x:lc} in lowercase".format_map({'x' : LowerableStr("This")})
>>'This is this in lowercase'
>>
>>do?
>
>You're perfectly correct. ":lc" can be shoehorned into doing what I ask.
>But __format__ is in the wrong place for how I'd like to do this.

Just to follow up on this, I've been experimenting with Stephen's 
suggestion of using ":foo" style format specifiers. With enough success 
that I'm probably going to run with it is I can make the implementation 
clean enough.

I'm currently making a subclass of the Formatter builtin class, which 
supplies the string parser and lets one override various methods to 
implemenent the "{...}" parts.

Currently I can do this:

I've got a little ontology, saying that a tag named "colour" is "a 
colour, a hue" and expects to be a Python str.

It also has metadata for the particular colour "blue".

{ 'type.colour': TagSet:{'description': 'a colour, a hue', 'type': 'str'},
  'meta.colour.blue': TagSet:{'url': 'https://en.wikipedia.org/wiki/Blue', 
'wavelengths': '450nm-495nm'}
}

And I've got a tag set describing some object which is blue:

{'colour': 'blue', 'labels': ['a', 'b', 'c'], 'size': 9}

The TagSet class has a .format_as(format_string) method which hooks into 
the Formatter subclass and formats a string according to the TagSet.

A little test programme to write information into some command line 
supplied format strings:

[~/hg/css-tagsets(hg:tagsets)]fleet2*> py3 -m cs.tagset '{colour}' 
'{colour:meta}' '{colour:meta.url}'
{colour}
=> 'blue'
{colour:meta}
=> 'url="https://en.wikipedia.org/wiki/Blue"; wavelengths="450nm-495nm"'
{colour:meta.url}
=> 'https://en.wikipedia.org/wiki/Blue'

Looking promising to me.

Cheers,
Cameron Simpson 
___
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at 
https://mail.python.org/archives/list/python-ideas@python.org/message/GGLPSQBFWM6FDR3DYEHSYSMGEBD5DBNU/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: Add support for private variables, methods and functions in Python

2021-05-05 Thread Steven D'Aprano
Hi Shreyan,

You say:

On Wed, May 05, 2021 at 02:18:55PM -, Shreyan Avigyan wrote:

> I don't know if it's worth adding private to python modules but what 
> about classes? Private in class is an important feature in OOP that 
> Python lacks (Most OOP languages have private like Java, C++, etc.). I 
> don't know why it was introduced in the first place but it's kind of a 
> convention to have that feature in OOP.

If you don't know why private was introduced, what makes you think it is 
a good feature to have?

Programmers in languages with "private, protected" etc usually end up 
spending large amounts of time fighting with the compiler, because some 
over-zealous other programmers made things private that shouldn't have 
been.

Python finds a nice middle ground between languages which offer no 
protection and those that encourage too much unnecessary protection. We 
have a very strong convention not to rely on or use other people's 
underscore variables, while still allowing people to inspect and even 
modify those variables if necessary; but if you really, truly want to 
hide the existence of class attributes you can write the class in C.

Explain to us, what *exactly* are you worried about? Suppose you write a 
class, and have an underscore private attribute or method:

class MyClass:
def __init__(self):
self._spam = 1


Now what? What are you worried about happening if somebody else gets 
access to your code, say they download it from Github or something, and 
use that private attribute?

What harm are you trying to prevent?


-- 
Steve
___
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at 
https://mail.python.org/archives/list/python-ideas@python.org/message/QO6CJ6ZQRWN2TOBBEPA3H3RVZ3F5MU4P/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: Changing The Theme of Python Docs Site

2021-05-05 Thread Neil Girdhar
I agree with the comment about removing full justification.

Also, I think the Masonite docs' navigation is far superior to the Python 
docs.  I like the full contents on the left, along with the version button, 
and the local jump on the right.  The python docs require you to navigate 
somehwere else for the full contents.  And, I don't undrstand why anyone 
would want "previous topic/next topic"—it's not like you're curling up with 
the Python docs before bed :)

Finally, putting the docs in the center of the screen is better on today's 
giant monitors.



On Tuesday, May 4, 2021 at 11:21:48 PM UTC-4 Jonathan Goble wrote:

> On Tue, May 4, 2021 at 11:05 PM Mike Miller  
> wrote:
>
>> One  thing  that  drives me  nuts  about  the current  Python  docs  
>> theme  is
>> the FULL  JUSTIFICATION that  adds random  spaces into  each  line to 
>> make the
>> edges   line  
>>  up!
>>
>> Whatever y'all do, please remove that. :D  I sometimes deactivate it in 
>> the 
>> browser dev tools but there it is again next refresh.
>>
>
> Please. Full justification is nice with narrow columns like newspapers, 
> but on the web with wider paragraphs, it's annoying. I'd love to see it 
> yanked from the Python docs.
>
___
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at 
https://mail.python.org/archives/list/python-ideas@python.org/message/ISTQ4PLQ3TNLXXL5BRWWJLI5PIDAGD33/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: Namespaces!

2021-05-05 Thread Wes Turner
On Wed, May 5, 2021, 02:11 Steven D'Aprano  wrote:

> My comments follow, interleaved with Matt's.
>
>
> On Mon, May 03, 2021 at 11:30:51PM +0100, Matt del Valle wrote:
>
> > But you've pretty much perfectly identified the benefits here, I'll just
> > elaborate on them a bit.
> >
> > - the indentation visually separates blocks of conceptually-grouped
> > attributes/methods in the actual code (a gain in clarity when code is
> read)
>
> Indeed, that is something I often miss: a way to conceptually group
> named functions, classes and variables which is lighter weight than
> separating them into a new file.
>
> But you don't need a new keyword for that. A new keyword would be nice,
> but grouping alone may not be sufficient to justify a keyword.
>
>
> > - the dot notation you use to invoke such methods improves the experience
> > for library consumers by giving a small amount conceptually-linked
> > autocompletions at each namespace step within a class with a large API,
> > rather getting a huge flat list.
>
> We don't need a new keyword for people to separate names with dots.
>
> Although I agree with your position regarding nested APIs, *to a point*,
> I should mention that, for what it is worth, it goes against the Zen:
>
> Flat is better than nested.
>
>
> [...]
> > - you can put functions inside a namespace block, which would become
> > methods if you had put them in a class block
>
> This is a feature which I have *really* missed.
>
>
> > - you don't have the same (in some cases extremely unintuitive)
> > scoping/variable binding rules that you do within a class block (see the
> > link in my doc). It's all just module scope.
>
> On the other hand, I don't think I like this. What I would expect is
> that namespaces ought to be a separate scope.
>
> To give an example:
>
> def spam():
> return "spam spam spam!"
>
> def eggs():
> return spam()
>
> namespace Shop:
> def spam():
> return "There's not much call for spam here."
> def eggs():
> return spam()
>
> print(eggs())
> # should print "spam spam spam!"
> print(Shop.eggs())
> # should print "There's not much call for spam here."
>
>
> If we have a namespace concept, it should actually be a namespace, not
> an weird compiler directive to bind names in the surrounding global
> scope.
>

I agree with this. Great proposal though.


>
> > - it mode clearly indicates intent (you don't want a whole new class,
> just
> > a new namespace)
>
> Indeed.
>
>
> > When using the namespaces within a method (using self):
> >
> > - It allows you to namespace out your instance attributes without needing
> > to create intermediate objects (an improvement to the memory footprint,
> and
> > less do-nothing classes to clutter up your codebase)
> >
> > - While the above point of space complexity will not alway be relevant I
> > think the more salient point is that creating intermediate objects for
> > namespacing is often cognitively more effort than it's worth. And humans
> > are lazy creatures by nature. So I feel like having an easy and intuitive
> > way of doing it would have a positive effect on people's usage patterns.
> > It's one of those things where you likely wouldn't appreciate the
> benefits
> > until you'd actually gotten to play around with it a bit in the wild.
>
>
> I'm not entirely sure what this means.
>
>
> > For example, you could rewrite this:
> >
> > class Legs:
> >   def __init__(self, left, right):
> >   self.left, self.right = left, right
> >
> >
> > class Biped:
> > def __init__(self):
> > self.legs = Legs(left=LeftLeg(), right=RightLeg())
> >
> >
> > As this:
> >
> > class Biped:
> > def __init__(self):
> > namespace self.legs:
> > left, right = LeftLeg(), RightLeg()
>
>
> Oh, I hope that's not what you consider a good use-case! For starters,
> the "before" with two classes seems to be a total misuse of classes.
> `Legs` is a do-nothing class, and `self.legs` seems to be adding an
> unnecessary level of indirection that has no functional or conceptual
> benefit.
>
> I hope that the purpose of "namespace" is not to encourage people to
> write bad code like the above more easily.
>
>
> > And sure, the benefit for a single instance of this is small. But across
> a
> > large codebase it adds up. It completely takes away the tradeoff between
> > having neatly namespaced code where it makes sense to do so and writing a
> > lot of needless intermediate classes.
> >
> > SimpleNamespace does not help you here as much as you would think because
> > it cannot be understood by static code analysis tools when invoked like
> > this:
> >
> > class Biped:
> > def __init__(self):
> > self.legs = SimpleNamespace(left=LeftLeg(), right=RightLeg())
>
> Surely that's just a limitation of the *specific* tools. There is no
> reason why they couldn't be upgraded to understand SimpleNamespace.
>
>
> [...]
> > > 2. If __dict__ contains "B.C" a

[Python-ideas] Re: Add support for private variables, methods and functions in Python

2021-05-05 Thread Shreyan Avigyan
See my comment here - 
https://mail.python.org/archives/list/python-ideas@python.org/message/L5LUQDNNV5ZTF4E33L2JSOYIKPJUJJK5/
___
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at 
https://mail.python.org/archives/list/python-ideas@python.org/message/P5SBXBPZAXKHY75KKXWIAKPPSKGCYC3I/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: Add support for private variables, methods and functions in Python

2021-05-05 Thread Shreyan Avigyan
I don't know if it's worth adding private to python modules but what about 
classes? Private in class is an important feature in OOP that Python lacks 
(Most OOP languages have private like Java, C++, etc.). I don't know why it was 
introduced in the first place but it's kind of a convention to have that 
feature in OOP. Moreover why does private exist in the first place? If there's 
a reason then shouldn't it apply to Python as well. 

And yes you're right the unprivileged code can just do the same thing. But I'm 
not only speaking of security in this context.
___
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at 
https://mail.python.org/archives/list/python-ideas@python.org/message/L5LUQDNNV5ZTF4E33L2JSOYIKPJUJJK5/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: Add support for private variables, methods and functions in Python

2021-05-05 Thread Stestagg
One issue with many common programming languages is that they appear to
offer access protections via private/protected etc, but seldom do so
securely (`private` modifiers are never, to my knowledge, intended to be a
security mechanism).

/
Take for example C++:
#include 
#include 

class Secrets {

private:
const std::string password;

public:
Secrets(const char * password): password(password) {}
};

void consumer(Secrets &sec) {
  auto haxor = (const char *)&sec;
  for (size_t i=0; i<32; ++i) {
 std::cout << haxor + i << std::endl;
  }
}

int main() {
  Secrets sec("5exret_Paxxw0rd");
  consumer(sec);
  return 0;
}
/

It's fairly trivial to bypass the `private` access modified for member
variables by reading the memory directly.  Even with heap-allocated
structures, this is not much harder to do.

Likewise for Java:
///
import java.lang.reflect.Field;
import java.lang.NoSuchFieldException;

class MyClass {
private String password;
MyClass(String password) {
this.password = password;
}
}

class Test {
public static void main(String[] a) {
  MyClass mc = new MyClass("5exret_Paxxw0rd");
  try{
  Field f = MyClass.class.getDeclaredField("password");
  f.setAccessible(true);
  System.out.println((String)f.get(mc));
  } catch(Exception e) {
  }
   }
}


Some languages (Java) have optional security managers to try to avoid
allowing such things, but they are not always perfect at preventing
determined users.

My advice would be to design your system to avoid trying to hide
information from users who have the ability to run code from within the
same address space as the secrets you're trying to protect.

Thanks

Steve


On Wed, May 5, 2021 at 2:44 PM Shreyan Avigyan 
wrote:

> Private methods, functions and variables are very common in programming
> languages. But Python doesn't support private. It has conventions for
> naming so considered private but not private. Most of the time private is
> never required, what Python provides is more than enough. But the need for
> private come into place when we're dealing with passphrases and servers.
> For example consider this code,
>
> class A:
> def get():
> // code to get the password
> self.password = password
>
> Now consider this,
>
> >>> x = A(); x.get(); x.password
>
> See what just happened? Someone just got the member variable value that
> the person wasn't supposed to.
>
> I suggest to add private support for functions (module __all__ methods to
> be more clear), methods and variables (module __all__ variables or class
> variables).
>
> (I very bad at reading PEPs so I may miss out something critical that's
> been explained already (sometimes I miss out a feature in a PEP and think
> about suggesting that feature when it's already there and then I realize
> "Oh! It's already here in this PEP"). If that's the case then please
> correct me.)
>
> With Regards,
> Shreyan Avigyan
> ___
> Python-ideas mailing list -- python-ideas@python.org
> To unsubscribe send an email to python-ideas-le...@python.org
> https://mail.python.org/mailman3/lists/python-ideas.python.org/
> Message archived at
> https://mail.python.org/archives/list/python-ideas@python.org/message/DD2L56GCOCWEUBBZBDKKKMPPVWB7PRFB/
> Code of Conduct: http://python.org/psf/codeofconduct/
>
___
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at 
https://mail.python.org/archives/list/python-ideas@python.org/message/ESC7EJS667JKJQ2SFKO6RBPHGFM32IAY/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: Add support for private variables, methods and functions in Python

2021-05-05 Thread Chris Angelico
On Wed, May 5, 2021 at 11:43 PM Shreyan Avigyan
 wrote:
>
> Private methods, functions and variables are very common in programming 
> languages. But Python doesn't support private. It has conventions for naming 
> so considered private but not private. Most of the time private is never 
> required, what Python provides is more than enough. But the need for private 
> come into place when we're dealing with passphrases and servers. For example 
> consider this code,
>
> class A:
> def get():
> // code to get the password
> self.password = password
>
> Now consider this,
>
> >>> x = A(); x.get(); x.password
>
> See what just happened? Someone just got the member variable value that the 
> person wasn't supposed to.
>

That's only a problem if you have untrusted code running in the same
Python interpreter as privileged code. There's fundamentally no way
that you can get the password without the untrusted code also being
able to get it. Do you have an actual use-case where you have
passphrases like this? How does the "code to get the password" do it,
and how do you ensure that the unprivileged code can't just do the
same thing?

ChrisA
___
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at 
https://mail.python.org/archives/list/python-ideas@python.org/message/OEUKVHQO6WGKCNX462NJL4SJ6UNIWS3I/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: Add support for private variables, methods and functions in Python

2021-05-05 Thread Felipe Rodrigues
Hey Shreyan,

>From what I understand, Python's design focuses on enabling the developer to
do whatever she feels right. Having a class attribute or something marked
as "private" is more of a warning to people _using_ that class that they
shouldn't tinker with that field. If I'm using a class that deals with a
bank account, for example, and the current balance is marked as
"private" - or prefixed with __, in Python - I should read that as

"well, this value has some elaborated logic behind it. I should not
go around messing with it because there may be consequences
that this class's author didn't want"

and not

"I shouldn't be able to see this value!"

This is not an information security aspect, it is more of a code usability
thing.

That said,

> Someone just got the member variable value that the person wasn't
supposed to

If they can't access a piece of data, they shouldn't be allowed to execute
code inside
that server to begin with. There's actually a whole class of security flaws
that
deal with code execution. Once you allow someone to run code on your server,
you're done and no keyword in the code will prevent bad things from
happening.

Best,

--Bidu



On Wed, May 5, 2021 at 10:41 AM Shreyan Avigyan 
wrote:

> Private methods, functions and variables are very common in programming
> languages. But Python doesn't support private. It has conventions for
> naming so considered private but not private. Most of the time private is
> never required, what Python provides is more than enough. But the need for
> private come into place when we're dealing with passphrases and servers.
> For example consider this code,
>
> class A:
> def get():
> // code to get the password
> self.password = password
>
> Now consider this,
>
> >>> x = A(); x.get(); x.password
>
> See what just happened? Someone just got the member variable value that
> the person wasn't supposed to.
>
> I suggest to add private support for functions (module __all__ methods to
> be more clear), methods and variables (module __all__ variables or class
> variables).
>
> (I very bad at reading PEPs so I may miss out something critical that's
> been explained already (sometimes I miss out a feature in a PEP and think
> about suggesting that feature when it's already there and then I realize
> "Oh! It's already here in this PEP"). If that's the case then please
> correct me.)
>
> With Regards,
> Shreyan Avigyan
> ___
> Python-ideas mailing list -- python-ideas@python.org
> To unsubscribe send an email to python-ideas-le...@python.org
> https://mail.python.org/mailman3/lists/python-ideas.python.org/
> Message archived at
> https://mail.python.org/archives/list/python-ideas@python.org/message/DD2L56GCOCWEUBBZBDKKKMPPVWB7PRFB/
> Code of Conduct: http://python.org/psf/codeofconduct/
>
___
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at 
https://mail.python.org/archives/list/python-ideas@python.org/message/XORTSLR5K3VFG32LB6K523SYZKU7VKHF/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Add support for private variables, methods and functions in Python

2021-05-05 Thread Shreyan Avigyan
Private methods, functions and variables are very common in programming 
languages. But Python doesn't support private. It has conventions for naming so 
considered private but not private. Most of the time private is never required, 
what Python provides is more than enough. But the need for private come into 
place when we're dealing with passphrases and servers. For example consider 
this code,

class A:
def get():
// code to get the password
self.password = password

Now consider this,

>>> x = A(); x.get(); x.password

See what just happened? Someone just got the member variable value that the 
person wasn't supposed to.

I suggest to add private support for functions (module __all__ methods to be 
more clear), methods and variables (module __all__ variables or class 
variables).

(I very bad at reading PEPs so I may miss out something critical that's been 
explained already (sometimes I miss out a feature in a PEP and think about 
suggesting that feature when it's already there and then I realize "Oh! It's 
already here in this PEP"). If that's the case then please correct me.)

With Regards,
Shreyan Avigyan
___
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at 
https://mail.python.org/archives/list/python-ideas@python.org/message/DD2L56GCOCWEUBBZBDKKKMPPVWB7PRFB/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: Namespaces!

2021-05-05 Thread Steven D'Aprano
Thanks Paul, you channelled my thinking exactly correctly.

I am not an expert on C++, but I think that's roughly how C++ namespaces 
work. Any C++ coders care to confirm or correct me?


Steve



On Wed, May 05, 2021 at 12:05:56PM +0100, Paul Moore wrote:
> On Wed, 5 May 2021 at 11:33, Matt del Valle  wrote:
> 
> >> To give an example:
> >>
> >> def spam():
> >> return "spam spam spam!"
> >>
> >> def eggs():
> >> return spam()
> >>
> >> namespace Shop:
> >> def spam():
> >> return "There's not much call for spam here."
> >> def eggs():
> >> return spam()
> >>
> >> print(eggs())
> >> # should print "spam spam spam!"
> >> print(Shop.eggs())
> >> # should print "There's not much call for spam here."
> >
> >
> > I'm guessing this was a typo and you meant to type:
> >
> > print(spam())
> > # should print "spam spam spam!"
> > print(Shop.spam())
> > # should print "There's not much call for spam here."
> >
> > Because if you did, then this is precisely how it would work under this 
> > proposal. :)
> 
> I'm not the OP, but I read their question precisely as it was written.
> The global eggs() returns the value from calling spam() and should use
> the *global* spam. The eggs in namespace Shop calls spam and returns
> its value, and I'd expect that call to resolve to Shop.spam, using the
> namespace eggs is defined in. If that's not how you imagine namespaces
> working, I think they are going to be quite non-intuitive for at least
> a certain set of users (including me...)
> 
> Paul
> 
___
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at 
https://mail.python.org/archives/list/python-ideas@python.org/message/7S3QSLGIL3HTDD2FK4P6WQUI32BY4A3E/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: Namespaces!

2021-05-05 Thread Matt del Valle
Whoops. I totally misread that! My brain unhelpfully supplied string quotes
in the return statement of the `eggs` methods, rather than parsing them as
function calls. ...for some reason I could not explain to you.

Maybe I've grown too dependent on syntax highlighting!

I see what Steven meant now. Ignore what I typed earlier, then.

To be honest, I do completely agree. I think the most useful and least
surprising implementation would be to give the namespace block its own
temporary scope (with outer names still available), and then only at the
end of the block just before the scope is destroyed do any names bound to
it get set on the parent scope.

So:

def spam():
return "spam spam spam!"


def eggs():
return spam()


namespace Shop:
old_spam = spam  # No NameError, the `spam` from module scope is
still accessible here if we want it!

def spam():
return "There's not much call for spam here."

new_spam = spam  # this now refers to the function defined immediately above

def eggs():
return spam()  # this refers to the same object as `new_spam`,
not the `spam` from globals()

# at this point globals()['Shop.spam'] would still raise a
NameError. It doesn't exist yet!

namespace Shelf:
this_is_shop_spam = spam  # However, we can access it from
inside another nested namespace as a simple name. The scoping rules on
nested classes would not allow this!

# at this point globals()['Shop.spam'] exists!


Sorry Steven! I totally misunderstood your example. It was a really good
point. Thanks :)




On Wed, May 5, 2021 at 12:06 PM Paul Moore  wrote:

> On Wed, 5 May 2021 at 11:33, Matt del Valle  wrote:
>
> >> To give an example:
> >>
> >> def spam():
> >> return "spam spam spam!"
> >>
> >> def eggs():
> >> return spam()
> >>
> >> namespace Shop:
> >> def spam():
> >> return "There's not much call for spam here."
> >> def eggs():
> >> return spam()
> >>
> >> print(eggs())
> >> # should print "spam spam spam!"
> >> print(Shop.eggs())
> >> # should print "There's not much call for spam here."
> >
> >
> > I'm guessing this was a typo and you meant to type:
> >
> > print(spam())
> > # should print "spam spam spam!"
> > print(Shop.spam())
> > # should print "There's not much call for spam here."
> >
> > Because if you did, then this is precisely how it would work under this
> proposal. :)
>
> I'm not the OP, but I read their question precisely as it was written.
> The global eggs() returns the value from calling spam() and should use
> the *global* spam. The eggs in namespace Shop calls spam and returns
> its value, and I'd expect that call to resolve to Shop.spam, using the
> namespace eggs is defined in. If that's not how you imagine namespaces
> working, I think they are going to be quite non-intuitive for at least
> a certain set of users (including me...)
>
> Paul
>
___
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at 
https://mail.python.org/archives/list/python-ideas@python.org/message/JOPSMGLXNWQTN6RXB6CEDOAAARDU23PI/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: Namespaces!

2021-05-05 Thread Paul Moore
On Wed, 5 May 2021 at 11:33, Matt del Valle  wrote:

>> To give an example:
>>
>> def spam():
>> return "spam spam spam!"
>>
>> def eggs():
>> return spam()
>>
>> namespace Shop:
>> def spam():
>> return "There's not much call for spam here."
>> def eggs():
>> return spam()
>>
>> print(eggs())
>> # should print "spam spam spam!"
>> print(Shop.eggs())
>> # should print "There's not much call for spam here."
>
>
> I'm guessing this was a typo and you meant to type:
>
> print(spam())
> # should print "spam spam spam!"
> print(Shop.spam())
> # should print "There's not much call for spam here."
>
> Because if you did, then this is precisely how it would work under this 
> proposal. :)

I'm not the OP, but I read their question precisely as it was written.
The global eggs() returns the value from calling spam() and should use
the *global* spam. The eggs in namespace Shop calls spam and returns
its value, and I'd expect that call to resolve to Shop.spam, using the
namespace eggs is defined in. If that's not how you imagine namespaces
working, I think they are going to be quite non-intuitive for at least
a certain set of users (including me...)

Paul
___
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at 
https://mail.python.org/archives/list/python-ideas@python.org/message/SCBZDQQT3A3OISOTSOB7WSQNI5HFHSBL/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: Namespaces!

2021-05-05 Thread Chris Angelico
On Wed, May 5, 2021 at 8:33 PM Matt del Valle  wrote:
> Creating lots of unnecessary classes just for namespacing, as we currently 
> have to resort to, isn't ideal.
>
> What you're calling 'an unnecessary level of indirection', quickly becomes a 
> big boost to clarity (both in the written code and when using said code in an 
> IDE) in more complex situations. Ask yourself why library authors namespace 
> out the API of their library across multiple modules/packages. It's the same 
> reason.
>

I absolutely agree that creating lots of classes just for namespacing
is unideal. Where we disagree is where the problem is. You think the
problem is in the "creating lots of classes". I think the problem is
in "needing that much namespacing" :)

That's another reason to go looking for *real* examples. Every example
given in this thread can be dismissed for being too simple, while
simultaneously being defended as "just an example". Three levels of
namespacing just to find one leg out of eight is a complete waste of
effort. So find us some better examples to discuss, examples that
really support your proposal. These ones, as mentioned, are great for
explaining/discussing what it does, but not for explaining why it
needs to be done.

ChrisA
___
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at 
https://mail.python.org/archives/list/python-ideas@python.org/message/S6ZRZQO6MKGAYRGYHBKLLMKIAN4L6AOO/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: Namespaces!

2021-05-05 Thread Matt del Valle
>
> So if A is capable of looking up "B.C.D", but it's also capable of
> looking up "B" and following the chain... what happens when you
> reassign something? What does this line of code do?
>

A is capable of looking up B.C.D in one step if you use `getattr` because
the way A forwards on attribute lookups is roughly equivalent to
(copy-pasting this from an earlier post):

class NamespaceProxy:
...
def __getattr__(self, name):
return getattr(self.__parent_scope__,
f"{self.__namespace_name__}.{name}")

def __setattr__(self, name, value):
setattr(self.__parent_scope__,
f"{self.__namespace_name__}.{name}", value)


So it would concatenate its own name ("A") with a dot with the name being
looked up ("B.C.D") and then serve up globals()['A.B.C.D'], which is the
key under which the value of D is stored. It can also follow the chain
because:

>>>globals()['A']
 of  >

>>>globals()['A.B']
 of  >

>>>globals()['A.B.C']
 of  >

These also exist in the module globals(), (they were set there with those
names in the `namespace` statement). A chained lookup just involves looking
these namespace objects up one-by-one in the globals().

>>> A.B.C.D = "spam"
>
> Does it change what getattr(A, "B.C.D") returns?
>


Yes, it would, because it is no different to just explicitly setting:

globals()[''A.B.C.D'] = "spam"


That's not why ideas get dismissed out of hand. Onus is not on the
> status quo to prove itself; onus is on the proposal to show its value.
> If you want your idea to be taken seriously, you have to demonstrate
> that it would give some sort of real improvement.
>

I get this, I do. And you're not wrong.

I guess what I'm trying to say is that there's a lot to be said for being
kind. I've seen several instances of people coming here with a new idea and
sort-of cringed sympathetically at the kind of response they've gotten. I
can just imagine someone relatively new to python getting really puppy-dog
excited because they think they've got something worthwhile to contribute
(without understanding why it may not work) and jumping through a few hoops
to get onto this list only to be practically yelled out of the room by
cranky old developers. What a horribly demoralizing experience that must
be! There are some people who genuinely act like it is a personal attack on
them when someone else comes along to discuss their shiny new idea on a
list intended for... discussing potential new language ideas. I don't think
that reflects on our community very well to newcomers. It costs us nothing
to be kind, even if you *do* have to say something another person might not
like to hear. There are ways to soften it and be informational rather than
rude. Especially in a medium like this where tone doesn't carry and it's
easy to misconstrue something as harsher than the person meant it.

Even little things like your smiley face earlier:

Precisely. :)
>

Go a shockingly long way towards conveying that we're on the same page
having a discussion to try and improve python together, rather than an
ego-fuelled shouting match.

That's not the same, though. Binary operators are NOT syntactic sugar
> for method calls - they do a number of checks that allow for reflected
> methods and such.
>

Fair enough, I just used the first example that came to mind, which in this
case was wrong. My point was more about syntactic sugar in general.


> To give an example:
>
> def spam():
> return "spam spam spam!"
>
> def eggs():
> return spam()
>
> namespace Shop:
> def spam():
> return "There's not much call for spam here."
> def eggs():
> return spam()
>
> print(eggs())
> # should print "spam spam spam!"
> print(Shop.eggs())
> # should print "There's not much call for spam here."
>


I'm guessing this was a typo and you meant to type:

print(spam())
# should print "spam spam spam!"
print(Shop.spam())
# should print "There's not much call for spam here."

Because if you did, then this is precisely how it *would* work under this
proposal. :)

In the module globals() you would have the first version of `spam` under
the key 'spam', and the second one under 'Shop.spam', which is the object
that the attribute lookup `Shop.spam` would return

If we have a namespace concept, it should actually be a namespace, not
> an weird compiler directive to bind names in the surrounding global
> scope.
>

This is an implementation detail that the end-user would basically not need
to worry about except when iterating dynamically over the globals()/class
__dict__/object __dict__. But that's the entire point. `namespace` is
intended to build namespaces within some scope, not to create whole new
scopes. If you wanted a new scope you could create a new
class/object/module.

> For example, you could rewrite this:
> >
> > class Legs:
> >   def __init__(self, left, right):
> >   self.left, self.right = left, right
> >
> >
> > class Biped:
> > def