Changeset 511
- Timestamp:
- 11/09/09 13:02:22 (3 years ago)
- Location:
- elixir/trunk
- Files:
-
- 1 added
- 3 modified
-
CHANGES (modified) (1 diff)
-
elixir/entity.py (modified) (5 diffs)
-
elixir/options.py (modified) (3 diffs)
-
tests/test_abstract.py (added)
Legend:
- Unmodified
- Added
- Removed
-
elixir/trunk/CHANGES
r510 r511 2 2 3 3 New features: 4 - Entities can now be declared "abstract" so that they do not create a table, 5 etc... This allows, among others, an entity to inherit from multiple abstract 6 classes (patch from Stéphane Klein, closes #89). 4 7 5 8 Changes: -
elixir/trunk/elixir/entity.py
r510 r511 19 19 20 20 import elixir 21 from elixir.statements import process_mutators 21 from elixir.statements import process_mutators, MUTATORS 22 22 from elixir import options 23 23 from elixir.properties import Property … … 65 65 for base in entity.__bases__: 66 66 if isinstance(base, EntityMeta): 67 if is_entity(base): 67 if ( 68 is_entity(base) and 69 (not is_abstract_entity(base)) 70 ): 68 71 if self.parent: 69 72 raise Exception( … … 693 696 return base_props 694 697 698 def is_abstract_entity(dict_or_cls): 699 if isinstance(dict_or_cls, dict): 700 mutators = dict_or_cls.get(MUTATORS, []) 701 else: 702 mutators = getattr(dict_or_cls, MUTATORS, []) 703 704 for m in mutators: 705 if 'abstract' in m[2]: 706 return m[2]['abstract'] 707 708 return False 695 709 696 710 def instrument_class(cls): … … 706 720 707 721 # Determine whether this entity is a *direct* subclass of its base entity 708 entity_base = None722 entity_bases = [] 709 723 for base in cls.__bases__: 710 724 if isinstance(base, EntityMeta): 711 if not is_entity(base): 712 entity_base = base 713 714 if entity_base: 725 if not is_entity(base) or is_abstract_entity(base): 726 entity_bases.append(base) 727 728 base_props = [] 729 if entity_bases: 715 730 # If so, copy the base entity properties ('Property' instances). 716 731 # We use inspect.getmembers (instead of __dict__) so that we also 717 732 # get the properties from the parents of the base_class if any. 718 base_props = getmembers(entity_base, 719 lambda a: isinstance(a, Property)) 720 base_props = [(name, deepcopy(attr)) for name, attr in base_props] 721 else: 722 base_props = [] 733 for base in entity_bases: 734 base_props += [(name, deepcopy(attr)) for name, attr in 735 getmembers(base, lambda a: isinstance(a, Property))] 723 736 724 737 # Process attributes (using the assignment syntax), looking for … … 750 763 # be registered in an entity collection, nor to have a table name and 751 764 # so on. 765 766 if is_abstract_entity(dict_): 767 return 768 752 769 if not is_entity(cls): 753 770 if isinstance(cls, EntityMeta): -
elixir/trunk/elixir/options.py
r505 r511 35 35 | | #mapping-class-inheritance-hierarchies for an | 36 36 | | explanation of the different kinds of inheritances. | 37 +---------------------+-------------------------------------------------------+ 38 | ``abstract`` | Set 'abstract'=True to declare abstract entity. | 39 | | Abstract base classes are useful when you want to put | 40 | | some common information into a number of other | 41 | | entities. Abstract entity will not be used to create | 42 | | any database table. Instead, when it is used as a base| 43 | | class for other entity, its fields will be added to | 44 | | those of the child class. | 37 45 +---------------------+-------------------------------------------------------+ 38 46 | ``polymorphic`` | Whether the inheritance should be polymorphic or not. | … … 165 173 using_options_defaults (nor specifically on a particular Entity) will use the 166 174 global defaults, so you don't have to provide a default value for all options, 167 but only those you want to change. 168 175 but only those you want to change. Please also note that this statement does 176 not work on normal entities, and the normal using_options statement does not 177 work on base classes (because normal options do not and should not propagate to 178 the children classes). 169 179 ''' 170 180 … … 205 215 # 206 216 options_defaults = dict( 217 abstract=False, 207 218 inheritance='single', 208 219 polymorphic=True,
