Wow: list of immediate subclasses?

Carl Banks imbosol at aerojockey.com
Fri Aug 1 01:49:33 EDT 2003


Roman Suzi wrote:
> 
> I am very surprised that modern classes (inherited from object)
> in Python 2.3 show their ancestry, eg:
> 
>>>> object.__subclasses__()
> [<type 'type'>, <type 'int'>, <type 'basestring'>, <type 'list'>, <type 
> 'NoneType'>, <type 'NotImplementedType'>, <type 'module'>, <type 
> 'zipimport.zipimporter'>, <type 'posix.stat_result'>, <type 
> 'posix.statvfs_result'>, <type 'dict'>, <type 'function'>, <type 'dictproxy'>, 
> <type 'member_descriptor'>, <type 'getset_descriptor'>, <type 'tuple'>, <type 
> 'wrapper_descriptor'>, <type 'builtin_function_or_method'>, <type 
> 'method_descriptor'>, <type 'file'>]
> 
> This seems cool introspection tool but raises questions:
> 
> 1- I wonder if it has security consequences (knowing what other
> classes are in there, probably in some other modules). As it adds
> a hole starting from base class "object". Earlier it was possible
> to "chroot" to some custom builtin namespace and provide
> restricted execution.
> 
> 2- how do I get rid of a class completely?
> 
> This doesn't work:
> 
>>>> object.__subclasses__()
> [<type 'type'>, <type 'int'>, <type 'basestring'>, <type 'list'>, <type 
> 'NoneType'>, <type 'NotImplementedType'>, <type 'module'>, <type 
> 'zipimport.zipimporter'>, <type 'posix.stat_result'>, <type 
> 'posix.statvfs_result'>, <type 'dict'>, <type 'function'>]
>>>> class A(object): pass
> ...
>>>> object.__subclasses__()
> [<type 'type'>, <type 'int'>, <type 'basestring'>, <type 'list'>, <type 
> 'NoneType'>, <type 'NotImplementedType'>, <type 'module'>, <type 
> 'zipimport.zipimporter'>, <type 'posix.stat_result'>, <type 
> 'posix.statvfs_result'>, <type 'dict'>, <type 'function'>, <class 
> '__main__.A'>]
>>>> del A
>>>> object.__subclasses__()
> [<type 'type'>, <type 'int'>, <type 'basestring'>, <type 'list'>, <type 
> 'NoneType'>, <type 'NotImplementedType'>, <type 'module'>, <type 
> 'zipimport.zipimporter'>, <type 'posix.stat_result'>, <type 
> 'posix.statvfs_result'>, <type 'dict'>, <type 'function'>, <class 
> '__main__.A'>]
>>>>
> 
> Sincerely yours, Roman Suzi


__subclasses__ is a list of weak references, so the class can be
collected even though it's listed in __subclasses__.  For whatever
reason, class A isn't deleted by reference counts, but cyclic garbage
collection gets it.



Python 2.2.3c1 (#12, May 27 2003, 21:32:04) 
[GCC 2.95.4 20011002 (Debian prerelease)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> class A(object): pass
... 
>>> object.__subclasses__()
[<type 'type'>, <type 'list'>, <type 'NoneType'>, <type 'NotImplementedT
ype'>, <type 'module'>, <type 'posix.stat_result'>, <type 'posix.statvfs
_result'>, <type 'dict'>, <type 'function'>, <type 'str'>, <type 'file'>
, <class '__main__.A'>]
>>> del A
>>> object.__subclasses__()
[<type 'type'>, <type 'list'>, <type 'NoneType'>, <type 'NotImplementedT
ype'>, <type 'module'>, <type 'posix.stat_result'>, <type 'posix.statvfs
_result'>, <type 'dict'>, <type 'function'>, <type 'str'>, <type 'file'>
, <class '__main__.A'>]
>>> 1
1
>>> 1
1
>>> 1
1
>>> import gc
>>> gc.collect()
6
>>> object.__subclasses__()
[<type 'type'>, <type 'list'>, <type 'NoneType'>, <type 'NotImplementedT
ype'>, <type 'module'>, <type 'posix.stat_result'>, <type 'posix.statvfs
_result'>, <type 'dict'>, <type 'function'>, <type 'str'>, <type 'file'>
]



-- 
CARL BANKS




More information about the Python-list mailing list