1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169
|
# Copyright 2002 by Jeffrey Chang, Andrew Dalke. All rights reserved.
# This code is part of the Biopython distribution and governed by its
# license. Please see the LICENSE file that should have been included
# as part of this package.
# This is based on some older code by Andrew Dalke.
"""This module implements some base classes used in the Registry
system for Biopython.
Classes:
Registry Implements a Biopython Registry.
RegisterableObject Base class for objects in the Registry.
RegisterableGroup Base class for groups of objects in the Registry.
"""
class Registry:
"""This is a dictionary-like object for storing and retrieving
objects in a registry.
Methods:
register Add a RegisterableObject into the Registry.
Dictionary interface:
__getitem__
get
keys
values
items
"""
def __init__(self, name, load_path=None):
"""Registry(name[, load_path])
Create a new registry. name is the name of the registry.
load_path is an optional path (e.g. Bio.config.dbdefs) that
contains objects for the registry.
"""
self._name = name
self._load_path = load_path
self._name_table, self._abbrev_table = {}, {}
self._autoloaded = self._autoloading = 0
def _autoload(self):
if self._autoloaded or self._autoloading:
return
self._autoloading = 1
self._load(self._load_path)
self._autoloading = 0
self._autoloaded = 1
def _load(self, path):
if path is None:
return
import _support
# Get a list of all the modules in that path.
modulenames = _support.find_submodules(path)
modulenames = filter(lambda x: not x.startswith("_"), modulenames)
modulenames.sort()
# Now load each one of the modules and look for
# RegisterableObject objects in them.
for name in modulenames:
module = _support.load_module(name)
for name, obj in module.__dict__.items():
if name.startswith("_") or \
not isinstance(obj, RegisterableObject):
continue
self.register(obj)
def register(self, obj):
"""S.register(obj)
Add an object to the registry. obj must be a
RegisterableObject object.
"""
self._autoload()
name, abbrev = obj.name, obj.abbrev
abbrev = abbrev or name
if self._name_table.has_key(name):
raise ValueError("%r is a duplicate entry" % (name,))
if self._abbrev_table.has_key(abbrev):
raise ValueError("%r is a duplicate entry" % (abbrev,))
self._name_table[name] = obj
self._abbrev_table[abbrev] = obj
def __getitem__(self, name):
self._autoload()
return self._name_table[name] # raises KeyError for unknown entries
def get(self, name, default=None):
self._autoload()
return self._name_table.get(name, default)
def keys(self):
self._autoload()
return self._name_table.keys()
def values(self):
self._autoload()
return self._name_table.values()
def items(self):
self._autoload()
return self._name_table.items()
def __str__(self):
objs = self.keys()
objs.sort()
if not objs:
return self._name
obj_str = ', '.join(map(repr, objs))
return "%s, exporting %s" % (self._name, obj_str)
__repr__ = __str__
class RegisterableObject:
"""This is a base class for objects that can be added to a registry.
Members:
name The name of the object.
abbrev An abbreviation for the name
"""
def __init__(self, name, abbrev, doc):
"""RegisterableObject(name, abbrev, doc)"""
import re
self.name = name
self.abbrev = abbrev or name
_legal_abbrev = re.compile(r"[a-zA-Z][a-zA-Z0-9_]*$")
check_abbrev = _legal_abbrev.match
if not check_abbrev(self.abbrev):
raise ValueError, "abbrev name of %r is not allowed" % self.abbrev
self.__doc__ = doc
class RegisterableGroup(RegisterableObject):
"""This is a base class for a RegisterableObject that groups many
objects together.
Methods:
add Add an object to the end of the group.
add_after Add an object to the group after another object.
add_before Add an object to the group before another object.
"""
def __init__(self, name, abbrev, doc):
RegisterableObject.__init__(self, name, abbrev, doc)
self.objs = []
def add(self, obj, index=None):
if index is None:
index = len(self.objs)
self.objs.insert(index, obj)
def add_after(self, obj, after):
for i in range(len(self.objs)):
if self.objs[i] == after:
break
else:
raise ValueError, "I couldn't find the insertion point"
self.add(obj, i+1)
def add_before(self, obj, before):
for i in range(len(self.objs)):
if self.objs[i] == before:
break
else:
raise ValueError, "I couldn't find the insertion point"
self.add(obj, i)
|