|
Fixes and Enhancements since Version 0.5 alpha 2 |
|
|
|
Changed, Enhanced, or Newly Deprecated Features |
|
|
|
- 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 |
|
returned key in a binding's 'offerAs' list, or as the target of a 'bindTo()' |
|
or 'lookupComponent()'. The key is constructed using |
|
'config.ProviderOf(storage.IDataManager,class)'. |
|
|
|
- You can now register utilities that are keyed by the combination of an |
|
interface and one or more classes, using 'config.ProviderOf(iface,*classes)' |
|
as a configuration key. Providers are registered under an '(iface,klass)' |
|
tuple for each specified class, and looked up using the MRO order of the |
|
class specified for lookup. In other words, searching for a provider will |
|
find a provider for the requested class, or one of its base classes, with |
|
precedence given to the more-specific provider. This is primarily intended |
|
for services like data managers and Specialists. |
|
|
|
- It's now possible to extend .ini file parsing with custom section types, |
|
and PEAK defines its own built-in section types using this extension |
|
mechanism. Custom section types must include at least one space, (e.g. |
|
'[My Section]') or they will be treated as a plain property name. |
|
See the 'peak.config.iniFile.sectionParsers' section in 'peak.ini' for |
|
more details, along with the 'config.ISettingParser' and 'config.IIniParser' |
|
interfaces. |
|
|
|
- When creating a 'PropertyName()', it's now possible to force conversion of |
|
invalid characters to '_', using the 'PropertyName.fromString()' |
|
constructor. (Note that the input must be a plain-ASCII string.) Unless |
|
you request that wildcards ('?' and '*') be kept, they will also be |
|
converted to '_' characters. This can be convenient for converting things |
|
like filenames or text that might contain spaces, to property names. |
|
|
|
- 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. |
|
The 'config.IConfigKey' interface has been changed to cleanly support |
|
implied keys at both registration and lookup time, so you can implement |
|
your own key types that work the way interfaces or property names do for |
|
configuration lookups. |
|
|
|
- The 'EigenRegistry' class has been moved from 'peak.util.EigenData' to |
|
'peak.config.registries', as it hasn't really been useful outside PEAK for |
|
a while now. |
|
|
|
- .ini files now support "smart property" objects ('config.ISmartProperty'). |
|
If a property rule defined in an .ini file evaluates at runtime to an object |
|
that implements 'ISmartProperty', the object will be given a chance to |
|
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 |
|
the use of helper classes. Also, 'naming.LinkRef' and 'naming.Reference' |
|
(indirectly) support this interface, so you can now use them in .ini files |
|
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 |
|
'config:' URL, and 'naming.Reference' didn't exist.) |
|
|
|
- 'peak.util.imports.whenImported()' can now be used even when the specified |
|
module has already been loaded. |
|
|
|
- The naming system no longer has 'objectFactories' and 'stateFactories' as |
|
utilities; they have been replaced with new mechanisms involving adaptation. |
|
Previously, addresses had a 'retrieve()' method that could be used to |
|
retrieve the object defined by the address. Now, to retrieve an object for |
|
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 |
|
object. (This is simpler than it sounds; for URLs that reference |
|
ManagedConnections, for example, all you need to do is provide the fully |
|
qualified name of the connection class.) |
|
|
|
Meanwhile, 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. |
|
|
|
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'. |
|
|
|
- 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. |
|
|
|
- Added simple example scripts and small applications in the 'examples' |
|
directory. |
|
|
|
- There is a new command-line namespace introspection tool, 'n2', which |
|
can be accessed by running 'peak n2'. Type 'peak n2 -h' for help. |
|
|
|
- The PEAK_CONFIG environment variable can now list multiple files, separated |
|
by the platform's 'os.pathsep' (e.g. ':' on Unix, ';' on Windows). |
|
|
|
- It's no longer necessary to provide a '_defaultState()' implementation |
|
for an EntityDM: a default implementation is now supplied. |
|
|
|
- Added automatic installation of 'datetime' package for Python < 2.3. |
|
|
|
- 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. |
|
|
|
- There is now a 'peak.security' package, available from 'peak.api' as |
|
'security'. It provides permission management functions: you can define |
|
abstract permissions by subclassing 'security.Permission', then create |
|
permission checking rules by subclassing 'security.RuleSet', and declare |
|
the permissions needed to access attributes of a class with |
|
'security.allow()'. The test suite demonstrates a complex application |
|
ruleset with dynamic, data-driven permissions. |
|
|
|
- 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.) |
|
|
|
- REMOVED 'naming.ParsedURL'; it was deprecated as of 0.5 alpha 2. |
|
|
|
- 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()'. |
|
|
|
Also, 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()'. If you do *not* want |
|
a binding to suggest a parent component, use 'suggestParent=False' in the |
|
binding definition. |
|
|
|
Corrected Problems |
|
|
|
- There was a typo in peak.naming.arithmetic that caused homogeneous non-URL |
|
name subtraction to fail. |
|
|
|
- The default reactor supplied in 'peak.running.scheduler' would consume |
|
CPU continuously if it was waiting for I/O and no tasks were scheduled. |
|
|
|
- The 'peak.util.imports.whenImported' function didn't work. |
|
|
|
|
|
|
|
|
Fixes and Enhancements since Version 0.5 alpha 1 |
Fixes and Enhancements since Version 0.5 alpha 1 |
|
|
- Refactored naming.ParsedURL to be a peak.model.Struct; this means that |
Changed, Enhanced, or Newly Deprecated Features |
existing ParsedURL subclasses will need to be revised if they used fields |
|
other than 'scheme' and 'body'. See PEAK's ParsedURL subclasses for |
- Added a 'shellcmd:' URL scheme that returns a function that calls |
examples of the needed changes. Mainly, '__init__' methods go away, |
'os.system()' on the body of the URL. It's intended for use as a command |
'parse' methods change slightly, and explicit field definitions (using |
factory, as is needed by the 'URLChecker' periodic task. |
'model.structField' or similar) are required. |
|
|
- You can now define adapters from arbitrary types to 'binding.IBindingNode', |
|
and thus be able to use them as part of a component hierarchy - without |
|
needing to directly add 'getParentComponent()' or 'getComponentName()' |
|
methods to them. |
|
|
|
- Added experimental 'invoke.c' script for POSIX-ish platforms with funky |
|
'#!' support, or lack thereof. |
|
|
|
'invoke' is designed to be used like this:: |
|
|
|
#!/usr/local/bin/invoke peak somearg otherarg... |
|
|
|
This should work on most sane platforms with a long-enough commandline. |
|
(See "this page":http://homepages.cwi.nl/~aeb/std/hashexclam-1.html for |
|
details on the insanely incompatible ways different Unixes interpret '#!' |
|
lines.) |
|
|
|
The script is not currently built or installed by setup.py. On the |
|
platforms it's targeted at, you should be able to build it with:: |
|
|
|
gcc -o invoke invoke.c |
|
|
|
(Yes, it really is that simple of a script.) |
|
|
|
- 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. There are two periodic tasks that can be configured and |
|
run from such a file: 'CleanupFiles' and 'URLChecker'. 'CleanupFiles' will |
|
delete files matching a pattern that are older than a certain age, while |
|
'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 |
|
amusing demo, try specifying a 'file:' URL with a 'shellcmd:touch theFile' |
|
to recreate the file, then add a 'CleanupFiles' that deletes the file the |
|
checker looks for. This can be hours (well, minutes) of exciting fun as you |
|
watch the dueling daemons undoing each others' work. |
|
|
|
- Added 'zconfig.schema' URL scheme that loads an enhanced ZConfig schema |
|
object that can act as a command line interpreter using the 'peak' script. |
|
|
|
To use it, run 'peak zconfig.schema:urlToSchema urlOfConfig'. Or, add |
|
a line like this:: |
|
|
|
#!/usr/bin/env peak zconfig.schema:pkgfile:some.package/schema.xml |
|
|
|
to the top of a configuration file, and make the configuration file |
|
executable. Note that the schema specified must convert to an object |
|
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' |
|
entry to shorten the URL reference in your #! line. E.g.:: |
|
|
|
#!/usr/bin/env peak mySchema |
|
|
|
will suffice if you have defined 'peak.running.shortcuts.mySchema' as |
|
'naming.LinkRef("zconfig.schema:pkgfile:some.package/schema.xml")'. |
|
|
|
There is also a 'peak ZConfig urlOfSchema urlOfConfig' variant, that was |
|
added to support putting '#!/usr/bin/env peak ZConfig' at the top of |
|
schema files, but unfortunately that's not valid XML. |
|
|
|
- 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. Also, mof2py no longer emits 'config.setupModule()' |
|
calls in generated code, as in practice they are not needed. |
|
|
|
- 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. |
|
You can, however run any test suite from the command line with a dotted |
|
module/attribute path, e.g 'peak test foo.bar.test_suite'. |
|
|
|
- '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()'. |
|
|
|
- REMOVED ability to use '__implements__' and '__class_implements__' to |
|
declare support for interfaces. Use 'protocols.advise()' or a related |
|
API to do this now. The 'protocols' package is available automatically |
|
from 'peak.api'. |
|
|
|
Similarly, 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 |
|
should work with both PEAK and Zope interfaces. |
|
|
|
- Replaced all use of 'zope.interface' with 'protocols' package because |
|
the 'protocols' package: |
|
|
|
* is considerably smaller and simpler than 'zope.interface' |
|
|
|
* produces Interface objects that can be inspected with the Python |
|
'pydoc' and 'help()' tools |
|
|
|
* supports and implements the PEP 246 'adapt()' protocol |
|
|
|
* transparently supports transitive adaptation - i.e. if adapter AB |
|
adapts from A to B, and adapter BC adapts from B to C, then an adapt(x,C) |
|
where 'x' is an 'A', will be implemented as BC(AB(x)). |
|
|
|
* Supports "open protocols" that allow you to "superclass" a protocol |
|
to create a subset protocol; objects that support the first protocol |
|
will automatically support the subset protocol. For example, if one |
|
person defines a "dictionary" protocol, someone else can create a |
|
"read-only dictionary" protocol, and all objects supporting the |
|
"dictionary protocol" will be considered to implement the "read-only |
|
dictionary" protocol. |
|
|
|
* can interoperate with other interface packages, including Zope's, but |
|
does not require them |
|
|
|
* works with module inheritance (for everything but moduleProvides(), and |
|
we should get to that by 0.5a2) |
|
|
|
* lets you use Interfaces as abstract base classes (i.e., you can |
|
inherit from an interface and turn it into an implementation, and |
|
you can define default attribute values or method implementations in |
|
your interfaces |
|
|
|
* Lets you mix interface declarations from any number of frameworks and |
|
any number of interface types, in a single 'implements()' or |
|
'classProvides()' |
|
|
|
* uses adaptation as the fundamental approach to dealing with interfaces, |
|
and avoids the use of 'isImplementedBy()'. In the *rare* case that you |
|
need to introspect rather than adapt, you can always call adapt() and |
|
check the result. (But introspection usually means that you're using |
|
interfaces as a form of metadata; it's better to create an explicit |
|
interface that provides the metadata you seek, and adapt to that |
|
interface, than to use interfaces as data.) |
|
|
|
Most of these features are unavailable in 'zope.interface', and some have |
|
been declared by the Zope Pope to be unacceptable or undesirable features |
|
for Zope interfaces. (Others may be available in some form in future |
|
versions of Zope X3.) So, we no longer require or distribute |
|
'zope.interface'. |
|
|
|
- The signatures of the 'getObjectInstance()', 'getStateToBind()', and |
|
'getURLContext()' methods in the 'peak.naming' package have changed, to |
|
place the context or parent component as the first, non-optional argument. |
|
(If you don't know what these methods are for, you don't need to do anything |
|
about this, as they are part of the naming package's extensibility |
|
framework.) |
|
|
|
- 'binding.bindTo()' now accepts a 'default=' argument, whose value will be |
|
used in case of a 'NameNotFound' error. |
|
|
|
- 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 |
|
provides a new URL parsing framework based on 'peak.model'. Upgrading from |
|
'ParsedURL' to 'URL.Base' is trivial for ParsedURL subclasses that used |
|
only the 'scheme' and 'body' fields, and in fact may not require any |
|
changes except for the choice of base class. Also, the 'retrieve()' method |
|
of URLs is deprecated; please begin defining the 'getObjectInstance()' |
|
method instead. This is to cut down a bit on the number of ways that the |
|
naming package spells the idea of retrieving something! |
|
|
|
For more complex URL classes, the '__init__' methods go away, 'parse' |
|
methods change slightly, and explicit field definitions (using |
|
'model.structField' or similar) are required. See PEAK's 'URL.Base' |
|
subclasses for examples. There is also a sophisticated parsing and |
|
formatting framework (see the 'peak.naming.URL' and 'peak.util.fmtparse' |
|
modules) that can be used in place of the old regex-based approach. |
|
|
|
- Added 'peak.util.fmtparse', a parsing and formatting framework, and |
|
integrated it with 'peak.model' so that any element type can have a |
|
syntax for parsing from, or formatting to, a string. |
|
|
- Added 'binding.whenAssembled(...)' as syntax sugar for |
- Added 'binding.whenAssembled(...)' as syntax sugar for |
'binding.Once(...,activateUponAssembly=True)'. |
'binding.Once(...,activateUponAssembly=True)'. |
'_getConfigData', 'getComponentName', or 'notifyUponAssembly', you need |
'_getConfigData', 'getComponentName', or 'notifyUponAssembly', you need |
to wrap them with 'binding.metamethod' now. |
to wrap them with 'binding.metamethod' now. |
|
|
|
- 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). |
|
|
|
|
|
Corrected Problems |
|
|
|
- Fixed a problem in ZConfig 'schema.dtd'; I used 'PCDATA' where I should've |
|
used 'CDATA'. |
|
|
|
- Fixed a problem with 'binding.supertype()' not working correctly if the MRO |
|
it was searching contained a "classic" class. Now 'supertype()' skips any |
|
classic classes it finds. (It probably should be rewritten entirely.) |
|
|
|
- Fixed misc. problems with 'fromZConfig()' component constructor |
|
|
|
- Fixed source distributions missing essential setup files |
|
|
|
- Fixed a problem with assembly events, where a parent component that didn't |
|
need assembly notification, wouldn't ever notify its children of assembly |
|
if they requested the notification after the parent had already received |
|
it. |
|
|
|
- Fixed a bug in automatic metaclass generation that caused extra unneeded |
|
metaclasses to be generated. |
|
|
|
- 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. |
|
|
|
- Fixed a problem where initializing single-valued immutable fields of |
|
'peak.model' types did not perform type/value normalization. |
|
|
|
- Fixed a problem where bindTo would use the attribute name as the |
|
default value for a lookup, if the requested name/property/utility |
|
was not found. |
|
|
- Fixed 'mof2py' generator script not working |
- Fixed 'mof2py' generator script not working |
|
|
- Fixed model.Element not getting parent component set when passed as a |
- Fixed model.Element not getting parent component set when passed as a |
|
|
- Fixed IndentedStream generating all-whitespace lines |
- Fixed IndentedStream generating all-whitespace lines |
|
|
- 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). |
|
|
|