[Subversion] / PEAK / CHANGES.txt  

Diff of /PEAK/CHANGES.txt

Parent Directory | Revision Log

version 1752, Fri Jun 4 22:34:24 2004 UTC version 1978, Thu Jan 6 01:03:58 2005 UTC
Line 1 
Line 1 
 Fixes and Enhancements since Version 0.5 alpha 3  Fixes and Enhancements since Version 0.5 alpha 3
   
    - The old 'peak.security' implementation has been removed, and replaced with
      a simpler, more flexible implementation based on generic functions (using
      less than half the code and seven fewer interfaces).  Complete documentation
      and API tests for the new implementation can be found in 'rules.txt' in the
      'peak.security' package directory.
   
      (Note: as a side-effect of this change, the old 'security.IInteraction'
      interface and 'security.Interaction' class can now be temporarily found
      as 'web.IInteraction' and 'web.Interaction' respectively.  Both will soon
      be refactored out of existence, however, so please update your code
      accordingly!)
   
      Also, the new implemetation does not require redundant
      'security.allow(security.Anybody)' declarations just because you've declared
      other permissions for a class, so these declarations have been removed from
      ``peak.web``.  They don't do any harm, however, so you can leave them in
      your own code as long as you change them to use 'binding.metadata()' instead
      of the deprecated 'security.allow()'.
   
    - 'security.allow()' is now DEPRECATED; please use 'binding.metadata()'
      instead.  (There is no change to the calling signature, but
      'binding.metadata' accepts any metadata, not just permissions.)
   
    - Added 'peak.running.options', a new option-parsing framework that extends
      'optparse' to support the PEAK 'commands' framework.  Command instances
      can now refer to 'self.parsed_args' to find their non-option arguments,
      and to trigger setting of their attributes (or calling of methods) based on
      their raw arguments from 'self.argv'.  See 'options.txt' in the
      'peak.running' package directory for a complete tutorial.
   
    - There is now a 'binding.initAttrs()' function that can be used to initialize
      an object's attributes from e.g. constructor keyword arguments, similar to
      how 'binding.Component' and 'binding.Attribute' constructors work.
   
    - Security permissions can now be declared as attribute metadata.
   
      That is, instead of doing declarations like this::
   
           class Foo:
               bar = binding.Require("Something", permissionNeeded=SomePerm)
   
           class AnElement(model.Element):
               class someFeature(model.Attribute):
                   permissionNeeded = SomePerm
   
      you can (and should) now do them like this::
   
           class Foo:
               bar = binding.Require("Something", [SomePerm])
   
           class AnElement(model.Element):
               class someFeature(model.Attribute):
                   metadata = [SomePerm]
   
      or this::
   
           class Foo:
               binding.metadata(bar = [SomePerm])
   
           class AnElement(model.Element):
   
               binding.metadata(someFeature = [SomePerm])
   
               class someFeature(model.Attribute):
                   # ...
   
      It isn't necessary to enclose metadata in brackets, but it helps to
      emphasize its annotational nature.  Also note that e.g. 'web.bindResource()'
      needs 'metadata' to be a keyword argument.
   
    - The 'permissionNeeded' attribute of 'model.Feature' and 'binding.Attribute'
      objects is now DEPRECATED.  See examples above for how to upgrade, and please
      switch to using metadata as soon as practical.  In addition the
      'security.IGuardedDescriptor' interface has been removed, because it was
      only used in connection with the 'permissionNeeded' attribute mechanism.
   
    - Added a new "attribute metadata" mini-framework to 'peak.binding'.  This
      framework makes it possible to declare arbitrary metadata about attributes,
      using either a class advisor ('binding.metadata()', similar in form and
      function to the existing 'security.allow()') or using a 'metadata' attribute
      of attribute bindings (which is the second positional parameter in all
      the standard bindings like 'Make', 'Obtain', etc.).  Over time, existing
      metadata mechanisms will be refactored to use this new mini-framework,
      instead of the various integrated ad-hoc mechanisms that exist now (like
      the 'permissionNeeded' attribute).  For more information on how the new
      metadata hooks work, including doctest examples, see the 'attributes.txt'
      file in the 'peak.binding' package, under the heading "Attribute Metadata".
   
    - Added a new function, 'binding.activateClass()', that can be used to
      activate any bindings in the class.  This can now be used in place of
      subclassing a PEAK base class or using a PEAK metaclass.  In future, this
      will be integrated into PEAK attribute descriptors such that defining a
      descriptor within a class' body is sufficient to cause this function to be
      invoked.
   
    - 'binding.IBindingNode' was REMOVED, consolidated into 'binding.IComponent',
      as its various individual methods have been replaced with generic functions
      in the existing 'binding' API.  For example, 'binding.getParentComponent(x)'
      should be used in preference to 'x.getParentComponent()' unless it is
      a requirement that 'x' implement the full 'binding.IComponent' interface.
      This makes it easier to define what 'binding.getParentComponent()' and
      'binding.getComponentName()' will mean for non-component types, as you do
      not have to define an adapter class with all of the 'IBindingNode' methods.
      Also, this makes PEAK itself cleaner, as we often weren't bothering to
      properly implement the full 'IBindingNode' interface anyway.
   
      In addition, 'binding.suggestParentComponent()' is now also a generic
      function, dispatching on the target (i.e. child) object.
   
    - '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
      functionality.
   
    - There is a new 'config.getStreamFactory' generic function, to make it easy
      to accept URLs, filenames, or 'naming.IStreamFactory' objects as the source
      of a "file".
   
      Its typical usage is just::
   
          factory = config.getStreamFactory(self,source)
          stream = factory.open('t')  # open for reading in text mode
   
      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
      'naming.IStreamFactory' that can then be '.open()'-ed for reading, or used
      in other ways as needed.
   
      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.::
   
       [config.getStreamFactory.when(MyType)]
       def getStreamFactory(context,source):
           """Return a naming.IStreamFactory for 'source' (a 'MyType' instance)"""
   
      Wherever practical, as we encounter them, we'll be changing PEAK API's that
      take filenames to also accept stream sources.
   
    - Added an optional 'base' argument to 'naming.parseURL()', to allow parsing
      URLs relative to a base URL.  For a URL scheme to support this, it must
      implement the new 'naming.IBaseURL' interface.  See the
      'peak.naming.factories.openable' module for example implementations.
   
    - Added a 'data:' URL scheme, implementing RFC 2397 (although it's not as
      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,
      since a 'data:' URL can be a 'config.getStreamFactory()' source.
   
    - Added 'config.processXML()', a function that provides a high-level,
      configuration-driven interface to 'peak.util.SOX.NegotiatingParser'.  This
      simple front-end lets you supply as little as a configuration context and
      a stream source, to do XML processing of arbitrary complexity, controlled by
      the configuration of the context.
   
    - Added 'config.XMLKey()', an 'IConfigKey' type that can be used to register
      configuration values for XML attribute and element names under specified
      XML namespace URI's.  Also, there are now '[XML Attributes for nsuri]' and
      '[XML Elements for nsuri]' section types available for use in .ini files.
      (Replace 'nsuri' with the appropriate XML namespace URI, or use '*' for a
      wildcard.)
   
    - 'web.IResource' is gone, replaced by 'web.IPlace'.  The notion of a place is
      broader than the notion of a resource, and we will soon need to have
      other "location" objects that implement 'IPlace'.
   
    - In order to support obtaining the line and column locations of problems in
      XML files, we are now using Python 2.4's version of the 'pyexpat' module,
      built as 'peak.util.pyexpat'.
   
    - There's a new class, 'config.IniLoader', that can be used to lazily load
      .ini files as configuration.  'IniLoader' instances have an 'iniFiles'
      attribute that lists the configuration sources (filenames/URLs/factories)
      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'
      for one or more addresses.  You can use it like this::
   
        [Named Services]
   
        some.example = naming.Reference('ini',
            ['pkgfile:peak/peak.ini', '/etc/something.ini']
         )
   
        another.example = naming.LinkRef(
            'ref:ini@pkgfile:peak/peak.ini||/etc/something.ini'
         )
   
      The two examples above will each load the same pair of specified .ini files.
      You can also directly instantiate an 'IniLoader', as in::
   
        cfg = config.IniLoader(self, iniFiles=['pkgfile:peak/peak.ini'])
   
      Attempting to look up any configuration properties via the 'cfg' object
      will cause it to load the specified .ini file.
   
    - 'config.fileNearModule()' is DEPRECATED, in favor of 'config.packageFile()'.
      The latter returns a 'naming.IStreamFactory', which is more suitable for
      working with e.g. module data files compressed in a zipfile.  Uses of
      'fileNearModule()' that were being passed to 'config.loadConfigFile()' can
      be safely changed to 'config.packageFile()' without needing any other code
      changes, but if you were directly using 'fileNearModule()' as a filename,
      you will need to rewrite appropriately.
   
    - 'config.loadConfigFile()' and 'config.loadConfigFiles()' now accept URLs,
      'naming.IStreamFactory' objects, and other 'config.getStreamFactory()'
      targets as well as filenames.  This was primarily added to support use of
      'config.packageFile()' or 'pkgfile:' URLs, in place of using
      'config.fileNearModule()'.
   
    - The 'naming.IStreamFactory' interface now has an 'address' attribute, which
      is the string form of the canonical URL of the target stream.  This was
      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
      location of an error.  (Note: if you implement 'naming.IStreamFactory', be
      sure to add this attribute to your implementations.)
   
    - The 'peak.util.WSGIServer' module has been moved to the
      'wsgiref.simple_server' module.  The 'wsgiref' reference library for WSGI
      (aka PEP 333) is now distributed with PEAK.
   
    - Added a 'WSGI' command to the 'peak' script, to allow you to run "foreign"
      (i.e. non-PEAK) PEP 333 applications in PEAK's various servers and
      launchers.  Basically, by prefixing 'WSGI' before the import specifier, you
      can now run such foreign apps.
   
      For example::
   
          peak launch WSGI import:some_app.application
   
      will run 'some_app.application' in the local web browser, and::
   
          peak CGI WSGI import:some_app.application
   
      will run it under the CGI/FastCGI runner.  Similarly, you can use this in
      the "Command" spec for the "peak supervise" pre-forking FastCGI supervisor
      subsystem.
   
    - There is a new 'running.IWSGIApplication' interface, for PEP 333-compliant
      "application" objects, and all of PEAK's provided applications now implement
      it instead of 'running.IRerunnableCGI'.  If you write your apps to the newer
      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
      adapter that allows 'IWSGIApplication' objects to run in the CGI-based
      containers, but not the other way around, so using 'IRerunnableCGI' directly
      now limits your portability.  (For example, the "peak launch" and "peak
      serve" commands will soon require 'IWSGIApplication', and will not support
      'IRerunnableCGI' any more.)
   
      Of course, if you use the 'peak.web' framework, you don't need to worry
      about any of this; your apps will automatically be wrapped as
      'IWSGIApplication', and run in any PEAK server or gateway.
   
    - Most 'peak.web' interfaces have changed significantly.  If you implemented
      anything based on the older interfaces, and it still works, it's sheer
      bloody luck.  In particular, note that every method in 'web.IWebTraversable'
      now has different inputs and/or outputs than before.  Please read the new
      interface docs and update your code!  The changed interfaces offer much
      more flexibility and functionality than before, but they will require you to
      update your code.
   
    - 'web.ContainerAsTraversable' has been removed.  It was redundant, since the
      new default traversal mechanism used by 'Traversable' and 'Decorator' now
      handles getitem, getattr, and views.
   
    - Added Zope 3-like "namespaces" to 'peak.web'.  Path segments in a URL
      may be prefixed with '"++some_id++"' in order to invoke a corresponding
      namespace handler registered under '"peak.web.namespaces.some_id"'.
      Namespace handlers must implement 'web.INamespaceHandler', and they are
      supplied with the original path segment as well as the separated namespace
      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
      'resources'.  'skin' treats the rest of its path segment as a skin name,
      and sets the current skin, while 'resources' begins traversal to resources
      found in the current skin.  The other namespaces are as described at:
   
      "Resources and traversal in peak.web":http://www.eby-sarna.com/pipermail/peak/2004-August/001712.html
   
    - Fixed several 'peak.events' bugs, as reported by Vladimir Iliev, Yaroslav
      Samchuk, and Alexander Smishlajev:
   
      * 'events.AnyOf' could hold multiple references to a single event source,
        and nesting 'AnyOf()' calls could leak references to the nested events.
   
      * 'events.subscribe()' had a potential race condition wherein a callback
        could be invoked after its weak reference was garbage collected, leading
        to bizarre error messages about 'self' being 'None'.
   
      * 'select()' could be called on select event objects even if there were
        no current subscribers to the event, potentially leading to calling
        'select()' on a closed socket.
   
      * Non-default signal handlers were remaining installed even when there
        were no current subscribers to the applicable event, as long as a
        reference to the event object existed.
   
      As a result of these changes, certain I/O event types (esp. signals and
      stream readable/writeable events) are now longer-lived.  For example,
      signal event objects are now immortal, and the read/write event for a
      particular 'fileno()' will be reused for as long as its supplying
      'Selector' or 'EventLoop' instance exists.  (Previously, weak references
      were used so that these objects would be recycled when not in use.)
   
    - Added 'config.registeredProtocol()' API, that supports defining named and
      local protocols.  This allows easy emulation of Zope 3's "named" and "local"
      adapters and views.
   
    - 'binding.Component' objects no longer support instance configuration at
      runtime (i.e., they no longer implement 'config.IConfigurable').  If you
      need a component to be configurable at runtime, you must now derive from
      (or mix in) 'binding.Configurable' instead.  If you get errors about
      a missing 'registerProvider' attribute, or about being unable to adapt to
      'IConfigurable', try changing your base class from 'binding.Component'
      to 'binding.Configurable', or add it as a mixin if you're deriving from
      a class that uses 'binding.Component' as its base.
   
    - 'binding.IComponent' no longer derives from 'config.IConfigurable' or
      'config.IConfigMap', only 'config.IConfigSource'.  This means that
      'IComponent' no longer guarantees or requires the presence of the
      'registerProvider()' method: now only 'config.IConfigurable' does that.
   
    - The 'config.IConfigMap' interface is now DEPRECATED.  Use
      'config.IConfigurable' instead.  The '_configKeysMatching()' method
      of 'IConfigMap' was moved to 'config.IConfigSource', so if you've
      implemented a custom 'IConfigSource', be sure to add this method.
   
    - 'web.ISkinService' and 'web.ILayerService' were consolidated into
      'web.IInteractionPolicy', because the need to have configurable
      implementations of these services is negligible.  That is, the
      corresponding property namespaces ('peak.web.skins' and 'peak.web.layers')
      are more than adequate as registries.
   
    - Removed 'peak.running.timers' and 'peak.util.dispatch'.  Neither was in
      active use, and both are being replaced by the new generic functions
      package in PyProtocols.
   
    - The 'config.iterParents' API is now moved to 'binding.iterParents', and all
      'binding' functions that walk the component hierarchy use it.  It has also
      been changed to avoid infinite loops in the case of a pathological
      component structure.
   
    - The 'persistence' package has been moved to 'peak.persistence' to avoid
      conflicts with ZODB3 and the latest version of Zope 3.  It will eventually
      be phased out, but for now this move is the simplest way to get it out of
      the way.
   
    - The 'peak.util.SOX' module now uses only one parser, based directly on
      'expat', instead of using SAX.  The new parser expects a new node interface,
      'IXMLBuilder', but adapters from the previous interfaces ('ISOXNode' and
      'ISOXNode_NS') are supplied for backward compatibility.  All of PEAK's
      direct XML handling (currently just 'peak.storage.xmi' and
      'peak.web.templates') have been refactored to use the new interface.  Some
      parsing classes (such as 'ObjectMakingHandler', 'NSHandler', and
      'DOMletParser') are no longer available.
   
  - 'peak.web' no longer uses Zope X3 for HTTP publishing support; it has been   - 'peak.web' no longer uses Zope X3 for HTTP publishing support; it has been
    refactored to use a "simpler, more uniform architecture":http://www.eby-sarna.com/pipermail/peak/2004-May/001462.html     refactored to use a "simpler, more uniform architecture":http://www.eby-sarna.com/pipermail/peak/2004-May/001462.html
    See also "more on the architecture":http://www.eby-sarna.com/pipermail/peak/2004-June/001482.html     See also "more on the architecture":http://www.eby-sarna.com/pipermail/peak/2004-June/001482.html
Line 80 
Line 435 
   
  - Added a 'zconfig.schema' factory, so that 'ref:zconfig.schema@streamURL'   - Added a 'zconfig.schema' factory, so that 'ref:zconfig.schema@streamURL'
    will load a schema loader.  Schema loaders are themselves object factories,     will load a schema loader.  Schema loaders are themselves object factories,
    so you can do something like:     so you can do something like::
   
      [Named Services]       [Named Services]
      peak.naming.factories.myschema = \       peak.naming.factories.myschema = \
          naming.LinkRef('ref:zconfig.schema@pkgfile:mypkg/Schema.xml')           naming.LinkRef('ref:zconfig.schema@pkgfile:mypkg/Schema.xml')
   
    in order to make URLs like 'ref:myschema@filename' work.  Note, by the way,     in order to make URLs like 'ref:myschema@filename' work.  Note, by the way,
    that the above could also read:     that the above could also read::
   
      [Named Services]       [Named Services]
      peak.naming.factories.myschema = \       peak.naming.factories.myschema = \


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

cvs-admin@eby-sarna.com

Powered by ViewCVS 1.0-dev

ViewCVS and CVS Help