Ahem; I typed (without checking...):
> Module Symbol.py--
>    class Symbol(str):               <<-  should be: "class Symbol:"
>        def __init__(self):          <<-  should be: "def __init__(self, str):"
>            self.data = intern(str)
and yet again:
> Example use--- 
>    x = Symbol('abc')
>    y = Symbol('a' + 'bc')
>    x is y                       -> yes: same dictionary/property-list    
of course this is wrong, since x and y are different class 
instance objects (I really have to build Python here soon...).  
You'd need to do:
     x.data is y.data             -> yes: same dictionary/property-list    
unless you store the Symbol class itself in the string dictionary:
Module Symbol2.py---
 
    class Symbol:
        def __init__(self, str):
            self.data = {'name':str}
        def __repr__(self):
            return self.getprop('name')
        def getprop(self, key):
            try:
                return self.data[key]
            except KeyError:
                return None
        def putprop(self, key, value):
            self.data[key] = value
         
    _tab = {}   
    def intern(str):
        try:
            return _tab[str]
        except KeyError:                  
            _tab[str] = Symbol(str)      
            return _tab[str]             
 
New-and-improved example use---
 
    x = intern('abc')
    y = intern('a' + 'bc')
    x is y                       -> yes: same class instance   
    print y                      -> 'abc' 
    y.getprop('name')            -> 'abc'
    y.putprop('value', 99)
Now, since this makes 'Symbol' just a wrapper on top of a dictionary,
and since a class is a form of dictionary itself, you can use getattr()
and setattr() built-in methods, and get rid of the dictionary altogether,
saving space:
Module Symbol3.py---
 
    class Symbol:
        def __init__(self, str):
            self.name = str
        def __repr__(self):
            return self.name
        def getprop(self, key):
            try: 
                return getattr(self, key)
            except KeyError:
                return None
        def putprop(self, key, value):
            setattr(self, key, value)
    <rest stays the same>
  
or you could get rid of getprop, putprop as well:
Module Symbol4.py---
 
    class Symbol:
        def __init__(self, str):
            self.name = str
        def __repr__(self):
            return self.name
    _tab = {}   
    def intern(str):
        try:
            return _tab[str]
        except KeyError:                  
            _tab[str] = Symbol(str)      
            return _tab[str]  
New-and-re-improved example use---
 
    x = intern('abc')
    y = intern('a' + 'bc')
    x is y                       -> yes: same class instance    
    print y                      -> 'abc' 
    y.getattr('name')            -> 'abc'
    y.setattr('value', 99)
which is very simple code, but will still run much slower than 
built-in symbol table support.   Sorry for the confusion.
Mark Lutz