Is types.InstanceType no longer valid with Python 2.2 
Author Message
 Is types.InstanceType no longer valid with Python 2.2

Hi,

after updating to python 2.2 I've gotten some errors yielded by my
lines:

class foo:
    pass

ss = 'foo()'
ff = eval(ss)
assert(type(ff) == types.InstanceType)

Because until version 2.1 of Python any instantiated object has its
type 'instance', but with Python 2.2 this has been changed. Now the
same object if for example is created dynamically with 'eval()' (in my
case) it's a 'new-style'-class and its type-output has been changed:

type(ff) = '__main__.foo'

That's okay, but with my asserts I only wanted to assure that there an
instantiated object, instead of a list or a tuple will be used!

For deeper leveled classes it will look like:

from BBX.Base.corbautil import ORBFacade
orb_facade = ORBFacade()
type(orb_facade)

Quote:
>>> 'BBX.Base.corbautil.ORBFacade'

I don't want to add the whole nesting level of the testable object in
an 'isinstance'-call nor can I use the assert-statement any longer.

Do you know a short way to assure that the variable is an object
independent of the class-type?

Any comments and issues are appreciated.

Ciao, Georg



Mon, 21 Jun 2004 22:37:49 GMT  
 Is types.InstanceType no longer valid with Python 2.2


Quote:
> Hi,

> after updating to Python 2.2 I've gotten some errors yielded by my
> lines:

> class foo:
>     pass

> ss = 'foo()'
> ff = eval(ss)
> assert(type(ff) == types.InstanceType)

> Because until version 2.1 of Python any instantiated object has its
> type 'instance', but with Python 2.2 this has been changed. Now the
> same object if for example is created dynamically with 'eval()' (in my
> case) it's a 'new-style'-class and its type-output has been changed:

> type(ff) = '__main__.foo'

> That's okay, but with my asserts I only wanted to assure that there an
> instantiated object, instead of a list or a tuple will be used!

> For deeper leveled classes it will look like:

> from BBX.Base.corbautil import ORBFacade
> orb_facade = ORBFacade()
> type(orb_facade)

> >>> 'BBX.Base.corbautil.ORBFacade'

> I don't want to add the whole nesting level of the testable object in
> an 'isinstance'-call nor can I use the assert-statement any longer.

> Do you know a short way to assure that the variable is an object
> independent of the class-type?

> Any comments and issues are appreciated.

> Ciao, Georg

assert isinstance(ff, foo)

--

Emile van Sebille

---------



Mon, 21 Jun 2004 23:39:28 GMT  
 Is types.InstanceType no longer valid with Python 2.2
Emile,

On Thu, 3 Jan 2002 07:39:28 -0800, "Emile van Sebille"

[snipped]

Quote:

>assert isinstance(ff, foo)

thanks for coming back. It's a pity, but I really have to apologize
for myself not having spended more time to describe my problem in
shorter terms.

I'm only looking for a solution to decide wether a variable is an
instantiated object. The class's name is not of any interest.

In my special case I 'flatten' a deeply structured Python-object via
recursively calling a small helper script. Inside of that the type of
the current passed variable to flatten have to be decided. The
algorithm itself does not know anything about the type. It's only some
sort of meta-processing -- only dealing with the data, not changing or
interpreting them.
If the passed variable is an instance of a class, the __dict__ entries
will be examined by calling the algorithm again. Lists and
dictionaries have to be handled in a different manner.

Therefore I need recognizing an instantion of a class. If I could be
assured that only a class-instantiation could have a __dict__ then a
possible solution would be try..catch AttributeError to catch all
other items. But with Python 2.1 the InstanceType decision was more
elegant.

Ciao, Georg



Tue, 22 Jun 2004 00:49:34 GMT  
 Is types.InstanceType no longer valid with Python 2.2

    Georg> after updating to Python 2.2 I've gotten some errors yielded by
    Georg> my lines:

    Georg> class foo:
    Georg>     pass

    Georg> ss = 'foo()'
    Georg> ff = eval(ss)
    Georg> assert(type(ff) == types.InstanceType)

    Georg> Because until version 2.1 of Python any instantiated object has
    Georg> its type 'instance', but with Python 2.2 this has been
    Georg> changed.

Works for me:

    >>> class foo: pass
    ...
    >>> ff = foo()
    >>> type(ff)
    <type 'instance'>
    >>> import types
    >>> type(ff) == types.InstanceType
    1
    >>> ss = 'foo()'
    >>> ff = eval(ss)
    >>> type(ff) == types.InstanceType
    1

Try pasting a simple interactive session or script (with output) that
demonstrates that this fails for you.

--



Tue, 22 Jun 2004 00:17:13 GMT  
 Is types.InstanceType no longer valid with Python 2.2


[snipped]

Quote:
> Therefore I need recognizing an instantion of a class. If I could be
> assured that only a class-instantiation could have a __dict__ then a
> possible solution would be try..catch AttributeError to catch all
> other items. But with Python 2.1 the InstanceType decision was more
> elegant.

> Ciao, Georg

Aside from Skip verifying that InstanceType works in 2.2 (which I hadn't,
but have since) and so it should for you, one attribute that may do it is
__class__.  I'm not aware that this is used otherwise.

HTH,

--

Emile van Sebille

---------



Tue, 22 Jun 2004 02:51:51 GMT  
 Is types.InstanceType no longer valid with Python 2.2

Quote:
> Aside from Skip verifying that InstanceType works in 2.2 (which I hadn't,
> but have since) and so it should for you, one attribute that may do it is
> __class__.  I'm not aware that this is used otherwise.

Python 2.2+ (#486, Dec 22 2001, 21:46:52)
[GCC 2.95.3 20010315 (SuSE)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
Quote:
>>> list.__class__

<type 'type'>

Regards,
Martin



Tue, 22 Jun 2004 10:02:35 GMT  
 Is types.InstanceType no longer valid with Python 2.2
Skip,



[snipped]

Quote:
>Try pasting a simple interactive session or script (with output) that
>demonstrates that this fails for you.

Python 2.2 (#28, Dec 21 2001, 12:21:22) [MSC 32 bit (Intel)] on win32
Type "copyright", "credits" or "license" for more information.
IDLE 0.8 -- press F1 for help
Quote:
>>> import types
>>> class foo:

        pass

Quote:
>>> f = foo()
>>> type(f)
<type 'instance'>
>>> type(f) == types.InstanceType
1
>>> class foo2(object):

        pass

Quote:
>>> f2 = foo2()
>>> type(f2)

<class '__main__.foo2'>

Quote:
>>> type(f2) == types.InstanceType
0

You see the problem?! With old-type classes the comparision succeeds,
with new-type classes it fails.
The type of the instance will show the whole class-structure, but
that's not of any interest (as mentioned in posting to Emile).
Okay, one way would be to compare the type of the object with all
other types in 'types' (except InstanceType). If all fail, the object
must be an instance of a class. Not very satisfying, is it.

Ciao, Georg



Wed, 23 Jun 2004 00:29:03 GMT  
 Is types.InstanceType no longer valid with Python 2.2

    ...

Quote:
> If the passed variable is an instance of a class, the __dict__ entries
> will be examined by calling the algorithm again. Lists and
> dictionaries have to be handled in a different manner.

So what do you want to do if the passed variable is an instance of
a class (with its own __dict__ or __slots__) AND is a list or dictionary
too?

class fooledyou(list):
    def __init__(self, *any):
        list.__init__(self, *any)
        self.also = 'an attribute'

This is Python 2.2, and indeed the key improvement out of all the
many ones that are in 2.2 over 2.1.  "Being a class's instance",
"having a __dict__", and "being a list" (or dict) are not mutually
exclusive any more.

So, you probably need to re-think your approach.

Alex



Wed, 23 Jun 2004 01:09:12 GMT  
 Is types.InstanceType no longer valid with Python 2.2

Quote:
> You see the problem?! With old-type classes the comparision succeeds,
> with new-type classes it fails.
> The type of the instance will show the whole class-structure, but
> that's not of any interest (as mentioned in posting to Emile).
> Okay, one way would be to compare the type of the object with all
> other types in 'types' (except InstanceType). If all fail, the object
> must be an instance of a class. Not very satisfying, is it.

  isinstance(x, object)    # true for all new-style instances

  issubclass(type(x), object)    # ditto

## Jason Orendorff    http://www.jorendorff.com/



Wed, 23 Jun 2004 01:01:23 GMT  
 Is types.InstanceType no longer valid with Python 2.2

    >>> f = foo()
    >>> type(f)
    <type 'instance'>
    >>> type(f) == types.InstanceType
    1
    >>> f2 = foo2()
    >>> type(f2)
    <class '__main__.foo2'>
    >>> type(f2) == types.InstanceType
    0

Hmmm...  Now I'm a bit perplexed.  There's a whole lot of meta-stuff going
on I think.  First, I tried this:

    >>> hasattr(f1, "__class__")
    1
    >>> hasattr(f2, "__class__")
    1

That seemed okay, except all the type constructors also have __class__
attributes:

    >>> hasattr(list, "__class__")
    1
    >>> hasattr(object, "__class__")
    1
    >>> hasattr(int, "__class__")
    1

Bummer.  Next I tried:

    >>> type(f1) == types.InstanceType or isinstance(f1, object)
    1
    >>> type(f2) == types.InstanceType or isinstance(f2, object)
    1

Seemed logical, except the type constructors are also instances of object:

    >>> type(list) == types.InstanceType or isinstance(list, object)
    1

The last thing I tried was using issubclass, but this gave me some bizarre
results:

    >>> isinstance(f1, object)
    1

Huh?  I thought, "so foo must be a subclass of object", but it's not:

    >>> issubclass(foo, object)
    0

How can foo be a classic class with no bases, f1 be both an instance of foo
and of object, but foo not be a subclass of object?  Just to pull all the
bits together in a simple example, starting from a fresh interpreter prompt:

    >>> class foo: pass
    ...
    >>> f1 = foo()
    >>> f1.__class__
    <class __main__.foo at 0x821b964>
    >>> f1.__class__.__bases__
    ()
    >>> isinstance(f1, foo)
    1
    >>> isinstance(f1, object)
    1
    >>> issubclass(foo, object)
    0

I thought I understood this stuff, but my brain is about to explode, so I'll
have to stop here.

Skip



Wed, 23 Jun 2004 01:19:25 GMT  
 Is types.InstanceType no longer valid with Python 2.2
        ...

Quote:
> How can foo be a classic class with no bases, f1 be both an instance of
> foo
> and of object, but foo not be a subclass of object?  Just to pull all the

Implementatively speaking, it boils down to half a line in source file:
Objects/typeobject.c:

    387 int
    388 PyType_IsSubtype(PyTypeObject *a, PyTypeObject *b)
    389 {
        ...
    392         if (!(a->tp_flags & Py_TPFLAGS_HAVE_CLASS))
    393                 return b == a || b == &PyBaseObject_Type;

The "half a line" being the part of line 393 from the || to the ; --
basically, this says "if the second argument is builtin `object', then,
yes, type a IS a subtype of it, WHATEVER type a may be".

The insinstance built-in boils down to PyType_IsSubtype when the second
argument is not a class -- in Objects/abstract.c:

   1890 int
   1891 PyObject_IsInstance(PyObject *inst, PyObject *cls)
   1892 {
        ...
   1897         if (PyClass_Check(cls) && PyInstance_Check(inst)) {
        ...
   1902         else if (PyType_Check(cls)) {
   1903                 retval = PyObject_TypeCheck(inst, (PyTypeObject
*)cls);

OTOH,  PyObject_IsSubclass (lines 1946 ff of the same source file) does
not call PyType_IsSubtype under any circumstances -- rather, it works
via abstract_get_bases (lines 1842 ff, same source).

I'm not implying this is RIGHT, mind you -- I have no opinion on that yet;
it's just what  IS happening in this case you're observing.

Alex



Wed, 23 Jun 2004 03:29:28 GMT  
 Is types.InstanceType no longer valid with Python 2.2
        ...

Quote:
> Okay, one way would be to compare the type of the object with all
> other types in 'types' (except InstanceType). If all fail, the object
> must be an instance of a class. Not very satisfying, is it.

Particularly not *correct* -- it would identify, e.g., the result of an
array.array call as "an instance of a class", which it most surely ISN'T.

Alex



Wed, 23 Jun 2004 05:39:51 GMT  
 Is types.InstanceType no longer valid with Python 2.2

Quote:

[snip]

> How can foo be a classic class with no bases, f1 be both an instance of foo
> and of object, but foo not be a subclass of object?  Just to pull all the
> bits together in a simple example, starting from a fresh interpreter prompt:

>     >>> class foo: pass
>     ...
>     >>> f1 = foo()
>     >>> f1.__class__
>     <class __main__.foo at 0x821b964>
>     >>> f1.__class__.__bases__
>     ()
>     >>> isinstance(f1, foo)
>     1
>     >>> isinstance(f1, object)
>     1
>     >>> issubclass(foo, object)
>     0

> I thought I understood this stuff, but my brain is about to explode, so I'll
> have to stop here.

That surprised me a lot too. However, I noticed that:

Quote:
>>> class foo:pass
...
>>> isinstance(foo(), object)
1
>>> issubclass(foo, object)
0
>>> issubclass(type(foo()), object)
1
>>> import types
>>> issubclass(types.InstanceType, object)
1
>>> types.InstanceType.__bases__

(<type 'object'>,)

It may be that foo() appears to be an instance of object because
type(foo()) is a subclass of object. not because object is some sort of
hidden baseclass of foo. The surprise then, comes from type(foo()) !=
foo for old style classes.

Since one of the results of healing the type class dichotomy would be
type(foo()) == foo, and hence

isinstance(A(), B) == issubclass(type(A()), B),

I have halfway convinced myself that it does make sense after all.

Hope this helps,

Roeland
--

"Half of what I say is nonsense. Unfortunately I don't know which half"



Wed, 23 Jun 2004 07:24:10 GMT  
 Is types.InstanceType no longer valid with Python 2.2

Quote:

> How can foo be a classic class with no bases, f1 be both an instance of foo
> and of object, but foo not be a subclass of object?  

Would you agree that the following is sensible:

Quote:
>>> class foo:pass
...
>>> f=foo()
>>> import types
>>> isinstance(f,types.InstanceType)

1

f's type is <type 'instance'>, so f is an instance of InstanceType,
just as isinstance(1, int). Now, would you also agree that

Quote:
>>> types.InstanceType.__bases__

(<type 'object'>,)

is meaningful, i.e. that object is a base of instance? (every type,
eventually, has object as a base type)

If you accept both separately, you should also accept
isinstance(f, object).

Regards,
Martin



Wed, 23 Jun 2004 15:37:12 GMT  
 Is types.InstanceType no longer valid with Python 2.2


Quote:


>    ...
>> If the passed variable is an instance of a class, the __dict__ entries
>> will be examined by calling the algorithm again. Lists and
>> dictionaries have to be handled in a different manner.

>So what do you want to do if the passed variable is an instance of
>a class (with its own __dict__ or __slots__) AND is a list or dictionary
>too?

>class fooledyou(list):
>    def __init__(self, *any):
>        list.__init__(self, *any)
>        self.also = 'an attribute'

>This is Python 2.2, and indeed the key improvement out of all the
>many ones that are in 2.2 over 2.1.  "Being a class's instance",
>"having a __dict__", and "being a list" (or dict) are not mutually
>exclusive any more.

>So, you probably need to re-think your approach.

After having a look at the code you mentioned, their seems no way to
differ between instances of class-objects and all other built-in types
using something like the already mentioned types.InstanceType.

So, I really have to change the algorithm and check for other
indicators than to that one.

Thank you and all the others for information,

Ciao, Georg



Wed, 23 Jun 2004 21:29:34 GMT  
 
 [ 17 post ]  Go to page: [1] [2]

 Relevant Pages 

1. Python 2.2, creating new types from base types

2. New User Question: extension types and python 2.2/class/type

3. py2exe for Python 2.2 not finding modules? [long]

4. Problem: new type in Python 2.2

5. Python ActiveX Scripting Engine (0x80020009) Error - KeyboardInterrupt - python 2.2

6. Python 2.2 + Win32All 146 = Python/ASP Failures

7. Python 2.0 / Python 2.2

8. Python 2.1 == Jython 2.1 != Python 2.2?

9. VIM - python errors after upgrading to Python 2.2 (Windows OLE)

10. The object named 'type', in 2.2

11. prep my types for 2.2?

12. Integer coercion and 2.2 Type/Class changes

 

 
Powered by phpBB® Forum Software