Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

problems with the types module

0 views
Skip to first unread message

Michele Simionato

unread,
Dec 11, 2002, 2:23:06 PM12/11/02
to
Consider the following script:

------ begin types1.py -----

from types import *

class C(object):
def m(self,x): return x*x
assert type(m) is FunctionType
print 'type of m inside its class:',type(m)

print 'type of C.m:', type(C.m)
assert type(C.m) is MethodType

------ end types1.py -----

The output is

type of m inside its class: <type 'function'>
type of C.m: <type 'instance method'>

i.e. the same object is seen as a function inside the class scope and as an
instance method outside the class scope. To me, this fact was quite surprising,
I don't like to have a changing type depending on the context. Maybe a unique
'function' type for both functions and methods would have been a simpler
solution.

In any case, this not such a big problem. However, consider the following
script, where static methods appear:

------ begin types2.py -----

from types import *

class C(object):
def m(self,x): return x*x
m=staticmethod(m)
#assert type(m) is ?????
print 'type of m inside its class:',type(m)

print 'type of C.m:', type(C.m)
assert type(C.m) is MethodType

------ end types2.py -----

The output of this script is

type of m inside its class: <type 'staticmethod'>
type of C.m: <type 'function'>

Now, C.m is no more an instance method, but it is a function (I understand
the logic in that), whereas the type of m is ?????
By ????? I mean that in the types modules there is no StaticMethodType,
I couldn't find any correct assertion for the type of m !
According to the documentation in types the following names are defined:

NoneType
TypeType
IntType
LongType
FloatType
ComplexType
StringType
UnicodeType
TupleType
ListType
DictType
DictionaryType
FunctionType
LambdaType
GeneratorType
CodeType
ClassType
InstanceType
MethodType
UnboundMethodType
BuiltinFunctionType
BuiltinMethodType
ModuleType
FileType
XRangeType
SliceType
EllipsisType
TracebackType
FrameType
BufferType
StringTypes

There is no StaticMethodType. At the best, this in inconsistent with the
output of type(m) when invoked in its class. I am looking forward for
reactions and comments, yours

--
Michele Simionato - Dept. of Physics and Astronomy
210 Allen Hall Pittsburgh PA 15260 U.S.A.
Phone: 001-412-624-9041 Fax: 001-412-624-9163
Home-page: http://www.phyast.pitt.edu/~micheles/

Terry Reedy

unread,
Dec 11, 2002, 3:51:45 PM12/11/02
to

"Michele Simionato" <mi...@pitt.edu> wrote in message
news:2259b0e2.02121...@posting.google.com...

> class C(object):
> def m(self,x): return x*x
> print 'type of m inside its class:',type(m)
>
> print 'type of C.m:', type(C.m)

> The output is


>
> type of m inside its class: <type 'function'>
> type of C.m: <type 'instance method'>
>
> i.e. the same object is seen as a function inside the class scope
and as an
> instance method outside the class scope. To me, this fact was quite
surprising,
> I don't like to have a changing type depending on the context.

Does the following 'changing type' surprise or bother you?

>>> a=1
>>> type(a)
<type 'int'>
>>> a=[a]
>>> type(a)
<type 'list'>

Your problem is your preconception/misunderstanding of class
construction and attribute access. Its somewhat baroque. Using id()
reveals the folowing:

>>> class demo:
... def f(): pass
... print id(f), type(f)
...
7958288 <type 'function'>
>>> print id(demo.f), type(demo.f)
7716912 <type 'instance method'>

The name 'f' is *not* (bound to) the same object in the two contexts,
any more than 'a' is in my snippet above (where the rebinding is more
obvious). When a class statement is executed, the body (code) is
executed first, in a new namespace, *before* the class object exists.
Then the class name, bases tuple, and new namespace are passed as
arguments to the class constructor (its metatype or metaclass). At
some point, the function is wrapped with an instance method object,
just as I wrapped an int with a list. Introspecting just a bit more
reveals:

>>> dir(demo.f)
[...<standard attributes>... 'im_class', 'im_func', 'im_self']
>> id(demo.f.im_func), type(demo.f.im_func)
(7958288, <type 'function'>) # ie, this is original function
>>> demo == demo.f.im_class
1 #ie, method knows what class its a method of: it is not just a
function
# im_self is None here, but see below

At some point, its as if the following is done:
demo.f = instance_method(demo,f,None/instance)
But when?

>>> demo.__dict__['f']
<function f at 0x00796F10>
>>> 0x00796F10
7958288 #same as before
>>> print id(demo.f), type(demo.f)
7905904 <type 'instance method'> # new id!
>>> demo.f
<unbound method demo.f>
>>> d=demo()
>>> print id(d.f),type(d.f),d.f
7905904 <type 'instance method'> # id same here, not always
>>> d.f
<bound method demo.f of <__main__.demo instance at 0x00794D00>>
>>> d.f.im_self
<__main__.demo instance at 0x00794D00>

So the rebinding happens magically upon access, with im_self being set
or not depending on the access path (via class or instance), and with
__repr__ also being slightly different.

Terry J. Reedy


Carl Banks

unread,
Dec 11, 2002, 3:40:37 PM12/11/02
to
Michele Simionato wrote:
> Consider the following script:
>
> ------ begin types1.py -----
>
> from types import *
>
> class C(object):
> def m(self,x): return x*x
> assert type(m) is FunctionType
> print 'type of m inside its class:',type(m)
>
> print 'type of C.m:', type(C.m)
> assert type(C.m) is MethodType
>
> ------ end types1.py -----
>
> The output is
>
> type of m inside its class: <type 'function'>
> type of C.m: <type 'instance method'>
>
> i.e. the same object is seen as a function inside the class scope
> and as an instance method outside the class scope. To me, this fact
> was quite surprising, I don't like to have a changing type depending
> on the context. Maybe a unique 'function' type for both functions
> and methods would have been a simpler solution.

It's not the same object, though. When you access m in the class
scope, it's just a function, as you defined it.

However, when you write C.m, the class does not return the m you
defined. Instead, it returns a completely different object of type
instancemethod. The instancemethod object holds a reference to the
actual function m. When the instance method is called, calls the
actual function m with the appropriate self argument.

[snip]


> Now, C.m is no more an instance method, but it is a function (I understand
> the logic in that), whereas the type of m is ?????
> By ????? I mean that in the types modules there is no StaticMethodType,
> I couldn't find any correct assertion for the type of m !
> According to the documentation in types the following names are defined:
>

[snip]


>
> There is no StaticMethodType. At the best, this in inconsistent with the
> output of type(m) when invoked in its class. I am looking forward for
> reactions and comments, yours


Maybe it should.

But, IIRC, the language designers are trying to phase out the types
module. A lot of built in types (those with constructors, anyways)
have built in symbols that serve as name of the type. So, instead of
using IntType, you should use int. Instead of StringType, you should
use str. Instead of FileType, you should use file.

For static methods, you can use staticmethod.

And one other thing: a lot of people, myself included, believe that
using types explicitly can defeat the dynamicism of Python, which is
what makes Python so great.


--
CARL BANKS

Erik Max Francis

unread,
Dec 11, 2002, 4:05:53 PM12/11/02
to
Michele Simionato wrote:

> i.e. the same object is seen as a function inside the class scope and
> as an
> instance method outside the class scope. To me, this fact was quite
> surprising,
> I don't like to have a changing type depending on the context. Maybe a
> unique
> 'function' type for both functions and methods would have been a
> simpler
> solution.

But they're not the same. Remember that first "self" argument;
functions and methods are handled differently, so a distinction needs to
be made.

--
Erik Max Francis / m...@alcyone.com / http://www.alcyone.com/max/
__ San Jose, CA, USA / 37 20 N 121 53 W / &tSftDotIotE
/ \ Substance is one of the greatest of our illusions.
\__/ Sir Arthur Eddington
The laws list / http://www.alcyone.com/max/physics/laws/
Laws, rules, principles, effects, paradoxes, etc. in physics.

Manuel M. Garcia

unread,
Dec 11, 2002, 4:47:27 PM12/11/02
to
On 11 Dec 2002 11:23:06 -0800, mi...@pitt.edu (Michele Simionato)
wrote:
(edit)

>I couldn't find any correct assertion for the type of m !

I see you already have received pretty complete answers, but here is
your code with the correct 'assert' statement

~~~

import types

class C(object):
def m(self,x): return x*x
m=staticmethod(m)

assert type(m) is staticmethod
print 'type of m inside its class: %r' % (type(m))

assert type(C.m) is types.FunctionType
print 'type of C.m: %r', (type(C.m))

~~~

I agree with Carl Banks, the less type checking your Python code does,
the better. Python has very fluid types and classes; methods and
attributes can be added to a class or an instance anytime during run
time. The "Pythonic" thing to do is to press ahead without type
checking, catching any errors from missing attributes or methods with
"try: except:"

Manuel

David Necas (Yeti)

unread,
Dec 11, 2002, 4:20:29 PM12/11/02
to
On Wed, Dec 11, 2002 at 01:05:53PM -0800, Erik Max Francis wrote:
> Michele Simionato wrote:
>
> > i.e. the same object is seen as a function inside the class scope and
> > as an
> > instance method outside the class scope. To me, this fact was quite
> > surprising,
> > I don't like to have a changing type depending on the context. Maybe a
> > unique
> > 'function' type for both functions and methods would have been a
> > simpler
> > solution.
>
> But they're not the same. Remember that first "self" argument;
> functions and methods are handled differently, so a distinction needs to
> be made.

IIUC type(object) doesn't return type of the object, as we
all thought and as is written everywhere. The underlying
object is unique and can have only one type (and it has not
a name, since it's just some thing in memory).

type(object) in fact returns type of the reference `object'
to the unnamed object, and this is of course contextually
dependent.

OTOH having something NOT contextually dependent would be
nice.

Yeti


Terry Reedy

unread,
Dec 11, 2002, 9:31:42 PM12/11/02
to

"David Necas (Yeti)" <ye...@physics.muni.cz> wrote in message
news:mailman.1039641699...@python.org...

> IIUC type(object) doesn't return type of the object, as we
> all thought and as is written everywhere.

Huh? As I understand and perceive by experiment, yes it does.

>>> a=1
>>> at=type(a)
>>> at
<type 'int'>
>>> type(at)
<type 'type'>

As far as I can tell, type(object) returns the instance of the type
type that is the type of the object. Or did you mean something else?

> The underlying
> object is unique and can have only one type (and it has not
> a name, since it's just some thing in memory).

If you are saying that there is only one instance of type type for
each type (and we would not want more), you are correct.

>>> id(type(a))
504009944
>>> id(type(2))
504009944
>>> type(int)
<type 'type'>
>>> id(int)
504009944

> type(object) in fact returns type of the reference `object'
> to the unnamed object, and this is of course contextually
> dependent.

I am not sure what you are saying above. However, except for possible
complications introduced by new style class or anything I have
forgotten about, the type of an object is fixed at creation (along
with its id). There is no context dependence at all.

Terry J. Reedy


Michele Simionato

unread,
Dec 12, 2002, 9:13:03 AM12/12/02
to
Carl Banks <imb...@vt.edu> wrote in message news:<at894m$csj$1...@solaris.cc.vt.edu>...

> But, IIRC, the language designers are trying to phase out the types
> module. A lot of built in types (those with constructors, anyways)
> have built in symbols that serve as name of the type. So, instead of
> using IntType, you should use int. Instead of StringType, you should
> use str. Instead of FileType, you should use file.
> For static methods, you can use staticmethod.

It is nice to know, but where is it documented ?

I was mislead from the standard documentation. When you look for the
builtin-in function "type", you obtain

type(object)
Return the type of an object. The return value is a type object.
The standard module types defines names for all built-in types.
For instance:

>>> import types
>>> if type(x) == types.StringType: print "It's a string"


If really the types module has to be deprecated (which I now think it
would be a good idea) the example should be changed to

>>> if type(x) is str: print "It's a string"

which is much much better. Are really there plans to deprecated the types
module and will be the documentation changed for Python 2.3 ?

Michael Hudson

unread,
Dec 12, 2002, 10:10:00 AM12/12/02
to
mi...@pitt.edu (Michele Simionato) writes:

> I was mislead from the standard documentation.

Poor gullible fool :) Seriously, this looks quite bad.

> When you look for the builtin-in function "type", you obtain
>
> type(object)
> Return the type of an object. The return value is a type object.
> The standard module types defines names for all built-in types.
> For instance:
>
> >>> import types
> >>> if type(x) == types.StringType: print "It's a string"

Oh dear, that's wrong on so many levels...

> If really the types module has to be deprecated (which I now think it
> would be a good idea) the example should be changed to
>
> >>> if type(x) is str: print "It's a string"
>
> which is much much better.

Of course, the way to write that is

>>> if isinstance(x, str): print "It's not a moose!"

but that doesn't involve the type builtin...

> Are really there plans to deprecated the types
> module

Unlikely. You shouldn't use it for things like StringType, but for
things like TracebackType there's nowhere else to go.

> and will be the documentation changed for Python 2.3 ?

I hope so. Filing a bug report would make it more likely, I guess.

Cheers,
M.

--
The ultimate laziness is not using Perl. That saves you so much
work you wouldn't believe it if you had never tried it.
-- Erik Naggum, comp.lang.lisp

Ronald Oussoren

unread,
Dec 12, 2002, 2:58:31 AM12/12/02
to

On Wednesday, Dec 11, 2002, at 22:20 Europe/Amsterdam, David Necas
(Yeti) wrote:

> On Wed, Dec 11, 2002 at 01:05:53PM -0800, Erik Max Francis wrote:
>> Michele Simionato wrote:
>>
>>> i.e. the same object is seen as a function inside the class scope and
>>> as an
>>> instance method outside the class scope. To me, this fact was quite
>>> surprising,
>>> I don't like to have a changing type depending on the context. Maybe
>>> a
>>> unique
>>> 'function' type for both functions and methods would have been a
>>> simpler
>>> solution.
>>
>> But they're not the same. Remember that first "self" argument;
>> functions and methods are handled differently, so a distinction needs
>> to
>> be made.
>

> IIUC type(object) doesn't return type of the object, as we

> all thought and as is written everywhere. The underlying


> object is unique and can have only one type (and it has not
> a name, since it's just some thing in memory).

type(value) does return the type of the object, the examples of
the OP just print the types of different objects:

class Foo:
def bar(self):
pass

print id(bar), type(bar)

print id(Foo.bar), type(Foo.bar)

On my system this prints:
1118848 <type 'function'>
1155808 <type 'instance method'>

When class Foo is constructed the function object 'bar' is converted to
an instancemethod object.

Ronald


Michele Simionato

unread,
Dec 12, 2002, 3:39:27 PM12/12/02
to
Michael Hudson <m...@python.net> wrote in message news:<7h38yyv...@pc150.maths.bris.ac.uk>...

> mi...@pitt.edu (Michele Simionato) writes:
> > Are really there plans to deprecated the types
> > module
>
> Unlikely. You shouldn't use it for things like StringType, but for
> things like TracebackType there's nowhere else to go.
>
> > and will be the documentation changed for Python 2.3 ?
>
> I hope so. Filing a bug report would make it more likely, I guess.
>
> Cheers,
> M.

Okay, I have filed a documentation bug report, even it is not really a
bug but a request of documentation improving.

M.

Michael Hudson

unread,
Dec 13, 2002, 6:35:30 AM12/13/02
to
mi...@pitt.edu (Michele Simionato) writes:

Cool. Those things count as bugs in our world.

I should try to have a docco bugsplatting day sometime soonish.

Cheers,
M.

--
MARVIN: Oh dear, I think you'll find reality's on the blink again.
-- The Hitch-Hikers Guide to the Galaxy, Episode 12

Laura Creighton

unread,
Dec 13, 2002, 8:56:02 AM12/13/02
to
We have just found a deficiency in our bug submitting process. (Those of
you arriving late can read it all below). Michele didn't know a docco
deficiency was a real bug, and might very likely have gone away and not
filed it unless Michael and others were personally supportive of her
effort. This means we need to change the bug reporting interface so
that it immediately announces 'we like doccu deficiency reports', so
that she wouldn't go away. Of course this will not help if she is so
conditioned to the idea that nobody cares about doccu deficiencies that
she didn't even consider submitting it, that just means society is broken,
but we need to encourage everybody who makes this effort as much as we can.

Thank you Michele for helping us debug our process.

Laura


> mi...@pitt.edu (Michele Simionato) writes:
>
> > Michael Hudson <m...@python.net> wrote in message news:<7h38yyvgto8.fsf@pc15


> 0.maths.bris.ac.uk>...
> > > mi...@pitt.edu (Michele Simionato) writes:
> > > > Are really there plans to deprecated the types
> > > > module
> > >
> > > Unlikely. You shouldn't use it for things like StringType, but for
> > > things like TracebackType there's nowhere else to go.
> > >
> > > > and will be the documentation changed for Python 2.3 ?
> > >
> > > I hope so. Filing a bug report would make it more likely, I guess.
> > >
> > > Cheers,
> > > M.
> >
> > Okay, I have filed a documentation bug report, even it is not really a
> > bug but a request of documentation improving.
>
> Cool. Those things count as bugs in our world.
>
> I should try to have a docco bugsplatting day sometime soonish.
>
> Cheers,
> M.
>
> --
> MARVIN: Oh dear, I think you'll find reality's on the blink again.
> -- The Hitch-Hikers Guide to the Galaxy, Episode 12

> --
> http://mail.python.org/mailman/listinfo/python-list

0 new messages