[Subversion] / PEAK / CHANGES.txt  

Diff of /PEAK/CHANGES.txt

Parent Directory | Revision Log

version 1341, Fri Aug 15 21:51:58 2003 UTC version 1997, Sun Jan 30 18:51:56 2005 UTC
Line 1 
Line 1 
 Fixes and Enhancements since Version 0.5 alpha 2  Fixes and Enhancements since Version 0.5 alpha 3
   
  Changed, Enhanced, or Newly Deprecated Features   - PEAK no longer supports Python 2.2; Python 2.3.4 or better is required.
   
  - 'peak.running.scheduler.UntwistedReactor' now supports a configuration   - The kjbuckets extension module is no longer built and installed by default;
    property ('peak.running.reactor.checkInterval') to determine how long it     you must explicitly enable it with a '--with-kjbuckets' flag passed to
    should run 'select()' calls for, when there are no scheduled tasks.     'setup.py'.  Please port your code as soon as practical, this option will
      go away soon.
  - 'peak.running.scheduler.UntwistedReactor' now supports using a "signal  
    manager" component (via the 'peak.running.signalManager' property) to   - Use of the included 'kjbuckets' module is now DEPRECATED, due to increasing
    process signals while a 'run()' loop is in progress.  Signal managers can     bitrot.  Aaron Watters originally wrote this extension for Python 1.2, and
    also be added or removed at any time via the new 'peak.util.signal_stack'     it has not been well-maintained for newer versions of the Python/C API.
    module.     Instead of 'kjSet' objects, use the Python 2.3 'Set' type, and instead of
      the 'kjGraph' type, use the new 'Graph' type in 'peak.util.Graph'.  Some
  - 'peak.running.commands.AbstractCommand' now offers a '_run()' method that     porting effort may be required, as these types are not precisely the same
    can be overridden in subclasses, instead of 'run()'.  If you override the     in signature as the originals.
    new '_run()' method instead, you get the advantage of automatic handling  
    for invocation errors and 'SystemExit' exceptions, provided for you by the   - The '_setNS()' method of the 'peak.util.SOX.ISOXNode_NS' interface has
    'run()' method.     changed signature, due to a lack of use of the second argument in the code
      base, and its dependency on 'kjbuckets'.
  - There is now a 'storage.DMFor(class)' function that returns a configuration  
    key for registering or looking up data managers by class.  You can use the   - The old 'peak.security' implementation has been removed, and replaced with
    returned key in a binding's 'offerAs' list, or as the target of a 'bindTo()'     a simpler, more flexible implementation based on generic functions (using
    or 'lookupComponent()'.  The key is constructed using     less than half the code and seven fewer interfaces).  Complete documentation
    'config.ProviderOf(storage.IDataManager,class)'.     and API tests for the new implementation can be found in 'rules.txt' in the
      'peak.security' package directory.
  - You can now register utilities that are keyed by the combination of an  
    interface and one or more classes, using 'config.ProviderOf(iface,*classes)'     Also, the new implemetation does not require redundant
    as a configuration key.  Providers are registered under an '(iface,klass)'     'security.allow(security.Anybody)' declarations just because you've declared
    tuple for each specified class, and looked up using the MRO order of the     other permissions for a class, so these declarations have been removed from
    class specified for lookup.  In other words, searching for a provider will     ``peak.web``.  They don't do any harm, however, so you can leave them in
    find a provider for the requested class, or one of its base classes, with     your own code as long as you change them to use 'binding.metadata()' instead
    precedence given to the more-specific provider.  This is primarily intended     of the deprecated 'security.allow()'.
    for services like data managers and Specialists.  
    - 'security.allow()' is now DEPRECATED; please use 'binding.metadata()'
  - It's now possible to extend .ini file parsing with custom section types,     instead.  (There is no change to the calling signature, but
    and PEAK defines its own built-in section types using this extension     'binding.metadata' accepts any metadata, not just permissions.)
    mechanism.  Custom section types must include at least one space, (e.g.  
    '[My Section]') or they will be treated as a plain property name.   - Added 'peak.running.options', a new option-parsing framework that extends
    See the 'peak.config.iniFile.sectionParsers' section in 'peak.ini' for     'optparse' to support the PEAK 'commands' framework.  Command instances
    more details, along with the 'config.ISettingParser' and 'config.IIniParser'     can now refer to 'self.parsed_args' to find their non-option arguments,
    interfaces.     and to trigger setting of their attributes (or calling of methods) based on
      their raw arguments from 'self.argv'.  See 'options.txt' in the
  - When creating a 'PropertyName()', it's now possible to force conversion of     'peak.running' package directory for a complete tutorial.
    invalid characters to '_', using the 'PropertyName.fromString()'  
    constructor.  (Note that the input must be a plain-ASCII string.)  Unless   - There is now a 'binding.initAttrs()' function that can be used to initialize
    you request that wildcards ('?' and '*') be kept, they will also be     an object's attributes from e.g. constructor keyword arguments, similar to
    converted to '_' characters.  This can be convenient for converting things     how 'binding.Component' and 'binding.Attribute' constructors work.
    like filenames or text that might contain spaces, to property names.  
    - Security permissions can now be declared as attribute metadata.
  - It's now possible to declare an attribute as offering a wildcard property;  
    such lookups now follow the same rules as other wildcard property lookups.     That is, instead of doing declarations like this::
    The 'config.IConfigKey' interface has been changed to cleanly support  
    implied keys at both registration and lookup time, so you can implement          class Foo:
    your own key types that work the way interfaces or property names do for              bar = binding.Require("Something", permissionNeeded=SomePerm)
    configuration lookups.  
           class AnElement(model.Element):
  - The 'EigenRegistry' class has been moved from 'peak.util.EigenData' to              class someFeature(model.Attribute):
    'peak.config.registries', as it hasn't really been useful outside PEAK for                  permissionNeeded = SomePerm
    a while now.  
      you can (and should) now do them like this::
  - .ini files now support "smart property" objects ('config.ISmartProperty').  
    If a property rule defined in an .ini file evaluates at runtime to an object          class Foo:
    that implements 'ISmartProperty', the object will be given a chance to              bar = binding.Require("Something", [SomePerm])
    compute a value for the property, in place of being used itself.  This helps  
    to simplify definition of complex property rules in .ini files, by allowing          class AnElement(model.Element):
    the use of helper classes.  Also, 'naming.LinkRef' and 'naming.Reference'              class someFeature(model.Attribute):
    (indirectly) support this interface, so you can now use them in .ini files                  metadata = [SomePerm]
    to refer to an object via the naming system.  (Previously, 'naming.LinkRef'  
    wouldn't do the right thing unless the property was looked up via a     or this::
    'config:' URL, and 'naming.Reference' didn't exist.)  
           class Foo:
  - 'peak.util.imports.whenImported()' can now be used even when the specified              binding.metadata(bar = [SomePerm])
    module has already been loaded.  
           class AnElement(model.Element):
  - The naming system no longer has 'objectFactories' and 'stateFactories' as  
    utilities; they have been replaced with new mechanisms involving adaptation.              binding.metadata(someFeature = [SomePerm])
    Previously, addresses had a 'retrieve()' method that could be used to  
    retrieve the object defined by the address.  Now, to retrieve an object for              class someFeature(model.Attribute):
    an address, you must either define a context that processes the address, or                  # ...
    the address must have a 'defaultFactory' attribute, which provides a name  
    to be imported to get an 'IObjectFactory' that can construct the referenced     It isn't necessary to enclose metadata in brackets, but it helps to
    object.  (This is simpler than it sounds; for URLs that reference     emphasize its annotational nature.  Also note that e.g. 'web.bindResource()'
    ManagedConnections, for example, all you need to do is provide the fully     needs 'metadata' to be a keyword argument.
    qualified name of the connection class.)  
    - The 'permissionNeeded' attribute of 'model.Feature' and 'binding.Attribute'
    Meanwhile, writable naming contexts must have a 'serializationProtocol'     objects is now DEPRECATED.  See examples above for how to upgrade, and please
    attribute, specifying what interface an object should be adapted to before     switch to using metadata as soon as practical.  In addition the
    attempting to store it in that context.     'security.IGuardedDescriptor' interface has been removed, because it was
      only used in connection with the 'permissionNeeded' attribute mechanism.
    The naming system no longer processes the 'creationName' keyword argument;  
    this is now considered the sole responsibility of 'peak.binding'.  The   - Added a new "attribute metadata" mini-framework to 'peak.binding'.  This
    'IComponent.lookupComponent()' method still accepts the keyword argument,     framework makes it possible to declare arbitrary metadata about attributes,
    and attribute bindings still handle the creation name transparently.  It is     using either a class advisor ('binding.metadata()', similar in form and
    just not available via naming system APIs, and naming contexts no longer     function to the existing 'security.allow()') or using a 'metadata' attribute
    have to deal with it.     of attribute bindings (which is the second positional parameter in all
      the standard bindings like 'Make', 'Obtain', etc.).  Over time, existing
    The naming system base classes no longer use 'attrs' as an input parameter     metadata mechanisms will be refactored to use this new mini-framework,
    or return value.  If you've subclassed anything from 'peak.naming.contexts',     instead of the various integrated ad-hoc mechanisms that exist now (like
    note that your '_get()' methods should now just return the lookup value,     the 'permissionNeeded' attribute).  For more information on how the new
    rather than a 'state,attrs' tuple.  For most naming contexts, this just     metadata hooks work, including doctest examples, see the 'attributes.txt'
    means you should change 'return foo, None' statements to just 'return foo'.     file in the 'peak.binding' package, under the heading "Attribute Metadata".
   
  - Property definition rules in an .ini file can now refer to 'rulePrefix' and   - Added a new function, 'binding.activateClass()', that can be used to
    'ruleSuffix' variables.  'rulePrefix' is a '.'-terminated string,     activate any bindings in the class.  This can now be used in place of
    representing the name the rule was defined with.  For example, if the     subclassing a PEAK base class or using a PEAK metaclass.  In future, this
    rule was defined for '"foo.bar.*"', then 'rulePrefix' will be '"foo.bar."'.     will be integrated into PEAK attribute descriptors such that defining a
    The 'ruleSuffix' will be the portion of the 'propertyName' that follows     descriptor within a class' body is sufficient to cause this function to be
    'rulePrefix'.  So, if looking up property '"foo.bar.baz"', then the     invoked.
    '"foo.bar.*"' rule will execute with a 'ruleSuffix' of '"baz"'.  This should  
    make it easier to work with hierarchical property namespaces.   - 'binding.IBindingNode' was REMOVED, consolidated into 'binding.IComponent',
      as its various individual methods have been replaced with generic functions
  - Added simple example scripts and small applications in the 'examples'     in the existing 'binding' API.  For example, 'binding.getParentComponent(x)'
    directory.     should be used in preference to 'x.getParentComponent()' unless it is
      a requirement that 'x' implement the full 'binding.IComponent' interface.
  - There is a new command-line namespace introspection tool, 'n2', which     This makes it easier to define what 'binding.getParentComponent()' and
    can be accessed by running 'peak n2'.  Type 'peak n2 -h' for help.     'binding.getComponentName()' will mean for non-component types, as you do
      not have to define an adapter class with all of the 'IBindingNode' methods.
  - The PEAK_CONFIG environment variable can now list multiple files, separated     Also, this makes PEAK itself cleaner, as we often weren't bothering to
    by the platform's 'os.pathsep' (e.g. ':' on Unix, ';' on Windows).     properly implement the full 'IBindingNode' interface anyway.
   
  - It's no longer necessary to provide a '_defaultState()' implementation     In addition, 'binding.suggestParentComponent()' is now also a generic
    for an EntityDM: a default implementation is now supplied.     function, dispatching on the target (i.e. child) object.
   
  - Added automatic installation of 'datetime' package for Python < 2.3.   - 'naming.IReferenceable' was REMOVED, as it is not in use anywhere in PEAK.
      This will be replaced with a generic function when we do actually need this
  - CGI support has been moved from 'peak.running.zpublish' into     functionality.
    'peak.running.commands' (for "raw" CGI/FastCGI) and 'peak.web' (for the  
    PEAK high-level publishing framework).  You can use 'peak CGI someName' to   - There is a new 'config.getStreamFactory' generic function, to make it easy
    adapt 'someName' to a 'running.IRerunnableCGI' and run it as a CGI/FastCGI.     to accept URLs, filenames, or 'naming.IStreamFactory' objects as the source
      of a "file".
  - There is now a 'peak.security' package, available from 'peak.api' as  
    'security'.  It provides permission management functions: you can define     Its typical usage is just::
    abstract permissions by subclassing 'security.Permission', then create  
    permission checking rules by subclassing 'security.RuleSet', and declare         factory = config.getStreamFactory(self,source)
    the permissions needed to access attributes of a class with         stream = factory.open('t')  # open for reading in text mode
    'security.allow()'.  The test suite demonstrates a complex application  
    ruleset with dynamic, data-driven permissions.     where 'source' is a string or a 'naming.IStreamFactory', and 'self' is a
      component to be used as lookup context.  The returned 'factory' is a
  - There is now an interface for "Active Descriptors":     'naming.IStreamFactory' that can then be '.open()'-ed for reading, or used
    'binding.IActiveDescriptor'.  'peak.binding' now uses this interface to     in other ways as needed.
    identify active descriptors, so you can now create your own.  (Previously,  
    'peak.binding' used 'isinstance()' to detect active descriptors.)     If you have special objects that you'd like to be able to treat as stream
      sources, you can register them by defining an extension, e.g.::
  - REMOVED 'naming.ParsedURL'; it was deprecated as of 0.5 alpha 2.  
       [config.getStreamFactory.when(MyType)]
  - The 'provides' keyword argument to various 'peak.binding' APIs has been      def getStreamFactory(context,source):
    renamed to 'offerAs', and it must be a sequence of configuration keys.          """Return a naming.IStreamFactory for 'source' (a 'MyType' instance)"""
    (Previously, it accepted either a single key or a tuple of keys.)  
    The signature of 'binding.Constant()' was changed as well; the first     Wherever practical, as we encounter them, we'll be changing PEAK API's that
    positional argument is now the constant value, and 'offerAs' is now a     take filenames to also accept stream sources.
    keyword argument.  (Previously, 'provides' was the first positional argument  
    of 'binding.Constant()'.)  The 'registerProvider()' method of   - Added an optional 'base' argument to 'naming.parseURL()', to allow parsing
    'config.IConfigurable()' also now accepts only a single configuration key,     URLs relative to a base URL.  For a URL scheme to support this, it must
    as does 'EigenRegistry.register()'.     implement the new 'naming.IBaseURL' interface.  See the
      'peak.naming.factories.openable' module for example implementations.
    Also, all 'peak.binding' APIs now only accept positional parameters for  
    items unique to that API.  Items common to multiple APIs (such as 'offerAs',   - Added a 'data:' URL scheme, implementing RFC 2397 (although it's not as
    'doc', 'attrName', etc.) should now be supplied as keyword arguments.     strict in its parsing of the content type and parameters as the RFC calls
      for).  This is a semi-convenient way to provide configuration data in-line,
    Bindings also now automatically "suggest" the containing object as a parent     since a 'data:' URL can be a 'config.getStreamFactory()' source.
    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   - Added 'config.processXML()', a function that provides a high-level,
    or computed will be adapted to the specified protocol before the parent     configuration-driven interface to 'peak.util.SOX.NegotiatingParser'.  This
    component is suggested.  'binding.New()' no longer relies on the     simple front-end lets you supply as little as a configuration context and
    'IComponentFactory' interface, but instead uses the new adapt/suggest     a stream source, to do XML processing of arbitrary complexity, controlled by
    mechanisms.     the configuration of the context.
   
    Previously, parent components were only "suggested" when a binding was set   - Added 'config.XMLKey()', an 'IConfigKey' type that can be used to register
    via component constructor keyword arguments.  Now, this is done at any time     configuration values for XML attribute and element names under specified
    bindings are set, but *not* for non-binding keyword arguments.  In other     XML namespace URI's.  Also, there are now '[XML Attributes for nsuri]' and
    words, ordinary attributes of a component do not receive "suggested parent"     '[XML Elements for nsuri]' section types available for use in .ini files.
    notices, even when set via constructor keyword arguments.  If you want an     (Replace 'nsuri' with the appropriate XML namespace URI, or use '*' for a
    attribute to do this, you must define the attribute with the binding API;     wildcard.)
    e.g. via 'requireBinding()' or 'binding.Constant()'.  If you do *not* want  
    a binding to suggest a parent component, use 'suggestParent=False' in the   - 'web.IResource' is gone, replaced by 'web.IPlace'.  The notion of a place is
    binding definition.     broader than the notion of a resource, and we will soon need to have
      other "location" objects that implement 'IPlace'.
  Corrected Problems  
    - In order to support obtaining the line and column locations of problems in
   - There was a typo in peak.naming.arithmetic that caused homogeneous non-URL     XML files, we are now using Python 2.4's version of the 'pyexpat' module,
     name subtraction to fail.     built as 'peak.util.pyexpat'.
   
   - The default reactor supplied in 'peak.running.scheduler' would consume   - There's a new class, 'config.IniLoader', that can be used to lazily load
     CPU continuously if it was waiting for I/O and no tasks were scheduled.     .ini files as configuration.  'IniLoader' instances have an 'iniFiles'
      attribute that lists the configuration sources (filenames/URLs/factories)
   - The 'peak.util.imports.whenImported' function didn't work.     to be used, and automatically load the .ini files as soon as you try to get
      any configuration data for them.  Previously, similar functionality was only
      available via 'config.makeRoot()'.
   
      Also, there's now an 'ini' reference type that instantiates an 'IniLoader'
 Fixes and Enhancements since Version 0.5 alpha 1     for one or more addresses.  You can use it like this::
   
  Changed, Enhanced, or Newly Deprecated Features       [Named Services]
   
  - Added a 'shellcmd:'  URL scheme that returns a function that calls       some.example = naming.Reference('ini',
    'os.system()' on the body of the URL.  It's intended for use as a command           ['pkgfile:peak/peak.ini', '/etc/something.ini']
    factory, as is needed by the 'URLChecker' periodic task.        )
   
  - You can now define adapters from arbitrary types to 'binding.IBindingNode',       another.example = naming.LinkRef(
    and thus be able to use them as part of a component hierarchy - without           'ref:ini@pkgfile:peak/peak.ini||/etc/something.ini'
    needing to directly add 'getParentComponent()' or 'getComponentName()'        )
    methods to them.  
      The two examples above will each load the same pair of specified .ini files.
  - Added experimental 'invoke.c' script for POSIX-ish platforms with funky     You can also directly instantiate an 'IniLoader', as in::
    '#!' support, or lack thereof.  
        cfg = config.IniLoader(self, iniFiles=['pkgfile:peak/peak.ini'])
    'invoke' is designed to be used like this::  
      Attempting to look up any configuration properties via the 'cfg' object
      #!/usr/local/bin/invoke peak somearg otherarg...     will cause it to load the specified .ini file.
   
    This should work on most sane platforms with a long-enough commandline.   - 'config.fileNearModule()' is DEPRECATED, in favor of 'config.packageFile()'.
    (See "this page":http://homepages.cwi.nl/~aeb/std/hashexclam-1.html for     The latter returns a 'naming.IStreamFactory', which is more suitable for
    details on the insanely incompatible ways different Unixes interpret '#!'     working with e.g. module data files compressed in a zipfile.  Uses of
    lines.)     'fileNearModule()' that were being passed to 'config.loadConfigFile()' can
      be safely changed to 'config.packageFile()' without needing any other code
    The script is not currently built or installed by setup.py.  On the     changes, but if you were directly using 'fileNearModule()' as a filename,
    platforms it's targeted at, you should be able to build it with::     you will need to rewrite appropriately.
   
      gcc -o invoke invoke.c   - 'config.loadConfigFile()' and 'config.loadConfigFiles()' now accept URLs,
      'naming.IStreamFactory' objects, and other 'config.getStreamFactory()'
    (Yes, it really is that simple of a script.)     targets as well as filenames.  This was primarily added to support use of
      'config.packageFile()' or 'pkgfile:' URLs, in place of using
  - Added a ZConfig schema for 'running.commands.EventDriven' applications,     'config.fileNearModule()'.
    a ZConfig component definition for adaptive tasks, and a running shortcut  
    called 'EventDriven'.   - The 'naming.IStreamFactory' interface now has an 'address' attribute, which
      is the string form of the canonical URL of the target stream.  This was
    It should now be possible to do this::     added to make it easier to e.g. report errors in a stream that's being
      parsed, since the parser only needs the factory in order to report the
      #!/usr/bin/env peak EventDriven     location of an error.  (Note: if you implement 'naming.IStreamFactory', be
      sure to add this attribute to your implementations.)
    at the top of a ZConfig file formatted according to the new schema, and  
    have it run.  There are two periodic tasks that can be configured and   - The 'peak.util.WSGIServer' module has been moved to the
    run from such a file: 'CleanupFiles' and 'URLChecker'.  'CleanupFiles' will     'wsgiref.simple_server' module.  The 'wsgiref' reference library for WSGI
    delete files matching a pattern that are older than a certain age, while     (aka PEP 333) is now distributed with PEAK.
    'URLChecker' will check to see if the target of a naming system URL is  
    up/available/working, and if not, runs a command to restart it.  As an   - Added a 'WSGI' command to the 'peak' script, to allow you to run "foreign"
    amusing demo, try specifying a 'file:' URL with a 'shellcmd:touch theFile'     (i.e. non-PEAK) PEP 333 applications in PEAK's various servers and
    to recreate the file, then add a 'CleanupFiles' that deletes the file the     launchers.  Basically, by prefixing 'WSGI' before the import specifier, you
    checker looks for.  This can be hours (well, minutes) of exciting fun as you     can now run such foreign apps.
    watch the dueling daemons undoing each others' work.  
      For example::
  - Added 'zconfig.schema' URL scheme that loads an enhanced ZConfig schema  
    object that can act as a command line interpreter using the 'peak' script.         peak launch WSGI import:some_app.application
   
    To use it, run 'peak zconfig.schema:urlToSchema urlOfConfig'.  Or, add     will run 'some_app.application' in the local web browser, and::
    a line like this::  
          peak CGI WSGI import:some_app.application
      #!/usr/bin/env peak zconfig.schema:pkgfile:some.package/schema.xml  
      will run it under the CGI/FastCGI runner.  Similarly, you can use this in
    to the top of a configuration file, and make the configuration file     the "Command" spec for the "peak supervise" pre-forking FastCGI supervisor
    executable.  Note that the schema specified must convert to an object     subsystem.
    that's usable with the commands bootstrap framework.  Also note that  
    if you have a local PEAK_CONFIG file, you can add a 'peak.running.shortcuts'   - There is a new 'running.IWSGIApplication' interface, for PEP 333-compliant
    entry to shorten the URL reference in your #! line.  E.g.::     "application" objects, and all of PEAK's provided applications now implement
      it instead of 'running.IRerunnableCGI'.  If you write your apps to the newer
      #!/usr/bin/env peak mySchema     interface, they'll be portable to any PEP 333-compliant web server, not just
      the PEAK CGI, FastCGI, and "supervisor" containers.  There is a simple
    will suffice if you have defined 'peak.running.shortcuts.mySchema' as     adapter that allows 'IWSGIApplication' objects to run in the CGI-based
    'naming.LinkRef("zconfig.schema:pkgfile:some.package/schema.xml")'.     containers, but not the other way around, so using 'IRerunnableCGI' directly
      now limits your portability.  (For example, the "peak launch" and "peak
    There is also a 'peak ZConfig urlOfSchema urlOfConfig' variant, that was     serve" commands will soon require 'IWSGIApplication', and will not support
    added to support putting '#!/usr/bin/env peak ZConfig' at the top of     'IRerunnableCGI' any more.)
    schema files, but unfortunately that's not valid XML.  
      Of course, if you use the 'peak.web' framework, you don't need to worry
  - Standardized file-based URL syntaxes (e.g logfiles and lockfiles) to     about any of this; your apps will automatically be wrapped as
    follow RFC 1738/2396, and Python 'urllib'.  This shouldn't affect much     'IWSGIApplication', and run in any PEAK server or gateway.
    besides the canonical forms of the URLs.  Added 'pkgfile:some.pkg/filepath'  
    URL syntax for ease of referring to files near modules.  (A convenience   - Most 'peak.web' interfaces have changed significantly.  If you implemented
    intended mainly for referencing ZConfig schemas.)     anything based on the older interfaces, and it still works, it's sheer
      bloody luck.  In particular, note that every method in 'web.IWebTraversable'
  - Added the UML 1.4 metamodel, and thus the ability to load UML 1.4     now has different inputs and/or outputs than before.  Please read the new
    models encoded in XMI 1.1.     interface docs and update your code!  The changed interfaces offer much
      more flexibility and functionality than before, but they will require you to
  - Added support in the mof2py code generator for "unprefixing" enumerated     update your code.
    values, so that UML and other metamodels' enumerations work correctly  
    when loading from XMI.  Also, mof2py no longer emits 'config.setupModule()'   - 'web.ContainerAsTraversable' has been removed.  It was redundant, since the
    calls in generated code, as in practice they are not needed.     new default traversal mechanism used by 'Traversable' and 'Decorator' now
      handles getitem, getattr, and views.
  - Running 'peak test' from the command line is roughly equivalent to running  
    'unittest.py', except that the test suite defaults to the PEAK test suite.   - Added Zope 3-like "namespaces" to 'peak.web'.  Path segments in a URL
    You can, however run any test suite from the command line with a dotted     may be prefixed with '"++some_id++"' in order to invoke a corresponding
    module/attribute path, e.g 'peak test foo.bar.test_suite'.     namespace handler registered under '"peak.web.namespaces.some_id"'.
      Namespace handlers must implement 'web.INamespaceHandler', and they are
  - 'binding.Acquire()' now accepts a 'default' value argument, and     supplied with the original path segment as well as the separated namespace
    'binding.New()' no longer accepts the 'bindToOwner' flag.     and name.  Also, as in Zope 3, '"@@foo"' is a shortcut for '"++view++foo"'.
      Builtin namespaces at this time include 'view', 'item', 'attr', 'skin', and
  - There is a new 'binding.IComponentKey' interface that is used to implement     'resources'.  'skin' treats the rest of its path segment as a skin name,
    'IComponent.lookupComponent()'.  Now you can implement this interface,     and sets the current skin, while 'resources' begins traversal to resources
    or create an adapter for it, in order to make an object usable as an     found in the current skin.  The other namespaces are as described at:
    argument to 'binding.lookupComponent()' - and therefore usable as a key  
    for 'binding.bindTo()' or 'binding.bindToSequence()'.  Not that it's     "Resources and traversal in peak.web":http://www.eby-sarna.com/pipermail/peak/2004-August/001712.html
    necessarily very useful to do so; you're probably better off simply  
    creating a naming scheme.  But it might be useful for lookups done   - Fixed several 'peak.events' bugs, as reported by Vladimir Iliev, Yaroslav
    in the context of classes, since naming schemes aren't usable there.     Samchuk, and Alexander Smishlajev:
    (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     * 'events.AnyOf' could hold multiple references to a single event source,
    much else.)       and nesting 'AnyOf()' calls could leak references to the nested events.
   
  - PEAK has been refactored to avoid the use of 'isImplementedBy()' and     * 'events.subscribe()' had a potential race condition wherein a callback
    similar introspection, in favor of 'adapt()'.  As a result, some       could be invoked after its weak reference was garbage collected, leading
    'peak.naming' interfaces have changed.  This should not affect you       to bizarre error messages about 'self' being 'None'.
    if you are only subclassing PEAK-provided naming components and not  
    implementing these interfaces "from scratch".  However, the various     * 'select()' could be called on select event objects even if there were
    'isAddress', 'isAddressClass', 'isResolver', and 'isName' APIs have       no current subscribers to the event, potentially leading to calling
    also been removed, as they were based on 'isImplementedBy()'.       'select()' on a closed socket.
   
  - REMOVED ability to use '__implements__' and '__class_implements__' to     * Non-default signal handlers were remaining installed even when there
    declare support for interfaces.  Use 'protocols.advise()' or a related       were no current subscribers to the applicable event, as long as a
    API to do this now.  The 'protocols' package is available automatically       reference to the event object existed.
    from 'peak.api'.  
      As a result of these changes, certain I/O event types (esp. signals and
    Similarly, the ability  to use 'isImplementedBy()' with interfaces declared     stream readable/writeable events) are now longer-lived.  For example,
    by PEAK is REMOVED.  You can still use 'isImplementedBy()' with Zope     signal event objects are now immortal, and the read/write event for a
    interfaces, of course, but we recommend you switch to 'adapt()', which     particular 'fileno()' will be reused for as long as its supplying
    should work with both PEAK and Zope interfaces.     'Selector' or 'EventLoop' instance exists.  (Previously, weak references
      were used so that these objects would be recycled when not in use.)
  - Replaced all use of 'zope.interface' with 'protocols' package because  
    the 'protocols' package:   - Added 'config.registeredProtocol()' API, that supports defining named and
      local protocols.  This allows easy emulation of Zope 3's "named" and "local"
    * is considerably smaller and simpler than 'zope.interface'     adapters and views.
   
    * produces Interface objects that can be inspected with the Python   - 'binding.Component' objects no longer support instance configuration at
      'pydoc' and 'help()' tools     runtime (i.e., they no longer implement 'config.IConfigurable').  If you
      need a component to be configurable at runtime, you must now derive from
    * supports and implements the PEP 246 'adapt()' protocol     (or mix in) 'binding.Configurable' instead.  If you get errors about
      a missing 'registerProvider' attribute, or about being unable to adapt to
    * transparently supports transitive adaptation - i.e. if adapter AB     'IConfigurable', try changing your base class from 'binding.Component'
      adapts from A to B, and adapter BC adapts from B to C, then an adapt(x,C)     to 'binding.Configurable', or add it as a mixin if you're deriving from
      where 'x' is an 'A', will be implemented as BC(AB(x)).     a class that uses 'binding.Component' as its base.
   
    * Supports "open protocols" that allow you to "superclass" a protocol   - 'binding.IComponent' no longer derives from 'config.IConfigurable' or
      to create a subset protocol; objects that support the first protocol     'config.IConfigMap', only 'config.IConfigSource'.  This means that
      will automatically support the subset protocol.  For example, if one     'IComponent' no longer guarantees or requires the presence of the
      person defines a "dictionary" protocol, someone else can create a     'registerProvider()' method: now only 'config.IConfigurable' does that.
      "read-only dictionary" protocol, and all objects supporting the  
      "dictionary protocol" will be considered to implement the "read-only   - The 'config.IConfigMap' interface is now DEPRECATED.  Use
      dictionary" protocol.     'config.IConfigurable' instead.  The '_configKeysMatching()' method
      of 'IConfigMap' was moved to 'config.IConfigSource', so if you've
    * can interoperate with other interface packages, including Zope's, but     implemented a custom 'IConfigSource', be sure to add this method.
      does not require them  
    - 'web.ISkinService' and 'web.ILayerService' were consolidated into
    * works with module inheritance (for everything but moduleProvides(), and     'web.IInteractionPolicy', because the need to have configurable
      we should get to that by 0.5a2)     implementations of these services is negligible.  That is, the
      corresponding property namespaces ('peak.web.skins' and 'peak.web.layers')
    * lets you use Interfaces as abstract base classes (i.e., you can     are more than adequate as registries.
      inherit from an interface and turn it into an implementation, and  
      you can define default attribute values or method implementations in   - Removed 'peak.running.timers' and 'peak.util.dispatch'.  Neither was in
      your interfaces     active use, and both are being replaced by the new generic functions
      package in PyProtocols.
    * Lets you mix interface declarations from any number of frameworks and  
      any number of interface types, in a single 'implements()' or   - The 'config.iterParents' API is now moved to 'binding.iterParents', and all
      'classProvides()'     'binding' functions that walk the component hierarchy use it.  It has also
      been changed to avoid infinite loops in the case of a pathological
    * uses adaptation as the fundamental approach to dealing with interfaces,     component structure.
      and avoids the use of 'isImplementedBy()'.  In the *rare* case that you  
      need to introspect rather than adapt, you can always call adapt() and   - The 'persistence' package has been moved to 'peak.persistence' to avoid
      check the result.  (But introspection usually means that you're using     conflicts with ZODB3 and the latest version of Zope 3.  It will eventually
      interfaces as a form of metadata; it's better to create an explicit     be phased out, but for now this move is the simplest way to get it out of
      interface that provides the metadata you seek, and adapt to that     the way.
      interface, than to use interfaces as data.)  
    - The 'peak.util.SOX' module now uses only one parser, based directly on
    Most of these features are unavailable in 'zope.interface', and some have     'expat', instead of using SAX.  The new parser expects a new node interface,
    been declared by the Zope Pope to be unacceptable or undesirable features     'IXMLBuilder', but adapters from the previous interfaces ('ISOXNode' and
    for Zope interfaces.  (Others may be available in some form in future     'ISOXNode_NS') are supplied for backward compatibility.  All of PEAK's
    versions of Zope X3.)  So, we no longer require or distribute     direct XML handling (currently just 'peak.storage.xmi' and
    'zope.interface'.     'peak.web.templates') have been refactored to use the new interface.  Some
      parsing classes (such as 'ObjectMakingHandler', 'NSHandler', and
  - The signatures of the 'getObjectInstance()', 'getStateToBind()', and     'DOMletParser') are no longer available.
    'getURLContext()' methods in the 'peak.naming' package have changed, to  
    place the context or parent component as the first, non-optional argument.   - 'peak.web' no longer uses Zope X3 for HTTP publishing support; it has been
    (If you don't know what these methods are for, you don't need to do anything     refactored to use a "simpler, more uniform architecture":http://www.eby-sarna.com/pipermail/peak/2004-May/001462.html
    about this, as they are part of the naming package's extensibility     See also "more on the architecture":http://www.eby-sarna.com/pipermail/peak/2004-June/001482.html
    framework.)     and subsequent posts in that thread.
   
  - 'binding.bindTo()' now accepts a 'default=' argument, whose value will be     As a consequence, "various features have been removed":http://www.eby-sarna.com/pipermail/peak/2004-June/001500.html
    used in case of a 'NameNotFound' error.     from 'peak.web', for possible return at a future date.  Here is a rough
      outline of the changes made so far:
  - DEPRECATED 'naming.ParsedURL'.  It will disappear in 0.5 alpha 3 or beta.  
    It is replaced by the new 'naming.URL.Base'.  The 'naming.URL' package      * The 'pageProtocol', 'pathProtocol', and 'errorProtocol' machinery are
    provides a new URL parsing framework based on 'peak.model'.  Upgrading from        gone.  They will be replaced in the future with an explicit "controller"
    'ParsedURL' to 'URL.Base' is trivial for ParsedURL subclasses that used        wrapping mechanism to allow application-specific renderings of the same
    only the 'scheme' and 'body' fields, and in fact may not require any        underlying components.
    changes except for the choice of base class.  Also, the 'retrieve()' method  
    of URLs is deprecated; please begin defining the 'getObjectInstance()'      * The Zope 'request' and 'response' objects are gone, along with all of
    method instead.  This is to cut down a bit on the number of ways that the        their special handling for cookies, character sets, form variables,
    naming package spells the idea of retrieving something!        automatically marshalling parameters to functions, etc.  These items of
         functionality will be gradually replaced by functions in 'peak.web.api'.
    For more complex URL classes, the '__init__' methods go away, 'parse'  
    methods change slightly, and explicit field definitions (using        As a result of this, arbitrary functions and methods can no longer be
    'model.structField' or similar) are required.  See PEAK's 'URL.Base'        used as web pages; instead, functions and methods to be published must
    subclasses for examples.  There is also a sophisticated parsing and        use the same inputs and outputs as the 'IHTTPHandler.handle_http()'
    formatting framework (see the 'peak.naming.URL' and 'peak.util.fmtparse'        method.
    modules) that can be used in place of the old regex-based approach.  
       * The 'IWebPage', 'IWebInteraction', 'ITraversalContext', 'Traversal',
  - Added 'peak.util.fmtparse', a parsing and formatting framework, and        'TraversalContext', and 'Interaction' interfaces and classes no longer
    integrated it with 'peak.model' so that any element type can have a        exist, as they are unneeded in the new architecture.  Instead of
    syntax for parsing from, or formatting to, a string.        having a central 'IWebInteraction' that's referenced by numerous
         'ITraversalContext' objects, the new approach uses an 'environ' mapping
  - Added 'binding.whenAssembled(...)' as syntax sugar for        for most functions.  For access control, a 'security.IInteraction' is
    'binding.Once(...,activateUponAssembly=True)'.        now used, whose function is limited to security checks.  Most
         functions previously performed by 'IWebInteraction' have moved to
  - Removed 'LOG_XYZ' convenience functions from 'peak.api', and refactored        'IInteractionPolicy' or to 'peak.web.api' functions operating on
    'peak.running.logs' to use a PEP 282-like interface, 'running.ILogger'.        'environ' mappings.
    Under the new scheme, messages must be sent to a specific entry point  
    (e.g. 'self.logger.warning("foo")').  Components can bind an attribute      * Web exceptions can define a 'levelName' attribute that determines the
    directly to a logger object, or via configuration properties or utilities.        severity level with which the exception will be logged.  This allows
    PEAK components that do logging all define a 'logger' attribute, bound        one to e.g. avoid logging tracebacks for 'NotFound' errors.
    to a configuration property in the 'peak.logs' property namespace.  By  
    a default in 'peak.ini', 'peak.logs.*' is configured to output messages      * Various interface calling signatures have changed slightly.  For example,
    of 'WARNING' priority or higher to 'sys.stderr'.        'IAuthService.getUser()' now accepts an 'environ' mapping instead of
         an interaction.  'IInteractionPolicy.newInteraction()' now takes keyword
    For compatibility with the PEP 282 logging package, a 'logging.logger:'        arguments, but not a 'request'.  The 'IWebTraversable' interface no longer
    URL scheme has been added; looking up the URL '"logging.logger:foo.bar"'        has a 'getObject()' method, and the 'IWebException.handleException()'
    is equivalent to 'logging.getLogger("foo.bar")', unless the 'logging'        method signature has changed as well.  Finally, all methods that
    package is not available, in which case the configuration property        previously accepted 'ITraversalContext' (such as
    'peak.logs.foo.bar' will be looked up in the target context of the        'IDOMletState.renderFor()') now expect 'environ' mappings.
    lookup.  Optionally, you can configure the 'logging.logger' URL scheme so  
    that it only uses PEAK loggers, and never uses the PEP 282 loggers.      * 'web.TestInteraction' was replaced with 'web.TestPolicy', and
         'web.Interaction' was removed, since 'IWebInteraction' is no longer part
  - Added 'binding.metamethod()' wrapper for metaclass methods that might        of the architecture.
    not be accessible from their instances if the instances (classes) also  
    defined the method for *their* instances.  You must now use this wrapper   - The 'log()' method of PEAK loggers ('logs.ILogger') now accepts a level name
    on any such metaclass-defined methods, as PEAK no longer works around     *or* a number, for convenient invocation.
    this via the 'x.__class__.foo(x,...)' trick that was used previously.  
    In particular, if you have metaclass definitions of 'getParentComponent',   - SQL transaction semantics have changed.  Now, issuing an SQL statement
    '_getConfigData', 'getComponentName', or 'notifyUponAssembly', you need     *always* causes the connection to join the active PEAK transaction, even if
    to wrap them with 'binding.metamethod' now.     you request that the SQL be issued "outside" a transaction.  Such SQL will
      be issued outside of the *database* transaction, but not outside of the
  - Made 'NOT_GIVEN' and 'NOT_FOUND' recognizable by humans (they 'repr'     PEAK transaction.  This simplifies the overall processing model for dealing
    and 'str' to their names) and by Python (they can be pickled, and     with "untransacted" SQL such as Sybase DDL or read-only Oracle transactions.
    when restored they come back as the same object).     (In particular, the requirement that triggered this change was to allow
      Oracle read-only transactions to be released at the end of the current PEAK
      transaction.)  Also, got rid of the now-meaningless 'begin' command in n2.
  Corrected Problems  
    - The 'events.IEventSource' interface now returns a 'canceller' function from
  - Fixed a problem in ZConfig 'schema.dtd'; I used 'PCDATA' where I should've     the 'addCallback()' method, allowing you to cancel a previously-scheduled
    used 'CDATA'.     callback.  This fixes a memory leak and performance problem with
      'events.AnyOf()', which previously could accumulate unneeded callbacks on
  - Fixed a problem with 'binding.supertype()' not working correctly if the MRO     the sources it was monitoring.  Note that if you have developed any custom
    it was searching contained a "classic" class.  Now 'supertype()' skips any     event sources with 'addCallback()' methods, you must make sure that they
    classic classes it finds.  (It probably should be rewritten entirely.)     return a canceller from now on.
   
  - Fixed misc. problems with 'fromZConfig()' component constructor   - Added 'ref:factory@addr1||addr2' URL scheme that maps to a corresponding
      'naming.Reference("factory",["addr1","addr2"])'.  'factory' can be either a
  - Fixed source distributions missing essential setup files     dotted import string referencing a 'naming.IObjectFactory', or you can
      define a factory in the 'peak.naming.factories' property space.
  - Fixed a problem with assembly events, where a parent component that didn't  
    need assembly notification, wouldn't ever notify its children of assembly   - Added a 'zconfig.schema' factory, so that 'ref:zconfig.schema@streamURL'
    if they requested the notification after the parent had already received     will load a schema loader.  Schema loaders are themselves object factories,
    it.     so you can do something like::
   
  - Fixed a bug in automatic metaclass generation that caused extra unneeded       [Named Services]
    metaclasses to be generated.       peak.naming.factories.myschema = \
            naming.LinkRef('ref:zconfig.schema@pkgfile:mypkg/Schema.xml')
  - Fixed 'naming.lookup()' and related APIs not setting the parent component  
    of created objects without an explicitly supplied 'creationParent' keyword     in order to make URLs like 'ref:myschema@filename' work.  Note, by the way,
    argument.  This used to "sort of work" when we had implicit configuration     that the above could also read::
    parents, but was broken when we went "all explicit" for 0.5 alpha 1.  
        [Named Services]
  - Fixed a problem where initializing single-valued immutable fields of       peak.naming.factories.myschema = \
   'peak.model' types did not perform type/value normalization.           naming.Reference('zconfig.schema',['pkgfile:mypkg/Schema.xml'])
   
  - Fixed a problem where bindTo would use the attribute name as the     which runs somewhat faster at lookup time.  Similarly, one can also use
    default value for a lookup, if the requested name/property/utility     'naming.Reference("myschema",["somefile"])' in place of a
    was not found.     'naming.LinkRef("ref:myschema@filename")'.  As well as being faster, for
      some use cases it's easier to 'Reference' directly than to glue together
  - Fixed 'mof2py' generator script not working     a 'ref:' URL string.
   
  - Fixed model.Element not getting parent component set when passed as a  
    constructor argument.  
   
  - Fixed property/utility lookups not working correctly on model.*  
    objects.  
   
  - Fixed IndentedStream generating all-whitespace lines  
   


Generate output suitable for use with a patch program
Legend:
Removed from v.1341  
changed lines
  Added in v.1997

cvs-admin@eby-sarna.com

Powered by ViewCVS 1.0-dev

ViewCVS and CVS Help