Re: Since when builtin dict preserve key order?

2018-03-24 Thread Marko Rauhamaa
Chris Angelico :

> On Sat, Mar 24, 2018 at 3:34 PM, Arkadiusz Bulski
>  wrote:
>> I already asked on PYPY and they confirmed that any version of pypy,
>> including 2.7, has dict preserving insertion order. I am familiar
>> with ordered **kw which was introduced in 3.6 but I also heard that
>> builtin dict preserves order since 3.5. Is that true?
>>
>
> I don't think 3.5 had it. According to the tracker, it landed in 3.6:
>
> https://bugs.python.org/issue27350
>
> But yes, current versions of CPython preserve insertion order.

Is that part of the Python Language Specification? If not, it shouldn't
be exploited in application programs.


Marko
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Since when builtin dict preserve key order?

2018-03-24 Thread Chris Angelico
On Sat, Mar 24, 2018 at 7:48 PM, Marko Rauhamaa  wrote:
> Chris Angelico :
>
>> On Sat, Mar 24, 2018 at 3:34 PM, Arkadiusz Bulski
>>  wrote:
>>> I already asked on PYPY and they confirmed that any version of pypy,
>>> including 2.7, has dict preserving insertion order. I am familiar
>>> with ordered **kw which was introduced in 3.6 but I also heard that
>>> builtin dict preserves order since 3.5. Is that true?
>>>
>>
>> I don't think 3.5 had it. According to the tracker, it landed in 3.6:
>>
>> https://bugs.python.org/issue27350
>>
>> But yes, current versions of CPython preserve insertion order.
>
> Is that part of the Python Language Specification? If not, it shouldn't
> be exploited in application programs.
>

Yes, it is; but the language spec wasn't locked in quite as soon as
the functionality was. So you may find that CPython 3.6 preserves
order more than the language requires. Starting with 3.7 (I believe),
the language spec is significantly tighter.

ChrisA
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Since when builtin dict preserve key order?

2018-03-24 Thread Serhiy Storchaka

24.03.18 10:48, Marko Rauhamaa пише:

Chris Angelico :

On Sat, Mar 24, 2018 at 3:34 PM, Arkadiusz Bulski
 wrote:

I already asked on PYPY and they confirmed that any version of pypy,
including 2.7, has dict preserving insertion order. I am familiar
with ordered **kw which was introduced in 3.6 but I also heard that
builtin dict preserves order since 3.5. Is that true?



I don't think 3.5 had it. According to the tracker, it landed in 3.6:

https://bugs.python.org/issue27350

But yes, current versions of CPython preserve insertion order.


Is that part of the Python Language Specification? If not, it shouldn't
be exploited in application programs.


Only in the future version 3.7. Surprisingly it isn't mentioned in 
"What’s New In Python 3.7" yet.


--
https://mail.python.org/mailman/listinfo/python-list


Re: Since when builtin dict preserve key order?

2018-03-24 Thread Marko Rauhamaa
Chris Angelico :

> On Sat, Mar 24, 2018 at 7:48 PM, Marko Rauhamaa  wrote:
>> Is that part of the Python Language Specification? If not, it
>> shouldn't be exploited in application programs.
>
> Yes, it is; but the language spec wasn't locked in quite as soon as
> the functionality was. So you may find that CPython 3.6 preserves
> order more than the language requires. Starting with 3.7 (I believe),
> the language spec is significantly tighter.

I take it, then, that the Language Specification follows CPython's
version numbering. I wonder how other Python implementations declare
their standards compliance.


Marko
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Since when builtin dict preserve key order?

2018-03-24 Thread Chris Angelico
On Sat, Mar 24, 2018 at 10:48 PM, Marko Rauhamaa  wrote:
> Chris Angelico :
>
>> On Sat, Mar 24, 2018 at 7:48 PM, Marko Rauhamaa  wrote:
>>> Is that part of the Python Language Specification? If not, it
>>> shouldn't be exploited in application programs.
>>
>> Yes, it is; but the language spec wasn't locked in quite as soon as
>> the functionality was. So you may find that CPython 3.6 preserves
>> order more than the language requires. Starting with 3.7 (I believe),
>> the language spec is significantly tighter.
>
> I take it, then, that the Language Specification follows CPython's
> version numbering. I wonder how other Python implementations declare
> their standards compliance.
>

Have you thought to look?

$ pypy
Python 2.7.12 (5.6.0+dfsg-4, Nov 20 2016, 10:43:30)
[PyPy 5.6.0 with GCC 6.2.0 20161109] on linux2

Tada.

ChrisA
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Since when builtin dict preserve key order?

2018-03-24 Thread Marko Rauhamaa
Chris Angelico :

> On Sat, Mar 24, 2018 at 10:48 PM, Marko Rauhamaa  wrote:
>> I take it, then, that the Language Specification follows CPython's
>> version numbering. I wonder how other Python implementations declare
>> their standards compliance.
>
> Have you thought to look?
>
> $ pypy
> Python 2.7.12 (5.6.0+dfsg-4, Nov 20 2016, 10:43:30)
> [PyPy 5.6.0 with GCC 6.2.0 20161109] on linux2
>
> Tada.

FTFY:

   Yes, that's how it works. For example PyPy prints out this initial
   prompt:

   $ pypy
   Python 2.7.12 (5.6.0+dfsg-4, Nov 20 2016, 10:43:30)
   [PyPy 5.6.0 with GCC 6.2.0 20161109] on linux2


Marko
-- 
https://mail.python.org/mailman/listinfo/python-list


Pip Version Confusion

2018-03-24 Thread Tim Johnson
I'm on Ubuntu 16.04.

I'm getting the following message from pip:

You are using pip version 8.1.1, however version 9.0.3 is available.
You should consider upgrading via the 'pip install --upgrade pip' command.

# But then I get this :
tim@linus:~/Downloads$ which pip
/home/tim/.local/bin/pip

# and this:
tim@linus:~/Downloads$ pip --version
pip 9.0.3 from /home/tim/.local/lib/python2.7/site-packages (python 2.7)

Not sure how to resolve - please advise,
thanks

--
Tim
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Pip Version Confusion

2018-03-24 Thread Steven D'Aprano
On Sat, 24 Mar 2018 07:40:17 -0800, Tim Johnson wrote:

> I'm on Ubuntu 16.04.
> 
> I'm getting the following message from pip:
> 
> You are using pip version 8.1.1, however version 9.0.3 is available. You
> should consider upgrading via the 'pip install --upgrade pip' command.
[...]
> Not sure how to resolve - please advise, thanks


Well, what happens when you try running 

pip install --upgrade pip

as it says?


I expect that you've probably got two (or more!) pips installed, and 
somehow sometimes you get one and sometimes the other. The problem is, it 
seems to me, that we can get pip installed through at least three 
mechanisms:

- installing pip by hand, via source or some other mechanism;

- using ensure-pip in a sufficiently recent Python;

- using your OS's package manager.

And of course each version of Python can have its own pip.


To diagnose this, I would try:

Query your package manager, what version of pip does it say is installed?

How many versions of Python do you have installed? Which one are you 
running?

Precisely what command line did you give to get the message above?

If you cd out of whatever directory you are in, does the message change?

If you run pip as a different user, what happens?

If you run "locate pip", how many pip installations does it find, and 
what are they?


-- 
Steve

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Putting Unicode characters in JSON

2018-03-24 Thread Peter J. Holzer
On 2018-03-24 11:21:09 +1100, Chris Angelico wrote:
> On Sat, Mar 24, 2018 at 11:11 AM, Steven D'Aprano
>  wrote:
> > On Fri, 23 Mar 2018 07:46:16 -0700, Tobiah wrote:
> >> If I changed my database tables to all be UTF-8 would this work cleanly
> >> without any decoding?
> >
> > Not reliably or safely. It will appear to work so long as you have only
> > pure ASCII strings from the database, and then crash when you don't:
> >
> > py> text_from_database = u"hello wörld".encode('latin1')
> > py> print text_from_database
> > hello w�rld
[...]
> 
> If the database has been configured to use UTF-8 (as mentioned, that's
> "utf8mb4" in MySQL), you won't get that byte sequence back. You'll get
> back valid UTF-8.

Actually (with python3 and mysql.connector), you'll get back str values,
not byte values encoded in utf-8 or latin-1. You don't have to decode
them because the driver already did it.

So as a Python programmer, you don't care what character set the
database uses internally, as this is almost completely hidden from you
(The one aspect that isn't hidden is of course the set of characters
that you can store in a character field: Obviously, you can't store
Chinese characters in a latin1 field).

If you are using Python2, manual encoding and decoding may be necessary.
(AFAICS the OP still hasn't stated which Python version he uses)

hp

-- 
   _  | Peter J. Holzer| we build much bigger, better disasters now
|_|_) || because we have much more sophisticated
| |   | [email protected] | management tools.
__/   | http://www.hjp.at/ | -- Ross Anderson 


signature.asc
Description: PGP signature
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Best practice for managing secrets (passwords, private keys) used by Python scripts running as daemons

2018-03-24 Thread Peter J. Holzer
On 2018-03-23 11:50:52 -0700, Dan Stromberg wrote:
> I'd put them in a file with access to the daemon..
> 
> Putting credentials in an environment variable is insecure on Linux,
> because ps auxwwe lists environment variables.

But only those of your own processes. So both methods are about equally
secure: If you can become the daemon user (or root), then you can read
the secret.

(Historically, many unixes allowed all users to read the environment
variables of all processes. I don't know if this is still the case for
e.g. Solaris or AIX - or macOS)

hp

-- 
   _  | Peter J. Holzer| we build much bigger, better disasters now
|_|_) || because we have much more sophisticated
| |   | [email protected] | management tools.
__/   | http://www.hjp.at/ | -- Ross Anderson 


signature.asc
Description: PGP signature
-- 
https://mail.python.org/mailman/listinfo/python-list


Accessing parent objects

2018-03-24 Thread D'Arcy Cain
I'm not even sure how to describe what I am trying to do which perhaps
indicates that what I am trying to do is the wrong solution to my
problem in the first place but let me give it a shot.  Look at the
following code.

class C1(dict):
  class C2(object):
def f(self):
  return X['field']

O1 = C1()
O1['field'] = 1
O2 = O1.C2()
print(O2.f())

I am trying to figure out what "X" should be.  I know how to access the
parent class but in this case I am trying to access the parent object.
I tried various forms of super() but that didn't seem to work.

-- 
D'Arcy J.M. Cain
Vybe Networks Inc.
http://www.VybeNetworks.com/
IM:[email protected] VoIP: sip:[email protected]


-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Pip Version Confusion

2018-03-24 Thread Tim Johnson
* Steven D'Aprano  [180324 08:29]:
> On Sat, 24 Mar 2018 07:40:17 -0800, Tim Johnson wrote:
> 
> > I'm on Ubuntu 16.04.
> > 
> > I'm getting the following message from pip:
> > 
> > You are using pip version 8.1.1, however version 9.0.3 is available. You
> > should consider upgrading via the 'pip install --upgrade pip' command.
> [...]
> > Not sure how to resolve - please advise, thanks
> 
> 
> Well, what happens when you try running 
> 
> pip install --upgrade pip
tim@linus:~/Downloads$ pip install --upgrade pip
Requirement already up-to-date: pip in
/home/tim/.local/lib/python2.7/site-packages
> 
> I expect that you've probably got two (or more!) pips installed, and 
> somehow sometimes you get one and sometimes the other. The problem is, it 
> seems to me, that we can get pip installed through at least three 
> mechanisms:
 
   pips all over the place ... pips, pips2, pips2.7
   all but /usr/bin/pip2 show version as 9.0.3
   /usr/bin/pip2 is version 8.1.1
   # code follows
#!/usr/bin/python
# EASY-INSTALL-ENTRY-SCRIPT: 'pip==8.1.1','console_scripts','pip2'
__requires__ = 'pip==8.1.1'
import sys
from pkg_resources import load_entry_point

if __name__ == '__main__':
sys.exit(
load_entry_point('pip==8.1.1', 'console_scripts', 'pip2')()
)

Looks like I should not have install pip via the ubuntu package manager.

> - installing pip by hand, via source or some other mechanism;
> 
> - using ensure-pip in a sufficiently recent Python;
> 
> - using your OS's package manager.
> 
> And of course each version of Python can have its own pip.
> 
> 
> To diagnose this, I would try:
> 
> Query your package manager, what version of pip does it say is installed?
> 
> How many versions of Python do you have installed? Which one are you 
> running?
> 
> Precisely what command line did you give to get the message above?
> 
> If you cd out of whatever directory you are in, does the message change?
> 
> If you run pip as a different user, what happens?
> 
> If you run "locate pip", how many pip installations does it find, and 
> what are they?
> 
> 
> -- 
> Steve
> 
> -- 
> https://mail.python.org/mailman/listinfo/python-list

-- 
Tim Johnson
http://www.akwebsoft.com, http://www.tj49.com
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Pip Version Confusion

2018-03-24 Thread Tim Johnson
* Tim Johnson  [180324 10:32]:
> * Steven D'Aprano  [180324 08:29]:
> > On Sat, 24 Mar 2018 07:40:17 -0800, Tim Johnson wrote:
> > 
> > > I'm on Ubuntu 16.04.
> > > 
> > > I'm getting the following message from pip:
> > > 
> > > You are using pip version 8.1.1, however version 9.0.3 is available. You
> > > should consider upgrading via the 'pip install --upgrade pip' command.
> > [...]
> > > Not sure how to resolve - please advise, thanks
> > 
> > 
> > Well, what happens when you try running 
> > 
> > pip install --upgrade pip
> tim@linus:~/Downloads$ pip install --upgrade pip
> Requirement already up-to-date: pip in
> /home/tim/.local/lib/python2.7/site-packages
> > 
> > I expect that you've probably got two (or more!) pips installed, and 
> > somehow sometimes you get one and sometimes the other. The problem is, it 
> > seems to me, that we can get pip installed through at least three 
> > mechanisms:
>  
>pips all over the place ... pips, pips2, pips2.7
>all but /usr/bin/pip2 show version as 9.0.3
>/usr/bin/pip2 is version 8.1.1
># code follows
> #!/usr/bin/python
> # EASY-INSTALL-ENTRY-SCRIPT: 'pip==8.1.1','console_scripts','pip2'
> __requires__ = 'pip==8.1.1'
> import sys
> from pkg_resources import load_entry_point
> 
> if __name__ == '__main__':
> sys.exit(
> load_entry_point('pip==8.1.1', 'console_scripts', 'pip2')()
> )
> 
> Looks like I should not have install pip via the ubuntu package manager.
  From the package manager:
python-pip/xenial-updates,xenial-updates,now 8.1.1-2ubuntu0.4 all
[installed]
python-pip-whl/xenial-updates,xenial-updates,now 8.1.1-2ubuntu0.4
all [installed,automatic]

Think I've found it... I'll trying 'deinstalling' that package and
see if the nonsense goes away.

Thank you Steven!

-- 
Tim Johnson
http://www.akwebsoft.com, http://www.tj49.com
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Accessing parent objects

2018-03-24 Thread Peter Otten
D'Arcy Cain wrote:

> I'm not even sure how to describe what I am trying to do which perhaps
> indicates that what I am trying to do is the wrong solution to my
> problem in the first place but let me give it a shot.  Look at the
> following code.
> 
> class C1(dict):
>   class C2(object):
> def f(self):
>   return X['field']
> 
> O1 = C1()
> O1['field'] = 1
> O2 = O1.C2()
> print(O2.f())
> 
> I am trying to figure out what "X" should be.  I know how to access the
> parent class but in this case I am trying to access the parent object.
> I tried various forms of super() but that didn't seem to work.

You can make an arbitrary number of C1 instances and an arbitrary number of 
C2 instances; there cannot be an implicit connection between any pair.

You have to be explicit:

class C1(dict):
def C2(self):
return C2(self)

class C2(object):
def __init__(self, parent):
self.parent = parent
def f(self):
return self.parent["field"] 

O1 = C1()
O1['field'] = 1
O2 = O1.C2()
print(O2.f())


-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Putting Unicode characters in JSON

2018-03-24 Thread Chris Angelico
On Sun, Mar 25, 2018 at 3:35 AM, Peter J. Holzer  wrote:
> On 2018-03-24 11:21:09 +1100, Chris Angelico wrote:
>> If the database has been configured to use UTF-8 (as mentioned, that's
>> "utf8mb4" in MySQL), you won't get that byte sequence back. You'll get
>> back valid UTF-8.
>
> Actually (with python3 and mysql.connector), you'll get back str values,
> not byte values encoded in utf-8 or latin-1. You don't have to decode
> them because the driver already did it.
>
> So as a Python programmer, you don't care what character set the
> database uses internally, as this is almost completely hidden from you
> (The one aspect that isn't hidden is of course the set of characters
> that you can store in a character field: Obviously, you can't store
> Chinese characters in a latin1 field).

Good. I mentioned earlier that that's how it is with PostgreSQL and
psycopg2, but wasn't sure about the MySQL interface modules. Glad to
know that it is.

ChrisA
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Best practice for managing secrets (passwords, private keys) used by Python scripts running as daemons

2018-03-24 Thread Chris Angelico
On Sun, Mar 25, 2018 at 4:24 AM, Peter J. Holzer  wrote:
> On 2018-03-23 11:50:52 -0700, Dan Stromberg wrote:
>> I'd put them in a file with access to the daemon..
>>
>> Putting credentials in an environment variable is insecure on Linux,
>> because ps auxwwe lists environment variables.
>
> But only those of your own processes. So both methods are about equally
> secure: If you can become the daemon user (or root), then you can read
> the secret.

If you can become the daemon user, you can do whatever the daemon user
can. (Do people ever write HTTP crawler scripts that run as user
"spiderman"? Yeah, probably.) So, pretty much _by definition_, both
methods are insecure there. (And obviously if you can become root,
everything's wiide open.) Normally, I would consider that to be
fine; proper use of Unix user isolation is usually sufficient. But if
you are absolutely crazily paranoid, you CAN try other methods; just
be aware that whatever you do is going to move the problem around, not
solve it. First thing that comes to my mind is storing the secret on a
completely separate computer, and the daemon establishes a socket
connection to that computer to request the secret. If another process
attempts to get the secret, the secret-manager first pings its
existing socket, saying "hey, you okay there?", and then between you,
you decide what to do.

Could be fun to mess around with, but normally I would just depend on
file and process ownership.

ChrisA
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Putting Unicode characters in JSON

2018-03-24 Thread Peter J. Holzer
On 2018-03-25 06:30:54 +1100, Chris Angelico wrote:
> On Sun, Mar 25, 2018 at 3:35 AM, Peter J. Holzer  wrote:
> > On 2018-03-24 11:21:09 +1100, Chris Angelico wrote:
> >> If the database has been configured to use UTF-8 (as mentioned, that's
> >> "utf8mb4" in MySQL), you won't get that byte sequence back. You'll get
> >> back valid UTF-8.
> >
> > Actually (with python3 and mysql.connector), you'll get back str values,
> > not byte values encoded in utf-8 or latin-1. You don't have to decode
> > them because the driver already did it.
> >
> > So as a Python programmer, you don't care what character set the
> > database uses internally, as this is almost completely hidden from you
> > (The one aspect that isn't hidden is of course the set of characters
> > that you can store in a character field: Obviously, you can't store
> > Chinese characters in a latin1 field).
> 
> Good. I mentioned earlier that that's how it is with PostgreSQL and
> psycopg2, but wasn't sure about the MySQL interface modules. Glad to
> know that it is.

I'm surprised that PEP 249 doesn't specify this. It seems worth
standardizing (OTOH it's the "one obvious way to do it", so maybe it
doesn't need to be specified explicitely).

The interfaces for the 4 databases I use (psycopg2 for PostgreSQL,
cx_Oracle, mysql.connector and sqlite3) all behave the same for varchar
fields, which makes me reasonably confident that this is also the case
for other databases.

hp

-- 
   _  | Peter J. Holzer| we build much bigger, better disasters now
|_|_) || because we have much more sophisticated
| |   | [email protected] | management tools.
__/   | http://www.hjp.at/ | -- Ross Anderson 


signature.asc
Description: PGP signature
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Accessing parent objects

2018-03-24 Thread Chris Angelico
On Sun, Mar 25, 2018 at 5:14 AM, D'Arcy Cain  wrote:
> I'm not even sure how to describe what I am trying to do which perhaps
> indicates that what I am trying to do is the wrong solution to my
> problem in the first place but let me give it a shot.  Look at the
> following code.
>
> class C1(dict):
>   class C2(object):
> def f(self):
>   return X['field']
>
> O1 = C1()
> O1['field'] = 1
> O2 = O1.C2()
> print(O2.f())
>
> I am trying to figure out what "X" should be.  I know how to access the
> parent class but in this case I am trying to access the parent object.
> I tried various forms of super() but that didn't seem to work.
>

What you'd need here is for O1.C2 to be an instance method, instead of
simply a nested class. That way, it can retain a reference to O1.
Something like:

class C1(dict):
class _C2(object):
def __init__(self, parent):
self.parent = parent
def f(self):
return self.parent["field"]
def C2(self):
return self._C2(self)

It may also be possible to do this through __new__, but I haven't
confirmed it. Might need some careful shenanigans if you want to have
O1.C2 actually be the class.

ChrisA
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Best practice for managing secrets (passwords, private keys) used by Python scripts running as daemons

2018-03-24 Thread Thomas Jollans
On 24/03/18 20:41, Chris Angelico wrote:
> On Sun, Mar 25, 2018 at 4:24 AM, Peter J. Holzer  wrote:
>> On 2018-03-23 11:50:52 -0700, Dan Stromberg wrote:
>>> I'd put them in a file with access to the daemon..
>>>
>>> Putting credentials in an environment variable is insecure on Linux,
>>> because ps auxwwe lists environment variables.
>>
>> But only those of your own processes. So both methods are about equally
>> secure: If you can become the daemon user (or root), then you can read
>> the secret.
> 
> If you can become the daemon user, you can do whatever the daemon user
> can.

If you're using something like SELinux, I don't think that's
*necessarily* true (but I really don't know much about SELinux).

Normally, though, I should think that protecting the secret with user
isolation (e.g. by putting it into a file with the right permissions)
should be fine.

Environment variables should be fine too, but really this just moves the
problem up one level: where does the parent process get the secret when
it sets up the environment?
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Best practice for managing secrets (passwords, private keys) used by Python scripts running as daemons

2018-03-24 Thread Chris Angelico
On Sun, Mar 25, 2018 at 7:23 AM, Thomas Jollans  wrote:
> On 24/03/18 20:41, Chris Angelico wrote:
>> On Sun, Mar 25, 2018 at 4:24 AM, Peter J. Holzer  wrote:
>>> On 2018-03-23 11:50:52 -0700, Dan Stromberg wrote:
 I'd put them in a file with access to the daemon..

 Putting credentials in an environment variable is insecure on Linux,
 because ps auxwwe lists environment variables.
>>>
>>> But only those of your own processes. So both methods are about equally
>>> secure: If you can become the daemon user (or root), then you can read
>>> the secret.
>>
>> If you can become the daemon user, you can do whatever the daemon user
>> can.
>
> If you're using something like SELinux, I don't think that's
> *necessarily* true (but I really don't know much about SELinux).

Me neither. Anyone here happen to know?

> Normally, though, I should think that protecting the secret with user
> isolation (e.g. by putting it into a file with the right permissions)
> should be fine.
>
> Environment variables should be fine too, but really this just moves the
> problem up one level: where does the parent process get the secret when
> it sets up the environment?

A common situation is that the secret is owned by *root*, not the
daemon process's user. So the parent process, running as root, reads
the secret into memory, then forks, drops privileges, and exec's to
the daemon with the secret in the environment.

ChrisA
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Accessing parent objects

2018-03-24 Thread Rick Johnson
On Saturday, March 24, 2018 at 1:20:24 PM UTC-5, D'Arcy Cain wrote:
> I'm not even sure how to describe what I am trying to do
> which perhaps indicates that what I am trying to do is the
> wrong solution to my problem in the first place but let me
> give it a shot.  Look at the following code.
> 
> class C1(dict):
>   class C2(object):
> def f(self):
>   return X['field']
> 
> O1 = C1()
> O1['field'] = 1
> O2 = O1.C2()
> print(O2.f())

I hope this dynamic setting of instance attributes is done
for a good reason, and not because you don't know how to do
it any other way? Also, i hope this nested class structure is
also done for a very good reason, because i consider such to
be a code smell.

> I am trying to figure out what "X" should be.  I know how
> to access the parent class but in this case I am trying to
> access the parent object.

Your poor utilization of OOP terminology is defeating you.

In every OOP object there can be zero or more "class level
variables" (aka: class attributes) and there can be zero or
more "instance level variables" (aka: instance attributes).

A class attribute can be accessed from anywhere (if you know
the class symbol and the attribute name, that is). But an
instance attribute can only be accessed in one of two
manners: from within an instance (via `self.attrname`) or
from outside an instance (using a symbol bound to the
instance, such as: `O1.field` or O1['field']). And while
there might be a way to walk down the "proverbial node tree"
and arrive at the specific instance you wish to target (a la
DHTML), such would be considered black magic, as it does not
follow the standard protocols of OOP attribute access.

My suspicion is that your attempting to solve this problem
using the wrong methodology. If you would be so kind as to
explain exactly what your are doing, perhaps someone here
could offer a better solution. Perhaps OOP is not the best
solution. Or perhaps it is? But we cannot be sure until we
know more about the general problem.

> I tried various forms of super() but that didn't seem to
> work.

Python's super (at least <= 2.x) is notoriously blinkered. I
avoid it like the plague. And i'd advise you to do the same.

PS: I am pleased to see you old fellers are finally warming
up to the wonderful OOP paradigm, but i gotta say, what is
most entertaining to me is watching you seasoned pros
struggle with the simplist OOP concepts. And don't get
angry, because i'm laughing at you, not with you. (or is it
the other way 'round??? o_O)
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Since when builtin dict preserve key order?

2018-03-24 Thread Dan Stromberg
On Fri, Mar 23, 2018 at 9:34 PM, Arkadiusz Bulski  wrote:
> I already asked on PYPY and they confirmed that any version of pypy,
> including 2.7, has dict preserving insertion order. I am familiar with
> ordered **kw which was introduced in 3.6 but I also heard that builtin dict
> preserves order since 3.5. Is that true?

Empirically speaking:
$ cat dict-order
below cmd output started 2018 Sat Mar 24 01:28:15 PM PDT
#!/usr/local/cpython-2.7/bin/python

"""Check if a dictionary appears to have insertion-order preserved."""

n = 10

expected_list = list(range(n - 1, -1, -1))

dict_ = {}
for i in expected_list:
dict_[i] = 2*i

actual_list = list(dict_)

if actual_list != expected_list:
raise AssertionError('%s != %s' % (actual_list, expected_list))
above cmd output done2018 Sat Mar 24 01:28:15 PM PDT
dstromberg@zareason2:~/src/python-tests x86_64-unknown-linux-gnu 15808

$ make
below cmd output started 2018 Sat Mar 24 01:28:18 PM PDT
pythons --file dict-order
/usr/local/cpython-1.0/bin/python (1.0.1) bad
  File "dict-order", line 3
"""Check if a dictionary appears to have insertion-order preserved."""
   ^
SyntaxError: invalid syntax
/usr/local/cpython-1.1/bin/python (1.1) bad
Traceback (innermost last):
  File "dict-order", line 7, in ?
expected_list = list(range(n - 1, -1, -1))
NameError: list
/usr/local/cpython-1.2/bin/python (1.2) bad
Traceback (innermost last):
  File "dict-order", line 7, in ?
expected_list = list(range(n - 1, -1, -1))
NameError: list
/usr/local/cpython-1.3/bin/python (1.3) bad
Traceback (innermost last):
  File "dict-order", line 7, in ?
expected_list = list(range(n - 1, -1, -1))
NameError: list
/usr/local/cpython-1.4/bin/python (1.4) bad
Traceback (innermost last):
  File "dict-order", line 13, in ?
actual_list = list(dict_)
TypeError: list() argument must be a sequence
/usr/local/cpython-1.5/bin/python (1.5.2) bad
Traceback (innermost last):
  File "dict-order", line 13, in ?
actual_list = list(dict_)
TypeError: list() argument must be a sequence
/usr/local/cpython-1.6/bin/python (1.6.1) bad
Traceback (most recent call last):
  File "dict-order", line 13, in ?
actual_list = list(dict_)
TypeError: list() argument must be a sequence
/usr/local/cpython-2.0/bin/python (2.0.1) bad
Traceback (most recent call last):
  File "dict-order", line 13, in ?
actual_list = list(dict_)
TypeError: list() argument must be a sequence
/usr/local/cpython-2.1/bin/python (2.1.0) bad
Traceback (most recent call last):
  File "dict-order", line 13, in ?
actual_list = list(dict_)
TypeError: list() argument must be a sequence
/usr/local/cpython-2.2/bin/python (2.2.0) bad
Traceback (most recent call last):
  File "dict-order", line 16, in ?
raise AssertionError('%s != %s' % (actual_list, expected_list))
AssertionError: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] != [9, 8, 7, 6, 5,
4, 3, 2, 1, 0]
/usr/local/cpython-2.3/bin/python (2.3.0) bad
Traceback (most recent call last):
  File "dict-order", line 16, in ?
raise AssertionError('%s != %s' % (actual_list, expected_list))
AssertionError: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] != [9, 8, 7, 6, 5,
4, 3, 2, 1, 0]
/usr/local/cpython-2.4/bin/python (2.4.0) bad
Traceback (most recent call last):
  File "dict-order", line 16, in ?
raise AssertionError('%s != %s' % (actual_list, expected_list))
AssertionError: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] != [9, 8, 7, 6, 5,
4, 3, 2, 1, 0]
/usr/local/cpython-2.5/bin/python (2.5.6) bad
Traceback (most recent call last):
  File "dict-order", line 16, in 
raise AssertionError('%s != %s' % (actual_list, expected_list))
AssertionError: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] != [9, 8, 7, 6, 5,
4, 3, 2, 1, 0]
/usr/local/cpython-2.6/bin/python (2.6.9) bad
Traceback (most recent call last):
  File "dict-order", line 16, in 
raise AssertionError('%s != %s' % (actual_list, expected_list))
AssertionError: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] != [9, 8, 7, 6, 5,
4, 3, 2, 1, 0]
/usr/local/cpython-2.7/bin/python (2.7.13) bad
Traceback (most recent call last):
  File "dict-order", line 16, in 
raise AssertionError('%s != %s' % (actual_list, expected_list))
AssertionError: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] != [9, 8, 7, 6, 5,
4, 3, 2, 1, 0]
/usr/local/cpython-3.0/bin/python (3.0.1) bad
Traceback (most recent call last):
  File "dict-order", line 16, in 
raise AssertionError('%s != %s' % (actual_list, expected_list))
AssertionError: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] != [9, 8, 7, 6, 5,
4, 3, 2, 1, 0]
/usr/local/cpython-3.1/bin/python (3.1.5) bad
Traceback (most recent call last):
  File "dict-order", line 16, in 
raise AssertionError('%s != %s' % (actual_list, expected_list))
Assertio

Re: Since when builtin dict preserve key order?

2018-03-24 Thread Arkadiusz Bulski
What exactly do you mean its present but not guaranteed? Do you mean its a
property of CPython 3.6 implementation but not Python as a standard?

sob., 24 mar 2018 o 21:33 użytkownik Dan Stromberg 
napisał:

> On Fri, Mar 23, 2018 at 9:34 PM, Arkadiusz Bulski 
> wrote:
> > I already asked on PYPY and they confirmed that any version of pypy,
> > including 2.7, has dict preserving insertion order. I am familiar with
> > ordered **kw which was introduced in 3.6 but I also heard that builtin
> dict
> > preserves order since 3.5. Is that true?
>
> Empirically speaking:
> $ cat dict-order
> below cmd output started 2018 Sat Mar 24 01:28:15 PM PDT
> #!/usr/local/cpython-2.7/bin/python
>
> """Check if a dictionary appears to have insertion-order preserved."""
>
> n = 10
>
> expected_list = list(range(n - 1, -1, -1))
>
> dict_ = {}
> for i in expected_list:
> dict_[i] = 2*i
>
> actual_list = list(dict_)
>
> if actual_list != expected_list:
> raise AssertionError('%s != %s' % (actual_list, expected_list))
> above cmd output done2018 Sat Mar 24 01:28:15 PM PDT
> dstromberg@zareason2:~/src/python-tests x86_64-unknown-linux-gnu 15808
>
> $ make
> below cmd output started 2018 Sat Mar 24 01:28:18 PM PDT
> pythons --file dict-order
> /usr/local/cpython-1.0/bin/python (1.0.1) bad
>   File "dict-order", line 3
> """Check if a dictionary appears to have insertion-order
> preserved."""
>
>  ^
> SyntaxError: invalid syntax
> /usr/local/cpython-1.1/bin/python (1.1) bad
> Traceback (innermost last):
>   File "dict-order", line 7, in ?
> expected_list = list(range(n - 1, -1, -1))
> NameError: list
> /usr/local/cpython-1.2/bin/python (1.2) bad
> Traceback (innermost last):
>   File "dict-order", line 7, in ?
> expected_list = list(range(n - 1, -1, -1))
> NameError: list
> /usr/local/cpython-1.3/bin/python (1.3) bad
> Traceback (innermost last):
>   File "dict-order", line 7, in ?
> expected_list = list(range(n - 1, -1, -1))
> NameError: list
> /usr/local/cpython-1.4/bin/python (1.4) bad
> Traceback (innermost last):
>   File "dict-order", line 13, in ?
> actual_list = list(dict_)
> TypeError: list() argument must be a sequence
> /usr/local/cpython-1.5/bin/python (1.5.2) bad
> Traceback (innermost last):
>   File "dict-order", line 13, in ?
> actual_list = list(dict_)
> TypeError: list() argument must be a sequence
> /usr/local/cpython-1.6/bin/python (1.6.1) bad
> Traceback (most recent call last):
>   File "dict-order", line 13, in ?
> actual_list = list(dict_)
> TypeError: list() argument must be a sequence
> /usr/local/cpython-2.0/bin/python (2.0.1) bad
> Traceback (most recent call last):
>   File "dict-order", line 13, in ?
> actual_list = list(dict_)
> TypeError: list() argument must be a sequence
> /usr/local/cpython-2.1/bin/python (2.1.0) bad
> Traceback (most recent call last):
>   File "dict-order", line 13, in ?
> actual_list = list(dict_)
> TypeError: list() argument must be a sequence
> /usr/local/cpython-2.2/bin/python (2.2.0) bad
> Traceback (most recent call last):
>   File "dict-order", line 16, in ?
> raise AssertionError('%s != %s' % (actual_list, expected_list))
> AssertionError: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] != [9, 8, 7, 6, 5,
> 4, 3, 2, 1, 0]
> /usr/local/cpython-2.3/bin/python (2.3.0) bad
> Traceback (most recent call last):
>   File "dict-order", line 16, in ?
> raise AssertionError('%s != %s' % (actual_list, expected_list))
> AssertionError: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] != [9, 8, 7, 6, 5,
> 4, 3, 2, 1, 0]
> /usr/local/cpython-2.4/bin/python (2.4.0) bad
> Traceback (most recent call last):
>   File "dict-order", line 16, in ?
> raise AssertionError('%s != %s' % (actual_list, expected_list))
> AssertionError: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] != [9, 8, 7, 6, 5,
> 4, 3, 2, 1, 0]
> /usr/local/cpython-2.5/bin/python (2.5.6) bad
> Traceback (most recent call last):
>   File "dict-order", line 16, in 
> raise AssertionError('%s != %s' % (actual_list, expected_list))
> AssertionError: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] != [9, 8, 7, 6, 5,
> 4, 3, 2, 1, 0]
> /usr/local/cpython-2.6/bin/python (2.6.9) bad
> Traceback (most recent call last):
>   File "dict-order", line 16, in 
> raise AssertionError('%s != %s' % (actual_list, expected_list))
> AssertionError: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] != [9, 8, 7, 6, 5,
> 4, 3, 2, 1, 0]
> /usr/local/cpython-2.7/bin/python (2.7.13) bad
> Traceback (most recent call last):
>   File "dict-order", line 16, in 
> raise AssertionError('%s != %s' % (actual_list, expected_list))
> AssertionError: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] != [9, 8, 7, 6, 5,
> 4, 3, 2, 1, 0]
> /usr/local/cpython-3.0/bin/python (3.0.1) bad
> Traceback (most recent call last):
>   File "dict-order", line 16, in 
>

Re: Since when builtin dict preserve key order?

2018-03-24 Thread Chris Angelico
On Sun, Mar 25, 2018 at 8:52 AM, Arkadiusz Bulski  wrote:
> What exactly do you mean its present but not guaranteed? Do you mean its a
> property of CPython 3.6 implementation but not Python as a standard?

Correct. The implementation was done in CPython (basically lifting it
from PyPy, AIUI), and then a lengthy discussion eventually settled on
making it a language requirement.

ChrisA
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Entering a very large number

2018-03-24 Thread Peter J. Holzer
On 2018-03-23 14:12:27 +0100, ast wrote:
> Le 23/03/2018 à 13:55, Wolfgang Maier a écrit :
> > On 03/23/2018 01:30 PM, Wolfgang Maier wrote:
> > > On 03/23/2018 01:16 PM, ast wrote:

[quoted from the first mail in this thread:]
> > > > It works but is it not optimal since there is a
> > > > string to int conversion.


> > n = int(
> >      ''.join("""
> > 37107287533902102798797998220837590246510135740250
> > 46376937677490009712648124896970078050417018260538
> > 74324986199524741059474233309513058123726617309629
> ...
> 
> > 45876576172410976447339110607218265236877223636045
> > 17423706905851860660448207621209813287860733969412
> > """.split())
> > )
> > 
> 
> yes, good idea

Not if you want to avoid that string to int conversion (as you stated).

That is still there, but in addition you now split the string into a
list and then join the list into a different string.

hp

-- 
   _  | Peter J. Holzer| we build much bigger, better disasters now
|_|_) || because we have much more sophisticated
| |   | [email protected] | management tools.
__/   | http://www.hjp.at/ | -- Ross Anderson 


signature.asc
Description: PGP signature
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Accessing parent objects

2018-03-24 Thread Steven D'Aprano
On Sat, 24 Mar 2018 13:31:13 -0700, Rick Johnson wrote:

> On Saturday, March 24, 2018 at 1:20:24 PM UTC-5, D'Arcy Cain wrote:
[...]
>> I tried various forms of super() but that didn't seem to work.

Define "doesn't see to work".


> Python's super (at least <= 2.x) is notoriously blinkered. I avoid it
> like the plague. And i'd advise you to do the same.

There's nothing wrong with super() in Python 2. You just have to 
understand what you're doing. It's still the right solution for doing  
inheritance the right way.

(Of course it doesn't exist in Python 1, so if Rick is still using Python 
1.5, that's a good excuse not to use super().)

The trick is to use new-style classes that inherit from object, and avoid 
the old-style classes that don't:

# Good
class Spam(object):
...

# Not so good
class Spam:
...



> PS: I am pleased to see you old fellers are finally warming up to the
> wonderful OOP paradigm, but i gotta say, what is most entertaining to me
> is watching you seasoned pros struggle with the simplist OOP concepts.

Ah yes, simple concepts like being unable to get super() working in 
Python 2. Good one Rick.



-- 
Steve

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Entering a very large number

2018-03-24 Thread Steven D'Aprano
On Sun, 25 Mar 2018 00:05:56 +0100, Peter J. Holzer wrote:

[...]
>> yes, good idea
> 
> Not if you want to avoid that string to int conversion (as you stated).
> 
> That is still there, but in addition you now split the string into a
> list and then join the list into a different string.

I'm glad I wasn't the only one who spotted that.

There's something very curious about somebody worried about efficiency 
choosing a *less* efficient solution than what they started with. To 
quote W.A. Wulf:

"More computing sins are committed in the name of efficiency (without 
necessarily achieving it) than for any other single reason — including 
blind stupidity."

As Donald Knuth observed:

"We should forget about small efficiencies, say about 97% of the time: 
premature optimization is the root of all evil."

The Original Poster (OP) is concerned about saving, what, a tenth of a 
microsecond in total? Hardly seems worth the effort, especially if you're 
going to end up with something even slower.



-- 
Steve

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Accessing parent objects

2018-03-24 Thread Rick Johnson
On Saturday, March 24, 2018 at 6:57:29 PM UTC-5, Steven D'Aprano wrote:
> There's nothing wrong with super() in Python 2. You just
> have to understand what you're doing. It's still the right
> solution for doing inheritance the right way.

The problem is, Python's super is not intuitive.

And i'd like to use it. I really would! Because, yes, you
are correct when you say: "super is the proper way to do
inherence". But for some reason, i just cannot get it to
work reliably.

And reading the docs doesn't help.

Seriously, i find it difficult to believe no one else has
been stumped by Python's super. I have used super in other
languages with no issues -- everything is intuitive -- but
in Python, my favorite language, forget about it.

So now, i've got all this Python code with explicit
inheritance, and it works, but it just feels ugly.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Accessing parent objects

2018-03-24 Thread Chris Angelico
On Sun, Mar 25, 2018 at 1:20 PM, Rick Johnson
 wrote:
> On Saturday, March 24, 2018 at 6:57:29 PM UTC-5, Steven D'Aprano wrote:
>> There's nothing wrong with super() in Python 2. You just
>> have to understand what you're doing. It's still the right
>> solution for doing inheritance the right way.
>
> The problem is, Python's super is not intuitive.
>
> And i'd like to use it. I really would! Because, yes, you
> are correct when you say: "super is the proper way to do
> inherence". But for some reason, i just cannot get it to
> work reliably.
>
> And reading the docs doesn't help.
>
> Seriously, i find it difficult to believe no one else has
> been stumped by Python's super. I have used super in other
> languages with no issues -- everything is intuitive -- but
> in Python, my favorite language, forget about it.
>
> So now, i've got all this Python code with explicit
> inheritance, and it works, but it just feels ugly.

So tell me, how do these other (beautifully intuitive) languages
handle multiple inheritance? I'm sure it's really easy to make super()
work when there's exactly one superclass that you can lock in at
compile time.

ChrisA
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Accessing parent objects

2018-03-24 Thread Rick Johnson
On Saturday, March 24, 2018 at 9:29:02 PM UTC-5, Chris Angelico wrote:
> So tell me, how do these other (beautifully intuitive)
> languages handle multiple inheritance? I'm sure it's really
> easy to make super() work when there's exactly one
> superclass that you can lock in at compile time.

After sending my response to Steven, i began to ponder why i
had rejected Python's super (because, after all, it's been a
few years now, and frankly, i forgot), and i realized it was
more a matter of consistency.

You see, Tkinter (the Py2 version) uses old style classes
(though i beleve that design flaw has been rectified in
Py3), and being that i rely heavily on Tkinter for a large
portion of my GUI apps (not because i necessarily prefer
Tkinter over the other offerings, mind you, but simply
because it is in the stdlib) the inconsistency of using
super _outside_ of Tkinter code whilst simultaneously using
explicit inheritance _inside_ Tkinter code was quite
frankly, disturbing to me. Thus, i chose to abandon super
altogether.

But when i make the switch to Python4000, i will probably
adopt super at that time, along with all the other fully
matured goodies.

In light of this revelation, I still don't believe Python's
super() function is as intuitive, as say, Ruby's super
statement is, but it is the correct way to do things,
nonetheless.

So yeah, i'll have to cross that rickety old bridge at some
point in the future. Just not right now.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Accessing parent objects

2018-03-24 Thread Steven D'Aprano
On Sat, 24 Mar 2018 20:08:47 -0700, Rick Johnson wrote:

> After sending my response to Steven, i began to ponder why i had
> rejected Python's super (because, after all, it's been a few years now,
> and frankly, i forgot), and i realized it was more a matter of
> consistency.
> 
> You see, Tkinter (the Py2 version) uses old style classes

That would be an inconvenience and annoyance.


> (though i beleve that design flaw has been rectified in Py3),

Indeed.

Not so much a design flaw as such, just an annoyance due to historical 
reasons. What was a reasonable design back in 1994 didn't age well, but 
backwards-compatibility prevented fixing it until Python 3.


[...]
> the inconsistency of using super
> _outside_ of Tkinter code whilst simultaneously using explicit
> inheritance _inside_ Tkinter code was quite frankly, disturbing to me.

“A foolish consistency is the hobgoblin of little minds, adored by little 
statesmen and philosophers and divines.”

https://en.wikiquote.org/wiki/Consistency



> Thus, i chose to abandon super altogether.

Baby, bathwater.


> But when i make the switch to Python4000, i will probably adopt super at
> that time, along with all the other fully matured goodies.

So, having avoided the first unstable compatibility-breaking version, 
Python 3000, you're going to wait until the next hypothetical unstable, 
compatibility-breaking version before upgrading?

Python 3 is now six point releases in (and very soon to have a seventh, 
3.7 being in beta as we speak). It is stable, feature-rich, and a joy to 
work in. As well as a heap of great new features, there have been a 
metric tonne of performance improvements, making Python 3 faster than 2.7 
for many tasks, e.g.

https://mail.python.org/pipermail/python-dev/2017-July/148641.html

Python 4 is not going to be a massively compatibility-breaking change 
like Python 3 was, and version 4 is likely about 5 or 6 years away. Some 
hypothetical "Python 4000", or more likely "5000", is at least a decade 
away, if it ever occurs again. (Which it probably won't.)

In the meantime, Python 2.7 will fall out of extended support in less 
than two years.

Time to get with the programme, Rick, and stop living in the past :-)



> In light of this revelation, I still don't believe Python's super()
> function is as intuitive, as say, Ruby's super statement is, but it is
> the correct way to do things, nonetheless.

For comparison, here's how Python's super works in 3.x:

def method(self, spam, eggs, cheese):
result = super().method(spam, eggs, cheese)

In other words, you must explicitly state the method you are calling, and 
give the arguments you want to pass on. Of course you can manipulate or 
remove those arguments as needed, or add new ones:

result = super().method(spam+1, eggs*2, keyword='aardvark')

because it's just an ordinary method call. In fact, once you have got the 
super proxy, you can even call another method:

result = super().something_different(arg)

if you need to for some reason. Remember: super() in Python gives you a 
proxy to the parent classes themselves, not just the parent's method of 
the same name.

Ruby's super reduces typing, at the cost of needing more magic and less 
flexibility:

http://rubylearning.com/satishtalim/ruby_overriding_methods.html

Ruby's super doesn't return a superclass proxy, it automagically calls 
the same method as the current method, so you can't delegate to a 
different method if required. In addition, Ruby doesn't support multiple 
inheritance, which is exactly when super() is most important.


Ruby's super calls the method in two ways:

- with no arguments, using the parenthesis-free syntax, 
  Ruby automagically forwards the same arguments to the 
  (single) parent;

- with parentheses, you have to manually pass the arguments
  you want to pass.


So there's weird magic going on where `super` and `super()` both call the 
method but with different arguments. Ewww.

But yes, Ruby's super requires less typing for the common case of "call 
the parent's method and pass the exact same arguments".



> So yeah, i'll have to cross that rickety old bridge

I see what you did there.



-- 
Steve

-- 
https://mail.python.org/mailman/listinfo/python-list