modeling-cvs Mailing List for Object-Relational Bridge for python (Page 27)
Status: Abandoned
Brought to you by:
sbigaret
You can subscribe to this list here.
2003 |
Jan
|
Feb
|
Mar
(54) |
Apr
(29) |
May
(94) |
Jun
(47) |
Jul
(156) |
Aug
(132) |
Sep
(40) |
Oct
(6) |
Nov
(18) |
Dec
(24) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2004 |
Jan
(18) |
Feb
(59) |
Mar
(7) |
Apr
|
May
(8) |
Jun
(2) |
Jul
(12) |
Aug
(15) |
Sep
(12) |
Oct
(6) |
Nov
(25) |
Dec
(1) |
2005 |
Jan
|
Feb
|
Mar
|
Apr
|
May
(1) |
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
2006 |
Jan
|
Feb
(27) |
Mar
|
Apr
(16) |
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
2009 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
(1) |
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
From: <sbi...@us...> - 2003-05-27 19:03:50
|
Update of /cvsroot/modeling/ProjectModeling/Modeling/doc/HomePage In directory sc8-pr-cvs1:/tmp/cvs-serv17893/doc/HomePage Modified Files: main.tex Log Message: Added DB-server versions Index: main.tex =================================================================== RCS file: /cvsroot/modeling/ProjectModeling/Modeling/doc/HomePage/main.tex,v retrieving revision 1.13 retrieving revision 1.14 diff -C2 -d -r1.13 -r1.14 *** main.tex 6 May 2003 13:52:01 -0000 1.13 --- main.tex 27 May 2003 19:03:47 -0000 1.14 *************** *** 100,104 **** \begin{description} ! \item[Postgresql] python adaptors: \begin{rawhtml} <a href="http://initd.org/software/initd/psycopg">psycopg</a> --- 100,108 ---- \begin{description} ! \item[Postgresql] versions 7.2 and 7.3 (see \begin{rawhtml} ! <a href="http://modeling.sourceforge.net/UserGuide/env-vars-postgresql.html">Postgresql specificities</a>\end{rawhtml} in the User's Guide if you're using v7.3). ! ! ! Supported python adaptors: \begin{rawhtml} <a href="http://initd.org/software/initd/psycopg">psycopg</a> *************** *** 108,114 **** \end{rawhtml} or \begin{rawhtml} ! <a href="http://pypgsql.sourceforge.net">PyGreSQL</a> \end{rawhtml} ! \item[MySQL] python adaptor: \begin{rawhtml} <a href="http://sourceforge.net/projects/mysql-python">MySQL</a> --- 112,122 ---- \end{rawhtml} or \begin{rawhtml} ! <a href="http://pypgsql.sourceforge.net">PyPgSQL</a> \end{rawhtml} ! ! \item[MySQL] tested with v3.23.52 ! ! ! Supported python adaptor: \begin{rawhtml} <a href="http://sourceforge.net/projects/mysql-python">MySQL</a> |
From: <sbi...@us...> - 2003-05-27 17:03:59
|
Update of /cvsroot/modeling/ProjectModeling/Modeling/ModelMasons In directory sc8-pr-cvs1:/tmp/cvs-serv27194/ModelMasons Modified Files: PyModelMason.py Log Message: Fixed log() msgs not making the difference between creating and overwriting a xml-model file Index: PyModelMason.py =================================================================== RCS file: /cvsroot/modeling/ProjectModeling/Modeling/ModelMasons/PyModelMason.py,v retrieving revision 1.9 retrieving revision 1.10 diff -C2 -d -r1.9 -r1.10 *** PyModelMason.py 26 May 2003 15:44:48 -0000 1.9 --- PyModelMason.py 27 May 2003 17:03:57 -0000 1.10 *************** *** 161,166 **** #----------------------------------------------------------------- def create_model_files(self, xml_path, py_path): # model_<modelName>.xml ! self.log('Generating %s'%xml_path) if not self.fake_mode: self.model.saveModelAsXMLFile(xml_path) --- 161,170 ---- #----------------------------------------------------------------- def create_model_files(self, xml_path, py_path): + "Creates or overwrite the model (.xml and .py)" # model_<modelName>.xml ! if os.path.exists(xml_path): ! self.log('Overwriting %s'%xml_path) ! else: ! self.log('Generating %s'%xml_path) if not self.fake_mode: self.model.saveModelAsXMLFile(xml_path) *************** *** 218,223 **** try: os.mkdir(basePath) ! except: self.log('no\n') ! else: self.log('ok\n') self.createFileFromTemplate(init_base.init_base(), os.path.join(self.base_dir,"__init__.py"), --- 222,228 ---- try: os.mkdir(basePath) ! except: self.log('no') ! else: self.log('ok') ! self.log('\n') self.createFileFromTemplate(init_base.init_base(), os.path.join(self.base_dir,"__init__.py"), |
From: <sbi...@us...> - 2003-05-27 17:01:55
|
Update of /cvsroot/modeling/ProjectModeling/Modeling/DatabaseAdaptors/AbstractDBAPI2AdaptorLayer In directory sc8-pr-cvs1:/tmp/cvs-serv26344/DatabaseAdaptors/AbstractDBAPI2AdaptorLayer Modified Files: AbstractDBAPI2Adaptor.py Log Message: Fixed: no rollback on "administrative" cursor since they mostly are in autocommi mode Index: AbstractDBAPI2Adaptor.py =================================================================== RCS file: /cvsroot/modeling/ProjectModeling/Modeling/DatabaseAdaptors/AbstractDBAPI2AdaptorLayer/AbstractDBAPI2Adaptor.py,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** AbstractDBAPI2Adaptor.py 22 Apr 2003 17:05:26 -0000 1.2 --- AbstractDBAPI2Adaptor.py 27 May 2003 17:01:52 -0000 1.3 *************** *** 146,150 **** # problem, I suspect a delayed destruction of the cnx in dropDB() # causing the connection to persist when createDB begins. ! cur.rollback() ; cur.close() cnx.close() del cur, cnx --- 146,150 ---- # problem, I suspect a delayed destruction of the cnx in dropDB() # causing the connection to persist when createDB begins. ! cur.close() cnx.close() del cur, cnx *************** *** 170,174 **** # See comments in createDatabaseWithAdministrativeConnectionDictionary() # --> explicit closing and destruction of cnx and cur are intended here ! cur.rollback() ; cur.close() cnx.close() del cur; del cnx --- 170,174 ---- # See comments in createDatabaseWithAdministrativeConnectionDictionary() # --> explicit closing and destruction of cnx and cur are intended here ! cur.close() cnx.close() del cur; del cnx |
From: <sbi...@us...> - 2003-05-26 16:17:55
|
Update of /cvsroot/modeling/ProjectModeling In directory sc8-pr-cvs1:/tmp/cvs-serv1833 Modified Files: MANIFEST.in Log Message: Updated after merge from brch0.9pre6-1 Index: MANIFEST.in =================================================================== RCS file: /cvsroot/modeling/ProjectModeling/MANIFEST.in,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -d -r1.7 -r1.8 *** MANIFEST.in 26 May 2003 15:57:53 -0000 1.7 --- MANIFEST.in 26 May 2003 16:17:51 -0000 1.8 *************** *** 20,23 **** --- 20,25 ---- recursive-include Modeling/tests/xmlmodels *.txt *.xml + include Modeling/tests/xmlmodels/model_StoreEmployees.xml2 + include Modeling/tests/xmlmodels/model_StoreEmployees.xml3 include Modeling/DatabaseAdaptors/COPYING *************** *** 47,48 **** --- 49,52 ---- recursive-include Modeling/tests README *.py *.xml *.txt + include Modeling/tests/test_generate_python_code.sh + |
From: <sbi...@us...> - 2003-05-26 15:57:56
|
Update of /cvsroot/modeling/ProjectModeling In directory sc8-pr-cvs1:/tmp/cvs-serv26754 Modified Files: MANIFEST.in Log Message: Removed tests/test.cfg, replaced by Postgresql.cfg and MySQL.cfg Index: MANIFEST.in =================================================================== RCS file: /cvsroot/modeling/ProjectModeling/MANIFEST.in,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** MANIFEST.in 10 May 2003 17:38:23 -0000 1.6 --- MANIFEST.in 26 May 2003 15:57:53 -0000 1.7 *************** *** 16,20 **** include Modeling/tests/README include Modeling/tests/TODO ! include Modeling/tests/test.cfg recursive-include Modeling/tests/xmlmodels *.txt *.xml --- 16,21 ---- include Modeling/tests/README include Modeling/tests/TODO ! include Modeling/tests/Postgresql.cfg ! include Modeling/tests/MySQL.cfg recursive-include Modeling/tests/xmlmodels *.txt *.xml |
From: <sbi...@us...> - 2003-05-26 15:45:22
|
Update of /cvsroot/modeling/ProjectModeling/Modeling/ModelMasons/Python_bricks In directory sc8-pr-cvs1:/tmp/cvs-serv21164/ModelMasons/Python_bricks Modified Files: base_module.tmpl init.tmpl module_base.tmpl Added Files: init_base.tmpl Log Message: Merged changes from brch-0_9pre6-1-ModelMasons_base_generation_scheme to trunk Index: base_module.tmpl =================================================================== RCS file: /cvsroot/modeling/ProjectModeling/Modeling/ModelMasons/Python_bricks/base_module.tmpl,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** base_module.tmpl 20 Apr 2003 16:10:40 -0000 1.1 --- base_module.tmpl 26 May 2003 15:44:48 -0000 1.2 *************** *** 1,12 **** ## This template will build the <module>Base.py module ! # Modeling ! #set $custom = 1 #for entity in $entities: #if $entity.parentEntity() and $entity.parentEntity() not in $entities: ! from $entity.parentEntity().moduleName() import $entity.parentEntity().className() #elif $custom: from Modeling.CustomObject import CustomObject #set $custom=0 #end if #end for from Modeling.Validation import ValidationException --- 1,20 ---- ## This template will build the <module>Base.py module ! #import time ! # Generated by mdl_generate_python_code.py / $(time.strftime("%Y/%m/%d %H:%M")) ! # DO NOT MODIFY THIS FILE -- IT WILL BE OVERWRITTEN ! # Instead, modify $(model.packageName).$(entities[0].moduleName()) ! #set $custom=1 ! #set $imported=[] #for entity in $entities: + #if $entity.parentEntity() not in imported: #if $entity.parentEntity() and $entity.parentEntity() not in $entities: ! import $entity.parentEntity().className() # make sure we import in correct order ! from $(model.packageName()).$entity.parentEntity().moduleName() import $entity.parentEntity().className() ! $imported.append($entity.parentEntity())#slurp #elif $custom: from Modeling.CustomObject import CustomObject #set $custom=0 #end if + #end if #end for from Modeling.Validation import ValidationException *************** *** 22,28 **** $entity_props.sort(lambda x,y: cmp(x.name(), y.name())) #if $entity.parentEntity(): ! class $(class_name)Base($(entity.parentEntity().className())): #else ! class $(class_name)Base(CustomObject): #end if """ --- 30,36 ---- $entity_props.sort(lambda x,y: cmp(x.name(), y.name())) #if $entity.parentEntity(): ! class $(class_name)($(entity.parentEntity().className())): #else ! class $(class_name)(CustomObject): #end if """ *************** *** 84,92 **** self._$attr.name = $attr.name #end if - def validate$utils.capitalizeFirstLetter(attr.name())(self, value): - "Edit this to enforce custom business logic" - if 0: # your custom bizlogic - raise ValidationException - return #end if ##* isClassProperty *# #slurp #end for ##* Attributes *# #slurp --- 92,95 ---- Index: init.tmpl =================================================================== RCS file: /cvsroot/modeling/ProjectModeling/Modeling/ModelMasons/Python_bricks/init.tmpl,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** init.tmpl 25 Apr 2003 18:39:13 -0000 1.5 --- init.tmpl 26 May 2003 15:44:48 -0000 1.6 *************** *** 1,3 **** --- 1,5 ---- ## This template will build the __init__.py file + #import time + # Generated by mdl_generate_python_code.py / time.strftime("%Y/%m/%d %H:%M") #set $model_name = str($model().name()) # Load the model *************** *** 18,22 **** --- 20,28 ---- return try: + #if $base_dir: + from $(base_dir).model_$(model_name)_pickle import model_pickle + #else from model_$(model_name)_pickle import model_pickle + #end if import cPickle m=cPickle.loads(model_pickle) *************** *** 33,37 **** --- 39,47 ---- try: + #if $base_dir: + from $(base_dir).model_$(model_name) import model_src + #else from model_$(model_name) import model_src + #end if ModelSet.defaultModelSet().addModelFromXML({'string': model_src}) model=ModelSet.defaultModelSet().modelNamed("$(model_name)") Index: module_base.tmpl =================================================================== RCS file: /cvsroot/modeling/ProjectModeling/Modeling/ModelMasons/Python_bricks/module_base.tmpl,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** module_base.tmpl 25 Apr 2003 18:37:35 -0000 1.2 --- module_base.tmpl 26 May 2003 15:44:48 -0000 1.3 *************** *** 1,6 **** ## This template will build the module ! #for entity in $entities: ! from $(entity.moduleName())Base import $(entity.className())Base ! #end for from Modeling.Validation import ValidationException from mx.DateTime import DateTimeFrom --- 1,6 ---- ## This template will build the module ! #import time ! import $(base_dir) ! # Generated by mdl_generate_python_code.py / time.strftime("%Y/%m/%d %H:%M") from Modeling.Validation import ValidationException from mx.DateTime import DateTimeFrom *************** *** 8,16 **** #for entity in $entities: ! #set $class_name = str($entity.className) #if $entity.parentEntity(): ! class $(class_name)($(class_name)Base): #derive from $(entity.parentEntity().className()) #else ! class $(class_name)($(class_name)Base): #end if """ --- 8,19 ---- #for entity in $entities: ! #set $class_name = $entity.className() ! #set $module_name = $entity.moduleName() ! #set $entity_props=list($entity.newOrOverriddenPythonProperties()) ! $entity_props.sort(lambda x,y: cmp(x.name(), y.name())) #if $entity.parentEntity(): ! class $(class_name)($(base_dir).$(module_name).$(class_name)): #derive from $(entity.parentEntity().className()) #else ! class $(class_name)($(base_dir).$(module_name).$(class_name)): #end if """ *************** *** 23,27 **** # every parameter gets a default value, since the framework needs to be # able to instanciate an object with no parameter at all. ! $(class_name)Base.__init__(self) #end for --- 26,40 ---- # every parameter gets a default value, since the framework needs to be # able to instanciate an object with no parameter at all. ! $(base_dir).$(module_name).$(class_name).__init__(self) ! ! #for attr in $entity_props: ! #if $attr.isClassProperty() and not $attr in $entity.primaryKeyAttributes(): ! def validate$utils.capitalizeFirstLetter(attr.name())(self, value): ! "Edit this to enforce custom business logic" ! if 0: # your custom bizlogic ! raise ValidationException ! return ! #end if ##* isClassProperty *# ! #end for ##* Attributes *# #slurp #end for |
From: <sbi...@us...> - 2003-05-26 15:45:21
|
Update of /cvsroot/modeling/ProjectModeling/Modeling/ModelMasons In directory sc8-pr-cvs1:/tmp/cvs-serv21164/ModelMasons Modified Files: ModelMason.py PyModelMason.py Log Message: Merged changes from brch-0_9pre6-1-ModelMasons_base_generation_scheme to trunk Index: ModelMason.py =================================================================== RCS file: /cvsroot/modeling/ProjectModeling/Modeling/ModelMasons/ModelMason.py,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** ModelMason.py 20 Apr 2003 14:16:42 -0000 1.6 --- ModelMason.py 26 May 2003 15:44:48 -0000 1.7 *************** *** 24,30 **** """ - ModelMason ! Documentation forthcoming. See PyModelMason for an example of use. CVS information --- 24,34 ---- """ ! ModelMason contains the base class for every ''mason'' and is of no interest ! except if you plan to design a new module to generate code/files from a Model. ! ! When this is the case, the class' documentation indicate the rules that should ! be respected to ensure easy integration with the framework's tools such as the ! script mdl_generate_python_code or the ZModeler. CVS information *************** *** 40,46 **** class ModelMason: def __init__(self, model, rootPath, concreteBuilder, bricksDir, ! verbose_mode=0): """ Initializes the ModelMason so that the built files are based on the --- 44,84 ---- class ModelMason: + """ + This class should be the base class for every masons. + + When subclassing this class, you should take care of: + + - call ModelMason.__init__() if it is overridden + + - if the subclass needs to change/create sth. on the filesystem, it *must* + check whether 'fake_mode' is set: if it is set, absolutely no changes + should be made on the disk. + + Methods createEmptyFile(), createFileFromTemplate(), copyFile() and + build_package() can be used without this precaution since they already + check 'self.fake_mode' before making any changes on the disk. + + - call log() to record any action relative to the generation (such as the + creation of a file). Please note that you should be ready to log these + actions even when fake_mode is set. For example, suppose 'file.py' + should be generated but not overwritten; if the file does not exist + you'd log('Creating file file.py'), and if it exists you'd log('File.py + exists, skipping') whether fake_mode is set or not. This makes it + possible for the user to see what would happen whene (re)generating the + code without actually making the changes. + + Following these rules makes it easy to integrate a custom ''mason'' into + the script mdl_generate_python_code and the ZModeler. + + All subclasses need to override build() and put there the logic which + generates the code. You will probably override method tmpl_namespace() as + well (see its documentation for details). + + You can also refer to PyModelMason for an example of use. + + """ def __init__(self, model, rootPath, concreteBuilder, bricksDir, ! verbose_mode=0, fake_mode=0): """ Initializes the ModelMason so that the built files are based on the *************** *** 64,67 **** --- 102,108 ---- generating the files + fake_mode -- if true, do not create or change any file, just report what + would be done + Subclasses may decide to supply a default value for the product's base directory when parameter 'rootPath' is not supplied. *************** *** 75,79 **** bricksDir) self.verbose_mode=verbose_mode ! def fullPathForBrick(self, aBrick): """ --- 116,121 ---- bricksDir) self.verbose_mode=verbose_mode ! self.fake_mode=fake_mode ! def fullPathForBrick(self, aBrick): """ *************** *** 98,103 **** return self.log('Creating empty file %s\n'%filename) ! f = open(filename,"w") ! f.close() def copyFile(self, templateFilename, destinationFilename,overwrite=0): --- 140,146 ---- return self.log('Creating empty file %s\n'%filename) ! if not self.fake_mode: ! f = open(filename,"w") ! f.close() def copyFile(self, templateFilename, destinationFilename,overwrite=0): *************** *** 113,121 **** return self.log('Creating file %s\n'%destinationFilename) ! _f1 = open(self.fullPathForGeneratedFile(destinationFilename),'w') ! _f2 = open(self.fullPathForBrick(templateFilename),'r') ! _f1.write(_f2.read()) ! _f1.close() ! _f2.close() _marker=[] --- 156,165 ---- return self.log('Creating file %s\n'%destinationFilename) ! if not self.fake_mode: ! _f1 = open(self.fullPathForGeneratedFile(destinationFilename),'w') ! _f2 = open(self.fullPathForBrick(templateFilename),'r') ! _f1.write(_f2.read()) ! _f1.close() ! _f2.close() _marker=[] *************** *** 159,169 **** namespace=self.fix_tmpl_namespace(namespace) destFile = self.fullPathForGeneratedFile(destFile) ! if not overwrite and os.path.exists(destFile): self.log("File %s exists, skipping\n"%destFile) return ! self.log("Generating %s... " % destFile) ! f = open(destFile,'w') ! f.write("%s"%self.templateObjectForTemplate(template,namespace=namespace)) ! self.log("done\n") def build(self): --- 203,220 ---- namespace=self.fix_tmpl_namespace(namespace) destFile = self.fullPathForGeneratedFile(destFile) ! file_exists=os.path.exists(destFile) ! if not overwrite and file_exists: self.log("File %s exists, skipping\n"%destFile) return ! if not overwrite or (overwrite and not file_exists): ! self.log("Generating %s" % destFile) ! else: ! self.log("Overwriting %s" % destFile) ! ! if not self.fake_mode: ! f = open(destFile,'w') ! f.write("%s"%self.templateObjectForTemplate(template,namespace=namespace)) ! self.log("... done") ! self.log('\n') def build(self): *************** *** 201,205 **** {'model': self.model} ! Subclasses override this method to provide their own namespace """ return {'model': self.model} --- 252,258 ---- {'model': self.model} ! Subclasses override this method to provide their own namespace. This ! namespace is the default one transmitted to the Cheetah template when no ! specific namespace is passed to method createFileFromTemplate(). """ return {'model': self.model} *************** *** 215,224 **** for pack in string.split(self.model.packageName(), '.')[:-1]: currentPath=os.path.join(currentPath, pack) ! self.log('Creating directory %s... '%currentPath) ! try: ! os.mkdir(currentPath) ! except: self.log('no\n') ! else: self.log('ok\n') ! init=os.path.join(currentPath, '__init__.py') if os.path.exists(init): --- 268,279 ---- for pack in string.split(self.model.packageName(), '.')[:-1]: currentPath=os.path.join(currentPath, pack) ! self.log('Creating directory %s'%currentPath) ! if not self.fake_mode: ! try: ! os.mkdir(currentPath) ! except: self.log('... no') ! else: self.log('... ok') ! self.log('\n') ! init=os.path.join(currentPath, '__init__.py') if os.path.exists(init): *************** *** 226,237 **** else: self.log('Creating %s\n'%init) ! f=open(init,'w') ; f.close() # Last, create self.packagePath ! self.log('Creating directory %s... '%self.packagePath) ! try: ! os.mkdir(self.packagePath) ! except: self.log('no\n') ! else: self.log('ok\n') def log(self, msg): --- 281,295 ---- else: self.log('Creating %s\n'%init) ! if not self.fake_mode: ! f=open(init,'w') ; f.close() # Last, create self.packagePath ! self.log('Creating directory %s'%self.packagePath) ! if not self.fake_mode: ! try: ! os.mkdir(self.packagePath) ! except: self.log('... no') ! else: self.log('... ok') ! self.log('\n') def log(self, msg): Index: PyModelMason.py =================================================================== RCS file: /cvsroot/modeling/ProjectModeling/Modeling/ModelMasons/PyModelMason.py,v retrieving revision 1.8 retrieving revision 1.9 diff -C2 -d -r1.8 -r1.9 *** PyModelMason.py 20 Apr 2003 16:10:39 -0000 1.8 --- PyModelMason.py 26 May 2003 15:44:48 -0000 1.9 *************** *** 24,31 **** """ ! PyModelMason ! Documentation forthcoming CVS information --- 24,45 ---- """ ! PyModelMason generates the python package, modules and classes described ! in a model, ready to be used w/ the modeling framework. ! Its templates are located in sub-package 'Python_bricks'. The generated code ! is compatible with python v2.1 and v2.2. + Given a model, it can generate the appropriate python code in two different + ways: the flat, or 'compact' scheme, and the 'base' scheme. + + The former one generates all files within a single directory (namely: in + package model.packageName()), none of which (except the models) can be + overwritten when the code is regenerated. + + The so-called 'base' scheme adds a subpackage 'MDL' within the generated + package. All files within MDL/ are ALWAYS overwritten when the python code is + regenerated, while others (in the root package) are never overwritten if they + exist. This is probably the one you want to use if your model changes often. + CVS information *************** *** 40,48 **** from Cheetah.Template import Template ! from Python_bricks import init,model,base_module,module_base,module_compact,setup_tmpl class PyModelMason(ModelMason): def __init__(self, model, rootPath=None, verbose_mode=0, ! generation_scheme='compact'): """ Initializes the ModelMason so that the built files are based on the --- 54,118 ---- from Cheetah.Template import Template ! from Python_bricks import init,init_base,model,base_module,module_base,module_compact,setup_tmpl ! ! class InvalidModelError(Exception): ! "Raised by checkModelIsValid()" ! pass ! ! def checkModelIsValid(model, generation_scheme): ! """ ! Checks that the supplied model is valid for a given python-code generation ! scheme: ! ! - if 'generation_scheme' is 'compact', all models are valid, ! ! - if 'generation_scheme' is 'base', the model is valid iff a class/entity does ! not share the same module than any of its subclasses ! ! Parameters: ! ! model -- a instance of Modeling.Model.Model ! ! generation_scheme -- either 'compact' or 'base' ! ! Returns: None ! ! Raises InvalidModelError if the model is invalid. ! ! Note: this is NOT validation of the model itself (responsability of ! Modeling.ModelValidation) ! ! """ ! if generation_scheme=='compact': return ! if generation_scheme=='base': ! ! # Build ordered list of entities ! oe=[] ! entities=list(model.entities()) ! entities_processed=[] ! for entity in [e for e in entities if not e.parentEntity()]: ! oe.append(entity) ! entities_processed.append(entity.name()) ! entities.remove(entity) ! while entities: ! es=[e for e in entities if e.parentEntity().name() in entities_processed] ! for entity in es: ! entities.remove(entity) ! entities_processed.append(entity.name()) ! oe.append(entity) ! # check every parent against it subentities ! for e in oe: ! parent_moduleName=e.moduleName() ! subs=e.allSubEntities() ! for sub in subs: ! if sub.moduleName()==parent_moduleName: ! raise InvalidModelError, "Model is invalid wrt the 'base' generation scheme: entity '%s' and its subentity '%s' share the same moduleName.\nEither correct this or use the 'compact' generation scheme"%(e.name(), sub.name()) ! else: ! raise ValueError, "Invalid value for 'generation_scheme' (%s), should be either 'base' or 'compact'"%use_scheme class PyModelMason(ModelMason): + "See the module's documentation for details" def __init__(self, model, rootPath=None, verbose_mode=0, ! generation_scheme='compact', fake_mode=0): """ Initializes the ModelMason so that the built files are based on the *************** *** 51,71 **** Parameters: ! model -- ! rootPath -- ! verbode_mode -- use_scheme -- 'compact' or 'base' """ import Modeling if generation_scheme not in ('compact', 'base'): raise ValueError,"Parameter generation_scheme can be either 'compact' or 'base'" ModelMason.__init__(self, model, rootPath, Modeling.ModelMasons.PyModelMason, 'Python_bricks', ! verbose_mode) self._entities=[] # used during build self.generation_scheme=generation_scheme def tmpl_namespace(self): --- 121,145 ---- Parameters: ! model -- see ModelMason.__init__() ! rootPath -- see ModelMason.__init__() ! verbode_mode -- see ModelMason.__init__() use_scheme -- 'compact' or 'base' + fake_mode -- see ModelMason.__init__() + """ import Modeling if generation_scheme not in ('compact', 'base'): raise ValueError,"Parameter generation_scheme can be either 'compact' or 'base'" + checkModelIsValid(model, generation_scheme) ModelMason.__init__(self, model, rootPath, Modeling.ModelMasons.PyModelMason, 'Python_bricks', ! verbose_mode, fake_mode) self._entities=[] # used during build self.generation_scheme=generation_scheme + self.base_dir=generation_scheme=='base' and 'MDL' or '' def tmpl_namespace(self): *************** *** 77,80 **** --- 151,156 ---- 'model' : self.model, 'entities': self._entities, + 'base_dir': self.base_dir, + 'entitiesSet': self.entitiesSet, } return nameSpace *************** *** 83,86 **** --- 159,184 ---- def build(self): "-" + #----------------------------------------------------------------- + def create_model_files(self, xml_path, py_path): + # model_<modelName>.xml + self.log('Generating %s'%xml_path) + if not self.fake_mode: + self.model.saveModelAsXMLFile(xml_path) + self.log('... done') + self.log('\n') + # model_<modelName>.py + if not self.fake_mode: + xml=open(xml_path) + modelStr=xml.read() + xml.close() + else: + modelStr='fake' + self.createFileFromTemplate(model.model(), + py_path, + namespace={'model_str':modelStr}, + overwrite=1) + del modelStr + #----------------------------------------------------------------- + # Build as many directories with __init__.py as needed self.build_package() *************** *** 93,120 **** self.createEmptyFile("DEPENDENCIES.txt",overwrite=0) - # model_<modelName>.xml - modelFileName='model_'+self.model.name()+'.xml' - modelFileName=self.fullPathForGeneratedFile(modelFileName) - self.log('Generating %s... '%modelFileName) - self.model.saveModelAsXMLFile(modelFileName) - self.log('done\n') - - # model_<modelName>.py - xml=open(modelFileName) - modelStr=xml.read() - xml.close() - self.createFileFromTemplate(model.model(), - "model_%s.py"%self.model.name(), - namespace={'model_str':modelStr}, - overwrite=1) - del modelStr - # package's __init__.py self.createFileFromTemplate(init.init(),"__init__.py",overwrite=0) # setup.py ! self.createFileFromTemplate(setup_tmpl.setup_tmpl(),"setup.py") # COMPACT generation scheme if self.generation_scheme=='compact': # modules for self._entities in self.entitiesSet(): --- 191,206 ---- self.createEmptyFile("DEPENDENCIES.txt",overwrite=0) # package's __init__.py self.createFileFromTemplate(init.init(),"__init__.py",overwrite=0) # setup.py ! self.createFileFromTemplate(setup_tmpl.setup_tmpl(),"setup.py",overwrite=0) # COMPACT generation scheme if self.generation_scheme=='compact': + # Create model files (.xml/.py) + xmlp=self.fullPathForGeneratedFile('model_'+self.model.name()+'.xml') + pyp="model_%s.py"%self.model.name() + create_model_files(self, xmlp, pyp) + # modules for self._entities in self.entitiesSet(): *************** *** 126,137 **** # BASE generation scheme elif self.generation_scheme=='base': ! # create 'Base' ! #basePath=self.fullPathForGeneratedFile('Base') ! #self.log("Creating directory %s... "%basePath) ! #try: ! # os.mkdir(basePath) ! #except: self.log('no\n') ! #else: self.log('ok\n') ! # modules for self._entities in self.entitiesSet(): --- 212,232 ---- # BASE generation scheme elif self.generation_scheme=='base': ! # create 'Base' and model files (.xml/.py) ! basePath=self.fullPathForGeneratedFile(self.base_dir) ! self.log("Creating directory %s"%basePath) ! if not self.fake_mode: ! try: ! os.mkdir(basePath) ! except: self.log('no\n') ! else: self.log('ok\n') ! self.createFileFromTemplate(init_base.init_base(), ! os.path.join(self.base_dir,"__init__.py"), ! overwrite=1) ! ! create_model_files(self, ! os.path.join(basePath, ! 'model_'+self.model.name()+'.xml'), ! os.path.join(self.base_dir, ! "model_%s.py"%self.model.name())) # modules for self._entities in self.entitiesSet(): *************** *** 141,144 **** overwrite=0) self.createFileFromTemplate(base_module.base_module(), ! "%sBase.py" % module_name, overwrite=1) --- 236,240 ---- overwrite=0) self.createFileFromTemplate(base_module.base_module(), ! os.path.join(self.base_dir, ! "%s.py" % module_name), overwrite=1) |
From: <sbi...@us...> - 2003-05-26 15:45:21
|
Update of /cvsroot/modeling/ProjectModeling/Modeling In directory sc8-pr-cvs1:/tmp/cvs-serv21164 Modified Files: CHANGES Log Message: Merged changes from brch-0_9pre6-1-ModelMasons_base_generation_scheme to trunk Index: CHANGES =================================================================== RCS file: /cvsroot/modeling/ProjectModeling/Modeling/CHANGES,v retrieving revision 1.102 retrieving revision 1.103 diff -C2 -d -r1.102 -r1.103 *** CHANGES 10 May 2003 17:38:24 -0000 1.102 --- CHANGES 26 May 2003 15:44:47 -0000 1.103 *************** *** 8,11 **** --- 8,38 ---- -------------------------------------------------------- + [Merged from brch-0_9pre6-1-ModelMasons_base_generation_scheme] + + Summary: the ''base'' generation scheme has changed. Instead of putting + Writer.py and WriterBase.py in the same package, it now generates + a subpackage 'MDL' in which the base classes are dropped. + + * Added tests/test_generate_python_code.sh: tests the generation of python + code in different situations, and it also checks that the appropriate + python test (such as test_EditingContext_Global.py) succeeds with the + generated code. + Also added: xmlmodels/model_StoreEmployees.xml[2|3] + + * Updated documentation for ModelMason and PyModelMason + + * Added fake_mode to ModelMason, PyModelMason and option -n/--dry-run in + mdl_generate_python_code + + * scripts/mdl_generate_python_code (option -B), + PyModelMason.checkModelIsValid()): the 'base' scheme cannot generate a + python-package from a model where a class and at least one of its (direct + or indirect) subclasses leave in the same module. This is now checked and + correctly reported when the generation cannot be done. + + * Added the 'MDL' sub-directory containing the files that are overwritten + when mdl_generate_python_code.py (option: -B) regenerates a package + [/merged] + * RFE #726839: Added environment variable MDL_DB_CONNECTIONS_CFG; it points to a single ini-file which centralizes the sensitive informations |
Update of /cvsroot/modeling/ProjectModeling/Modeling/tests/xmlmodels In directory sc8-pr-cvs1:/tmp/cvs-serv21164/tests/xmlmodels Modified Files: README.txt model_AuthorBooks.xml Added Files: model_StoreEmployees.xml model_StoreEmployees.xml2 model_StoreEmployees.xml3 Log Message: Merged changes from brch-0_9pre6-1-ModelMasons_base_generation_scheme to trunk Index: README.txt =================================================================== RCS file: /cvsroot/modeling/ProjectModeling/Modeling/tests/xmlmodels/README.txt,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -C2 -d -r1.1.1.1 -r1.2 *** README.txt 30 Jul 2002 15:38:55 -0000 1.1.1.1 --- README.txt 26 May 2003 15:44:50 -0000 1.2 *************** *** 1,23 **** The following models are defined: ! 'model_testBothSidesRels.xml' -- used by test_Relationship and ! test_RelationshipManipulation ! 'model_AuthorBook.xml' -- used in test_Attribute, test_Entity, ! test_ImportExport, test_Qualifier, test_SQLExpression and test_SortOrderings ! **Important Note**: please do not use this model as a working example. It is ! here for historical reasons and will be removed as soon as the tests that ! rely on it will be adapted. It has a major flaw in its design: it uses a ! flattened attribute in a very bad way (flattened attributes can only be ! used when inheritance in mapped to a database schema using the 'vertical' ! approach, i.e. a subclass instance gets its data from both the superclass' ! table and its own table which only holds the attributes the subclass adds ! to the superclass' set of attributes). ! 'model_Author_Books.xml' -- used in test_EditingContext ! Note: - Removed 'used for locking' for attributes 'id' and 'FK_Writer_id' in - entity 'Writer' so that we can test that the 'usedForLocking' stuff is - not needed for fetching&saving! --- 1,47 ---- The following models are defined: ! * 'model_AuthorBooks.xml' ! 'model_StoreEmployees.xml' (.xml/.xml2/.xml3) ! Both models correspond to the one stored, resp., in modules ! testPackages.AuthorBooks and testPackages.StoreEmployees ! They are used by the test-script test_generate_python_code.sh which makes ! sure that every generated packages behave correctly as far as the ! modeling's unittests are concerned (specifically, ! test_EditingContext_Global.py is used for AuthorBooks, and ! test_EditingContext_Global_Inheritance.py for StoreEmployees) ! Note for AuthorBooks: ! ! Removed 'used for locking' for attributes 'id' and 'FK_Writer_id' in ! entity 'Writer' so that we can test that the 'usedForLocking' stuff is ! not needed for fetching&saving! ! ! Note for StoreEmployees: ! ! .xml -- the standard model as stored in testPackages.StoreEmployees ! ! .xml2 -- the same except that entities Executive and SalesClerk share the ! same module 'Employees' ! ! .xml3 -- entities same but entities Executive, SalesClerk and Employee ! share the module 'Employees' (making it impossible to generate ! python code with option -B ie the ''base'' generation scheme) ! ! * 'model_AuthorBook.xml' -- used in test_Attribute, test_Entity, ! test_ImportExport, test_Qualifier, test_SQLExpression and ! test_SortOrderings ! ! **Important Note**: please do not use this model as a working example. It ! is here for historical reasons and will be removed as soon as the tests ! that rely on it will be adapted. It has a major flaw in its design: it ! uses a flattened attribute in a very bad way (flattened attributes can ! only be used when inheritance in mapped to a database schema using the ! 'vertical' approach, i.e. a subclass instance gets its data from both ! the superclass' table and its own table which only holds the attributes ! the subclass adds to the superclass' set of attributes). ! ! * 'model_testBothSidesRels.xml' -- used by test_Relationship and ! test_RelationshipManipulation Index: model_AuthorBooks.xml =================================================================== RCS file: /cvsroot/modeling/ProjectModeling/Modeling/tests/xmlmodels/model_AuthorBooks.xml,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -C2 -d -r1.1.1.1 -r1.2 *** model_AuthorBooks.xml 30 Jul 2002 15:38:56 -0000 1.1.1.1 --- model_AuthorBooks.xml 26 May 2003 15:44:50 -0000 1.2 *************** *** 1,5 **** <?xml version='1.0' encoding='iso-8859-1'?> ! <!DOCTYPE model> ! <model name='AuthorBooks' packageName='AuthorBooks' adaptorName='Postgresql' connectionDictionary="{'database': 'AUTHOR_BOOKS', 'user': 'postgres', 'password': '', 'host': 'localhost'}"> <entity isReadOnly='0' externalName='WRITER' name='Writer' parentEntity='' className='Writer' typeName='Writer' isAbstract='0'> <primaryKey attributeName='id'/> --- 1,5 ---- <?xml version='1.0' encoding='iso-8859-1'?> ! <!-- <!DOCTYPE model SYSTEM "mdl_model.dtd"> --> ! <model name='AuthorBooks' packageName='AuthorBooks' adaptorName='' connectionDictionary="{'database': 'AUTHOR_BOOKS', 'user': '', 'password': '', 'host': ''}"> <entity isReadOnly='0' externalName='WRITER' name='Writer' parentEntity='' className='Writer' typeName='Writer' isAbstract='0'> <primaryKey attributeName='id'/> *************** *** 7,16 **** <attributesUsedForLocking attributeName='lastName'/> <attributesUsedForLocking attributeName='age'/> ! <attribute isClassProperty='1' width='40' columnName='FIRST_NAME' isRequired='0' precision='0' defaultValue='None' externalType='VARCHAR' name='firstName' scale='0' type='string' displayLabel='First Name'/> ! <attribute isClassProperty='1' width='30' columnName='LAST_NAME' isRequired='1' precision='0' defaultValue='None' externalType='VARCHAR' name='lastName' scale='0' type='string' displayLabel='Last Name'/> ! <attribute isClassProperty='1' width='0' columnName='AGE' isRequired='0' precision='0' defaultValue='0' externalType='INTEGER' name='age' scale='0' type='int' displayLabel='Age'/> ! <attribute isClassProperty='0' width='0' columnName='ID' isRequired='1' precision='0' defaultValue='0' externalType='INTEGER' name='id' scale='0' type='int' displayLabel=''/> ! <attribute isClassProperty='0' width='0' columnName='FK_WRITER_ID' isRequired='0' precision='0' defaultValue='0' externalType='INTEGER' name='FK_Writer_id' scale='0' type='int' displayLabel=''/> ! <attribute isClassProperty='1' width='0' columnName='BIRTHDAY' isRequired='0' precision='0' defaultValue='None' externalType='TIMESTAMP' name='birthday' scale='0' type='DateTime' displayLabel='birthday'/> <relation deleteRule='2' isClassProperty='1' multiplicityUpperBound='-1' multiplicityLowerBound='0' destinationEntity='Book' name='books' displayLabel='' joinSemantic='0'> <join sourceAttribute='id' destinationAttribute='FK_Writer_Id'/> --- 7,16 ---- <attributesUsedForLocking attributeName='lastName'/> <attributesUsedForLocking attributeName='age'/> ! <attribute isClassProperty='1' columnName='FIRST_NAME' name='firstName' isRequired='0' precision='0' defaultValue='None' externalType='VARCHAR' width='40' scale='0' type='string' displayLabel='First Name'/> ! <attribute isClassProperty='1' columnName='LAST_NAME' name='lastName' isRequired='1' precision='0' defaultValue='None' externalType='VARCHAR' width='30' scale='0' type='string' displayLabel='Last Name'/> ! <attribute isClassProperty='1' columnName='AGE' name='age' isRequired='0' precision='0' defaultValue='0' externalType='INTEGER' width='0' scale='0' type='int' displayLabel='Age'/> ! <attribute isClassProperty='0' columnName='ID' name='id' isRequired='1' precision='0' defaultValue='0' externalType='INTEGER' width='0' scale='0' type='int' displayLabel=''/> ! <attribute isClassProperty='0' columnName='FK_WRITER_ID' name='FK_Writer_id' isRequired='0' precision='0' defaultValue='0' externalType='INTEGER' width='0' scale='0' type='int' displayLabel=''/> ! <attribute isClassProperty='1' columnName='BIRTHDAY' name='birthday' isRequired='0' precision='0' defaultValue='None' externalType='TIMESTAMP' width='0' scale='0' type='DateTime' displayLabel='birthday'/> <relation deleteRule='2' isClassProperty='1' multiplicityUpperBound='-1' multiplicityLowerBound='0' destinationEntity='Book' name='books' displayLabel='' joinSemantic='0'> <join sourceAttribute='id' destinationAttribute='FK_Writer_Id'/> *************** *** 25,32 **** <attributesUsedForLocking attributeName='id'/> <attributesUsedForLocking attributeName='FK_Writer_Id'/> ! <attribute isClassProperty='1' width='40' columnName='title' isRequired='1' precision='0' defaultValue='None' externalType='VARCHAR' name='title' scale='0' type='string' displayLabel='Title'/> ! <attribute isClassProperty='0' width='0' columnName='id' isRequired='1' precision='0' defaultValue='0' externalType='INT' name='id' scale='0' type='int' displayLabel=''/> ! <attribute isClassProperty='0' width='0' columnName='FK_WRITER_ID' isRequired='0' precision='0' defaultValue='None' externalType='INTEGER' name='FK_Writer_Id' scale='0' type='string' displayLabel=''/> ! <attribute isClassProperty='1' width='0' columnName='PRICE' isRequired='0' precision='10' defaultValue='None' externalType='NUMERIC' name='price' scale='2' type='float' displayLabel=''/> <relation deleteRule='0' isClassProperty='1' multiplicityUpperBound='1' multiplicityLowerBound='0' destinationEntity='Writer' name='author' displayLabel='' joinSemantic='0'> <join sourceAttribute='FK_Writer_Id' destinationAttribute='id'/> --- 25,32 ---- <attributesUsedForLocking attributeName='id'/> <attributesUsedForLocking attributeName='FK_Writer_Id'/> ! <attribute isClassProperty='1' columnName='title' name='title' isRequired='1' precision='0' defaultValue='None' externalType='VARCHAR' width='40' scale='0' type='string' displayLabel='Title'/> ! <attribute isClassProperty='1' columnName='id' name='id' isRequired='1' precision='0' defaultValue='0' externalType='INT' width='0' scale='0' type='int' displayLabel=''/> ! <attribute isClassProperty='0' columnName='FK_WRITER_ID' name='FK_Writer_Id' isRequired='0' precision='0' defaultValue='None' externalType='INTEGER' width='0' scale='0' type='string' displayLabel=''/> ! <attribute isClassProperty='1' columnName='PRICE' name='price' isRequired='0' precision='10' defaultValue='None' externalType='NUMERIC' width='0' scale='2' type='float' displayLabel=''/> <relation deleteRule='0' isClassProperty='1' multiplicityUpperBound='1' multiplicityLowerBound='0' destinationEntity='Writer' name='author' displayLabel='' joinSemantic='0'> <join sourceAttribute='FK_Writer_Id' destinationAttribute='id'/> |
From: <sbi...@us...> - 2003-05-26 15:44:53
|
Update of /cvsroot/modeling/ProjectModeling/Modeling/scripts In directory sc8-pr-cvs1:/tmp/cvs-serv21164/scripts Modified Files: mdl_generate_python_code.py Log Message: Merged changes from brch-0_9pre6-1-ModelMasons_base_generation_scheme to trunk Index: mdl_generate_python_code.py =================================================================== RCS file: /cvsroot/modeling/ProjectModeling/Modeling/scripts/mdl_generate_python_code.py,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** mdl_generate_python_code.py 20 Apr 2003 16:10:41 -0000 1.4 --- mdl_generate_python_code.py 26 May 2003 15:44:49 -0000 1.5 *************** *** 55,60 **** del tb ! def build_python_code(model, generation_scheme, ! rootPath=None, typeOfCode='python', verbose_mode=0): """ Builds the python-code templates for the supplied model --- 55,60 ---- del tb ! def build_python_code(model, generation_scheme, rootPath=None, ! typeOfCode='python', verbose_mode=0, fake_mode=0): """ Builds the python-code templates for the supplied model *************** *** 75,78 **** --- 75,80 ---- is false. + fake_mode -- if true, do not create or change any file, just report what + would be done Raises TargetDirectoryAlreadyExists if 'overwrite' is false and the target *************** *** 86,90 **** from Modeling.ModelMasons.PyModelMason import PyModelMason mason = PyModelMason(model, rootPath, verbose_mode=verbose_mode, ! generation_scheme=generation_scheme) mason.build() --- 88,93 ---- from Modeling.ModelMasons.PyModelMason import PyModelMason mason = PyModelMason(model, rootPath, verbose_mode=verbose_mode, ! generation_scheme=generation_scheme, ! fake_mode=fake_mode) mason.build() *************** *** 104,113 **** General options: ---------------- ! -h --help gives this help ! -v --verbose verbose mode (default) ! -q --quiet quiet mode Generation options: ------------------- -B --base-generation-scheme use the 'base' scheme -C --compact-generation-scheme use the 'compact' scheme (default) --- 107,120 ---- General options: ---------------- ! -h --help gives this help ! -n --dry-run do not create or change any file, just report what would ! be done ! -q --quiet quiet mode ! -v --verbose verbose mode (default) Generation options: ------------------- + For an explanation on generation schemes, see below + -B --base-generation-scheme use the 'base' scheme -C --compact-generation-scheme use the 'compact' scheme (default) *************** *** 116,120 **** --generation_scheme=<scheme> use <scheme> as the generation scheme (either 'base' or 'compact') ! """ % prgName sys.stderr.write(_usage) --- 123,141 ---- --generation_scheme=<scheme> use <scheme> as the generation scheme (either 'base' or 'compact') ! ! 'compact' scheme: puts all generated file in the same directory (the package ! for the model). When re-generating the files, only the two files ! containing the model are overwritten, every other file that already exists ! is never overwritten ! ! 'base' scheme: adds a sub-module 'MDL' within the generated package. All files ! within MDL/ are ALWAYS overwritten when the python code is regenerated, ! while others (in the root package) are never overwritten if they exist. ! This is probably the one you want to use if your model changes often. ! ! Note: this can be used if and only if there is no entity sharing the same ! module with one of its (direct or indirect) subentities. If this is ! not the case, the generation will raise and indicate the problem. ! """ % prgName sys.stderr.write(_usage) *************** *** 126,137 **** me=args[0] try: options, args = getopt.getopt(sys.argv[1:], ! 'BCg:hqv', ["help", "quiet", "verbose", "generation_scheme=", "compact-generation-scheme", ! "base-generation-scheme"]) except: usage(me); return 1 global verbose generation_scheme='compact' for k, v in options: if k in ('-h', '--help'): usage(me); return 0 --- 147,160 ---- me=args[0] try: options, args = getopt.getopt(sys.argv[1:], ! 'BCg:hnqv', ["help", "quiet", "verbose", "generation_scheme=", "compact-generation-scheme", ! "base-generation-scheme", ! "dry-run"]) except: usage(me); return 1 global verbose generation_scheme='compact' + fake_mode=0 for k, v in options: if k in ('-h', '--help'): usage(me); return 0 *************** *** 140,143 **** --- 163,167 ---- if k in ('-C', '--compact-generation-scheme'): generation_scheme='compact'; continue if k in ('-B', '--base-generation-scheme'): generation_scheme='base'; continue + if k in ('-n', '--dry-run'): fake_mode=1; continue if len(args) not in (1,2): usage(me) ; return 1 *************** *** 159,163 **** model=ms.models()[0] try: ! build_python_code(model, generation_scheme, rootPath, verbose_mode=verbose) except TargetDirectoryAlreadyExists, exc: sys.stderr.write(str(sys.exc_info()[1])+'\n') --- 183,188 ---- model=ms.models()[0] try: ! build_python_code(model, generation_scheme, rootPath, verbose_mode=verbose, ! fake_mode=fake_mode) except TargetDirectoryAlreadyExists, exc: sys.stderr.write(str(sys.exc_info()[1])+'\n') |
From: <sbi...@us...> - 2003-05-26 15:44:53
|
Update of /cvsroot/modeling/ProjectModeling/Modeling/tests In directory sc8-pr-cvs1:/tmp/cvs-serv21164/tests Added Files: test_generate_python_code.sh Log Message: Merged changes from brch-0_9pre6-1-ModelMasons_base_generation_scheme to trunk |
From: <sbi...@us...> - 2003-05-26 15:40:30
|
Update of /cvsroot/modeling/ProjectModeling/Modeling/tests In directory sc8-pr-cvs1:/tmp/cvs-serv19805 Modified Files: test_EditingContext.py Log Message: Fixed initialization: wouldn't run with a .cfg file Index: test_EditingContext.py =================================================================== RCS file: /cvsroot/modeling/ProjectModeling/Modeling/tests/test_EditingContext.py,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** test_EditingContext.py 14 Mar 2003 11:40:13 -0000 1.4 --- test_EditingContext.py 26 May 2003 15:40:27 -0000 1.5 *************** *** 46,49 **** --- 46,54 ---- from testPackages.StoreEmployees.Employee import Employee + ms=ModelSet.defaultModelSet() + ModelSet.updateModelWithCFG(ms.modelNamed('AuthorBooks'), 'Postgresql.cfg') + ModelSet.updateModelWithCFG(ms.modelNamed('StoreEmployees'), 'Postgresql.cfg') + del ms + class TestEditingContext(unittest.TestCase): "Tests basic functionalities of EditingContext" |
From: <sbi...@us...> - 2003-05-26 15:00:58
|
Update of /cvsroot/modeling/ProjectModeling/Modeling In directory sc8-pr-cvs1:/tmp/cvs-serv326 Modified Files: Tag: brch-0_9pre6-1-ModelMasons_base_generation_scheme CHANGES Log Message: Added comment for the branch Index: CHANGES =================================================================== RCS file: /cvsroot/modeling/ProjectModeling/Modeling/CHANGES,v retrieving revision 1.95.2.4 retrieving revision 1.95.2.5 diff -C2 -d -r1.95.2.4 -r1.95.2.5 *** CHANGES 26 May 2003 14:43:21 -0000 1.95.2.4 --- CHANGES 26 May 2003 15:00:52 -0000 1.95.2.5 *************** *** 11,14 **** --- 11,18 ---- -------------------------------------------------------- + Note: this branch only addresses package Modeling and subpackages. In + particular, it does not contain any modification for zope products such + as the ZModeler. + ModelMasons |
From: <sbi...@us...> - 2003-05-26 14:51:58
|
Update of /cvsroot/modeling/ProjectModeling/Modeling/tests In directory sc8-pr-cvs1:/tmp/cvs-serv28706/tests Modified Files: Tag: brch-0_9pre6-1-ModelMasons_base_generation_scheme test_generate_python_code.sh Log Message: Some cleaning & beautification Index: test_generate_python_code.sh =================================================================== RCS file: /cvsroot/modeling/ProjectModeling/Modeling/tests/Attic/test_generate_python_code.sh,v retrieving revision 1.1.2.1 retrieving revision 1.1.2.2 diff -C2 -d -r1.1.2.1 -r1.1.2.2 *** test_generate_python_code.sh 20 May 2003 14:24:44 -0000 1.1.2.1 --- test_generate_python_code.sh 26 May 2003 14:51:55 -0000 1.1.2.2 *************** *** 1,13 **** #! /bin/sh ! GENERATE=../scripts/mdl_generate_python_code.py RMDIR='/bin/rm -rf' function test_AuthorBooks() { ! ./test_EditingContext_Global.py > /dev/null 2>&1 } function test_StoreEmployees() { ! ./test_EditingContext_Global_Inheritance.py > /dev/null 2>&1 } --- 1,15 ---- #! /bin/sh ! ## Tests mdl_generate_python_code.py ! ## See also xmlmodels/README.txt GENERATE=../scripts/mdl_generate_python_code.py RMDIR='/bin/rm -rf' + PYTHON=/usr/local/bin/python function test_AuthorBooks() { ! $PYTHON ./test_EditingContext_Global.py > /dev/null 2>&1 } function test_StoreEmployees() { ! $PYTHON ./test_EditingContext_Global_Inheritance.py > /dev/null 2>&1 } *************** *** 17,20 **** --- 19,24 ---- ##-------- + ## You should not need to modify anything below this line + ##-------- function check_success() { if [ $? -ne 0 ]; then *************** *** 33,40 **** function generate() { ! $GENERATE $* > /dev/null 2>&1 } ! ## Save the original trestPackages directories cp -Rp testPackages/AuthorBooks testPackages/AuthorBooks.ori cp -Rp testPackages/StoreEmployees testPackages/StoreEmployees.ori --- 37,44 ---- function generate() { ! $PYTHON $GENERATE $* > /dev/null 2>&1 } ! ## Save the original testPackages directories cp -Rp testPackages/AuthorBooks testPackages/AuthorBooks.ori cp -Rp testPackages/StoreEmployees testPackages/StoreEmployees.ori *************** *** 110,117 **** ## Restore original directories ! \rm -rf AuthorBooks ! \rm -rf StoreEmployees cp -Rp testPackages/AuthorBooks.ori testPackages/AuthorBooks && \ ! $RMDIR testPackages/AuthorBooks.ori cp -Rp testPackages/StoreEmployees.ori testPackages/StoreEmployees && \ ! $RMDIR testPackages/StoreEmployees.ori --- 114,121 ---- ## Restore original directories ! \rm -rf testPackages/AuthorBooks ! \rm -rf testPackages/StoreEmployees cp -Rp testPackages/AuthorBooks.ori testPackages/AuthorBooks && \ ! $RMDIR testPackages/AuthorBooks.ori cp -Rp testPackages/StoreEmployees.ori testPackages/StoreEmployees && \ ! $RMDIR testPackages/StoreEmployees.ori |
From: <sbi...@us...> - 2003-05-26 14:44:03
|
Update of /cvsroot/modeling/ProjectModeling/Modeling/ModelMasons In directory sc8-pr-cvs1:/tmp/cvs-serv24693/ModelMasons Modified Files: Tag: brch-0_9pre6-1-ModelMasons_base_generation_scheme PyModelMason.py Log Message: explicit overwrite=0 for setup.py Index: PyModelMason.py =================================================================== RCS file: /cvsroot/modeling/ProjectModeling/Modeling/ModelMasons/PyModelMason.py,v retrieving revision 1.8.2.3 retrieving revision 1.8.2.4 diff -C2 -d -r1.8.2.3 -r1.8.2.4 *** PyModelMason.py 18 May 2003 23:28:24 -0000 1.8.2.3 --- PyModelMason.py 26 May 2003 14:44:00 -0000 1.8.2.4 *************** *** 194,198 **** self.createFileFromTemplate(init.init(),"__init__.py",overwrite=0) # setup.py ! self.createFileFromTemplate(setup_tmpl.setup_tmpl(),"setup.py") # COMPACT generation scheme --- 194,198 ---- self.createFileFromTemplate(init.init(),"__init__.py",overwrite=0) # setup.py ! self.createFileFromTemplate(setup_tmpl.setup_tmpl(),"setup.py",overwrite=0) # COMPACT generation scheme |
From: <sbi...@us...> - 2003-05-26 14:43:24
|
Update of /cvsroot/modeling/ProjectModeling/Modeling In directory sc8-pr-cvs1:/tmp/cvs-serv24156 Modified Files: Tag: brch-0_9pre6-1-ModelMasons_base_generation_scheme CHANGES Log Message: Updated Index: CHANGES =================================================================== RCS file: /cvsroot/modeling/ProjectModeling/Modeling/CHANGES,v retrieving revision 1.95.2.3 retrieving revision 1.95.2.4 diff -C2 -d -r1.95.2.3 -r1.95.2.4 *** CHANGES 18 May 2003 23:29:47 -0000 1.95.2.3 --- CHANGES 26 May 2003 14:43:21 -0000 1.95.2.4 *************** *** 13,16 **** --- 13,23 ---- ModelMasons + [2003/05/20] + * Added tests/test_generate_python_code.sh: tests the generation of python + code in different situations, and it also checks that the appropriate + python test (such as test_EditingContext_Global.py) succeeds with the + generated code. + Also added: xmlmodels/model_StoreEmployees.xml[2|3] + [2003/05/19] * Updated documentation for ModelMason and PyModelMason |
From: <sbi...@us...> - 2003-05-26 14:42:47
|
Update of /cvsroot/modeling/ProjectModeling/Modeling/tests/xmlmodels In directory sc8-pr-cvs1:/tmp/cvs-serv23691/tests/xmlmodels Modified Files: Tag: brch-0_9pre6-1-ModelMasons_base_generation_scheme README.txt Log Message: Updated README Index: README.txt =================================================================== RCS file: /cvsroot/modeling/ProjectModeling/Modeling/tests/xmlmodels/README.txt,v retrieving revision 1.1.1.1 retrieving revision 1.1.1.1.4.1 diff -C2 -d -r1.1.1.1 -r1.1.1.1.4.1 *** README.txt 30 Jul 2002 15:38:55 -0000 1.1.1.1 --- README.txt 26 May 2003 14:42:44 -0000 1.1.1.1.4.1 *************** *** 1,23 **** The following models are defined: ! 'model_testBothSidesRels.xml' -- used by test_Relationship and ! test_RelationshipManipulation ! 'model_AuthorBook.xml' -- used in test_Attribute, test_Entity, ! test_ImportExport, test_Qualifier, test_SQLExpression and test_SortOrderings ! **Important Note**: please do not use this model as a working example. It is ! here for historical reasons and will be removed as soon as the tests that ! rely on it will be adapted. It has a major flaw in its design: it uses a ! flattened attribute in a very bad way (flattened attributes can only be ! used when inheritance in mapped to a database schema using the 'vertical' ! approach, i.e. a subclass instance gets its data from both the superclass' ! table and its own table which only holds the attributes the subclass adds ! to the superclass' set of attributes). ! 'model_Author_Books.xml' -- used in test_EditingContext ! Note: - Removed 'used for locking' for attributes 'id' and 'FK_Writer_id' in - entity 'Writer' so that we can test that the 'usedForLocking' stuff is - not needed for fetching&saving! --- 1,47 ---- The following models are defined: ! * 'model_AuthorBooks.xml' ! 'model_StoreEmployees.xml' (.xml/.xml2/.xml3) ! Both models correspond to the one stored, resp., in modules ! testPackages.AuthorBooks and testPackages.StoreEmployees ! They are used by the test-script test_generate_python_code.sh which makes ! sure that every generated packages behave correctly as far as the ! modeling's unittests are concerned (specifically, ! test_EditingContext_Global.py is used for AuthorBooks, and ! test_EditingContext_Global_Inheritance.py for StoreEmployees) ! Note for AuthorBooks: ! ! Removed 'used for locking' for attributes 'id' and 'FK_Writer_id' in ! entity 'Writer' so that we can test that the 'usedForLocking' stuff is ! not needed for fetching&saving! ! ! Note for StoreEmployees: ! ! .xml -- the standard model as stored in testPackages.StoreEmployees ! ! .xml2 -- the same except that entities Executive and SalesClerk share the ! same module 'Employees' ! ! .xml3 -- entities same but entities Executive, SalesClerk and Employee ! share the module 'Employees' (making it impossible to generate ! python code with option -B ie the ''base'' generation scheme) ! ! * 'model_AuthorBook.xml' -- used in test_Attribute, test_Entity, ! test_ImportExport, test_Qualifier, test_SQLExpression and ! test_SortOrderings ! ! **Important Note**: please do not use this model as a working example. It ! is here for historical reasons and will be removed as soon as the tests ! that rely on it will be adapted. It has a major flaw in its design: it ! uses a flattened attribute in a very bad way (flattened attributes can ! only be used when inheritance in mapped to a database schema using the ! 'vertical' approach, i.e. a subclass instance gets its data from both ! the superclass' table and its own table which only holds the attributes ! the subclass adds to the superclass' set of attributes). ! ! * 'model_testBothSidesRels.xml' -- used by test_Relationship and ! test_RelationshipManipulation |
From: <sbi...@us...> - 2003-05-26 14:18:41
|
Update of /cvsroot/modeling/ProjectModeling/Modeling/ModelMasons In directory sc8-pr-cvs1:/tmp/cvs-serv11742/ModelMasons Modified Files: Tag: brch-0_9pre6-1-ModelMasons_base_generation_scheme ModelMason.py Log Message: log msg corrected Index: ModelMason.py =================================================================== RCS file: /cvsroot/modeling/ProjectModeling/Modeling/ModelMasons/ModelMason.py,v retrieving revision 1.6.2.1 retrieving revision 1.6.2.2 diff -C2 -d -r1.6.2.1 -r1.6.2.2 *** ModelMason.py 18 May 2003 23:28:24 -0000 1.6.2.1 --- ModelMason.py 26 May 2003 14:18:35 -0000 1.6.2.2 *************** *** 203,210 **** namespace=self.fix_tmpl_namespace(namespace) destFile = self.fullPathForGeneratedFile(destFile) ! if not overwrite and os.path.exists(destFile): self.log("File %s exists, skipping\n"%destFile) return ! if not overwrite: self.log("Generating %s" % destFile) else: --- 203,211 ---- namespace=self.fix_tmpl_namespace(namespace) destFile = self.fullPathForGeneratedFile(destFile) ! file_exists=os.path.exists(destFile) ! if not overwrite and file_exists: self.log("File %s exists, skipping\n"%destFile) return ! if not overwrite or (overwrite and not file_exists): self.log("Generating %s" % destFile) else: |
From: <sbi...@us...> - 2003-05-26 12:57:24
|
Update of /cvsroot/modeling/NotificationFramework In directory sc8-pr-cvs1:/tmp/cvs-serv7797 Modified Files: Notification.py NotificationCenter.py __init__.py log.py Log Message: Slightly improved documentation Index: Notification.py =================================================================== RCS file: /cvsroot/modeling/NotificationFramework/Notification.py,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** Notification.py 26 May 2003 12:24:52 -0000 1.4 --- Notification.py 26 May 2003 12:57:20 -0000 1.5 *************** *** 22,26 **** #----------------------------------------------------------------------------- ! """$Id$""" __version__='$Revision$'[11:-2] --- 22,30 ---- #----------------------------------------------------------------------------- ! """ ! Notifications are the messages transmitted by the NotificationCenter. ! ! $Id$ ! """ __version__='$Revision$'[11:-2] Index: NotificationCenter.py =================================================================== RCS file: /cvsroot/modeling/NotificationFramework/NotificationCenter.py,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -d -r1.7 -r1.8 *** NotificationCenter.py 26 May 2003 12:24:52 -0000 1.7 --- NotificationCenter.py 26 May 2003 12:57:20 -0000 1.8 *************** *** 24,28 **** """ ! NotificationCenter This module acts as a NotificationCenter. --- 24,29 ---- """ ! NotificationCenter is the central object of the framework --full documentation ! is here. This module acts as a NotificationCenter. Index: __init__.py =================================================================== RCS file: /cvsroot/modeling/NotificationFramework/__init__.py,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** __init__.py 26 May 2003 12:24:52 -0000 1.3 --- __init__.py 26 May 2003 12:57:20 -0000 1.4 *************** *** 26,30 **** they have no idea of who and where the other objects live. ! The complete documentation can found in module NotificationCenter. It is distributed under the GNU General Public License. --- 26,31 ---- they have no idea of who and where the other objects live. ! The complete documentation can found in L{module ! NotificationCenter<NotificationCenter>}. It is distributed under the GNU General Public License. Index: log.py =================================================================== RCS file: /cvsroot/modeling/NotificationFramework/log.py,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** log.py 26 May 2003 12:24:52 -0000 1.3 --- log.py 26 May 2003 12:57:20 -0000 1.4 *************** *** 23,27 **** """ ! $Id$ """ --- 23,35 ---- """ ! Logging methods. ! ! All methods log(), warn() and trace() are disabled by default. To enable ! them set the environment variable 'NOTIFICATION_FRAMEWORK_TRACE' (for ! debugging purpose mainly) ! ! CVS Information ! ! $Id$ """ |
From: <sbi...@us...> - 2003-05-26 12:41:29
|
Update of /cvsroot/modeling/NotificationFramework In directory sc8-pr-cvs1:/tmp/cvs-serv31004 Added Files: README Log Message: Added --- NEW FILE: README --- The NotificationFramework is a python implementation of the "Observer" Design Pattern, allowing one-to-many dependency between objects even when they have no idea of who and where the other objects live. The complete documentation can found in module NotificationCenter, or at http://modeling.sourceforge.net/API/Notification-API/index.html It is distributed under the GNU General Public License. |
Update of /cvsroot/modeling/NotificationFramework/tests In directory sc8-pr-cvs1:/tmp/cvs-serv21217/tests Modified Files: compare_perfs.py run.py test_Notification.py test_NotificationCenter.py testmodule.py utils.py Log Message: Fixed license: this is the Notification Framework, not the Modeling! Index: compare_perfs.py =================================================================== RCS file: /cvsroot/modeling/NotificationFramework/tests/compare_perfs.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** compare_perfs.py 25 May 2003 19:06:50 -0000 1.1 --- compare_perfs.py 26 May 2003 12:24:52 -0000 1.2 *************** *** 2,16 **** #----------------------------------------------------------------------------- # ! # Modeling Framework: an Object-Relational Bridge for python # (c) 2001, 2002, 2003 Sebastien Bigaret # ! # This file is part of the Modeling Framework. # ! # The Modeling Framework is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License as published # by the Free Software Foundation; either version 2 of the License, or (at # your option) any later version. # ! # The Modeling Framework is distributed in the hope that it will be # useful, but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU --- 2,16 ---- #----------------------------------------------------------------------------- # ! # Notification Framework: "Observer" Design Pattern for python # (c) 2001, 2002, 2003 Sebastien Bigaret # ! # This file is part of the Notification Framework. # ! # The Notification Framework is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License as published # by the Free Software Foundation; either version 2 of the License, or (at # your option) any later version. # ! # The Notification Framework is distributed in the hope that it will be # useful, but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *************** *** 18,22 **** # # You should have received a copy of the GNU General Public License along ! # with the Modeling Framework; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # --- 18,22 ---- # # You should have received a copy of the GNU General Public License along ! # with the Notification Framework; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # Index: run.py =================================================================== RCS file: /cvsroot/modeling/NotificationFramework/tests/run.py,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** run.py 25 May 2003 19:06:50 -0000 1.3 --- run.py 26 May 2003 12:24:52 -0000 1.4 *************** *** 2,16 **** #----------------------------------------------------------------------------- # ! # Modeling Framework: an Object-Relational Bridge for python # (c) 2001, 2002, 2003 Sebastien Bigaret # ! # This file is part of the Modeling Framework. # ! # The Modeling Framework is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License as published # by the Free Software Foundation; either version 2 of the License, or (at # your option) any later version. # ! # The Modeling Framework is distributed in the hope that it will be # useful, but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU --- 2,16 ---- #----------------------------------------------------------------------------- # ! # Notification Framework: "Observer" Design Pattern for python # (c) 2001, 2002, 2003 Sebastien Bigaret # ! # This file is part of the Notification Framework. # ! # The Notification Framework is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License as published # by the Free Software Foundation; either version 2 of the License, or (at # your option) any later version. # ! # The Notification Framework is distributed in the hope that it will be # useful, but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *************** *** 18,22 **** # # You should have received a copy of the GNU General Public License along ! # with the Modeling Framework; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # --- 18,22 ---- # # You should have received a copy of the GNU General Public License along ! # with the Notification Framework; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # *************** *** 30,34 **** def usage(prgName, exitStatus=None): _usage="""%s [-v] [-V] ! Runs the tests for the Modeling package Options --- 30,34 ---- def usage(prgName, exitStatus=None): _usage="""%s [-v] [-V] ! Runs the tests for the Notification package Options Index: test_Notification.py =================================================================== RCS file: /cvsroot/modeling/NotificationFramework/tests/test_Notification.py,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** test_Notification.py 25 May 2003 18:56:08 -0000 1.4 --- test_Notification.py 26 May 2003 12:24:53 -0000 1.5 *************** *** 2,16 **** #----------------------------------------------------------------------------- # ! # Modeling Framework: an Object-Relational Bridge for python # (c) 2001, 2002, 2003 Sebastien Bigaret # ! # This file is part of the Modeling Framework. # ! # The Modeling Framework is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License as published # by the Free Software Foundation; either version 2 of the License, or (at # your option) any later version. # ! # The Modeling Framework is distributed in the hope that it will be # useful, but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU --- 2,16 ---- #----------------------------------------------------------------------------- # ! # Notification Framework: "Observer" Design Pattern for python # (c) 2001, 2002, 2003 Sebastien Bigaret # ! # This file is part of the Notification Framework. # ! # The Notification Framework is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License as published # by the Free Software Foundation; either version 2 of the License, or (at # your option) any later version. # ! # The Notification Framework is distributed in the hope that it will be # useful, but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *************** *** 18,22 **** # # You should have received a copy of the GNU General Public License along ! # with the Modeling Framework; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # --- 18,22 ---- # # You should have received a copy of the GNU General Public License along ! # with the Notification Framework; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # Index: test_NotificationCenter.py =================================================================== RCS file: /cvsroot/modeling/NotificationFramework/tests/test_NotificationCenter.py,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** test_NotificationCenter.py 25 May 2003 19:06:50 -0000 1.5 --- test_NotificationCenter.py 26 May 2003 12:24:53 -0000 1.6 *************** *** 2,16 **** #----------------------------------------------------------------------------- # ! # Modeling Framework: an Object-Relational Bridge for python # (c) 2001, 2002, 2003 Sebastien Bigaret # ! # This file is part of the Modeling Framework. # ! # The Modeling Framework is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License as published # by the Free Software Foundation; either version 2 of the License, or (at # your option) any later version. # ! # The Modeling Framework is distributed in the hope that it will be # useful, but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU --- 2,16 ---- #----------------------------------------------------------------------------- # ! # Notification Framework: "Observer" Design Pattern for python # (c) 2001, 2002, 2003 Sebastien Bigaret # ! # This file is part of the Notification Framework. # ! # The Notification Framework is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License as published # by the Free Software Foundation; either version 2 of the License, or (at # your option) any later version. # ! # The Notification Framework is distributed in the hope that it will be # useful, but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *************** *** 18,22 **** # # You should have received a copy of the GNU General Public License along ! # with the Modeling Framework; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # --- 18,22 ---- # # You should have received a copy of the GNU General Public License along ! # with the Notification Framework; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # Index: testmodule.py =================================================================== RCS file: /cvsroot/modeling/NotificationFramework/tests/testmodule.py,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** testmodule.py 10 Jan 2003 10:45:44 -0000 1.2 --- testmodule.py 26 May 2003 12:24:53 -0000 1.3 *************** *** 1,15 **** #----------------------------------------------------------------------------- # ! # Modeling Framework: an Object-Relational Bridge for python # (c) 2001, 2002, 2003 Sebastien Bigaret # ! # This file is part of the Modeling Framework. # ! # The Modeling Framework is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License as published # by the Free Software Foundation; either version 2 of the License, or (at # your option) any later version. # ! # The Modeling Framework is distributed in the hope that it will be # useful, but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU --- 1,15 ---- #----------------------------------------------------------------------------- # ! # Notification Framework: "Observer" Design Pattern for python # (c) 2001, 2002, 2003 Sebastien Bigaret # ! # This file is part of the Notification Framework. # ! # The Notification Framework is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License as published # by the Free Software Foundation; either version 2 of the License, or (at # your option) any later version. # ! # The Notification Framework is distributed in the hope that it will be # useful, but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *************** *** 17,21 **** # # You should have received a copy of the GNU General Public License along ! # with the Modeling Framework; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # --- 17,21 ---- # # You should have received a copy of the GNU General Public License along ! # with the Notification Framework; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # Index: utils.py =================================================================== RCS file: /cvsroot/modeling/NotificationFramework/tests/utils.py,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** utils.py 25 May 2003 18:55:36 -0000 1.3 --- utils.py 26 May 2003 12:24:53 -0000 1.4 *************** *** 1,15 **** #----------------------------------------------------------------------------- # ! # Modeling Framework: an Object-Relational Bridge for python # (c) 2001, 2002, 2003 Sebastien Bigaret # ! # This file is part of the Modeling Framework. # ! # The Modeling Framework is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License as published # by the Free Software Foundation; either version 2 of the License, or (at # your option) any later version. # ! # The Modeling Framework is distributed in the hope that it will be # useful, but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU --- 1,15 ---- #----------------------------------------------------------------------------- # ! # Notification Framework: "Observer" Design Pattern for python # (c) 2001, 2002, 2003 Sebastien Bigaret # ! # This file is part of the Notification Framework. # ! # The Notification Framework is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License as published # by the Free Software Foundation; either version 2 of the License, or (at # your option) any later version. # ! # The Notification Framework is distributed in the hope that it will be # useful, but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *************** *** 17,21 **** # # You should have received a copy of the GNU General Public License along ! # with the Modeling Framework; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # --- 17,21 ---- # # You should have received a copy of the GNU General Public License along ! # with the Notification Framework; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # |
From: <sbi...@us...> - 2003-05-26 12:24:55
|
Update of /cvsroot/modeling/NotificationFramework In directory sc8-pr-cvs1:/tmp/cvs-serv21217 Modified Files: Notification.py NotificationCenter.py __init__.py log.py mems_lib.py setup.py Log Message: Fixed license: this is the Notification Framework, not the Modeling! Index: Notification.py =================================================================== RCS file: /cvsroot/modeling/NotificationFramework/Notification.py,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** Notification.py 10 Jan 2003 10:45:44 -0000 1.3 --- Notification.py 26 May 2003 12:24:52 -0000 1.4 *************** *** 1,15 **** #----------------------------------------------------------------------------- # ! # Modeling Framework: an Object-Relational Bridge for python # (c) 2001, 2002, 2003 Sebastien Bigaret # ! # This file is part of the Modeling Framework. # ! # The Modeling Framework is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License as published # by the Free Software Foundation; either version 2 of the License, or (at # your option) any later version. # ! # The Modeling Framework is distributed in the hope that it will be # useful, but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU --- 1,15 ---- #----------------------------------------------------------------------------- # ! # Notification Framework: "Observer" Design Pattern for python # (c) 2001, 2002, 2003 Sebastien Bigaret # ! # This file is part of the Notification Framework. # ! # The Notification Framework is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License as published # by the Free Software Foundation; either version 2 of the License, or (at # your option) any later version. # ! # The Notification Framework is distributed in the hope that it will be # useful, but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *************** *** 17,21 **** # # You should have received a copy of the GNU General Public License along ! # with the Modeling Framework; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # --- 17,21 ---- # # You should have received a copy of the GNU General Public License along ! # with the Notification Framework; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # Index: NotificationCenter.py =================================================================== RCS file: /cvsroot/modeling/NotificationFramework/NotificationCenter.py,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** NotificationCenter.py 25 May 2003 19:06:50 -0000 1.6 --- NotificationCenter.py 26 May 2003 12:24:52 -0000 1.7 *************** *** 1,15 **** #----------------------------------------------------------------------------- # ! # Modeling Framework: an Object-Relational Bridge for python # (c) 2001, 2002, 2003 Sebastien Bigaret # ! # This file is part of the Modeling Framework. # ! # The Modeling Framework is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License as published # by the Free Software Foundation; either version 2 of the License, or (at # your option) any later version. # ! # The Modeling Framework is distributed in the hope that it will be # useful, but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU --- 1,15 ---- #----------------------------------------------------------------------------- # ! # Notification Framework: "Observer" Design Pattern for python # (c) 2001, 2002, 2003 Sebastien Bigaret # ! # This file is part of the Notification Framework. # ! # The Notification Framework is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License as published # by the Free Software Foundation; either version 2 of the License, or (at # your option) any later version. # ! # The Notification Framework is distributed in the hope that it will be # useful, but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *************** *** 17,21 **** # # You should have received a copy of the GNU General Public License along ! # with the Modeling Framework; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # --- 17,21 ---- # # You should have received a copy of the GNU General Public License along ! # with the Notification Framework; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # Index: __init__.py =================================================================== RCS file: /cvsroot/modeling/NotificationFramework/__init__.py,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** __init__.py 10 Jan 2003 10:45:44 -0000 1.2 --- __init__.py 26 May 2003 12:24:52 -0000 1.3 *************** *** 1,15 **** #----------------------------------------------------------------------------- # ! # Modeling Framework: an Object-Relational Bridge for python # (c) 2001, 2002, 2003 Sebastien Bigaret # ! # This file is part of the Modeling Framework. # ! # The Modeling Framework is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License as published # by the Free Software Foundation; either version 2 of the License, or (at # your option) any later version. # ! # The Modeling Framework is distributed in the hope that it will be # useful, but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU --- 1,15 ---- #----------------------------------------------------------------------------- # ! # Notification Framework: "Observer" Design Pattern for python # (c) 2001, 2002, 2003 Sebastien Bigaret # ! # This file is part of the Notification Framework. # ! # The Notification Framework is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License as published # by the Free Software Foundation; either version 2 of the License, or (at # your option) any later version. # ! # The Notification Framework is distributed in the hope that it will be # useful, but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *************** *** 17,23 **** # # You should have received a copy of the GNU General Public License along ! # with the Modeling Framework; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # #----------------------------------------------------------------------------- --- 17,31 ---- # # You should have received a copy of the GNU General Public License along ! # with the Notification Framework; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # #----------------------------------------------------------------------------- + """ + The NotificationFramework is a python implementation of the "Observer" + Design Pattern, allowing one-to-many dependency between objects even when + they have no idea of who and where the other objects live. + The complete documentation can found in module NotificationCenter. + + It is distributed under the GNU General Public License. + """ Index: log.py =================================================================== RCS file: /cvsroot/modeling/NotificationFramework/log.py,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** log.py 10 Jan 2003 10:45:44 -0000 1.2 --- log.py 26 May 2003 12:24:52 -0000 1.3 *************** *** 1,15 **** #----------------------------------------------------------------------------- # ! # Modeling Framework: an Object-Relational Bridge for python # (c) 2001, 2002, 2003 Sebastien Bigaret # ! # This file is part of the Modeling Framework. # ! # The Modeling Framework is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License as published # by the Free Software Foundation; either version 2 of the License, or (at # your option) any later version. # ! # The Modeling Framework is distributed in the hope that it will be # useful, but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU --- 1,15 ---- #----------------------------------------------------------------------------- # ! # Notification Framework: "Observer" Design Pattern for python # (c) 2001, 2002, 2003 Sebastien Bigaret # ! # This file is part of the Notification Framework. # ! # The Notification Framework is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License as published # by the Free Software Foundation; either version 2 of the License, or (at # your option) any later version. # ! # The Notification Framework is distributed in the hope that it will be # useful, but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *************** *** 17,21 **** # # You should have received a copy of the GNU General Public License along ! # with the Modeling Framework; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # --- 17,21 ---- # # You should have received a copy of the GNU General Public License along ! # with the Notification Framework; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # Index: mems_lib.py =================================================================== RCS file: /cvsroot/modeling/NotificationFramework/mems_lib.py,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -C2 -d -r1.1.1.1 -r1.2 *** mems_lib.py 30 Jul 2002 15:02:38 -0000 1.1.1.1 --- mems_lib.py 26 May 2003 12:24:52 -0000 1.2 *************** *** 1,5 **** ! ## ! ## The following code is taken from the ZODB Programmer's Guide ! ## from types import ClassType,TypeType --- 1,5 ---- ! """ ! The code in this module is borrowed from the ZODB Programmer's Guide ! """ from types import ClassType,TypeType Index: setup.py =================================================================== RCS file: /cvsroot/modeling/NotificationFramework/setup.py,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -d -r1.7 -r1.8 *** setup.py 25 May 2003 19:06:50 -0000 1.7 --- setup.py 26 May 2003 12:24:52 -0000 1.8 *************** *** 2,16 **** #----------------------------------------------------------------------------- # ! # Modeling Framework: an Object-Relational Bridge for python # (c) 2001, 2002, 2003 Sebastien Bigaret # ! # This file is part of the Modeling Framework. # ! # The Modeling Framework is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License as published # by the Free Software Foundation; either version 2 of the License, or (at # your option) any later version. # ! # The Modeling Framework is distributed in the hope that it will be # useful, but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU --- 2,16 ---- #----------------------------------------------------------------------------- # ! # Notification Framework: "Observer" Design Pattern for python # (c) 2001, 2002, 2003 Sebastien Bigaret # ! # This file is part of the Notification Framework. # ! # The Notification Framework is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License as published # by the Free Software Foundation; either version 2 of the License, or (at # your option) any later version. # ! # The Notification Framework is distributed in the hope that it will be # useful, but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *************** *** 18,22 **** # # You should have received a copy of the GNU General Public License along ! # with the Modeling Framework; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # --- 18,22 ---- # # You should have received a copy of the GNU General Public License along ! # with the Notification Framework; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # |
From: <sbi...@us...> - 2003-05-25 19:06:53
|
Update of /cvsroot/modeling/NotificationFramework/tests In directory sc8-pr-cvs1:/tmp/cvs-serv30958/tests Modified Files: run.py test_NotificationCenter.py Added Files: compare_perfs.py Log Message: RFE #742511 Added the ability to register multiple callbacks for an object, triggered by env. variable NOTIFICATION_CENTER_MULTIPLE_CALLBACKS_PER_OBSERVER (it is NOT enabled by default) Fixed addObserver() which did not inform the user that a single callback can be registered per object --> this possibly led to buggy behaviour. Now it raises ValueError when this happens (this could make existing code fails because of that --be prepared to correct this. Added script tests/compare_perfs.py which calculates the performance penalty implied by the activation of the ability to handle multiple callbacks per object. Fixed: when generic and specific observers were registered, postNotification() made the list of observers grow (observers are copied back to the list). This slowed down the framework and a observer could then be notified more than once for the same notification. Fixed test_Notification.py and test_NotificationCenter.py: they couldn't be executed as stand-alone scripts. Added tests for RFE #742511 and fixed bugs --- NEW FILE: compare_perfs.py --- #! /usr/bin/env python #----------------------------------------------------------------------------- # # Modeling Framework: an Object-Relational Bridge for python # (c) 2001, 2002, 2003 Sebastien Bigaret # # This file is part of the Modeling Framework. # # The Modeling Framework is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License as published # by the Free Software Foundation; either version 2 of the License, or (at # your option) any later version. # # The Modeling Framework is distributed in the hope that it will be # useful, but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License along # with the Modeling Framework; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # #----------------------------------------------------------------------------- """ Evaluates the performance penalty implied by the activation of the ability to handle multiple callbacks per object """ import os, sys, time import utils from test_NotificationCenter import TestObject from NotificationFramework import NotificationCenter as NC utils.fixpath() N=1000 def loop(nb_iterations): o1=TestObject() o2=TestObject() NC.addObserver(o1, TestObject.callback, 'MSG') NC.addObserver(o2, TestObject.callback, 'MSG') NC.addObserver(o1, TestObject.callback, 'MSG', '01') NC.addObserver(o2, TestObject.callback, 'MSG', '01') t=time.time() i=0 while i<nb_iterations: NC.postNotification('MSG','01') i+=1 return time.time()-t def run(): try: del os.environ[NC.env_handlesMultipleCallbackPerObserver] except: pass reload(NC) t0=loop(N) print 'Nb of iterations: %i'%N print 'Without multiple callbacks per observer: %.6f'%t0 os.environ[NC.env_handlesMultipleCallbackPerObserver]='1' reload(NC) t1=loop(N) print 'With multiple callbacks per observer: %.6f'%t1 print 'Ratio: %.4f'%(t1/t0) if __name__=='__main__': #import profile #profile.run('run()', 'profile.out') run() Index: run.py =================================================================== RCS file: /cvsroot/modeling/NotificationFramework/tests/run.py,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** run.py 10 Jan 2003 10:45:44 -0000 1.2 --- run.py 25 May 2003 19:06:50 -0000 1.3 *************** *** 46,53 **** def test_suite(): import test_Notification - import test_NotificationCenter suite=unittest.TestSuite() suite.addTest(test_Notification.test_suite()) - suite.addTest(test_NotificationCenter.test_suite()) return suite --- 46,51 ---- *************** *** 65,69 **** if args: usage(me, 1) #raise 'Unexpected arguments', args utils.fixpath(zope_path) ! return utils.run_suite(test_suite(), verbosity=verbose) if __name__ == "__main__": --- 63,70 ---- if args: usage(me, 1) #raise 'Unexpected arguments', args utils.fixpath(zope_path) ! ! errs=utils.run_suite(test_suite(), verbosity=verbose) ! import test_NotificationCenter ! errs+=test_NotificationCenter.run_tests(verbosity=verbose) if __name__ == "__main__": Index: test_NotificationCenter.py =================================================================== RCS file: /cvsroot/modeling/NotificationFramework/tests/test_NotificationCenter.py,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** test_NotificationCenter.py 10 Jan 2003 10:45:44 -0000 1.4 --- test_NotificationCenter.py 25 May 2003 19:06:50 -0000 1.5 *************** *** 25,30 **** """Test the Model""" ! import unittest ! from NotificationFramework import NotificationCenter # ZODB specific checks --- 25,32 ---- """Test the Model""" ! import unittest, os, sys ! import utils ! from NotificationFramework import NotificationCenter as NC ! utils.fixpath() # ZODB specific checks *************** *** 39,48 **** class TestObject: def __init__(self): ! self.state=0 self.nbOfNotificationsReceived=0 ! def callMe(self, *kw): self.nbOfNotificationsReceived += 1 self.state=kw[0].object() self.userInfo=kw[0].userInfo() class TestObjectUnregister: --- 41,54 ---- class TestObject: def __init__(self): ! self.state=self.state_2=0 self.nbOfNotificationsReceived=0 ! def callback(self, *kw): self.nbOfNotificationsReceived += 1 self.state=kw[0].object() self.userInfo=kw[0].userInfo() + def callback_2(self, *kw): + self.nbOfNotificationsReceived += 1 + self.state_2=kw[0].object() + self.userInfo_2=kw[0].userInfo() class TestObjectUnregister: *************** *** 52,56 **** self.state=kw[0].object() self.userInfo=kw[0].userInfo() ! NotificationCenter.removeObserver(self) if _is_ZODB_available: --- 58,62 ---- self.state=kw[0].object() self.userInfo=kw[0].userInfo() ! NC.removeObserver(self) if _is_ZODB_available: *************** *** 64,74 **** class TestNotificationCenter(unittest.TestCase): "Tests for the module NotificationCenter" ! def test_1_initial(self): "[NotificationCenter] Initial state" ! self.failIf(NotificationCenter._observers(), "test initial") ! def test_2_silent(self): "[NotificationCenter] Tests that functions keep silent" - NC=NotificationCenter one=TestObject() self.failIf(NC.removeObserver(one), "Unregister an unregistered object") --- 70,79 ---- class TestNotificationCenter(unittest.TestCase): "Tests for the module NotificationCenter" ! def test_01_initial(self): "[NotificationCenter] Initial state" ! self.failIf(NC._observers(), "test initial") ! def test_02_silent(self): "[NotificationCenter] Tests that functions keep silent" one=TestObject() self.failIf(NC.removeObserver(one), "Unregister an unregistered object") *************** *** 82,88 **** NC.removeObserver(one) ! def test_3_add_remove(self): "[NotificationCenter] Tests that addition+removal leaves state untouched" - NC=NotificationCenter one=TestObject() observers_before=NC._observers() --- 87,92 ---- NC.removeObserver(one) ! def test_03_add_remove(self): "[NotificationCenter] Tests that addition+removal leaves state untouched" one=TestObject() observers_before=NC._observers() *************** *** 107,130 **** self.failUnlessEqual(observers_before, observers_after) ! def test_4_generic_postNotification(self): "[NotificationCenter] Tests generic observers" - NC=NotificationCenter one=TestObject() two=TestObject() ! NC.addObserver(one, TestObject.callMe, 'notif_test_4') ! NC.addObserver(two, TestObject.callMe, 'notif_test_4') NC.postNotification('notif_test_4', 2); self.failIf(one.state!= 2) self.failIf(two.state!= 2) ! def test_5a_specific_postNotification(self): "[NotificationCenter] Tests specific observers" - NC=NotificationCenter one=TestObject() two=TestObject() userInfo={'1': 1, '2': '2'} ! NC.addObserver(one, TestObject.callMe, 'notif_test_5', 10) ! NC.addObserver(two, TestObject.callMe, 'notif_test_5', 20) NC.postNotification('notif_test_5', 2); self.failIf(one.state!= 0, "one shouldn't have received 'notif_test_5'") --- 111,148 ---- self.failUnlessEqual(observers_before, observers_after) ! def test_04_generic_postNotification(self): "[NotificationCenter] Tests generic observers" one=TestObject() two=TestObject() ! NC.addObserver(one, TestObject.callback, 'notif_test_4') ! NC.addObserver(two, TestObject.callback, 'notif_test_4') NC.postNotification('notif_test_4', 2); self.failIf(one.state!= 2) self.failIf(two.state!= 2) + + def test_04b_generic_one_callback_per_notification(self): + "[NotificationCenter] (generic) One callback per notification" + if not os.environ.get(NC.env_handlesMultipleCallbackPerObserver): + return + one=TestObject() + NC.addObserver(one, TestObject.callback, 'notif_test_4b_MSG_ONE') + NC.addObserver(one, TestObject.callback_2, 'notif_test_4b_MSG_TWO') + NC.postNotification('notif_test_4b_MSG_ONE', 'MSG_ONE'); + self.failIf(one.state != 'MSG_ONE') + self.failIf(one.state_2 != 0) + self.failIf(one.nbOfNotificationsReceived != 1) + NC.postNotification('notif_test_4b_MSG_TWO', 'MSG_TWO'); + self.failIf(one.state != 'MSG_ONE') + self.failIf(one.state_2 != 'MSG_TWO') + self.failIf(one.nbOfNotificationsReceived != 2) ! def test_05a_specific_postNotification(self): "[NotificationCenter] Tests specific observers" one=TestObject() two=TestObject() userInfo={'1': 1, '2': '2'} ! NC.addObserver(one, TestObject.callback, 'notif_test_5', 10) ! NC.addObserver(two, TestObject.callback, 'notif_test_5', 20) NC.postNotification('notif_test_5', 2); self.failIf(one.state!= 0, "one shouldn't have received 'notif_test_5'") *************** *** 138,145 **** self.failIf(two.state!= 20, "two hasn't received 'notif_test_5'") ! def test_5b_specific_postNotification(self): "[NotificationCenter] Tests specific observers unregistering themselves at notification time" ! # see comments in NoticicationCenter._listToNotifyForNotification() ! NC=NotificationCenter one=TestObject() unregister=TestObjectUnregister() --- 156,162 ---- self.failIf(two.state!= 20, "two hasn't received 'notif_test_5'") ! def test_05b_specific_postNotification(self): "[NotificationCenter] Tests specific observers unregistering themselves at notification time" ! # see comments in NotificationCenter._listToNotifyForNotification() one=TestObject() unregister=TestObjectUnregister() *************** *** 147,153 **** userInfo={'1': 1, '2': '2'} ! NC.addObserver(one, TestObject.callMe, 'notif_test_5b', 10) NC.addObserver(unregister, TestObjectUnregister.callMe, 'notif_test_5b',10) ! NC.addObserver(two, TestObject.callMe, 'notif_test_5b', 10) NC.postNotification('notif_test_5b', 10) self.failIf(one.state!= 10, "one should have received 'notif_test_5b'") --- 164,170 ---- userInfo={'1': 1, '2': '2'} ! NC.addObserver(one, TestObject.callback, 'notif_test_5b', 10) NC.addObserver(unregister, TestObjectUnregister.callMe, 'notif_test_5b',10) ! NC.addObserver(two, TestObject.callback, 'notif_test_5b', 10) NC.postNotification('notif_test_5b', 10) self.failIf(one.state!= 10, "one should have received 'notif_test_5b'") *************** *** 155,170 **** self.failIf(two.state!= 10, "two should have received 'notif_test_5b'") ! def test_6_ZTests(self): "[NotificationCenter] Tests the specific checks made when ZODB.Persistent is available" if not _is_ZODB_available: return - NC=NotificationCenter one=ZTestObject() self.failUnlessRaises(ValueError, NC.addObserver, ! one, TestObject.callMe, 'notif_test_6') ! def test_7_codeObjectObservers(self): "[NotificationCenter] Tests for code objects as observers" - NC=NotificationCenter one=TestObject() import testmodule --- 172,205 ---- self.failIf(two.state!= 10, "two should have received 'notif_test_5b'") ! def test_05c_specific_one_callback_per_notification(self): ! "[NotificationCenter] (specific) One callback per notification" ! if not os.environ.get(NC.env_handlesMultipleCallbackPerObserver): ! return ! one=TestObject() ! NC.addObserver(one, TestObject.callback, 'notif_test_5c_MSG','01') ! NC.addObserver(one, TestObject.callback_2, 'notif_test_5c_MSG', '02') ! NC.postNotification('notif_test_5c_MSG', '00'); ! self.failIf(one.state != 0) ! self.failIf(one.state_2 != 0) ! self.failIf(one.nbOfNotificationsReceived != 0) ! NC.postNotification('notif_test_5c_MSG', '01'); ! self.failIf(one.state != '01') ! self.failIf(one.state_2 != 0) ! self.failIf(one.nbOfNotificationsReceived != 1) ! NC.postNotification('notif_test_5c_MSG', '02'); ! self.failIf(one.state != '01') ! self.failIf(one.state_2 != '02') ! self.failIf(one.nbOfNotificationsReceived != 2) ! ! def test_06_ZTests(self): "[NotificationCenter] Tests the specific checks made when ZODB.Persistent is available" if not _is_ZODB_available: return one=ZTestObject() self.failUnlessRaises(ValueError, NC.addObserver, ! one, TestObject.callback, 'notif_test_6') ! def test_07_codeObjectObservers(self): "[NotificationCenter] Tests for code objects as observers" one=TestObject() import testmodule *************** *** 180,184 **** code=code.compile_command('import testmodule;'\ 'observer_object=testmodule.one') ! NC.addObserver(code, TestObject.callMe, 'notif_test_7') NC.postNotification('notif_test_7', 7, userInfo) self.failIf(one.state!= 7, "one hasn't received 'notif_test_7'") --- 215,219 ---- code=code.compile_command('import testmodule;'\ 'observer_object=testmodule.one') ! NC.addObserver(code, TestObject.callback, 'notif_test_7') NC.postNotification('notif_test_7', 7, userInfo) self.failIf(one.state!= 7, "one hasn't received 'notif_test_7'") *************** *** 190,196 **** self.failUnlessEqual(observers_before, NC._observers()) ! def test_8_observersAsModuleFunction(self): "[NotificationCenter] Tests a module function as an observer" - NC=NotificationCenter import testmodule # saves the current set of observers so that it can be compared --- 225,230 ---- self.failUnlessEqual(observers_before, NC._observers()) ! def test_08_observersAsModuleFunction(self): "[NotificationCenter] Tests a module function as an observer" import testmodule # saves the current set of observers so that it can be compared *************** *** 207,216 **** 'couldnt remove FunctionType observer?') ! def test_9_observerMultiplyRegistered(self): "[NotificationCenter] observerMultiplyRegistered" - NC=NotificationCenter one=TestObject() ! NC.addObserver(one, TestObject.callMe, 'notif_test_9') ! NC.addObserver(one, TestObject.callMe, 'notif_test_9', sameObserverRegistersOnce=0) NC.postNotification('notif_test_9', 9); --- 241,249 ---- 'couldnt remove FunctionType observer?') ! def test_09_observerMultiplyRegistered(self): "[NotificationCenter] observerMultiplyRegistered" one=TestObject() ! NC.addObserver(one, TestObject.callback, 'notif_test_9') ! NC.addObserver(one, TestObject.callback, 'notif_test_9', sameObserverRegistersOnce=0) NC.postNotification('notif_test_9', 9); *************** *** 226,231 **** # Tests that multiply registered observer can be removed and still # remains registered ! NC.addObserver(one, TestObject.callMe, 'notif_test_9') ! NC.addObserver(one, TestObject.callMe, 'notif_test_9', sameObserverRegistersOnce=0) NC.removeObserver(one, 'notif_test_9') # remove one --- 259,264 ---- # Tests that multiply registered observer can be removed and still # remains registered ! NC.addObserver(one, TestObject.callback, 'notif_test_9') ! NC.addObserver(one, TestObject.callback, 'notif_test_9', sameObserverRegistersOnce=0) NC.removeObserver(one, 'notif_test_9') # remove one *************** *** 234,240 **** self.failIf(one.nbOfNotificationsReceived!=3) def _test_observer(self): "Test with objects as observers" ! NotificationCenter.addObserver() def test_suite(): --- 267,301 ---- self.failIf(one.nbOfNotificationsReceived!=3) + def test_10_post_to_generic_specific_observers_leaves_obsvs_untouched(self): + "[NotificationCenter] post to generic specific observers leaves obsvs untouched" + # There was a bug in _listToNotifyForNotification triggered when + # generic and specific observers are listening to a single notification. + # This bug increases the size of the observers for a notification each + # time postNotification() was called + one=TestObject() + two=TestObject() + NC.addObserver(one, TestObject.callback, 'notif_test_10') + NC.addObserver(two, TestObject.callback, 'notif_test_10') + NC.addObserver(one, TestObject.callback, 'notif_test_10', '10') + NC.addObserver(two, TestObject.callback, 'notif_test_10', '10') + observers_before=NC._observers() + NC.postNotification('notif_test_10', '10'); + NC.postNotification('notif_test_10', '10'); + observers_after=NC._observers() + self.failUnlessEqual(observers_before, observers_after) + + def test_11_addObserver_and_multiple_callbacks(self): + "[NotificationCenter] addObserver() and multiple callbacks" + one=TestObject() + NC.addObserver(one, TestObject.callback, 'notif_test_11') + if not os.environ.get(NC.env_handlesMultipleCallbackPerObserver): + self.assertRaises(ValueError, NC.addObserver, + one, TestObject.callback_2, 'notif_test_11b') + else: + NC.addObserver(one, TestObject.callback_2, 'notif_test_11b') + def _test_observer(self): "Test with objects as observers" ! NC.addObserver() def test_suite(): *************** *** 243,248 **** return suite ! if __name__ == "__main__": ! errs = utils.run_suite(test_suite()) sys.exit(errs and 1 or 0) --- 304,320 ---- return suite ! def run_tests(verbosity=0): ! try: ! del os.environ[NC.env_handlesMultipleCallbackPerObserver] ! except: ! pass ! reload(NC) ! errs = utils.run_suite(test_suite(), verbosity=verbosity) ! os.environ[NC.env_handlesMultipleCallbackPerObserver]='1' ! reload(NC) ! errs += utils.run_suite(test_suite(), verbosity=verbosity) ! return errs ! if __name__ == "__main__": ! errs = run_tests() sys.exit(errs and 1 or 0) |
From: <sbi...@us...> - 2003-05-25 19:06:53
|
Update of /cvsroot/modeling/NotificationFramework In directory sc8-pr-cvs1:/tmp/cvs-serv30958 Modified Files: CHANGES setup.py NotificationCenter.py Log Message: RFE #742511 Added the ability to register multiple callbacks for an object, triggered by env. variable NOTIFICATION_CENTER_MULTIPLE_CALLBACKS_PER_OBSERVER (it is NOT enabled by default) Fixed addObserver() which did not inform the user that a single callback can be registered per object --> this possibly led to buggy behaviour. Now it raises ValueError when this happens (this could make existing code fails because of that --be prepared to correct this. Added script tests/compare_perfs.py which calculates the performance penalty implied by the activation of the ability to handle multiple callbacks per object. Fixed: when generic and specific observers were registered, postNotification() made the list of observers grow (observers are copied back to the list). This slowed down the framework and a observer could then be notified more than once for the same notification. Fixed test_Notification.py and test_NotificationCenter.py: they couldn't be executed as stand-alone scripts. Added tests for RFE #742511 and fixed bugs Index: CHANGES =================================================================== RCS file: /cvsroot/modeling/NotificationFramework/CHANGES,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** CHANGES 14 Jan 2003 08:51:38 -0000 1.5 --- CHANGES 25 May 2003 19:06:49 -0000 1.6 *************** *** 1,2 **** --- 1,27 ---- + 0.5 [2003/05/25] + + - RFE #742511 Added the ability to register multiple callbacks for an + object, triggered by env. variable + NOTIFICATION_CENTER_MULTIPLE_CALLBACKS_PER_OBSERVER (it is NOT enabled + by default) + + Fixed addObserver() which did not inform the user that a single callback + can be registered per object --> this possibly led to buggy + behaviour. Now it raises ValueError when this happens (this could make + existing code fails because of that --be prepared to correct this. + + - Added script tests/compare_perfs.py which calculates the performance + penalty implied by the activation of the ability to handle multiple + callbacks per object + + - Fixed: when generic and specific observers were registered, + postNotification() made the list of observers grow (observers are copied + back to the list). This slowed down the framework and a observer could + then be notified more than once for the same notification. + + - Fixed test_Notification.py and test_NotificationCenter.py: they couldn't + be executed as stand-alone scripts. Added tests for RFE #742511 and fixed + bugs + 0.4 Now distributed under the GNU General Public License Index: setup.py =================================================================== RCS file: /cvsroot/modeling/NotificationFramework/setup.py,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** setup.py 14 Jan 2003 09:03:41 -0000 1.6 --- setup.py 25 May 2003 19:06:50 -0000 1.7 *************** *** 31,35 **** setup(name="NotificationFramework", ! version="0.4", licence ="GNU General Public License", description=short_description, --- 31,35 ---- setup(name="NotificationFramework", ! version="0.5", licence ="GNU General Public License", description=short_description, Index: NotificationCenter.py =================================================================== RCS file: /cvsroot/modeling/NotificationFramework/NotificationCenter.py,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** NotificationCenter.py 10 Jan 2003 10:45:44 -0000 1.5 --- NotificationCenter.py 25 May 2003 19:06:50 -0000 1.6 *************** *** 38,47 **** objects that a notification they are listening to was posted. To achieve this, objects should supply their reference, as well as a callback method ! at registration time. ! The only possible listeners are: class instances ('types.InstanceType'), ! code objects or functions (such as functions defined in a module). See ! method 'addObserver' for full details ; we will focus in the following on ! class instances. For listeners being class instances, callbacks' signature should minimally --- 38,48 ---- objects that a notification they are listening to was posted. To achieve this, objects should supply their reference, as well as a callback method ! at registration time (Note: by default only one callback is accepted per ! object; see discussion below). ! The possible listeners are: class instances ('types.InstanceType'), code ! objects or functions (such as functions defined in a module). See method ! 'addObserver' for full details ; we will focus in the following on class ! instances. For listeners being class instances, callbacks' signature should minimally *************** *** 89,92 **** --- 90,141 ---- and object is posted. + Registering more than one callback per object + + By default, addObserver() checks that only one callback is registered per + object; if you try to register a different one, you'll get a ValueError. + + Of course, a single object can listen to multiple notifications. In that + case, you'll probably register a given method, say, handleNotification(), + dedicated to this task:: + + def handleNotification(self, notification): + notification_name=notification.name() + if notification_name == "NOTIFICATION_ONE": + # code for notification one + elif notification_name == "NOTIFICATION_TWO" + # code for notification two + else: + # Unhandled notification + + However, sometimes you do not want this; for example, you want to bind + several methods of an object defined by a third-party module, and you do + not want to modify its code. Registering multiple callbacks is possible + when the environment variable + 'NOTIFICATION_CENTER_MULTIPLE_CALLBACKS_PER_OBSERVER' is defined and + its value is not an empty string. + + IMPORTANT: this variable should be set *prior* to any import statement + importing the NotificationCenter module, or it wont have any + effect at all. + + Example: + + bash -- + export NOTIFICATION_CENTER_MULTIPLE_CALLBACKS_PER_OBSERVER='y' + + python -- + + import os + os.environ['NOTIFICATION_CENTER_MULTIPLE_CALLBACKS_PER_OBSERVER']='y' + from NotificationFramework import NotificationCenter + + Why is it not the default/only behaviour? + + Handling multiple callbacks per object implies a performance + penalty. You can test which are the consequences on your platform with + the supplied script 'compare_perfs.py' in directory tests/ On my + machine, postNotification() is about 2.4x slower when the handling of + multiple callbacks per object is activated. + Notification names and objects *************** *** 102,106 **** Zope: some important notes ! TBD!!! --- 151,159 ---- Zope: some important notes ! TBD!!! In the meantime you can look at the code for methods ! observerCodeForZopePersistentObject() and ! observerCodeForZopeTemporaryObject(), and to ! tests/test_NotificationCenter. test_7_codeObjectObservers(). ! *************** *** 115,119 **** from threading import RLock import mems_lib, log ! import code, types, weakref # ZODB specific checks --- 168,172 ---- from threading import RLock import mems_lib, log ! import code, os, types, weakref # ZODB specific checks *************** *** 126,129 **** --- 179,185 ---- pass + env_handlesMultipleCallbackPerObserver='NOTIFICATION_CENTER_MULTIPLE_CALLBACKS_PER_OBSERVER' + __handlesMultipleCallbackPerObserver=os.environ.get(env_handlesMultipleCallbackPerObserver,None) + ## The following are private, do NOT access it directly! __observers__={} *************** *** 138,143 **** lock() try: ! # first the observers=__observers__.get(notification, []) # Then check for observers listening to the NotificationName, whatever the # object --- 194,211 ---- lock() try: ! # first the specific observers observers=__observers__.get(notification, []) + # We need a copy, or the next 'if' block will possibly change 'observers' + # which is BAD! + # (cf. test_10_post_to_generic_specific_observers_leaves_obsvs_untouched) + + # Additional note: since the module's methods are reentrant within a + # thread, it is possible for a listener to unregister itself when + # receiving the notification ; in that case and if we do not return a copy + # here, the sequence on which we iterate in postNotification() will be + # alterated *during* the iteration and this leads to an observer not being + # notified. + + observers=list(observers) # Then check for observers listening to the NotificationName, whatever the # object *************** *** 148,163 **** log.trace('_listToNotifyForNotification(%s)'%notification, 'Returns: %s'%str(observers)) ! # return a copy: since the module's methods are reentrant within a thread, ! # it is possible for a listener to unregister itself when receiving the ! # notification ; in that case and if we do not return a copy here, the ! # sequence on which we iterate in postNotification() will be alterated ! # *during* the iteration and this leads to an observer not being notified. ! return list(observers) finally: unlock() def _observers(): # for testing purposes mainly "PRIVATE, DO NOT CALL DIRECTLY" ! return __observers__.copy() # shallow copy ## --- 216,246 ---- log.trace('_listToNotifyForNotification(%s)'%notification, 'Returns: %s'%str(observers)) ! return observers finally: unlock() + if __handlesMultipleCallbackPerObserver: + def _callbacksForObserverAndNotification(observer, notification): + "Private: do not call directly" + lock() + try: + callback=__observers_callbacks__.get((observer, notification)) + callbacks=callback and [callback] or [] + if notification.object() is not None: + general_notification=Notification(notification.name()) + general_callback=__observers_callbacks__.get((observer, general_notification),None) + if general_callback: + callbacks.append(general_callback) + return callbacks + finally: + unlock() + def _observers(): # for testing purposes mainly "PRIVATE, DO NOT CALL DIRECTLY" ! obs={} ! for k,v in __observers__.items(): ! obs[k]=list(v) ! return obs ! ## *************** *** 175,178 **** --- 258,266 ---- first time they are supposed to receive a notification. + addObserver() raises ValueError when an attempt is made to register an + object that was previously registered with a different callback than the one + supplied. Please refer to the module's documentation for a complete + discussion on this topic. + Parameters: *************** *** 203,207 **** import code ! code=code.compile_command('import aModule;'\ 'observer_object=aModule.anObject') --- 291,295 ---- import code ! code=code.compile_command('import aModule;'+ 'observer_object=aModule.anObject') *************** *** 248,251 **** --- 336,346 ---- notification=Notification(notificationName, object) try: + if not __handlesMultipleCallbackPerObserver: + if __observers_callbacks__.get(observer, callback)!=callback: + raise ValueError, "object is already registered with a different callback (%s)%"%__observers_callbacks__.get(observer) + __observers_callbacks__[observer]=callback + else: + __observers_callbacks__[(observer,notification)]=callback + if __observers__.get(notification): if sameObserverRegistersOnce: *************** *** 256,260 **** else: __observers__[notification]=[observer] - __observers_callbacks__[observer]=callback finally: unlock() --- 351,354 ---- *************** *** 333,337 **** if param: log.trace('postNotification', 'Notifying: %s'%observer) ! apply(__observers_callbacks__[observer], param) finally: unlock() --- 427,436 ---- if param: log.trace('postNotification', 'Notifying: %s'%observer) ! if not __handlesMultipleCallbackPerObserver: ! apply(__observers_callbacks__[observer], param) ! else: ! for c in _callbacksForObserverAndNotification(observer, ! searchNotification): ! apply(c,param) finally: unlock() *************** *** 359,360 **** --- 458,460 ---- _code=code.compile_command(codeStr) return _code + |
From: <sbi...@us...> - 2003-05-25 18:56:11
|
Update of /cvsroot/modeling/NotificationFramework/tests In directory sc8-pr-cvs1:/tmp/cvs-serv25952/tests Modified Files: test_Notification.py Log Message: Fixed: couldn't be executed stand-alone Index: test_Notification.py =================================================================== RCS file: /cvsroot/modeling/NotificationFramework/tests/test_Notification.py,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** test_Notification.py 10 Jan 2003 10:45:44 -0000 1.3 --- test_Notification.py 25 May 2003 18:56:08 -0000 1.4 *************** *** 25,30 **** """Test the Notification class""" ! import unittest from NotificationFramework.Notification import Notification class TestNotification(unittest.TestCase): --- 25,33 ---- """Test the Notification class""" ! import unittest, sys ! import utils from NotificationFramework.Notification import Notification + + utils.fixpath() class TestNotification(unittest.TestCase): |