Skip to content

Instantly share code, notes, and snippets.

@naftaliharris
Last active August 29, 2015 14:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save naftaliharris/68b4a09af50df8c15381 to your computer and use it in GitHub Desktop.
Save naftaliharris/68b4a09af50df8c15381 to your computer and use it in GitHub Desktop.
Finding intransitive subclass relationships in python
"""
transitivity.py
Author: Naftali Harris
Run this in a clean virtualenv to only find intransitive triples in the stdlib.
"""
import pkgutil
import inspect
import collections
from importlib import import_module
def all_classes(module):
return set([x[1] for x in inspect.getmembers(module, inspect.isclass)])
def all_python_classes():
res = set()
for module_loader, name, ispkg in pkgutil.walk_packages():
try:
module = import_module(name)
except:
print name
else:
res |= all_classes(module)
res |= all_classes(__builtins__)
return res
def short_name(A):
return A.__module__ + "." + A.__name__
def get_bad_triplets(types):
counts = collections.defaultdict(int)
for t1 in types:
for t2 in types:
if not issubclass(t1, t2):
continue
for t3 in types:
if issubclass(t2, t3):
counts["eligible"] += 1
if not issubclass(t1, t3):
counts["intransitive"] += 1
counts[("_", short_name(t2), short_name(t3))] += 1
return counts
if __name__ == "__main__":
types = all_python_classes()
counts = get_bad_triplets(types)
for triplet, count in sorted(counts.items(), key=lambda x: -x[1]):
print ("%d\t%s" % (count, triplet)).replace("'", '')
print len(types)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment