Hi everyone,
I possibly found a bug in class __init__ and would like to fix it. So I'm looking for a mentor to help me.
`class Foo: def __init__(self, bar=[]): self.list = bar
spam_1 = Foo() spam_2 = Foo()
spam_1.list.append(42) print(spam_2.list)`
At least I think it's a bug. Maybe it's a feature..
Best Regards, Jus
Hi everyone,
I possibly found a bug in class initialization and would like to fix it. Because it's my first journey to core-dev, I would really appreciate the help of a mentor that I may ask a few questions to get me up to speed.
To my person, I have previously worked on larger projects in python, c, and c++ if that information helps, and I'm really curious to learn more about the interiors of the greatest interpreter known to wo-/men.
Here comes the bug-producing example:
`class Foo: def __init__(self, bar=[]): self.list = bar
spam_1 = Foo() spam_2 = Foo()
spam_1.list.append(42) print(spam_2.list)`
At least I think it's a bug. Maybe it's a feature..
Best Regards, Jus
---
f*** me https://github.com/jusjusjus on github :)
On 21 April 2017 at 12:09, Justus Schwabedal jschwabedal@gmail.com wrote:
I possibly found a bug in class initialization and would like to fix it.
Here comes the bug-producing example:
`class Foo: def __init__(self, bar=[]): self.list = bar
spam_1 = Foo() spam_2 = Foo()
spam_1.list.append(42) print(spam_2.list)`
At least I think it's a bug. Maybe it's a feature..
It is not a bug.
It is the way in which Python handles mutable keyword arguments. If you want to use something in this way you should go with
def __init__(self, bar=None): if bar is None: bar = []
On Fri, Apr 21, 2017 at 12:09 PM, Justus Schwabedal jschwabedal@gmail.com wrote:
Hi everyone,
I possibly found a bug in class initialization and would like to fix it. Because it's my first journey to core-dev, I would really appreciate the help of a mentor that I may ask a few questions to get me up to speed.
To my person, I have previously worked on larger projects in python, c, and c++ if that information helps, and I'm really curious to learn more about the interiors of the greatest interpreter known to wo-/men.
Here comes the bug-producing example:
`class Foo: def __init__(self, bar=[]): self.list = bar
spam_1 = Foo() spam_2 = Foo()
spam_1.list.append(42) print(spam_2.list)`
At least I think it's a bug. Maybe it's a feature..
Sorry to resurrect an old-ish thread; I haven't looked at Python-dev in several weeks. I just wanted to point out that while everyone on this thread pointed out how this isn't a bug (clear to anyone who's spent enough time with Python), we have here an experienced C/C++ developer who is interested in helping out on Python core devel, and no one took him up on that offer.
Jus, for what it's worth, there are a slew of *actual* Python bugs to be worked on--many languishing for years--due to lack of available developer time. You can have a good look at the (daunting) list of bugs at the old bugs.python.org [1]. IIUC Python development is slowly moving over to GitHub, but the issue list hasn't migrated yet so that would still be the place to start.
If you find a bug that looks worth your time to try to fix, you should probably follow up on the issue for that bug itself. I can't make any promises anyone will have time for mentorship, but I'd be willing to point you in the right direction. I'm not a core developer but I know Python internals reasonably well and might be able to help *depending* on the issue.
Best, Erik
Justus, welcome.
Consider joining the core-mentorship mailing list. If you have specific questions on how to contribute or how to get started, we can help you there. https://mail.python.org/mailman/listinfo/core-mentorship
Thanks, Erik. Yes, CPython has moved to GitHub https://github.com/python/ cpython but we will continue using bugs.python.org as the issue tracker. We prefer that discussions happen on the issue tracker, and GitHub is for code reviewing only.
The Dev Guide has been updated with our new GitHub workflow, specifically: http://cpython-devguide.readthedocs.io/pullrequest.html http://cpython-devguide.readthedocs.io/gitbootcamp.html
Thanks :)
Mariatta Wijaya
On Tue, May 2, 2017 at 9:01 AM, Erik Bray erik.m.bray@gmail.com wrote:
On Fri, Apr 21, 2017 at 12:09 PM, Justus Schwabedal jschwabedal@gmail.com wrote:
Hi everyone,
I possibly found a bug in class initialization and would like to fix it. Because it's my first journey to core-dev, I would really appreciate the help of a mentor that I may ask a few questions to get me up to speed.
To my person, I have previously worked on larger projects in python, c,
and
c++ if that information helps, and I'm really curious to learn more about the interiors of the greatest interpreter known to wo-/men.
Here comes the bug-producing example:
`class Foo: def __init__(self, bar=[]): self.list = bar
spam_1 = Foo() spam_2 = Foo()
spam_1.list.append(42) print(spam_2.list)`
At least I think it's a bug. Maybe it's a feature..
Sorry to resurrect an old-ish thread; I haven't looked at Python-dev in several weeks. I just wanted to point out that while everyone on this thread pointed out how this isn't a bug (clear to anyone who's spent enough time with Python), we have here an experienced C/C++ developer who is interested in helping out on Python core devel, and no one took him up on that offer.
Jus, for what it's worth, there are a slew of *actual* Python bugs to be worked on--many languishing for years--due to lack of available developer time. You can have a good look at the (daunting) list of bugs at the old bugs.python.org [1]. IIUC Python development is slowly moving over to GitHub, but the issue list hasn't migrated yet so that would still be the place to start.
If you find a bug that looks worth your time to try to fix, you should probably follow up on the issue for that bug itself. I can't make any promises anyone will have time for mentorship, but I'd be willing to point you in the right direction. I'm not a core developer but I know Python internals reasonably well and might be able to help *depending* on the issue.
Best, Erik
[1] http://bugs.python.org/ _______________________________________________ Python-Dev mailing list Python-Dev@python.org https://mail.python.org/mailman/listinfo/python-dev Unsubscribe: https://mail.python.org/mailman/options/python-dev/ mariatta.wijaya%40gmail.com
On Fri, Apr 21, 2017 at 11:47:24AM +0200, Justus Schwabedal wrote:
At least I think it's a bug. Maybe it's a feature..
it's indeed a feature.
I possibly found a bug in class __init__ and would like to fix it
technically, it's a method. More precisely, it's the constructor method.
So I'm looking for a mentor to help me.
class Foo: def __init__(self, bar=[]): self.list = bar
spam_1 = Foo() spam_2 = Foo()
spam_1.list.append(42) print(spam_2.list)`
the argument `bar` of your method is instanciated at the time you're declaring the method. It's happening once for the the lifetime of the execution of your code.
By allocating the `bar` reference into the `self.list` member, you're assigning the same *instance* of that list into the `self.list` member.
So everytime you create a new Foo instance, you're actually assigning the same `[]` instance into `self.list` which is why, when you mutate the list, it's happening in all the instances of Foo as well.
I hope it makes sense to you !
In a nutshell. You create two instances and you assign the same list to both of them which you instantiate when you run your code.
id(spam_1.list)
4530230984 # <- Here
id(spam_2.list)
4530230984 # <- Here
id(spam_1)
4530231632 # Nice unique instance
id(spam_2)
4530231200 # Nice unique instance as well
Try
class Foo:
... def __init__(self, list=None): ... self.list = list ...
spam_1 = Foo() spam_2 = Foo([]) <- Cheating. spam_1
<__main__.Foo instance at 0x10e05d9e0>
spam_2
<__main__.Foo instance at 0x10e05d950>
spam_2.list.append(42) print(spam_1.list)
None
print(spam_2.list)
[42]
id(spam_1.list)
4527705752
id(spam_2.list)
4530231488
Or something along those lines :)
On 21 April 2017 at 16:03, Guyzmo via Python-Dev python-dev@python.org wrote:
On Fri, Apr 21, 2017 at 11:47:24AM +0200, Justus Schwabedal wrote:
At least I think it's a bug. Maybe it's a feature..
it's indeed a feature.
I possibly found a bug in class __init__ and would like to fix it
technically, it's a method. More precisely, it's the constructor method.
So I'm looking for a mentor to help me.
class Foo: def __init__(self, bar=[]): self.list = bar
spam_1 = Foo() spam_2 = Foo()
spam_1.list.append(42) print(spam_2.list)`
the argument `bar` of your method is instanciated at the time you're declaring the method. It's happening once for the the lifetime of the execution of your code.
By allocating the `bar` reference into the `self.list` member, you're assigning the same *instance* of that list into the `self.list` member.
So everytime you create a new Foo instance, you're actually assigning the same `[]` instance into `self.list` which is why, when you mutate the list, it's happening in all the instances of Foo as well.
I hope it makes sense to you !
-- Guyzmo _______________________________________________ Python-Dev mailing list Python-Dev@python.org https://mail.python.org/mailman/listinfo/python-dev Unsubscribe: https://mail.python.org/mailman/options/python-dev/mmavrofides%40gmail.com
And it is not related to __init__ method. You have the same behaviour with any other function or method.
def append_to_list(item, l=[]):
... l.append(item) ... return l ...
append_to_list(1)
[1]
append_to_list(2)
[1, 2]
2017-04-21 17:18 GMT+02:00 Manolis Mavrofidis mmavrofides@gmail.com:
In a nutshell. You create two instances and you assign the same list to both of them which you instantiate when you run your code.
id(spam_1.list)
4530230984 # <- Here
id(spam_2.list)
4530230984 # <- Here
id(spam_1)
4530231632 # Nice unique instance
id(spam_2)
4530231200 # Nice unique instance as well
Try
class Foo:
... def __init__(self, list=None): ... self.list = list ...
spam_1 = Foo() spam_2 = Foo([]) <- Cheating. spam_1
<__main__.Foo instance at 0x10e05d9e0>
spam_2
<__main__.Foo instance at 0x10e05d950>
spam_2.list.append(42) print(spam_1.list)
None
print(spam_2.list)
[42]
id(spam_1.list)
4527705752
id(spam_2.list)
4530231488
Or something along those lines :)
On 21 April 2017 at 16:03, Guyzmo via Python-Dev python-dev@python.org wrote:
On Fri, Apr 21, 2017 at 11:47:24AM +0200, Justus Schwabedal wrote:
At least I think it's a bug. Maybe it's a feature..
it's indeed a feature.
I possibly found a bug in class __init__ and would like to fix it
technically, it's a method. More precisely, it's the constructor method.
So I'm looking for a mentor to help me.
class Foo: def __init__(self, bar=[]): self.list = bar
spam_1 = Foo() spam_2 = Foo()
spam_1.list.append(42) print(spam_2.list)`
the argument `bar` of your method is instanciated at the time you're declaring the method. It's happening once for the the lifetime of the execution of your code.
By allocating the `bar` reference into the `self.list` member, you're assigning the same *instance* of that list into the `self.list` member.
So everytime you create a new Foo instance, you're actually assigning the same `[]` instance into `self.list` which is why, when you mutate the list, it's happening in all the instances of Foo as well.
I hope it makes sense to you !
-- Guyzmo _______________________________________________ Python-Dev mailing list Python-Dev@python.org https://mail.python.org/mailman/listinfo/python-dev Unsubscribe: https://mail.python.org/mailman/options/python-dev/
mmavrofides%40gmail.com
-- "Only those who will risk going too far can possibly find out how far one can go. "T.S. Eliot http://0x109.tuxfamily.org _______________________________________________ Python-Dev mailing list Python-Dev@python.org https://mail.python.org/mailman/listinfo/python-dev Unsubscribe: https://mail.python.org/mailman/options/python-dev/ antoine.rozo%40gmail.com
On 21/04/2017 16:03, Guyzmo via Python-Dev wrote:
On Fri, Apr 21, 2017 at 11:47:24AM +0200, Justus Schwabedal wrote:
At least I think it's a bug. Maybe it's a feature..
it's indeed a feature.
I possibly found a bug in class __init__ and would like to fix it
technically, it's a method. More precisely, it's the constructor method.
No, __new__ is the constructor, __init__ is the initializer. It is completely impossible to state when a Python object has been initialised as you can throw in attributes any time you like.
This is correct behaviour. I would suggest that you post this to python-list for a full discussion of what's going on here, but basically the default value for argument bar of __init__ is created at class creation time, and then reused for every instance. This is a common mistake made by newcomers, using mutable default arguments for functions (or methods).
A google search for "python mutable default argument" should find you some useful explanations of what's going on.
Cheers, Paul
On 21 April 2017 at 10:47, Justus Schwabedal jschwabedal@gmail.com wrote:
Hi everyone,
I possibly found a bug in class __init__ and would like to fix it. So I'm looking for a mentor to help me.
`class Foo: def __init__(self, bar=[]): self.list = bar
spam_1 = Foo() spam_2 = Foo()
spam_1.list.append(42) print(spam_2.list)`
At least I think it's a bug. Maybe it's a feature..
Best Regards, Jus
-- Justus Schwabedal
Handy (D): +49 177 939 5281 email: jschwabedal@googlemail.com skype: justus1802
Görlitzer Str. 22 01099 Dresden, Sachsen Germany
Steinkreuzstr. 23 53757 Sankt Augustin, NRW Germany
Python-Dev mailing list Python-Dev@python.org https://mail.python.org/mailman/listinfo/python-dev Unsubscribe: https://mail.python.org/mailman/options/python-dev/p.f.moore%40gmail.com