[Subversion] / PEAK / CHANGES.txt |
No default branch
Bookmark a link to HEAD:
(view)
(download)
Fixed 'peak.util.imports.whenImported()' function, so you can now register functions to be called when another module is imported. This should be useful for declaring adapters for external types, e.g. adapting Zope interfaces to IConfigKey, without causing the external type to be imported unless it's actually used.
Got rid of the 'adaptTo' requirement for retrieving objects from naming contexts. Note that if you have defined any URL schemes that do not also define a naming context class, you will need to revise them. Specifically, you need to add a 'defaultFactory' attribute referencing the name of the class of object that the URL should retrieve, and you need to have that class declare that it (not its instances) provide 'naming.IObjectFactory', and add a 'getObjectInstance()' classmethod to do the dirty work. If your URL scheme references a subclass of ManagedConnection, you don't need to do the object factory stuff, however, as it's already done for you in the ManagedConnection base. All you need is the 'defaultFactory' attribute. Also, if you defined any adapter declarations for your URLs to the target class, you should get rid of them.
Property definition rules in an .ini file can now refer to 'rulePrefix' and 'ruleSuffix' variables. 'rulePrefix' is a '.'-terminated string, representing the name the rule was defined with. For example, if the rule was defined for '"foo.bar.*"', then 'rulePrefix' will be '"foo.bar."'. The 'ruleSuffix' will be the portion of the 'propertyName' that follows 'rulePrefix'. So, if looking up property '"foo.bar.baz"', then the '"foo.bar.*"' rule will execute with a 'ruleSuffix' of '"baz"'. This should make it easier to work with hierarchical property namespaces.
Brought CHANGES.txt up-to-date.
Forgot to check this in with the PEAK_CONFIG change.
Added preliminary DM implementations for "Bulletins" app, and 'adduser' and 'showusers' commands. Also, changed 'storage.EntityDM' to supply a default implementation of the '_defaultState()' method.
Added Python/Zope 'datetime' package.
'peak.web' is born; just interface sketches and a draft of 'BaseInteraction' for now. CGI support has been moved from 'peak.running.zpublish' into 'peak.running.commands' (for "raw" CGI/FastCGI) and 'peak.web' (for the PEAK high-level publishing framework). You can use 'peak CGI someName' to adapt 'someName' to a 'running.IRerunnableCGI' and run it as a CGI/FastCGI. This will form the basis for creating the web version of an app later; you'll do something like:: class MyAppAsCGI(web.CGIPublisher): app = binding.New(MyAppClass) And then use 'peak CGI import:somepkg.MyAppAsCGI' to run it. Or, if your app wants to exec a config file, you might define your CGIPublisher subclass as an adapter from MyAppClass to IRerunnableCGI, rather than invoking it directly.
Added attribute name -> permission mappings for both declaration and checking. Added complex scenario-driven tests based on a data-driven permissions model.
Doc fixes: name -> attrName.
There is now an interface for "Active Descriptors": 'binding.IActiveDescriptor'. 'peak.binding' now uses this interface to identify active descriptors, so you can now create your own. (Previously, 'peak.binding' used 'isinstance()' to detect active descriptors.)
The naming system base classes no longer use 'attrs' as an input parameter or return value. If you've subclassed anything from 'peak.naming.contexts', note that your '_get()' methods should now just return the lookup value, rather than a 'state,attrs' tuple. For most naming contexts, this just means you should change 'return foo, None' statements to just 'return foo'.
'peak.naming' no longer automatically converts all addresses to the addressed objects. You must specifically request the interface you want by adapting the retrieved object to that interface. This can be done by supplying an 'adaptTo=ISomething' keyword argument to the attribute binding definition or your 'lookupComponent()' call. The naming system no longer has 'objectFactories' and 'stateFactories'; these have been replaced with adaptation. Writable naming contexts must have a 'serializationProtocol' attribute specifying what interface an object should be adapted to before attempting to store it in that context. The naming system no longer processes the 'creationName' keyword argument; this is now considered the sole responsibility of 'peak.binding'. The 'IComponent.lookupComponent()' method still accepts the keyword argument, and attribute bindings still handle the creation name transparently. It is just not available via naming system APIs, and naming contexts no longer have to deal with it. Also, removed 'naming.ParsedURL'; it was deprecated as of 0.5 alpha 2. (Note: 'smtp:' URLs are currently broken, in that we don't have an interface to adapt them to for retrieval, and I didn't want to create an SMTP naming context, since what we want to do with SMTP is still up in the air.)
All 'peak.binding' APIs now only accept positional parameters for items unique to that API. Items common to multiple APIs (such as 'offerAs', 'doc', 'attrName', etc.) should now be supplied as keyword arguments. Bindings also now automatically "suggest" the containing object as a parent component for the contained object, whenever a value is assigned to them or computed. If a non-None 'adaptTo' is set on the binding, the value assigned or computed will be adapted to the specified protocol before the parent component is suggested. 'binding.New()' no longer relies on the 'IComponentFactory' interface, but instead uses the new adapt/suggest mechanisms. Previously, parent components were only "suggested" when a binding was set via component constructor keyword arguments. Now, this is done at any time bindings are set, but *not* for non-binding keyword arguments. In other words, ordinary attributes of a component do not receive "suggested parent" notices, even when set via constructor keyword arguments. If you want an attribute to do this, you must define the attribute with the binding API; e.g. via 'requireBinding()' or 'binding.Constant()'.
The 'provides' keyword argument to various 'peak.binding' APIs has been renamed to 'offerAs', and it must be a sequence of configuration keys. (Previously, it accepted either a single key or a tuple of keys.) The signature of 'binding.Constant()' was changed as well; the first positional argument is now the constant value, and 'offerAs' is now a keyword argument. (Previously, 'provides' was the first positional argument of 'binding.Constant()'.) The 'registerProvider()' method of 'config.IConfigurable()' also now accepts only a single configuration key, as does 'EigenRegistry.register()'.
Fix HTML formatting of CHANGES file
Misc. doc cleanups/enhancements. Added info on 'invoke' command.
Finished URLChecker and FileCleaner demo daemons; updated CHANGES and TODO.
Fill in some items I missed documenting while I was focused on PyProtocols.
Misc. edits preparing for 0.5a2
Added a ZConfig schema for 'running.commands.EventDriven' applications, a ZConfig component definition for adaptive tasks, and a running shortcut called 'EventDriven'. It should now be possible to do this:: #!/usr/bin/env peak EventDriven at the top of a ZConfig file formatted according to the new schema, and have it run. Unfortunately, so far the only type of task that can be included is 'running.daemons.AdaptiveTask', which doesn't actually *do* anything. So, right now doing this is equivalent to creating an over- engineered 'sleep' command. ;) Also, fixed a problem in ZConfig 'schema.dtd'; I used 'PCDATA' where I should've used 'CDATA', and I fixed various problems with the 'fromZConfig()' component constructor. It's kind of annoying that ZConfig defaults unspecified items to 'None', even if you said they weren't required and had no default. :( I'll see if I can do something about this later; for now I just delete 'None' values from the data.
Added ZConfig URL support. ZConfig schemas and files can be loaded from any PEAK-supported stream URL, including 'pkgfile:'. Interfile references aren't tested yet, nor are there any unit tests. Those will be added once we have some meaningful schemas and configurations to test with. There is a 'zconfig.schema' URL scheme that loads a command interpreter, and a 'peak ZConfig' option as well. See 'CHANGES.txt' for details on the new features. Also, fixed up some issues with the 'fromZConfig()' component constructor. All we need now are some useful base schemas for daemons, and the last piece for 0.5a2 (besides PyProtocols) will be in place.
Standardized file-based URL syntaxes (e.g logfiles and lockfiles) to follow RFC 1738/2396, and Python 'urllib'. This shouldn't affect much besides the canonical forms of the URLs. Added 'pkgfile:some.pkg/filepath' URL syntax for ease of referring to files near modules. (A convenience intended mainly for referencing ZConfig schemas.)
Added the UML 1.4 metamodel, and thus the ability to load UML 1.4 models encoded in XMI 1.1. Added support in the mof2py code generator for "unprefixing" enumerated values, so that UML and other metamodels' enumerations work correctly when loading from XMI. Fixed source distributions missing essential setup files. Rescheduled UML 1.5 and CWM support to version 0.6. Hardly any tools use UML 1.5 yet, and we can't do anything useful with CWM until we have XMI writing, and some type of UI for editing models.
Finished switchover to using protocols.advise() API to declare interfaces.
Began the move of 'peak.interface' to a separate 'protocols' package for ease of distribution independently of PEAK. Also, removed caching of success/failed adapter lookups, because there was no way for them to be cleared when declarations were made for base classes of a class whose lookup was cached. (To do caching, I'll have to add a separate cache.) In the next pass, I'll add the new declaration API that Ty and I designed, and then change PEAK to use it, factoring out the interim API, and changing the few remaining introspections in PEAK to work via adapation. Then, it's off to documentation, unit tests, and packaging for the 'protocols' package.
Made interfaces thread-safe for registration. Added more interfaces to explain the interface of the interface package. :) Refined adapter comparison algorithm to better understand the "distance" between protocols. Removed classic-class adapter, since protocols now do reasonable caching for classic MRO's and subtypes.
And so we bid a fond farewell to introspection as well. 'isImplementedBy' is now a thing of the past. Refactored anything that used it, to now use adapt(), which has now opened up a lot of extension possibilities in places that were previously not extensible without modifying PEAK core code. See below. Also, the interface module has been refactored to support 'classProvides()' in a clean and kludge-free fashion, along with support for faster adaptation of old and new-style classes (by caching lookups, and by safely adding '__conform__' methods to classic classes), and the ability for classes to manage their own "implements" information. The core interface code is now quite elegant in the way it uses its own adaptation system as the basis for implementing adaptation. :) 'binding.Acquire()' now accepts a 'default' value argument, and 'binding.New()' no longer accepts the 'bindToOwner' flag. There is a new 'binding.IComponentKey' interface that is used to implement 'IComponent.lookupComponent()'. Now you can implement this interface, or create an adapter for it, in order to make an object usable as an argument to 'binding.lookupComponent()' - and therefore usable as a key for 'binding.bindTo()' or 'binding.bindToSequence()'. Not that it's necessarily very useful to do so; you're probably better off simply creating a naming scheme. But it might be useful for lookups done in the context of classes, since naming schemes aren't usable there. (It was actually added in order to factor out all the type testing that 'lookupComponent' used to do, so it doesn't matter if it's useful for much else.) PEAK has been refactored to avoid the use of 'isImplementedBy()' and similar introspection, in favor of 'adapt()'. As a result, some 'peak.naming' interfaces have changed. This should not affect you if you are only subclassing PEAK-provided naming components and not implementing these interfaces "from scratch". However, the various 'isAddress', 'isAddressClass', 'isResolver', and 'isName' APIs have also been removed, as they were based on 'isImplementedBy()'. The ability to use 'isImplementedBy()' with interfaces declared by PEAK is REMOVED. You can still use 'isImplementedBy()' with Zope interfaces, of course, but we recommend you switch to 'adapt()', which will work with both PEAK and Zope interfaces.
Added transitive adaptation: declaring an adapter "AB" from A to B, and "BC" from B to C, automatically implies adaptation from A to C via BC(AB()). Used it to simplify the mechanism for adapting an IExecutable to an ICmdLineAppFactory. Refactored some of the interface package's initial kludges to cleaner mechanisms based on adaptation. Learned some interesting things along the way... Classic classes don't have __mro__, which made adapt() break on them. The technique I was using in the hopes of suppressing unwanted TypeErrors suppressed wanted ones, and meanwhile there weren't any unwanted ones in PEAK. Finally, Python 2.2 doesn't support 'super()' access to properties, and metamethods are properties, so you have to use my new 'supermeta' to work around this when you need to call a super() metamethod. This is supposed to be fixed in Python 2.3, but not backported 2.2 because Guido considers it a "feature". Ah well.
Farewell, 'zope.interface'. You served us well.
__implements__ is dead, long live implements()! We are also no longer using 'zope.interface', but instead using a complete, interoperable replacement for it. Also, tweaked a few things so that using pydoc or 'help()' on PEAK component classes and interfaces now works halfway decently, as opposed to producing tracebacks (or dumping core!). 'zope.interface' will soon be removed from the PEAK distribution altogether. See CHANGES.txt for details of why this replacement was created.
DEPRECATED use of '__implements__' and '__class_implements__' to declare support for interfaces. Use 'implements()', 'classProvides()', 'directlyProvides()', 'moduleProvides()', etc. to do this now; they are now available automatically from 'peak.api'. Please note that alpha 2 will *not* support the use of __implements__ attributes at all! Start using the APIs for this *now*, even if you're using alpha 1 (which at least supports the 'implements()' and 'classProvides()' functions).
'EigenRegistry' and 'PropertyMap' no longer attempt to figure out whether implied (i.e. inherited) interfaces are more or less general with respect to a previous registration. This was behavior that emulated Zope adapter registries, but what we really wanted was more akin to a Zope "type" registry. The only parts of the test suite that used the old behavior were the tests specifically written to ensure that behavior! Also, changed the implementation of '__class_provides__' so that the registry becomes immutable as soon as it is computed by the class.
Fixed 'naming.lookup()' and related APIs not setting the parent component of created objects without an explicitly supplied 'creationParent' keyword argument. This used to "sort of work" when we had implicit configuration parents, but was broken when we went "all explicit" for 0.5 alpha 1. Also, fixed SPI-level calls that didn't go through "paramegeddon": 'getObjectInstance()', 'getStateToBind()', and 'getURLContext()' weren't following the "parent/context goes first" signature convention.
'binding.bindTo()' now accepts a 'default=' argument, whose value will be used in case of a 'NameNotFound' error.
Removed regular expression support from URL.Base; it was only there for ease of migration while I was switching all of PEAK's URL classes over to the new parsing framework. Since use of regular expressions for URL syntax is now deprecated (so that URLs can be formattable as well as parseable), there's no reason to keep this in URL.Base. Added the ability for other name types (composite and compound) to be used as structural feature types (e.g. for URL fields), and for compound name types to generate a corresponding composite name type. Changed LDAP urls to use this ability, which means the LDAP 'basedn' field is now always a composite name.
Misc. doc edits
Refactoring to support "canonical formatting" of URLs. This required creating a sizeable parsing/formatting framework. :( On the brigher side, the framework is highly powerful and expressive. Potentially it could be pulled out as a 'peak.model' parsing framework, to be reused for other parse/format applications on model elements that have a single canonical string syntax. It would probably need to be reviewed for Unicode compatibility, however. Anyway, now printing a parsed URL object should give you back a canonical form of that URL; equivalent URLs (apart from case-sensitivity issues) should produce identical canonical forms. Passing keyword arguments to a URL constructor should also allow you to selectively override the URL body content, making it easy to produce new versions of a URL with an altered field.
Repoint 'ParsedURL' -> 'URL.Base'; this will let existing 'ParsedURL' subclasses continue to work for a while, until 'ParsedURL' is removed in alpha 3.
Began work on replacing 'naming.ParsedURL' with a structure type using 'peak.model'. See 'CHANGES.txt' for a summary of how your ParsedURL subclasses must be changed. There is a further refactoring coming, however, to support simpler parsing mechanisms for complex URL syntaxes, and to support URLs generating a "canonical form" body part. This will be important for robust comparison of URLs, path manipulation, etc.
Added 'binding.whenAssembled(...)' as syntax sugar for 'binding.Once(...,activateUponAssembly=True)'.
Implemented log system refactoring; also added tests for misc. URL schemes. See CHANGES.txt and my mailing list post for details.
Finally got rid of 'x.__class__.foo(x,...)' hacks! Now, if a metaclass needs to have a method that one of its instances might also have as an instance method, you can wrap it with 'binding.metamethod(foo)'. This is nice and clean because it doesn't force every caller of the 'foo' method to try and guess whether it's working with a class or an instance. Even nicer, this solution requires no special work by the person writing these methods, unless the method is going into a metaclass, and even then they need only wrap it with 'metamethod'. Last, but not least, this cleans up some of our __class__ usage so that we'll be able to work correctly with 'zope.security'. As far as I know, the 'x.__class__.foo(x,..)' trick wouldn't have worked consistently when 'x' was a proxied object, whereas a normal call to 'foo' would properly pass through the proxy barrier as long as the caller had permission to access 'foo'. (Note: at the moment 'foo' translates to the 'getParentComponent', '_getConfigData', 'getComponentName', and 'notifyUponAssembly' methods.)
Updated change log.
Made 'NOT_GIVEN' and 'NOT_FOUND' recognizable by humans (they 'repr' and 'str' to their names) and by Python (they can be pickled, and when restored they come back as the same object).
Fixed a formatting error for the online API reference (now up-to-date at http://www.telecommunity.com/PEAK/doc/). Of course, it's only as complete as the docstrings to date. :(
Changing docs from TransWarp->PEAK, referenced new site at http://www.telecommunity.com/PEAK/, prepping docs for 0.5a1 release.
Added 'TWX' package for extensions; added 'TWX.Diagrams.GraphViz' diagramming utility module. Very hacky and first-draft, with no unit tests, but I've manually verified most of the functionality so far.
Added support for pickling instances of nested classes; this required changing all uses of '__name__' which needed an unqualified class name. Notably, one should use 'feature.attrName' instead of 'feature.__name__' in verb definitions.
SEF.DynamicBinding is now SEF.AutoCreated, and all AutoCreatable classes like SEF.App and SEF.Service must now have an '__init__' method that accepts their SEF parent component. This lets such objects have access to the SEF hierarchy during initialization. (Note that this means any '__init__' methods of such classes must be revised to take this into consideration. See TW.Database.DataModel.Database for an example of such a revision.) Also, I dropped the unused SEF.StaticBinding class.
'setupModule()' and 'adviseModule()' will now issue warnings for most questionable code structures and variable redefinitions that might not work the way you'd expect or intend under module inheritance.
Added tests and documentation for 'adviseModule()' API
Added a 'test' command to 'setup.py' that installs and then tests all of TransWarp. (It saves me time running the unit tests while I'm writing new code.)
Added warnings for detectable module-level modifications of mutables in modules which are used for inheritances or advice. Added an API function, 'configure(object, attr1=val, attr2=val,...)' to safely set attributes of mutables that might have been defined in a derived module. Also, misc. updates to TODO.
Removed 'Meta.ClassInit' and '__class_init__' support. Use metaclass '__init__' methods instead; see 'TW.Database.DataModel.RecordTypeMC' for one example of the conversion.
Improved key integrity checks in DataModel: Record objects now disallow modification of key fields unless the old value is None, and cache collisions between records with supposedly unique keys will result in an AssertionError. Also, made the requirement of an LDAPConnection object more visible in Database.LDAPModel, and made misc. CHANGES/TODO updates.
Added 'SET' method (ala WarpCORE's set_X procedures) to TW.Utils.MiniTable.
Added more docs to TW.Utils.Code, and removed 'iterFromEnd()' method from code objects. Added experimental 'nextSplit' index to codeIndex objects that does top-level block analysis to allow splitting a code object into smaller routines.
Fixed the "reference to rebound class within another class" problem with module inheritance, as reported by (who else?) Ulrich Eck. :)
New-style features have landed! Lots o'docs and examples. CHANGES and TODO have been updated accordingly. Enjoy.
Fixed misc. bugs in DataModel, LDAPModel, Connections, and TW.Caching found by Ulrich Eck. Thanks Ulrich! Also, added a fix to ensure that non-existent records are invalidated by RecordType.getItem().
* Added basic Specialist implementation to 'TW.SEF.Basic', and reverted naming from 'TypeService' and 'ITypeService' to 'Specialist' and 'ISpecialist'. Updated 'TW.SEF.Interfaces' to reflect "self"-less convention for documenting methods. * Dropped obsolete 'TW.Database.Records' module.
Many changes in preparation for 0.2 final, including: * Added 'SEF.bindToParent()' and 'SEF.bindToNames()' specifiers to allow more flexible component parameter bindings. * Fixed the base class "rebind by name" bugs in module inheritance, and updated the documentation to more clearly reflect what it is that metaclass generation and module inheritance does and does not do. Added test cases to prevent regression of the rebind-by-name problem. * The 'setup.py' script features a new command, 'happy', which can be used to generate the API reference docs, and this command runs as part of the 'sdist' command to build source distributions. * The API reference docs in the source distribution has been moved from the 'doc' directory to 'docs/html/reference'. * Added 'CHANGES.txt' file.
cvs-admin@eby-sarna.com Powered by ViewCVS 1.0-dev |
ViewCVS and CVS Help |