Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.python > #84454 > unrolled thread

__bases__ misleading error message

Started byMario Figueiredo <marfig@gmail.com>
First post2015-01-24 10:16 +0000
Last post2015-01-24 22:51 +0100
Articles 8 on this page of 28 — 7 participants

Back to article view | Back to comp.lang.python


Contents

  __bases__ misleading error message Mario Figueiredo <marfig@gmail.com> - 2015-01-24 10:16 +0000
    Re: __bases__ misleading error message Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2015-01-24 23:43 +1100
      Re: __bases__ misleading error message Mario Figueiredo <marfig@gmail.com> - 2015-01-24 22:14 +0100
        Re: __bases__ misleading error message Ian Kelly <ian.g.kelly@gmail.com> - 2015-01-24 14:45 -0700
          Re: __bases__ misleading error message Mario Figueiredo <marfig@gmail.com> - 2015-01-24 23:09 +0100
            Re: __bases__ misleading error message Chris Angelico <rosuav@gmail.com> - 2015-01-25 09:25 +1100
              Re: __bases__ misleading error message Mario Figueiredo <marfig@gmail.com> - 2015-01-24 23:33 +0100
                Re: __bases__ misleading error message Chris Angelico <rosuav@gmail.com> - 2015-01-25 09:37 +1100
                  Re: __bases__ misleading error message Mario Figueiredo <marfig@gmail.com> - 2015-01-24 23:59 +0100
        Re: __bases__ misleading error message Terry Reedy <tjreedy@udel.edu> - 2015-01-24 16:58 -0500
          Re: __bases__ misleading error message Mario Figueiredo <marfig@gmail.com> - 2015-01-24 23:02 +0100
            Re: __bases__ misleading error message Ian Kelly <ian.g.kelly@gmail.com> - 2015-01-24 15:16 -0700
              Re: __bases__ misleading error message Mario Figueiredo <marfig@gmail.com> - 2015-01-24 23:36 +0100
        Re: __bases__ misleading error message Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2015-01-25 14:18 +1100
          Re: __bases__ misleading error message Mario Figueiredo <marfig@gmail.com> - 2015-01-25 12:07 +0100
            Re: __bases__ misleading error message Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2015-01-25 23:00 +1100
              Re: __bases__ misleading error message Mario Figueiredo <marfig@gmail.com> - 2015-01-25 13:49 +0100
                Re: __bases__ misleading error message Marko Rauhamaa <marko@pacujo.net> - 2015-01-25 14:53 +0200
              Re: __bases__ misleading error message Terry Reedy <tjreedy@udel.edu> - 2015-01-25 16:35 -0500
              Re: __bases__ misleading error message Ian Kelly <ian.g.kelly@gmail.com> - 2015-01-25 19:21 -0700
      Re: __bases__ misleading error message Marco Buttu <marco.buttu@gmail.com> - 2015-01-24 23:09 +0100
      Re: __bases__ misleading error message Marco Buttu <marco.buttu@gmail.com> - 2015-01-24 15:12 +0100
    Re: __bases__ misleading error message Terry Reedy <tjreedy@udel.edu> - 2015-01-24 14:24 -0500
      Re: __bases__ misleading error message Mario Figueiredo <marfig@gmail.com> - 2015-01-24 22:03 +0100
      Re: __bases__ misleading error message Marco Buttu <marco.buttu@gmail.com> - 2015-01-24 22:51 +0100
        Re: __bases__ misleading error message Terry Reedy <tjreedy@udel.edu> - 2015-01-24 19:55 -0500
          Re: __bases__ misleading error message Marco Buttu <marco.buttu@gmail.com> - 2015-01-25 11:30 +0100
      Re: __bases__ misleading error message Marco Buttu <marco.buttu@gmail.com> - 2015-01-24 22:51 +0100

Page 2 of 2 — ← Prev page 1 [2]


#84503

FromMarco Buttu <marco.buttu@gmail.com>
Date2015-01-24 23:09 +0100
Message-ID<ma156n$5qj$1@speranza.aioe.org>
In reply to#84461
On 24/01/2015 13:43, Steven D'Aprano wrote:

> Mario Figueiredo wrote:
>
>> >         class Sub:
>> >             pass
>> >
>> >         foo = Sub()
>> >
>> >         Sub.__bases__
>> >         foo.__bases__
>> >
>> >The last statement originates the following error:
>> >
>> >         AttributeError: 'Sub' object has no attribute '__bases__'
> It's a bit ambiguous, but the way to read it is to think of object as a
> synonym for instance.
...
>
>> >Naturally the 'Sub' object has an attribute __bases__.
> Correct, in the sense that classes are objects too. But in the sense of
> object=instance, no. Isn't ambiguous terminology wonderful?

In my opinion it is not ambiguous, because as you say in Python an 
object is a synonym for instance. We can say in Python an object is an 
instance of the type object, that's all. And that's why everything is an 
object in Python:

 >>> isisntace(foo, object) # For every foo
True

So a class (a type) is an instance too, an instance of its metaclass. 
Therefore, the message says that the Sub instance has no attribute 
'__bases__'. In fact the Sub object (instance) has no attribute 
'__bases__' because it is not an instance of type, and only types 
(classes) have this attribute.

So if we want to find some differences between objects, we have to 
distinguish between types (classes) and non-types (non-classes) objects, 
and not between objects and classes.
In the Python documentation there is also a bit of confusion about 
this... In the descriptor howto: "The details of invocation depend on 
whether obj is an object or a class" :/


-- 
Marco Buttu

[toc] | [prev] | [next] | [standalone]


#84595

FromMarco Buttu <marco.buttu@gmail.com>
Date2015-01-24 15:12 +0100
Message-ID<mailman.18142.1422260120.18130.python-list@python.org>
In reply to#84461
On 24/01/2015 13:43, Steven D'Aprano wrote:

> Mario Figueiredo wrote:
>> >         class Sub:
>> >             pass
>> >
>> >         foo = Sub()
>> >
>> >         Sub.__bases__
>> >         foo.__bases__
>> >
>> >The last statement originates the following error:
>> >
>> >         AttributeError: 'Sub' object has no attribute '__bases__'
> It's a bit ambiguous, but the way to read it is to think of object as a
> synonym for instance.

In my opinion it is not ambiguous, because as you say in Python an 
object is a synonym for instance. We can say in Python an object is an 
instance of the type object, that's all. And that's why everything is an 
object in Python:

 >>> isisntace(foo, object) # For every foo
True

So a class (a type) is an instance too (of its metaclass). Therefore, 
the message says that the Sub instance has no attribute '__bases__'. In 
fact the Sub object (instance) has no attribute '__bases__' because it 
is not an instance of type, and only types (classes) have this attribute.

That means in Python sometimes, like the OP one, we have to underline 
the difference between types (classes) and non-types (non-classes) 
objects, instead of between objects and classes. The problem is in the 
Python documentation there is also a bit of confusion about this... In 
the descriptor howto: "The details of invocation depend on whether obj 
is an object or a class" :/

-- 
Marco Buttu

INAF-Osservatorio Astronomico di Cagliari
Via della Scienza n. 5, 09047 Selargius (CA)
Phone: 070 711 80 217
Email: mbuttu@oa-cagliari.inaf.it

[toc] | [prev] | [next] | [standalone]


#84486

FromTerry Reedy <tjreedy@udel.edu>
Date2015-01-24 14:24 -0500
Message-ID<mailman.18093.1422127493.18130.python-list@python.org>
In reply to#84454
On 1/24/2015 5:16 AM, Mario Figueiredo wrote:
>
> Consider the following code at your REPL of choice

>         class Sub:
>             pass
>
>         foo = Sub()
>
>         Sub.__bases__
>         foo.__bases__
>
> The last statement originates the following error:

This is an anomalous situation.  Normally, if a class has an attribute, 
instances have the same attribute (unless overriden).  But this does not 
matter.

>         AttributeError: 'Sub' object has no attribute '__bases__'

In this message, 'Sub' is an adjective, modifying 'object, not naming 
it.  If you attend to the last line of the traceback

     foo.__bases__

which is an integral part of the total error message, the interpretation 
of this exception message should be clear.

>         AttributeError: 'Sub' instance has no attribute '__bases__',

'Sub' is an instance of 'type', so "'Sub' instance" could also be taken 
to mean the class if the traceback were ignored.  But that would also be 
wrong.  An attribute error for the class, such as "Sub.xyz" give a 
message ending with
...
     Sub.xyz
AttributeError: type object 'Sub' has no attribute 'xyz'

-- 
Terry Jan Reedy

[toc] | [prev] | [next] | [standalone]


#84492

FromMario Figueiredo <marfig@gmail.com>
Date2015-01-24 22:03 +0100
Message-ID<MPG.2f2e26f46dbc1475989691@nntp.aioe.org>
In reply to#84486
In article <mailman.18093.1422127493.18130.python-list@python.org>, 
tjreedy@udel.edu says...
> >         AttributeError: 'Sub' object has no attribute '__bases__'
> 
> In this message, 'Sub' is an adjective, modifying 'object, not naming 
> it.  If you attend to the last line of the traceback
> 

My first reaction is to look at 'Sub' as a noun, not an adjective, since 
I know that NAME well on my code as being a noun. Meanwhile I know that 
objects may be qualified (adjectivized) as class objects or instance 
objects. So, I also happen to look at the word "object" as an adjective, 
as Python object semantics would me do.

What you propose is that I look at that phrase the other way around, 
which is kind of contrarian to how you actually use them in your code.


> >         AttributeError: 'Sub' instance has no attribute '__bases__',
> 
> 'Sub' is an instance of 'type', so "'Sub' instance" could also be taken 
> to mean the class if the traceback were ignored.

I agree. Sub instance is still somewhat ambiguous. So, maybe:

     AttributeError: Instance of object 'Sub' has no attribute 
'__bases__'

[toc] | [prev] | [next] | [standalone]


#84497

FromMarco Buttu <marco.buttu@gmail.com>
Date2015-01-24 22:51 +0100
Message-ID<54C413E4.5060208@gmail.com>
In reply to#84486
On 24/01/2015 20:24, Terry Reedy wrote:

> On 1/24/2015 5:16 AM, Mario Figueiredo wrote:
>>
>> Consider the following code at your REPL of choice
>
>>         class Sub:
>>             pass
>>
>>         foo = Sub()
>>
>>         Sub.__bases__
>>         foo.__bases__
>>
>> The last statement originates the following error:
>
> This is an anomalous situation.  Normally, if a class has an attribute,
> instances have the same attribute (unless overriden).  But this does not
> matter.

That is not true: if a class has an attribute, you can not say its 
instances have the same attribute. You can just say if a type defines an 
attribute, all its instances have that attribute. Look at this example:

 >>> class Foo(type):
...     foo = 33
...
 >>> Foo.foo
33
 >>> MyClass = Foo('MyClass', (), {})

MyClass is an instance of Foo, so it must have the attribute foo:

 >>> isinstance(MyClass, Foo)
True
 >>> MyClass.foo
33

But an instance of MyClass is not an instance of Foo, and so MyClass() 
must not have the attribute foo. In fact:

 >>> m = MyClass()
 >>> isinstance(m, Foo)
False
 >>> m.foo
Traceback (most recent call last):
     ...
AttributeError: 'MyClass' object has no attribute 'foo'


-- 
Marco Buttu

[toc] | [prev] | [next] | [standalone]


#84533

FromTerry Reedy <tjreedy@udel.edu>
Date2015-01-24 19:55 -0500
Message-ID<mailman.18117.1422147330.18130.python-list@python.org>
In reply to#84497
On 1/24/2015 4:51 PM, Marco Buttu wrote:
> On 24/01/2015 20:24, Terry Reedy wrote:
>
>> On 1/24/2015 5:16 AM, Mario Figueiredo wrote:
>>>
>>> Consider the following code at your REPL of choice
>>
>>>         class Sub:
>>>             pass
>>>
>>>         foo = Sub()
>>>
>>>         Sub.__bases__
>>>         foo.__bases__
>>>
>>> The last statement originates the following error:
>>
>> This is an anomalous situation.

'This situation' being that Someclass.attro works but Someclass().attro 
raises.

   Normally, if a class has an attribute,

In other words, if 'Someclass.attro' evaluates to an object

>> instances have the same attribute

then 'Someclass().attro' *normally* evaluates to the same object

>> (unless overriden).

(unless 'Someclass().attro' has been bound to a different object)
because attribute lookup on an instance reverts to attribute lookup on 
the class and even its super classes (__bases__).  Someclass.__bases__ 
is special; it is not listed by dir(Someclass), and it is not accessible 
via an instance.

> That is not true:

What I said, as I meant it to be understood, is true.

-- 
Terry Jan Reedy

[toc] | [prev] | [next] | [standalone]


#84561

FromMarco Buttu <marco.buttu@gmail.com>
Date2015-01-25 11:30 +0100
Message-ID<ma2gjf$3na$1@speranza.aioe.org>
In reply to#84533
On 25/01/2015 01:55, Terry Reedy wrote:

> 'This situation' being that Someclass.attro works but Someclass().attro
> raises...
>
> In other words, if 'Someclass.attro' evaluates to an object ...
> then 'Someclass().attro' *normally* evaluates to the same object

I am sorry Terry, but I do not agree, because the word "normally" in 
this context does not have any meaning, and instroduces just confusion. 
In facts this is exactly the case where "Someclass.attro' evaluates to 
an object" *but* hasattr(Someclass(), 'attro'), as expected, is False. 
What do you mean with "normally"?

> because attribute lookup on an instance reverts to attribute lookup on
> the class and even its super classes

Here's the point. The __bases__ attribute is defined by the class type. 
So if isinstance(obj, type) is true, then hasattr(obj, '__bases__') is 
true. In the OP case:

   >>> class Sub: # Python 3
   ...     pass
   ...
   >>> isinstance(Sub, type)
   True
   >>> hasattr(Sub, '__bases__')
   True

But Sub() is not an instance of type (because Sub is not a subclass of 
type), and so Sub() does not have to get the attributes, like __bases__, 
from type, and here's we are:

   >>> foo = Sub()
   >>> isinstance(foo, type)
   False
   >>> foo.__bases__
   Traceback (most recent call last):
     ...
   AttributeError: 'Sub' object has no attribute '__bases__'


In other words, speaking about the lookup machinery, because '__bases__' 
is not in foo.__dict__ Python looks for __bases__ in Sub.__dict__, but 
it does not found it. So it looks in the Sub bases, and we went back to 
the point: Sub is an instance of type, not a subclass of type.


> Someclass.__bases__
> is special; it is not listed by dir(Someclass), and it is not accessible
> via an instance.

In my point of view no attribute is special (maybe just a descriptor is 
a bit special, in some ways). To undestand what happens in these 
situations, we do not have to give a special meaning to the attribute. 
Given `obj.attr`, we just have to know what kind of object is `obj`: 
usually, like in this case, we have to differentiate between classes and 
non-classes objects. In fact __bases__ is not listed by dir(Sub) because 
Sub is a class, and the distinction between classes and non-classes 
objects matters, especially for dir()

-- 
Marco Buttu

[toc] | [prev] | [next] | [standalone]


#84498

FromMarco Buttu <marco.buttu@gmail.com>
Date2015-01-24 22:51 +0100
Message-ID<mailman.18100.1422136299.18130.python-list@python.org>
In reply to#84486
On 24/01/2015 20:24, Terry Reedy wrote:

> On 1/24/2015 5:16 AM, Mario Figueiredo wrote:
>>
>> Consider the following code at your REPL of choice
>
>>         class Sub:
>>             pass
>>
>>         foo = Sub()
>>
>>         Sub.__bases__
>>         foo.__bases__
>>
>> The last statement originates the following error:
>
> This is an anomalous situation.  Normally, if a class has an attribute,
> instances have the same attribute (unless overriden).  But this does not
> matter.

That is not true: if a class has an attribute, you can not say its 
instances have the same attribute. You can just say if a type defines an 
attribute, all its instances have that attribute. Look at this example:

 >>> class Foo(type):
...     foo = 33
...
 >>> Foo.foo
33
 >>> MyClass = Foo('MyClass', (), {})

MyClass is an instance of Foo, so it must have the attribute foo:

 >>> isinstance(MyClass, Foo)
True
 >>> MyClass.foo
33

But an instance of MyClass is not an instance of Foo, and so MyClass() 
must not have the attribute foo. In fact:

 >>> m = MyClass()
 >>> isinstance(m, Foo)
False
 >>> m.foo
Traceback (most recent call last):
     ...
AttributeError: 'MyClass' object has no attribute 'foo'


-- 
Marco Buttu

[toc] | [prev] | [standalone]


Page 2 of 2 — ← Prev page 1 [2]

Back to top | Article view | comp.lang.python


csiph-web