No default branch
Bookmark a link to HEAD: (view) (download)
'peak.running.options' is now a thin wrapper over 'peak.cli.options', from the separately-distributed 'CLI-Tools' package.
Added "paramstyle" support for SQL connections, so you can write backend-agnostic SQL with parameters. See CHANGES.txt for usage details.
The 'peak' script is now an .exe on Windows, using setuptools' "entry point" system. Also, cleaned up the setup script a bit so I won't have to use PyPI's web interface to keep the PEAK listing(s) up-to-date. The download URL now points to the snapshots directory, and there's a link for the subversion release as well. So "easy_install PEAK" will install the latest snapshot, and "easy_install PEAK==dev" will build PEAK from source.
PEAK no longer bundles any software that can be obtained automatically from PyPI. Running PEAK's setup script will attempt to download and install the needed packages. (Note that development snapshots of PEAK may require development snapshots of related packages.)
Added a series of new QueryDM and EntityDM convenience features. See this post: http://www.eby-sarna.com/pipermail/peak/2005-May/002296.html for a complete list and explanatory documentation.
Changed 'running.lookupCommand()' to use the command's 'getCommandParent()' method, so that commands using the '--config' option will utilize the specified configuration(s) to lookup subcommands. Also, fix WSGI launchers so that their target application is created under the --config service area, if one is specified.
Added a '-c/--config' option to PEAK bootstrap commands to load an .ini configuration file in a new service area before executing any subcommands. This allows you to do things like:: peak launch -c bulletins ref:firstname.lastname@example.org which loads the 'bulletins' configuration file before launching the sitemap. Note that if you are subclassing 'commands.Bootstrap' you can suppress this option using 'options.reject_inheritance("-c","--config")' in the body of your subclass' class definition. You may wish to do this if your application's subcommands must run in the same service area as the parent command. (E.g. if the parent command expects the subcommand to partake in a transaction controlled by the parent command.)
Added a 'value' property to 'model.Enumeration', so that you can access an enumeration instance's value (i.e., the value it hashes and compares equal to)
Added a 'binding.hasParent(component,parent)' API function, which is specially optimized for use with generic functions, so that you can define generic function methods that apply only within some part of a component hierarchy. Also, added a 'components.txt' doctest to the binding package, that illustrates not only the new 'hasParent()' function, but also some other hierarchy-related APIs as well.
PEAK now requires Python 2.3.4 or better; dropped support for building 2.3 modules with 2.2. The kjbuckets extension module is no longer built and installed by default, either; you must explicitly enable it with a '--with-kjbuckets' flag passed to 'setup.py'. Please port your code as soon as practical, this option will go away soon.
First pass at removing all uses of 'kjbuckets'; this takes care of all but 'peak.util.MiniTable', which still uses the 'kjDict' type. Note that this checkin also changes the ISOXNode_NS interface in peak.util.SOX; See CHANGES.txt for details.
Remove all vestigial traces of the old 'Interaction' interface/object from peak.web. Clean up miscellaneous cruft such as 'CGIPublisher' (now 'WSGIPublisher') and make your choice of interaction policy configurable, which is especially important now that the interaction policy controls all the security rules. The 'user' of a traversal context is now a first-class part of the traversal context, rather than hanging off of the now-useless 'interaction' attribute.
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 docs 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()'.
Note the deprecation of security.allow(); forgot this in the last checkin.
Options have landed! They're now integrated with the commands framework (via the 'parsed_args' attribute), and support option groups for fancy help displays. Now we can begin adding options to PEAK's built-in commands, such as options to control 'peak launch' and such.
Added a 'binding.initAttrs()' function that can be used to initialize an object's attributes from e.g. constructor keyword arguments, similar to how the 'binding.Component' and 'binding.Attribute' constructors work. (Also, refactored them to use this new function instead of harcoding their own versions.)
DEPRECATED 'permissionNeeded' attribute of descriptors, and removed 'security.IGuardedDescriptor'. Please see CHANGES.txt for more details, and information on upgrading. Now 'peak.security' is decoupled from the PEAK core frameworks, or more precisely, there are no "forward references" from the PEAK core to 'peak.security', except for the temporary vestigial implementations of 'permissionNeeded' that will be removed in the next release.
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. This is the first part of a refactoring to implement the attribute metadata framework for PEAK.
'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 the functionality.
Migrated 'config.IStreamSource' -> 'config.getStreamFactory'. To update your code, change all: factory = config.IStreamSource(source).getFactory(context) to: factory = config.getStreamFactory(context,source) Note that 'context' comes *before* 'source' in the argument list, so this now matches the normal order for PEAK API's that take a context parameter. Also, if you had an implementation or adapter for IStreamSource, you'll need to replace it with a 'config.getStreamFactory.when()' method.
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. Also, changed 'pkgfile:' URL implementation to actually track its 'module' and 'path' parts separately, so that it can implement relative URLs safely.
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.IStreamSource'.
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'. Also, added "empty" option to negotiating XML parser, so that tags which don't want any children can force an error if a child element appears within them.
Added 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. Please see CHANGES.txt for usage examples of both new features.
Changes to make it possible to use PEAK and PEAK apps' package data files from .zip files: - 'config.fileNearModule()' is DEPRECATED; use 'config.packageFile()' now. 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 'config.IStreamSource' objects as well as filenames. This was primarily added to support use of 'config.packageFile()' or 'pkgfile:' URLs, in place of using 'config.fileNearModule()'. (ZConfig loaders support this too.) - There is a new 'config.IStreamSource' protocol, 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.IStreamSource(data).getFactory(self) stream = factory.open('t') # open for reading in text mode where 'data' 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. Wherever practical, as we encounter them, we'll be changing PEAK API's that take filenames to also accept stream sources.
Moved 'peak.util.WSGIServer' to 'wsgiref.simple_server'.
Port all of PEAK's internal and example apps from IRerunnableCGI to IWSGIApplication, and add a new 'WSGI' command wrapper that lets you run non-PEAK WSGI applications in PEAK's containers. For the time being, we're keeping IRerunnableCGI around, however, because it's a more natural interface for the CGI/FastCGI containers to use. See CHANGES.txt for more details on these issues. Also, fixed an issue with templates outputting Unicode instead of ASCII (which is all they really support at the moment.)
Major overhaul of the traversal mechanisms in 'peak.web', including streamlining of traversal interfaces to avoid creating extra contexts and then stripping them back off. 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 if you implemented any of the affected interfaces. '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. This completes the bulk of the traversal namespace refactoring; hopefully these interfaces have now stabilized sufficiently. The only major issue remaining is permissions on views, and there is a small but nonzero chance that resolving the issue will affect an interface somewhere.
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, and 'resources' begins traversal to resources found in the current skin. The other namespaces are as described at: http://www.eby-sarna.com/pipermail/peak/2004-August/001712.html Note, however, that this doesn't include the change to default traversal described there, and there are a couple of other issues outstanding, like defining permissions for views, and fixing legacy uses of "@@" in the peak.web source. We also don't have any registration mechanisms for easy view declarations, or for setting up local "sites" or "sub-applications". Also, this refactoring may break existing uses of 'web.traverseAttr', which now has a completely different meaning and signature.
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.)
Recreate checkins lost when hard drive died (1 of 4); see: http://www.eby-sarna.com/pipermail/source-changes/2004q3/001807.html for original log info.
Consolidated 'web.ISkinService' and 'web.ILayerService' were 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. (Also, fixed some web-app problems caused by PyProtocols refactoring to use only one-argument adapter factories.)
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 has 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.
Make SOX and p.w.t use the same expat-based XML processor, as a prelude to adding XML configuration/serialization. See 'CHANGES.txt' for impact details.
Massive refactoring of 'peak.web' to remove all Zope dependencies. See 'CHANGES.txt' for details. Note that this is only the beginning of the refactoring, so please promptly report any problems you may find! That way, I hopefully won't get too far ahead, building on anything that might be broken.
The 'log()' method of PEAK loggers ('logs.ILogger') now accepts a level name *or* a number, for convenient invocation.
SQL transaction semantics have changed. Now, issuing an SQL statement *always* causes the connection to join the active PEAK transaction, even if 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 PEAK transaction. This simplifies the overall processing model for dealing with "untransacted" SQL such as Sybase DDL or read-only Oracle transactions. (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, and fixed tab completion in n2 to not start a transaction unintentionally (by making 'listObjects()' methods of DBs supporting "outside" mode be transaction-agnostic).
Change 'ref:' URL syntax to allow multiple addresses, separated by '||'. (This is preparation for adding "failover" support to managed connections.)
The 'events.IEventSource' interface now returns a 'canceller' function from the 'addCallback()' method, allowing you to cancel a previously- scheduled callback. This fixes a memory leak and performance problem with 'events.AnyOf()', which previously could accumulate unneeded callbacks on the sources it was monitoring. Note that if you have developed any custom event sources with 'addCallback()' methods, you must make sure that they return a canceller from now on.
Added 'ref:factory@addr' URL scheme that maps to a corresponding 'naming.Reference("factory",["addr"])'. 'factory' can be either a dotted import string referencing a 'naming.IObjectFactory', or you can define a factory in the 'peak.naming.factories' property space. Added a 'zconfig.schema' factory, so that 'ref:zconfig.schema@streamURL' will load a schema loader. See CHANGES.txt for more details on all the cool stuff you can do with this.
Changes to make the n2 \htmldump + ddt.SQLChecker combo work better on real data. Specifically, use 'repr()/eval()' instead of 'str()'.
Added 'peak.util.mockets', offering imitation socket services like 'socket()' and 'select()', allowing socket-based services to be tested without using real sockets. So far only emulates TCP streams, and no other protocols, with certain socket methods omitted. Needs to be used to test 'peak.events.io_events.Selector', and as a basis for testing/implementing nonblocking socket objects for 'peak.net'.
Sybase an Oracle: two-phase commit, read-only txns, and serializability. Changed Oracle "outside transaction" semantics to allow read operations only, and added a property to set Oracle transactions to "serializable" (which effectively requires two-phase commits). Note that the current version of DCOracle2 doesn't properly support two-phase commit except for empty (no-op) transactions, which isn't very useful. However, if a later release of DCOracle2 works correctly and doesn't change its API, the current PEAK driver should then work correctly. In the meantime, the cx_Oracle driver apparently *does* provide working support for two-phase commits. The controlling properties are of the form 'DRIVER.twoPhaseCommit' and 'DRIVER.serializable', where 'DRIVER' is the name of the DBAPI driver module, e.g. 'Sybase.twoPhaseCommit' or 'cx_Oracle.serializable'.
Added properties to the command-line applications framework, allowing non-command objects access to 'stdin', 'stdout', 'argv' etc. from their context. Also, misc. subcommand usage cleanups.
Fix broken docs and implementation of '[Named Services]'. The idea was for the expression to *be* the factory, not *designate* the factory.
Added '[Named Services]' section parser to 'peak.ini'. This new section type functions almost identically to '[Component Factories]', except that the keys are property names rather than references to interfaces or other component keys. This should be helpful for configuring shared services that all implement the same interface, such as SQL connection objects. Note that to look up a named service, you simply use the appropriate property name, as usual. The difference is that you are guaranteed to always use the same *instance* of the service, within a given service area. Also, added 'ddt.SQLChecker()', which verifies SQL results against a test document. 'SQLChecker' makes use of the new "Named Services" feature in order to ensure it's accessing the database you intend to test (as opposed to say, the nearest SQL connection object).
Added 'peak serve' and 'peak launch' commands, for running "CGI" apps in a browser from the local machine. For example, doing this:: PYTHONPATH=examples/trivial_cgi peak launch import:the_cgi.DemoCGI from the base directory of a PEAK CVS checkout or source distribution will launch the 'trivial_cgi' demo program in a new or current browser window. Any application runnable with 'peak CGI' should also be runnable with 'peak serve' or 'peak launch', which makes it very useful for running local browser-based apps or testing an application without CGI or FastCGI available. The modules that support this new functionality are 'peak.util.WSGIServer' (which implements a web server based on Python's 'BaseHTTPServer', that can run 'running.IRerunnableCGI' objects) and 'peak.tools.local_server' (which provides PEAK integration.)
Added "state of the PEAK union" doc (STATUS.txt). Moved old changes to HISTORY.txt. Updated copyright and package info. Moved ancient and improbable TODO's out to individual packages. Readjust a3 TODO targets so we can release it a lot sooner, preferably within 1-3 weeks.
DDT has landed! See CHANGES.txt and peak.ddt.demos for more info.
Big migration to 'peak.events': 'UntwistedReactor' and 'MainLoop' are now just facades over 'EventLoop'. Added untested Twisted support to implement 'peak.events' interfaces as facades over a reactor. Minor interface tweaks in 'peak.events' to cover the needs of real (and testable) event loops. Moved 'ifTwisted' and 'makeTwisted' to 'peak.events.api'. Ported 'TaskQueue' and 'FastCGIAcceptor' to use threads for scheduling. Por Other: fixed 'commands.AbstractInterpreter' failing with usage errors at construction time, rather than at use time. Refactored 'CGIInterpreter' to be an actual interpreter, and 'CGICommand' to not run an event loop unless FastCGI is being used. Also changed 'CGICommand' to perform setup at _run time rather than immediately upon assembly.
Lots of 'peak.events' migration: Added 'events.ISignalSource', that returns 'events.Broadcaster' objects for signals. This allows you to yield to signals in an 'events.Thread', or safely set one-time callbacks on them. 'running.ISignalManager' is now DEPRECATED; please use 'events.ISignalSource' instead. 'running.IMainLoop' has been changed to use an 'events.IReadable' for the 'lastActivity' attribute, and the 'setExitCode' and 'childForked' methods have been replaced with an 'exitWith()' method. The 'peak.running.mainLoop.signalHandler' property has been replaced with 'peak.running.mainLoop.stopOnSignals', which defaults to including SIGINT, SIGTERM, and SIGBREAK. If you need custom signal handling, please use the event sources provided by an 'events.ISignalSource'. 'peak.running.process.ChildProcess' has been rewritten to use 'events.ISignalSource' and an 'events.Thread' to monitor SIGCHLD. Removed 'checkStatus()' from the 'running.IProcessProxy' interface. Made most event sources weak-referenceable. Changed 'events.Thread' to keep a reference to an object it's yielding on, so that "weak" events like signals and I/O events will hang around until they call back to the thread.
Simplified configuration for using Twisted, roughly as proposed in http://www.eby-sarna.com/pipermail/peak/2004-January/001125.html Also, added 'iif' function for use in .ini files.
Added automatic installation of 'csv' module for Python < 2.3. This is preparatory to adding cursor formatting using csv, and maybe eventually a csv "connection" type to peak.storage. Both should be useful for extract-transform-load-test operations and for doing TinyTable-like things.
'peak.events' has landed, complete with docstrings and full unit tests.
"Global" services defined by '[Component Factories]' sections now live in the closest "service area" to the component that requests them. A "service area" is a parent component that implements 'config.IServiceArea', such as a configuration root returned by 'config.makeRoot()'. Applications loaded by the 'peak runIni' command are now created in their own service area, which means that settings in the .ini file being run will apply to services the application uses. (Because the application will have its own, application-specific service instances, and they will use the configuration loaded into the service area.) For more information, see CHANGES.txt, and especially: http://www.eby-sarna.com/pipermail/peak/2004-January/001087.html
First pass of 'logs' framework refactoring. Highlights include: * Lots of new unit tests for logging. * Logs are now accessed via a 'logs.ILoggingService' instance. The 'logger:' URL scheme automatically accesses the nearest such service. For backward compatibility, the old 'peak.logs' namespace is still used to supply the actual loggers. This will be gradually replaced with a plugin-based mechanism. * Log events don't use a positional 'message' argument any more, and loggers aren't responsible for interpolating message arguments any more. The new signature is 'Event(parent, msg=msg, args=args, ...)'. Loggers also now tell events what logger name they are, via the 'ident' keyword. * The logging system now uses a property namespace, 'peak.logging.levels', to obtain log level names and values. The various 'logs.LEVEL' constants are now DEPRECATED. Please use the 'getLevelFor()' method of the nearest 'logs.ILoggingService' instead. URL schemes such as 'logfile:' also no longer convert their level names to numbers, since the level names are only meaningful in the context of a logging service. * Support for integration with the Python 2.3/PEP 282 logging module has been scaled back. There are too many globalisms and dependencies there. When we add plugin-based log configuration, it should be possible to use the logging package's handlers and formatters with the PEAK logging services. At that point, you'll be able to replace 'logging.getLogger' and 'logging.getLevelName' with the corresponding methods of a PEAK logging service, if you need to force non-PEAK packages to use PEAK's logging. * 'config.Namespace()' objects now have a 'keys()' method that can be used when the namespace is bound to a context component. It returns a list of strings that may be used as keys for that namespace. See 'CHANGES.txt' for an example.
Plugins have landed! * Added 'binding.PluginKeys' and 'binding.PluginsFor'. These are component keys that can be used to 'Obtain' plugins registered within a property namespace. 'PluginKeys' obtains a list of the plugins' configuration keys, while 'PluginsFor' obtains a list of the actual plugins. * Replaced 'peak.config.registries.EigenRegistry' with 'peak.config.registries.ImmutableConfig'. The only use we had for 'EigenRegistry' was to keep track of 'offerAs' settings within classes, and it didn't need all the extra complexity of eigenstate management. The new, more-specialized class is shorter, simpler, and easier to use.
MAJOR API REFACTORING for 'peak.config', to support iterating over configuration keys, 'n2' navigability of properties, and much more. Many APIs are now DEPRECATED or renamed; please see CHANGES.txt for a complete description. A few highlights: - 'config.lookup()' replaces 'findUtility' and 'getProperty' - 'config.iterValues()' replaces 'findUtilities' - 'config.iterKeys()' finds keys in a specific namespace - NEW: 'config.parentProviding()' and 'config.parentsProviding()' APIs to find parent components that support a protocol. - NEW: You can now use 'peak n2 config:' to explore the default property namespace. For example 'ls -l peak.naming.schemes' will list all defined naming schemes. Please see CHANGES.txt for the list of deprecated or removed APIs.
Added 'config.MultiKey()' and 'config.UnionOf()' configuration key classes, to generalize existing specialty keys such as 'ProviderOf' and 'FactoryFor'. (The latter two are now defined in terms of the former two.) Also, made classes and types usable as configuration keys. This was needed for the above generalization, but also makes many other class-lookup concepts possible. (Note that there may be some slight changes to the effective registration and lookup order of these and other configuration keys as of this change, as there were some previous errors and/or ambiguities to the lookup order that were not covered by the test suite.)
Misc. cleanups: removed signal_stack module, clean up formatting/clarity issues in CHANGES.txt, fix 'StopOnStandardSignals' class unnecessarily scheduling the 'reactor.stop()' in the future, and made 'config.Namespace' objects cache attribute lookups by default. Also, made 'config.Namespace' objects usable as 'Make' recipes, so you don't need to use 'lambda:' to make a copy of the Namespace object.
Added "[Import on Demand]" section type to .ini files, allowing you to define shortcuts for modules that you frequently reference in your configuration. This lets you replace e.g. 'importString("foo.bar.baz:Spam")' with 'foo_baz.Spam' in expressions, by adding something like this:: [Import on Demand] foo_bar = "foo.bar.baz" to your configuration. The defined shortcut is then available for the remainder of that configuration file, and in any .ini files included from the current file. See 'peak.ini' for an example and more info.
Logging-related interfaces have been moved into the 'peak.running.logs' module. So, what used to be 'running.ILogger' is now 'logs.ILogger'. Log events now use a standard component construction signature, and the class used for event objects is now configurable as the factory for 'logs.ILogEvent'. (See "Component Factories" in 'peak.ini'.) By popular demand, 'logs.ILogger' (and its default implementation) now includes 'trace()', 'notice()', 'alert()' and 'emergency()' methods that use the corresponding 'syslog' priority levels. 'logs.IBasicLogger' has been added, to reflect the narrower interface provided by PEP 282, and there is an adapter that can extend PEP 282 loggers with the other methods. Finally, added 'logs.ILoggingService' (for future implementation), and updated TODO to reflect short-term project priorities that take precedence over the alpha 3 release for now.
The 'logging.logger:' URL scheme has been simplified to 'logger:'. Please convert your scripts and configuration files, as the longer form will go away in the alpha 4 development cycle. Also, fix 'peak help logs' breaking due to a missing 'mdl_typeCode' on 'naming.CompositeName'.
Added 'commands.lookupCommand()' to look up a command shortcut or URL, ala the 'peak' script or 'commands.Bootstrap' class. Also added various 'commands.ErrorSubcommand' subclasses to make it easier to issue errors from subcommands.
Added 'peak.core' as a minimal subset of 'peak.api'. 'peak.core' offers only "core" API packages and primitives, not the full set of available framework APIs. 'peak.api' will continue to expand as frameworks are added, but 'peak.core' will stay as small as practical. ('peak.exceptions' may in fact end up being removed from 'peak.core', or at least renamed.) Also, added 'peak.util.symbol' module, to contain 'NOT_GIVEN', 'NOT_FOUND', and the 'Symbol' class used to create them.
Renamed 'fd:' URL to 'fd.socket:', simplified its syntax to 'fd.socket:fileno/family/kind/protocol', and changed its attribute names to match the syntax. (The rename is because we may want 'fd.file:' later as well.)
Promote peak.running.supervisor to peak.tools.supervisor.
Give peak.running.tools a promotion... it's now just peak.tools
Configuration system cleanups and new features: - Replaced the "[Provide Utilities]" section of .ini files with "[Component Factories]". The new section type is easier to use, much more versatile, and does all registration and imports lazily. See the 'peak.ini' file for docs. "[Provide Utilities]" and 'config.ProvideInstance()' are now DEPRECATED, so please convert ASAP. - 'binding.Make()' now accepts configuration keys, using them to look up a factory object that's then invoked to create the attribute. This makes it a lot easier to define a component with its own transaction service, 'IBasicReactor', or other normally "global" component. It also makes it easier to globally specify a factory class for some interface. Factories are looked up under the 'config.FactoryFor(key)' configuration key. (See below.) - Added 'config.FactoryFor(key)', a 'config.IConfigKey' implementation that provides a configuration namespace for factories. When you use 'binding.Make(ISomething)', it's roughly equivalent to:: binding.Make( lambda self,d,a: binding.lookupComponent( self, config.FactoryFor(ISomething), adaptTo = binding.IRecipe )(self,d,a) ) That is, the 'config.FactoryFor(ISomething)' is looked up and invoked. - Added 'config.CreateViaFactory(key)', a 'config.IRule' implementation that creates an implementation of 'key', by looking up 'config.FactoryFor(key)'and invoking it. - Added 'config.ruleForExpr(name,expr)', that returns a 'config.IRule' that computes the Python expression in the string 'expr'. This is the mechanism used by configuration files to create rules, factored out into an API call so that configuration extensions can use it, too.
The 'referencedType' of a 'model.StructuralFeature' can now be any 'binding.IComponentKey', not just a type or a string. Types are also now implicitly component keys, which means you can use 'binding.Obtain(SomeType)' to look up 'SomeType'. (Right now, this is no different than using 'SomeType' without the 'binding.Obtain()', but in future releases this will use a "class replacement service" to allow easy replacement of model and other collaborator classes, while implementing AOP-like features.)
Added 'naming.Indirect(key)', a 'binding.IComponentKey' that can be used to do an indirect lookup via another 'IComponentKey' (such as a name). Using 'naming.Indirect()', you can replace code like this:: socket = binding.Obtain( lambda self: self.lookupComponent(self.socketURL), adaptTo = [IListeningSocket] ) with code like this:: socket = binding.Obtain( naming.Indirect('socketURL'), adaptTo = [IListeningSocket] )
Remove process supervisor from TODO, add it to CHANGES and README. Also, added a link from its ZConfig schema to the original design proposal, since it'll no longer be linked from the TODO.
Standardized these characteristics of name and address syntax: * '//' at the beginning of URL bodies is *mandatory* when the URL begins with an "authority" as described by RFC 2396. When the URL is not required to contain an authority (e.g. 'peak.storage.SQL.GenericSQL_URL'), the '//' is *optional*, and the canonical form of the URL will not include it. * Standardized names for RFC 2396 fields: 'user', 'passwd', 'host', and 'port'. In addition, added test cases for all name/address schemes, or documented why no tests are needed (or possible, in the case of icb). Also, refactor 'fd:' URL scheme to use 'model.Enumeration' types so that the URLs have a canonical form (at least within a given platform), and can be properly formatted as well as parsed. Finally, added more docs to 'fdURL' class.
Prototype fix: 'peak.running.commands.CGICommand' could become confused on certain BSD variants (such as Mac OS/X), and assume it was running under FastCGI, even if it wasn't. (Because the operating systems in question use socket pairs to implement pipes.)
Added 'peak.metamodels.ASDL', a metamodel for the Zephyr Abstract Syntax Description Language. ASDL is a convenient way to describe a domain model for an abstract syntax tree (AST), and the models generated with the new ASDL tool can be combined with concrete syntax to create a complete parsing solution for "mini languages", possibly including the Python language itself. (Future versions of the Python and Jython compilers are likely to use AST models based on ASDL, and in the current Python CVS sandbox there's already an ASDL model of Python's AST available.)
Enhanced 'fmtparse' and 'peak.model' to allow using types as syntax rules for parsing, including abstract types. An abstract type's syntax is the union (using 'fmtparse.Alternatives') of the syntaxes of its subclasses (as specified by 'mdl_subclassNames').
First draft of new 'SupervisorProcess' pre-forking process manager. Added 'IProcessTemplate' and a draft implementation thereof, along with a revised version of 'IProcessProxy' and a draft implementation of that. Also added 'IMainLoop.setExitCode()' and 'IMainLoop.childForked()' methods, to allow reactor-driven components to control the mainloop's exit code.
DEPRECATED 'peak.util.signal_stack'. Instead, bind to a 'running.ISignalManager' and use its 'addHandler()/removeHandler()' methods. This has the same effect as 'pushSignals()' and 'popSignals()', except that you do not have to remove handlers in the same order as you add them, and *all* active handlers are invoked for a given signal that they handle. Added 'IBasicReactor.crash()', which forces an immediate reactor loop exit, ignoring pending scheduled calls. This required changing some tests, because the precise moment of reactor termination is now different in some scheduling scenarios. Some changes were also made to task scheduling for CGI programs to account for this.
Added 'peak.running.commands.runMain()', a convenience function for starting an application's "main" command, that also makes it easy for forked child processes to exit and replace the parent process' "main". The 'peak' script has now been shortened to:: from peak.running import commands commands.runMain( commands.Bootstrap ) so it's now much easier to create alternative startup scripts, if you need to, or to add an 'if __name__=="__main__"' clause to a module.
Added 'peak.util.mockdb', a "mock object" implementation of a DBAPI 2.0 driver module. 'mockdb' connections can be told to 'expect()' queries and 'provide()' data to their callers, and will raise AssertionErrors when they are used in a way that doesn't conform to your supplied expectations. This is intended to be used for unit testing components that depend on a database connection: you can verify that they send the right SQL, and you can provide them with dummy data to use. There is also a 'mockdb:' URL and peak.storage driver, so you can easily use a mock DB connection in place of a real one within a PEAK application, for testing purposes. Note, however, that 'peak.util.mockdb' is a DBAPI 2.0 driver in itself, and thus can also be used to test DBAPI usage outside of PEAK.
Update PEAK's CHANGES for the 2.3 test suite bugfixes.
SQL connection objects now provide an 'appConfig' attribute that is a driver-specific 'config.Namespace()'. This allows you to easily set up configuration properties that are driver-specific. For example, you could use properties to configure driver-specific SQL snippets, then access them via the connection's 'appConfig' namespace. The namespaces are of the form 'DRIVER.appConfig', where 'DRIVER' is the name of the DBAPI module for that connection type (e.g. 'pgdb', 'cx_Oracle', etc.).
Merged 'Fallback' and 'PropertySet' to create 'config.Namespace'. Removed 'Fallback' and deprecated 'PropertySet'.
Added 'config.Fallback()' convenience class for redirecting property lookups from one namespace to another. See 'peak.ini' for usage examples.
SQL connection objects now get their type converters from a distinct property namespace for each DBAPI driver. For example a driver using the 'cx_Oracle' module will get its type converters from the 'cx_Oracle.sql_types' property namespace, instead of 'peak.sql_types'. For backward compatibility, these driver-specific namespaces are set up to fall back to 'peak.sql_types' for their defaults. Type converter construction has also been improved, to eliminate conversion overhead completely when no conversions are required for a specific query. Also, SQL connections now offer a method that will create a row conversion function for a given result description and optional postprocessing function. This new method should now be used in place of direct access to the 'typeMap' attribute of connection objects.
Misc. doc fixes.
First phase of the binding API simplification, including detailed docs for 'Descriptor' and 'Attribute'. (Second phase will be mass search-and-replace of the API's usage in PEAK, third will be additional tests and docs.) Added 'binding.Require', 'binding.Obtain', 'binding.Make', and 'binding.Delegate'. *ALL* other binding types are now DEPRECATED, and will go away before 0.5 beta is released. Please see CHANGES.txt for a detailed mapping of how to translate from the old to new API, and let me know if anything's missing. Note that the new 'Make' and 'Obtain' bindings also support sequences of recipes and keys, and in those cases will produce a sequence of the results from those recipes or keys. Also, 'Make' will accept no-argument and one-argument callables, where 'Once' always required three-argument functions. This should make it a lot easier to write short binding functions. Also, note that the 'activateUponAssembly' keyword is now 'uponAssembly', and 'isVolatile' is now 'noCache'. (The old names will work as keyword arguments until the alpha 4 development cycle begins.) The 'binding.IActiveDescriptor' interface also changed as a result of this. Last, but not least, a 'binding.IRecipe' interface was added, to support the new 'binding.Make' type.
Added a 'lockName' attribute to 'runnning.AdaptiveTask', and a 'LockURL' setting to its ZConfig schema. This allows a lockfile URL to be specified for adaptive tasks that need exclusive access to some resource while running.
Update misc. notes re: deprecated binding APIs.
A list or tuple of 'IComponentKey' instances is now treated as a single component key, that returns a tuple of the values returned by each constituent component key. This means that 'binding.bindTo()' and 'lookupComponent()' can now accept a list or tuple of component keys. This makes 'bindSequence()' obsolete, so 'bindSequence()' is now DEPRECATED. 'binding.bindSequence(key1,key2,...)' can now be replaced with 'binding.bindTo([key1,key,...])', and will produce the same results.
'naming.IBasicContext.lookup()' and 'naming.lookup()' now accept a 'default' argument, similar to that used by 'lookupComponent()' and most other lookup-like APIs in PEAK. This change was made so that component lookups don't need to rely on catching 'exceptions.NameNotFound' errors to tell them when to use the default value. This could hide 'NameNotFound' errors that were actually from a broken component somewhere in the lookup process. (In general, it's probably a bad idea to have an exception that's used for both control flow and real errors!) Also, removed most trapping of 'NameNotFound' errors throughout PEAK, except for those in N2, which I'll leave for Ty. :) Last, but not least, cleaned up documentation of related interfaces/methods.
Added new 'version' tool that automatically edits files to update version information in them. Just execute the 'version' file in the main PEAK source directory. (Use '--help' for help.) You can use this tool with your own projects by creating 'version' and 'version.dat' files in your project directory, similar to the ones used by PEAK. The 'version' file is a ZConfig file that describes your project's version numbering scheme(s), formats, and the files that need to be edited, while the 'version.dat' file contains the current version number values. Source for the tool, including the configuration file schema, is in the 'peak.running.tools.version' package. (Error handling and documentation, alas, are still minimal.) Also, bumped PEAK version stamps to 0.5a3, using the new tool. (Yay!)
Added new 'Alias' command in 'peak.running.commands'. An 'Alias' instance can be used as a 'peak.running.shortcut' property that expands to another command with arbitrary arguments inserted before the original command's arguments. Thus, one might alias 'mycommand' to 'runIni somefile --option', similar to command aliases in many shells.
Fix errors in a participant's 'abortTransaction()' from causing the overall abort operation to break.
Fix not closing SQL cursors when transaction aborted.
Misc. peak.binding cleanups and DEPRECATIONS, as follows: - The following 'binding' forms are now deprecated, and will go away before 0.5 beta is released: 'bindToProperty(x,y)' -- use 'bindTo(PropertyName(x),default=y)' 'bindToParent()' -- use 'bindTo("..")' 'bindToSelf()' -- use 'bindTo(".")' 'bindToUtilities()' -- no replacement; let me know if you're using this. - 'naming.IName' is now derived from 'binding.IComponentKey', so names and addresses must now support the 'findComponent()' method. All PEAK name and address types provide support for this. - The 'lookup()' method of 'binding.IComponentKey' is now called 'findComponent()', to better distinguish it from 'lookup()' in 'naming.IBasicContext', which does something very different. - 'binding.bindTo()' and 'binding.bindSequence()' now pre-adapt their arguments to 'IComponentKey', to speed lookups at runtime, and to ensure that errors due to an unusable parameter type occur at class creation time instead of waiting until lookup time.
Fix problem found by Yaroslav Samchuk: The logging system would raise an error if a log message with no arguments contained a '%' sign.
There's a new 'peak.storage.files' module, with handy classes like 'EditableFile'. 'EditableFile' is a class that lets you edit the contents of a file "in place", with atomic replacement of the original at transaction commit. If the transaction is aborted, the original file is left unchanged. Also, added 'delete()' method to standard 'openable.FileFactory' objects, and changed 'FileFactory.getObjectInstance()' so that new instances created from references use their retrieval context as a parent component.
Move signal management to UntwistedReactor, for better compatibility with Twisted's signal handling. Add 'installSignalHandlers' argument to 'run()' method, for the same reason.
'peak.running.scheduler.UntwistedReactor' now supports a configuration property ('peak.running.reactor.checkInterval') to determine how long it should run 'select()' calls for, when there are no scheduled tasks. Also, fixed reactor needlessly sleeping for the defined check interval, when there are neither scheduled tasks nor I/O handlers. This is important for Windows, where signals (e.g. ^C, BREAK) aren't processed during 'sleep()'. (Of course, this'll also burn CPU in a tight loop, but hey, it's Windows, and you won't have anything important running there, right?)
'peak.running.scheduler.MainLoop' now supports using a "signal manager" component (via the 'peak.running.signalManager' property) to process signals while a 'run()' loop is in progress. Signal managers can also be added or removed at any time via the new 'peak.util.signal_stack' module. Also, fixed scheduler tests using an app object without a config root.
'peak.running.commands.AbstractCommand' now offers a '_run()' method that can be overridden in subclasses, instead of 'run()'. If you override the new '_run()' method instead, you get the advantage of automatic handling for invocation errors and 'SystemExit' exceptions, provided for you by the 'run()' method.
Forgot to include CHANGES.txt in the checkin.
Update CHANGES.txt to describe 'PropertyName.fromString()' constructor.
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 '_', by supplying 'force=True'. This doesn't address syntactic issues (like having a non-terminating '*'), or character sets (non-ASCII characters are still rejected). But it's convenient for things like filenames or text that might contain spaces. Used this new ability to fix the SQL typeMap problem when spaces appear in SQL type 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. I also moved the 'EigenRegistry' class from 'peak.util.EigenData' to 'peak.config.registries', as it hasn't really been useful outside PEAK for a while now.
Added "smart properties" support, w/tests. You can now use 'naming.LinkRef' and 'naming.Reference' in .ini files and have them work, even without using peak.naming to look up the properties. Also, it should be possible to create useful caching rule objects, such as we will need for peak.web templates. Also, fixed a typo in peak.naming.arithmetic that caused certain name subtractions to fail.
Fixed 'peak.util.imports.whenImported()' function, so you can now register functions to be called when another module is imported. This should be useful for declaring adapters for external types, e.g. adapting Zope interfaces to IConfigKey, without causing the external type to be imported unless it's actually used.
Got rid of the 'adaptTo' requirement for retrieving objects from naming contexts. Note that if you have defined any URL schemes that do not also define a naming context class, you will need to revise them. Specifically, you need to add a 'defaultFactory' attribute referencing the name of the class of object that the URL should retrieve, and you need to have that class declare that it (not its instances) provide 'naming.IObjectFactory', and add a 'getObjectInstance()' classmethod to do the dirty work. If your URL scheme references a subclass of ManagedConnection, you don't need to do the object factory stuff, however, as it's already done for you in the ManagedConnection base. All you need is the 'defaultFactory' attribute. Also, if you defined any adapter declarations for your URLs to the target class, you should get rid of them.
Property definition rules in an .ini file can now refer to 'rulePrefix' and 'ruleSuffix' variables. 'rulePrefix' is a '.'-terminated string, representing the name the rule was defined with. For example, if the rule was defined for '"foo.bar.*"', then 'rulePrefix' will be '"foo.bar."'. The 'ruleSuffix' will be the portion of the 'propertyName' that follows 'rulePrefix'. So, if looking up property '"foo.bar.baz"', then the '"foo.bar.*"' rule will execute with a 'ruleSuffix' of '"baz"'. This should make it easier to work with hierarchical property namespaces.
Brought CHANGES.txt up-to-date.
Forgot to check this in with the PEAK_CONFIG change.
Added preliminary DM implementations for "Bulletins" app, and 'adduser' and 'showusers' commands. Also, changed 'storage.EntityDM' to supply a default implementation of the '_defaultState()' method.
Added Python/Zope 'datetime' package.
'peak.web' is born; just interface sketches and a draft of 'BaseInteraction' for now. CGI support has been moved from 'peak.running.zpublish' into 'peak.running.commands' (for "raw" CGI/FastCGI) and 'peak.web' (for the PEAK high-level publishing framework). You can use 'peak CGI someName' to adapt 'someName' to a 'running.IRerunnableCGI' and run it as a CGI/FastCGI. This will form the basis for creating the web version of an app later; you'll do something like:: class MyAppAsCGI(web.CGIPublisher): app = binding.New(MyAppClass) And then use 'peak CGI import:somepkg.MyAppAsCGI' to run it. Or, if your app wants to exec a config file, you might define your CGIPublisher subclass as an adapter from MyAppClass to IRerunnableCGI, rather than invoking it directly.
Added attribute name -> permission mappings for both declaration and checking. Added complex scenario-driven tests based on a data-driven permissions model.
Doc fixes: name -> attrName.
There is now an interface for "Active Descriptors": 'binding.IActiveDescriptor'. 'peak.binding' now uses this interface to identify active descriptors, so you can now create your own. (Previously, 'peak.binding' used 'isinstance()' to detect active descriptors.)
The naming system base classes no longer use 'attrs' as an input parameter or return value. If you've subclassed anything from 'peak.naming.contexts', note that your '_get()' methods should now just return the lookup value, rather than a 'state,attrs' tuple. For most naming contexts, this just means you should change 'return foo, None' statements to just 'return foo'.
'peak.naming' no longer automatically converts all addresses to the addressed objects. You must specifically request the interface you want by adapting the retrieved object to that interface. This can be done by supplying an 'adaptTo=ISomething' keyword argument to the attribute binding definition or your 'lookupComponent()' call. The naming system no longer has 'objectFactories' and 'stateFactories'; these have been replaced with adaptation. Writable naming contexts must have a 'serializationProtocol' attribute specifying what interface an object should be adapted to before attempting to store it in that context. The naming system no longer processes the 'creationName' keyword argument; this is now considered the sole responsibility of 'peak.binding'. The 'IComponent.lookupComponent()' method still accepts the keyword argument, and attribute bindings still handle the creation name transparently. It is just not available via naming system APIs, and naming contexts no longer have to deal with it. Also, removed 'naming.ParsedURL'; it was deprecated as of 0.5 alpha 2. (Note: 'smtp:' URLs are currently broken, in that we don't have an interface to adapt them to for retrieval, and I didn't want to create an SMTP naming context, since what we want to do with SMTP is still up in the air.)
All 'peak.binding' APIs now only accept positional parameters for items unique to that API. Items common to multiple APIs (such as 'offerAs', 'doc', 'attrName', etc.) should now be supplied as keyword arguments. Bindings also now automatically "suggest" the containing object as a parent component for the contained object, whenever a value is assigned to them or computed. If a non-None 'adaptTo' is set on the binding, the value assigned or computed will be adapted to the specified protocol before the parent component is suggested. 'binding.New()' no longer relies on the 'IComponentFactory' interface, but instead uses the new adapt/suggest mechanisms. Previously, parent components were only "suggested" when a binding was set via component constructor keyword arguments. Now, this is done at any time bindings are set, but *not* for non-binding keyword arguments. In other words, ordinary attributes of a component do not receive "suggested parent" notices, even when set via constructor keyword arguments. If you want an attribute to do this, you must define the attribute with the binding API; e.g. via 'requireBinding()' or 'binding.Constant()'.
The 'provides' keyword argument to various 'peak.binding' APIs has been renamed to 'offerAs', and it must be a sequence of configuration keys. (Previously, it accepted either a single key or a tuple of keys.) The signature of 'binding.Constant()' was changed as well; the first positional argument is now the constant value, and 'offerAs' is now a keyword argument. (Previously, 'provides' was the first positional argument of 'binding.Constant()'.) The 'registerProvider()' method of 'config.IConfigurable()' also now accepts only a single configuration key, as does 'EigenRegistry.register()'.
Fix HTML formatting of CHANGES file
Misc. doc cleanups/enhancements. Added info on 'invoke' command.
Finished URLChecker and FileCleaner demo daemons; updated CHANGES and TODO.
Fill in some items I missed documenting while I was focused on PyProtocols.
Misc. edits preparing for 0.5a2
Added a ZConfig schema for 'running.commands.EventDriven' applications, a ZConfig component definition for adaptive tasks, and a running shortcut called 'EventDriven'. It should now be possible to do this:: #!/usr/bin/env peak EventDriven at the top of a ZConfig file formatted according to the new schema, and have it run. Unfortunately, so far the only type of task that can be included is 'running.daemons.AdaptiveTask', which doesn't actually *do* anything. So, right now doing this is equivalent to creating an over- engineered 'sleep' command. ;) Also, fixed a problem in ZConfig 'schema.dtd'; I used 'PCDATA' where I should've used 'CDATA', and I fixed various problems with the 'fromZConfig()' component constructor. It's kind of annoying that ZConfig defaults unspecified items to 'None', even if you said they weren't required and had no default. :( I'll see if I can do something about this later; for now I just delete 'None' values from the data.
Added ZConfig URL support. ZConfig schemas and files can be loaded from any PEAK-supported stream URL, including 'pkgfile:'. Interfile references aren't tested yet, nor are there any unit tests. Those will be added once we have some meaningful schemas and configurations to test with. There is a 'zconfig.schema' URL scheme that loads a command interpreter, and a 'peak ZConfig' option as well. See 'CHANGES.txt' for details on the new features. Also, fixed up some issues with the 'fromZConfig()' component constructor. All we need now are some useful base schemas for daemons, and the last piece for 0.5a2 (besides PyProtocols) will be in place.
Standardized file-based URL syntaxes (e.g logfiles and lockfiles) to follow RFC 1738/2396, and Python 'urllib'. This shouldn't affect much besides the canonical forms of the URLs. Added 'pkgfile:some.pkg/filepath' URL syntax for ease of referring to files near modules. (A convenience intended mainly for referencing ZConfig schemas.)
Added the UML 1.4 metamodel, and thus the ability to load UML 1.4 models encoded in XMI 1.1. Added support in the mof2py code generator for "unprefixing" enumerated values, so that UML and other metamodels' enumerations work correctly when loading from XMI. Fixed source distributions missing essential setup files. Rescheduled UML 1.5 and CWM support to version 0.6. Hardly any tools use UML 1.5 yet, and we can't do anything useful with CWM until we have XMI writing, and some type of UI for editing models.
Finished switchover to using protocols.advise() API to declare interfaces.
Began the move of 'peak.interface' to a separate 'protocols' package for ease of distribution independently of PEAK. Also, removed caching of success/failed adapter lookups, because there was no way for them to be cleared when declarations were made for base classes of a class whose lookup was cached. (To do caching, I'll have to add a separate cache.) In the next pass, I'll add the new declaration API that Ty and I designed, and then change PEAK to use it, factoring out the interim API, and changing the few remaining introspections in PEAK to work via adapation. Then, it's off to documentation, unit tests, and packaging for the 'protocols' package.
Made interfaces thread-safe for registration. Added more interfaces to explain the interface of the interface package. :) Refined adapter comparison algorithm to better understand the "distance" between protocols. Removed classic-class adapter, since protocols now do reasonable caching for classic MRO's and subtypes.
And so we bid a fond farewell to introspection as well. 'isImplementedBy' is now a thing of the past. Refactored anything that used it, to now use adapt(), which has now opened up a lot of extension possibilities in places that were previously not extensible without modifying PEAK core code. See below. Also, the interface module has been refactored to support 'classProvides()' in a clean and kludge-free fashion, along with support for faster adaptation of old and new-style classes (by caching lookups, and by safely adding '__conform__' methods to classic classes), and the ability for classes to manage their own "implements" information. The core interface code is now quite elegant in the way it uses its own adaptation system as the basis for implementing adaptation. :) 'binding.Acquire()' now accepts a 'default' value argument, and 'binding.New()' no longer accepts the 'bindToOwner' flag. There is a new 'binding.IComponentKey' interface that is used to implement 'IComponent.lookupComponent()'. Now you can implement this interface, or create an adapter for it, in order to make an object usable as an argument to 'binding.lookupComponent()' - and therefore usable as a key for 'binding.bindTo()' or 'binding.bindToSequence()'. Not that it's necessarily very useful to do so; you're probably better off simply creating a naming scheme. But it might be useful for lookups done in the context of classes, since naming schemes aren't usable there. (It was actually added in order to factor out all the type testing that 'lookupComponent' used to do, so it doesn't matter if it's useful for much else.) PEAK has been refactored to avoid the use of 'isImplementedBy()' and similar introspection, in favor of 'adapt()'. As a result, some 'peak.naming' interfaces have changed. This should not affect you if you are only subclassing PEAK-provided naming components and not implementing these interfaces "from scratch". However, the various 'isAddress', 'isAddressClass', 'isResolver', and 'isName' APIs have also been removed, as they were based on 'isImplementedBy()'. The ability to use 'isImplementedBy()' with interfaces declared by PEAK is REMOVED. You can still use 'isImplementedBy()' with Zope interfaces, of course, but we recommend you switch to 'adapt()', which will work with both PEAK and Zope interfaces.
Added transitive adaptation: declaring an adapter "AB" from A to B, and "BC" from B to C, automatically implies adaptation from A to C via BC(AB()). Used it to simplify the mechanism for adapting an IExecutable to an ICmdLineAppFactory. Refactored some of the interface package's initial kludges to cleaner mechanisms based on adaptation. Learned some interesting things along the way... Classic classes don't have __mro__, which made adapt() break on them. The technique I was using in the hopes of suppressing unwanted TypeErrors suppressed wanted ones, and meanwhile there weren't any unwanted ones in PEAK. Finally, Python 2.2 doesn't support 'super()' access to properties, and metamethods are properties, so you have to use my new 'supermeta' to work around this when you need to call a super() metamethod. This is supposed to be fixed in Python 2.3, but not backported 2.2 because Guido considers it a "feature". Ah well.
Farewell, 'zope.interface'. You served us well.
__implements__ is dead, long live implements()! We are also no longer using 'zope.interface', but instead using a complete, interoperable replacement for it. Also, tweaked a few things so that using pydoc or 'help()' on PEAK component classes and interfaces now works halfway decently, as opposed to producing tracebacks (or dumping core!). 'zope.interface' will soon be removed from the PEAK distribution altogether. See CHANGES.txt for details of why this replacement was created.
DEPRECATED use of '__implements__' and '__class_implements__' to declare support for interfaces. Use 'implements()', 'classProvides()', 'directlyProvides()', 'moduleProvides()', etc. to do this now; they are now available automatically from 'peak.api'. Please note that alpha 2 will *not* support the use of __implements__ attributes at all! Start using the APIs for this *now*, even if you're using alpha 1 (which at least supports the 'implements()' and 'classProvides()' functions).
'EigenRegistry' and 'PropertyMap' no longer attempt to figure out whether implied (i.e. inherited) interfaces are more or less general with respect to a previous registration. This was behavior that emulated Zope adapter registries, but what we really wanted was more akin to a Zope "type" registry. The only parts of the test suite that used the old behavior were the tests specifically written to ensure that behavior! Also, changed the implementation of '__class_provides__' so that the registry becomes immutable as soon as it is computed by the class.
Fixed 'naming.lookup()' and related APIs not setting the parent component of created objects without an explicitly supplied 'creationParent' keyword argument. This used to "sort of work" when we had implicit configuration parents, but was broken when we went "all explicit" for 0.5 alpha 1. Also, fixed SPI-level calls that didn't go through "paramegeddon": 'getObjectInstance()', 'getStateToBind()', and 'getURLContext()' weren't following the "parent/context goes first" signature convention.
'binding.bindTo()' now accepts a 'default=' argument, whose value will be used in case of a 'NameNotFound' error.
Removed regular expression support from URL.Base; it was only there for ease of migration while I was switching all of PEAK's URL classes over to the new parsing framework. Since use of regular expressions for URL syntax is now deprecated (so that URLs can be formattable as well as parseable), there's no reason to keep this in URL.Base. Added the ability for other name types (composite and compound) to be used as structural feature types (e.g. for URL fields), and for compound name types to generate a corresponding composite name type. Changed LDAP urls to use this ability, which means the LDAP 'basedn' field is now always a composite name.
Misc. doc edits
Refactoring to support "canonical formatting" of URLs. This required creating a sizeable parsing/formatting framework. :( On the brigher side, the framework is highly powerful and expressive. Potentially it could be pulled out as a 'peak.model' parsing framework, to be reused for other parse/format applications on model elements that have a single canonical string syntax. It would probably need to be reviewed for Unicode compatibility, however. Anyway, now printing a parsed URL object should give you back a canonical form of that URL; equivalent URLs (apart from case-sensitivity issues) should produce identical canonical forms. Passing keyword arguments to a URL constructor should also allow you to selectively override the URL body content, making it easy to produce new versions of a URL with an altered field.
Repoint 'ParsedURL' -> 'URL.Base'; this will let existing 'ParsedURL' subclasses continue to work for a while, until 'ParsedURL' is removed in alpha 3.
Began work on replacing 'naming.ParsedURL' with a structure type using 'peak.model'. See 'CHANGES.txt' for a summary of how your ParsedURL subclasses must be changed. There is a further refactoring coming, however, to support simpler parsing mechanisms for complex URL syntaxes, and to support URLs generating a "canonical form" body part. This will be important for robust comparison of URLs, path manipulation, etc.
Added 'binding.whenAssembled(...)' as syntax sugar for 'binding.Once(...,activateUponAssembly=True)'.
Implemented log system refactoring; also added tests for misc. URL schemes. See CHANGES.txt and my mailing list post for details.
Finally got rid of 'x.__class__.foo(x,...)' hacks! Now, if a metaclass needs to have a method that one of its instances might also have as an instance method, you can wrap it with 'binding.metamethod(foo)'. This is nice and clean because it doesn't force every caller of the 'foo' method to try and guess whether it's working with a class or an instance. Even nicer, this solution requires no special work by the person writing these methods, unless the method is going into a metaclass, and even then they need only wrap it with 'metamethod'. Last, but not least, this cleans up some of our __class__ usage so that we'll be able to work correctly with 'zope.security'. As far as I know, the 'x.__class__.foo(x,..)' trick wouldn't have worked consistently when 'x' was a proxied object, whereas a normal call to 'foo' would properly pass through the proxy barrier as long as the caller had permission to access 'foo'. (Note: at the moment 'foo' translates to the 'getParentComponent', '_getConfigData', 'getComponentName', and 'notifyUponAssembly' methods.)
Updated change log.
Made 'NOT_GIVEN' and 'NOT_FOUND' recognizable by humans (they 'repr' and 'str' to their names) and by Python (they can be pickled, and when restored they come back as the same object).
Fixed a formatting error for the online API reference (now up-to-date at http://www.telecommunity.com/PEAK/doc/). Of course, it's only as complete as the docstrings to date. :(
Changing docs from TransWarp->PEAK, referenced new site at http://www.telecommunity.com/PEAK/, prepping docs for 0.5a1 release.
Added 'TWX' package for extensions; added 'TWX.Diagrams.GraphViz' diagramming utility module. Very hacky and first-draft, with no unit tests, but I've manually verified most of the functionality so far.
Added support for pickling instances of nested classes; this required changing all uses of '__name__' which needed an unqualified class name. Notably, one should use 'feature.attrName' instead of 'feature.__name__' in verb definitions.
SEF.DynamicBinding is now SEF.AutoCreated, and all AutoCreatable classes like SEF.App and SEF.Service must now have an '__init__' method that accepts their SEF parent component. This lets such objects have access to the SEF hierarchy during initialization. (Note that this means any '__init__' methods of such classes must be revised to take this into consideration. See TW.Database.DataModel.Database for an example of such a revision.) Also, I dropped the unused SEF.StaticBinding class.
'setupModule()' and 'adviseModule()' will now issue warnings for most questionable code structures and variable redefinitions that might not work the way you'd expect or intend under module inheritance.
Added tests and documentation for 'adviseModule()' API
Added a 'test' command to 'setup.py' that installs and then tests all of TransWarp. (It saves me time running the unit tests while I'm writing new code.)
Added warnings for detectable module-level modifications of mutables in modules which are used for inheritances or advice. Added an API function, 'configure(object, attr1=val, attr2=val,...)' to safely set attributes of mutables that might have been defined in a derived module. Also, misc. updates to TODO.
Removed 'Meta.ClassInit' and '__class_init__' support. Use metaclass '__init__' methods instead; see 'TW.Database.DataModel.RecordTypeMC' for one example of the conversion.
Improved key integrity checks in DataModel: Record objects now disallow modification of key fields unless the old value is None, and cache collisions between records with supposedly unique keys will result in an AssertionError. Also, made the requirement of an LDAPConnection object more visible in Database.LDAPModel, and made misc. CHANGES/TODO updates.
Added 'SET' method (ala WarpCORE's set_X procedures) to TW.Utils.MiniTable.
Added more docs to TW.Utils.Code, and removed 'iterFromEnd()' method from code objects. Added experimental 'nextSplit' index to codeIndex objects that does top-level block analysis to allow splitting a code object into smaller routines.
Fixed the "reference to rebound class within another class" problem with module inheritance, as reported by (who else?) Ulrich Eck. :)
New-style features have landed! Lots o'docs and examples. CHANGES and TODO have been updated accordingly. Enjoy.
Fixed misc. bugs in DataModel, LDAPModel, Connections, and TW.Caching found by Ulrich Eck. Thanks Ulrich! Also, added a fix to ensure that non-existent records are invalidated by RecordType.getItem().
* Added basic Specialist implementation to 'TW.SEF.Basic', and reverted naming from 'TypeService' and 'ITypeService' to 'Specialist' and 'ISpecialist'. Updated 'TW.SEF.Interfaces' to reflect "self"-less convention for documenting methods. * Dropped obsolete 'TW.Database.Records' module.
Many changes in preparation for 0.2 final, including: * Added 'SEF.bindToParent()' and 'SEF.bindToNames()' specifiers to allow more flexible component parameter bindings. * Fixed the base class "rebind by name" bugs in module inheritance, and updated the documentation to more clearly reflect what it is that metaclass generation and module inheritance does and does not do. Added test cases to prevent regression of the rebind-by-name problem. * The 'setup.py' script features a new command, 'happy', which can be used to generate the API reference docs, and this command runs as part of the 'sdist' command to build source distributions. * The API reference docs in the source distribution has been moved from the 'doc' directory to 'docs/html/reference'. * Added 'CHANGES.txt' file.
Powered by ViewCVS 1.0-dev