No default branch
Bookmark a link to HEAD: (view) (download)
Get rid of a bunch of completed or cancelled to-do items. This really isn't an accurate reflection of the long-term direction of PEAK any more, so it really needs more work. But for now I might as well remove the done's and the definite won't-do's.
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.
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.
Fix 'version' tool breakage caused by promotion of running.tools; misc. release prep.
Renamed old 'ddt.web' to 'ddt.view', and added new 'ddt.web' that publishes a directory of test documents. So, using:: peak ddt.web src/peak/ddt/tests would display a list of test documents in your browser, letting you click on the documents to run the tests and display the results.
Added tests for Twisted, upgraded Deferred adapter to support 'IValue' and other event interfaces. It's a little quirky, but about as clean as I can figure out how to make it.
Port process management tools to use 'peak.events' for everything (except 'IMainLoop' methods).
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 rough draft of 'RowProcessor'. Expanded 'ICellMapper' interface to cover new needs, and refactored mapper implementations to inherit from a common base for most of their methods. Added 'Score.__nonzero__' method, so that you can use 'if cell.score:' to tell whether a cell has already been marked.
Major upgrades to DDT package: * Added 'ICellMapper' interface to allow introspective actions on objects, with adapters predefined for methods, properties, and 'model.IFeature' objects. * Added 'MethodProcessor' and 'ModelProcessor' (test), and 'ActionProcessor' (not yet tested) * Lots and lots of docstrings added * The 'HTMLDocument' DM now always strips leading/trailing whitespace from cell text. * New functions 'ddt.titleAsMethodName()' and 'ddt.titleAsPropertyName()' for standardized parsing of certain types of cell data. * Updated demo classes to use both 'MethodProcessor' and 'ModelProcessor' * Fixed 'Cell.assertEqual()' to normalize its input value to the same type that it's interpreting the cell as. This effectively allows the fallthru comparison case to be 'str(value)==cell.text', when the "official" type for the cell is unknown. * Fix 'ddt.web' runner to work properly when serving a single file as the root. (We probably also need some way for this to support a convenient run-once-and-exit strategy.)
Implemented boolean operations on 'events.IConditional' objects, and added 'isTrue' and 'isFalse' event sources to 'IValue' objects. So now you can do things like 'yield aCondition & otherCondition' to wait until two conditions are true. Unfortunately, it is possible to have a race condition if some code sets 'aCondition' to true before setting 'otherCondition' to false, in that as soon as both are true, the waiting thread would resume. Sometimes this is what you want, and sometimes not. I'm beginning to wonder if one needs a sort of "transactionality" to events, so that one can set a variety of values or conditions, and *then* allow the callbacks to fire. But that will require some further thought.
Made better distinctions between Value and Condition behaviors, and added ability to easily adapt from one to the other. Added 'events.subscribe()' to allow automatic re-subscription to a source, with automatic or manual cancellation (automatic happens if the subscriber goes away). Revised derived values and all types of conditions to work via delegation rather than inheritance, making use of 'events.subscribe()'. We're now in a lot better shape for adding logical operations on conditions and making it easier to derive conditions or values from other conditions or values.
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.
Allow threads to have an exception raised if an event occurs while a nested generator is running. Added 'IScheduler.alarm()' and 'events.Interrupt'.
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.
Added draft 'ISelector' implementation, and refactored 'UntwistedReactor' to use it for I/O events.
Minor TODO additions.
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.
Fix 'setup.py' not installing 'csv.py'.
"csv" and "csv.<dialect_name>" cursor formaters using csv module. Issues: - end-of-line character handling. Right now n2 output redirection always gets you text mode. force csv line terminator to "\n" so you get local newlines for now. But what about binary output formats? Do we need some kind of binary-mode redirection operators? - dialect defaults for delimiter, etc are not overrideable by n2's go command line options. (problem? should "go -m csv -d "\t" work the same as "go -m csv.excel-tab"?) - csv.py not installed by setup.py? (haven't looked into it yet)
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.
Updated TODO with current a3-cycle plans.
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.
Fix win32 using 'time' instead of 'clock' for elapsed time.
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.)
Finished out timer service with wildcard 'addListener()' support, and a 'timer:foo.bar' URL scheme, so you can now 'Obtain("timer:myapp.whatever")' in your applications. Of course, to be really useful, we need some listeners that can log or otherwise output the statistics. And I'm still planning to move the time-critical parts of the Timer class to Pyrex. But the timing framework itself is now complete and ready-to-use.
Significant refactoring of skin/layer/resource/interaction/service classes in 'peak.web'. Primary goal was to allow layers to be shared between skins, but several other things were also accomplished: * Got rid of properties to configure services and factories, using "[Component Factories]" mechanism instead. * Added explicit interfaces for auth/skin/layer/resource services * Interaction and InteractionPolicy implement various services by delegation, so things like 'interaction.skin.getResource()' are now 'interaction.getResource()' and 'policy.skinSvc.getSkin()' is now 'policy.getSkin()', etc. * Cleaned up various "spaghetti bindings" that wandered all over the place. * Added 'IInteractionPolicy.newInteraction()' for cleaner creation of interaction instances. * Added layer service mechanism to allow layers to be reused among skins. Layers are defined in the 'peak.web.layers' property namespace. * Added skin service mechanism that locates skins using 'interaction.skinName' (which defaults to '"default"'). Skins are defined in the 'peak.web.skins' property namespace. * Simplified 'config.CreateViaFactory' to allow factories with no arguments.
Fixed 'text' DOMlet not XML-quoting output. Added 'xml' DOMlet for outputting already-quoted output. Added 'notag', 'text.notag', and 'xml.notag' variants that throw away their opening/closing tags. 'notag' does nothing except throw away the open/close tags, which is useful when 'pwt:define'-ing a block that has multiple elements in it, among other things. With 'text.notag' or 'xml.notag', you can now embed text in other text without needing to keep the "span" in the output.
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.
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.
Give peak.running.tools a promotion... it's now just peak.tools
Firm up the plans for 0.5a3 a bit.
Clean up __repr__'s for bindings, for convenient use of help() and other documentation tools.
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.
Semi-futile attempt to fix up the tutorial for the new binding API. We're probably going to have to scrap the tutorial altogether soon, it's aging far too rapidly relative to the capabilities of the codebase. :(
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.
Misc. TODO updates
'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.
Got rid of worst remaining 'isinstance()' occurrences in binding and naming; updated TODO.
Misc. TODO additions
Introduce peak.net for implementations of network protocols and other general networking-related features that don't really fit into storage, naming, etc. Also, an icb protocol implementation work-in-progress. ICB ("Internet CB") is an ancient chat protocol that's not widely used anymore except in some circles. This is more of an example than something likely to be useful by many people, but I have a use for it. Still needs work, though.
Split up items into alpha 3/alpha 4 releases, many more details, removed a few completed items.
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'.
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()'.
Finished URLChecker and FileCleaner demo daemons; updated CHANGES and TODO.
Removed items that were completed, redundant, or became non-goals. Also some minor rescheduling and feature additions.
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.
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.
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.
Farewell, 'zope.interface'. You served us well.
Misc. doc edits
Added 'fcgiapp' to distribution; this should be the final checkin for 0.5a1, barring any bug or doc fixes that come up while prepping the release.
Paramegeddon! Adjusted API signatures so that all calls that have a context component, have it as the first parameter. Changed functions, methods, and classes are: * binding.acquireComponent() * binding.lookupComponent() * config.getProperty() * config.findUtility() * config.findUtilities() * config.PropertyMap.getValueFor() * config.IConfigSource._getConfigData() * config.PropertySet() * naming.lookup() * naming.parseURL() Also, renamed 'config.LazyLoader' -> 'config.LazyRule' to reduce confusion with 'storage.LazyLoader', which has a very different purpose/function.
Tutorial edits to sync w/current API.
Stamp out '_provides', replace with 'declareAsProviderOf'. Removed extraneous '_provides' declarations left over from the days when classes could effectively be their own 'binding.New'. I decided not to document the interface of attribute binding objects at this time, because the implementation is tied to the classes right now anyway. Also, misc. TODO edits.
Finished adding tests for daemons and schedulers.
Added one more "assembly events" test case. Updated TODO to reflect what I hope is the final release checklist for 0.5a1.
Moved ZConfig integration from 0.5a1 to 0.5a2; there's just not enough time for it to make it in this week. The remaining unit tests, doc fixes and misc. cleanups are more important for this iteration.
Barring any emergencies, we should reach 0.5a1 within a week. Updated TODO to reflect current status; adjusted stream factory signatures so that 'autocommit' is only required to be specified for non-readonly operations.
Misc. TODO updates. 0.5a1 looms nearer!
Began update of TODO to match current 0.5 alpha release plans
First draft implementation of system scheduling proposal. (Also, misc. TODO additions.) Interfaces have been streamlined and names changed. Daemons are now "periodic tasks", and the provided base class implements an "adaptive task" interface. "Daemonic app", "event loop", and "daemon scheduler" are now just a single "system scheduler" interface, which can schedule periodic tasks as well as one-offs. I settled on "higher priority number" = "higher priority" for priority sorting. I'm beginning to like this whole "asynchronous programming" model that Twisted provides. AdaptiveTask (formerly BaseDaemon) is a lot simpler, MultiDaemon went away, and the system scheduler is only two screens of code to manage idle timeouts, prioritized task scheduling, and more. Heck, "shutdown after X" was as simple as 'callLater(duration,self.stop)'! There is one minor problem in this draft... if a task raises an unhandled exception, it won't be scheduled for further re-run. I'm not sure if this is a bug or feature yet. It should be easy to fix, though.
REINSTALL WARNING: a package was removed from setup.py on this change, so be sure to *delete* your PEAK installation from 'site-packages' before reinstalling. Also be sure to update your checkout with 'cvs update -dPA'. Change notes: * It's now possible to use 'config.declareModule()' to patch third-party (i.e. non-PEAK) modules, and also to pre-declare inheritance or patch data for modules inherited via package inheritance. This was done to make PEAK/Zope reusage/patching easier, and also to ease patching of large generated-code models (like UML and CWM). * The patches to add "Pythonic features" to UML models are now in a separate module, 'peak.metamodels.core_addons', so that they can be shared amongst all UML versions. This was made possible by the new 'declareModule()' function. * Cleaned up and removed the now-unnecessary subpackage of UML13 that was there just to provide a home for the patches that can now be applied by "remote control", so to speak. * 'lazyModule()' now has an extra parameter that can be used to hook the initial loading of a module. This was added so that 'declareModule()' can patch modules when they are loaded.
Got rid of deprecated 'peak.model' classes: Model, Package, Reference, etc.
Partial cleanup of '__class_provides__'; now it's supplied by the most basic metaclass (Activator), instead of being poked in by 'Once' attributes after the fact. There probably really should be a 'registerAttribute' interface method or something for this, but at least now it's not *too* unbearably ugly.
Added basic plans for 0.5a1 (bugfixes, cleanups, and XMI writing), and 0.5a2 (runtime infrastructure enhancements such as ZConfig support, and dynamic class mixins).
Removed some completed or no longer applicable "future" items.
Removed misc. completed, outdated, or redundant TODO items.
Added type conversion support for 'ManagedConnection.txnTime'.
Added FacadeDM - a data manager that "fronts" for other DM(s) via a different key: just override its 'retrieve()' and 'oidFor()' methods.
Support disjoint collections as allowed by the XMI spec. Misc. TODO updates to remove stuff recently accomplished.
Added lazy load for persistent object attrs and implemented QueryDM base class by refactoring EntityDM into QueryDM and EntityDM. Similarly split interfaces into IDataManager and IWritableDM.
Added LDAP field type converter support, with unit tests. This uses the 'peak.ldap.field_converters.*' property namespace, looking up the field names to find a converter (or import string thereof) that takes two arguments (name and value) and returns a replacement value. The value passed in may be 'None' if no value was present in the retrieved data. Otherwise, it's a list of values returned from the LDAP directory (except for the 'dn' field, which is always just a string.) Converters are imported from within the peak.storage package, so we can add some "standard" converters and then reference them with import strings like '"LDAP.someConverter"'.
AbstractRack -> EntityDM
Misc. typo fixes
Fixed hard tabs in TODO.txt; updated re: Persistence package merge.
Update for current status
Misc. additions/clarifications of TODO list.
SQL error handling and joinTxn() shortcut * SQL errors are now logged; __traceback_info__ is set, although our current traceback formatter for logging doesn't use it yet. We also maybe should log SQL warnings at LOG_WARNING level instead of LOG_ERROR. * You can now supply joinTxn=(a true value) as a keyword arg to a SQL query executed on an SQLConnection, and the connection will join the transaction. This seems cleaner in actual use than a separate .joinTxn() call. * Fixed some issues with Gadlfy not implementing the full DBAPI - or even a decent fraction of it. :(
PropertyName -> peak.api; Improved lazy import facility * naming.PropertyName is now simply PropertyName; it never really had much to do with naming in the first place, doesn't depend on anything else, and needs to be accessible in all major subpackages and in end-user API calls. So now it's in-line in the peak.api module. * Added a 'lazyModule(moduleName)' function to peak.util.imports. This new "next generation" way of creating a lazily-loaded module actually creates an object that *will be* the real module in sys.modules, and once loaded will be indistinguishable from an ordinary Python module. (Well, under Python 2.3 the type() will be different, but you can't have everything.) I was getting really fed up of tracing into lazyImport.__getattr__ during debugging sessions, so I was inspired to come up with something that would only have code overhead when it's first touched. Subclassing ModuleType, adding a __getattribute__ method, and clever use of the Python 'reload()' function saved the day. * This now completes all the non-documentation items I want for 0.5a1, although I may "work ahead" a little on the features list, especially if Ty keeps pressing for SQL type maps and LDAP schemas. ;) (In truth, I'd like those and some of the other database features Real Soon Now myself.)
pgsql works, and txn integration tested. Also note that txnTime should be converted when we have SQL result type converters.
Added [Load on demand] rules section, and made running.clusters use it. Also added basic unit tests for peak.running.clusters.
Components now support names and paths: * Objects created by naming system lookup, binding.New(), or AutoCreated, can all now automatically receive information about their name as well as their parent component. * binding.getComponentName() gets an object's name or 'None' * binding.getComponentPath(c, relativeTo=None) gets an object's path from its root component, or as a relative path from 'relativeTo' (assumes 'relativeTo' is a parent of 'c'). Unknown names are rendered as '*' in the path. * Added 'binding.Acquire' after all. * Improved management of _p_jar/_p_oid by model.Element, using _p_jar as the parent component, and _p_oid as the component name for elements. * Added unit tests for name and path support.
Added some more to-do items.
Added more details and items to TODO so I won't forget them. :)
Reorgs and and misc. cleanups; updated TODO for 0.5a1 vs 0.5final Moved ActiveDescriptor(s) classes from binding.meta to binding.once and the rest of binding.meta to model.method_exporter. Moved the method-exporter tests that lived in metamodels.tests.General to model.tests, where they really belonged, and added model.tests to the install and API test suite.
Added working support for Gadfly. Misc. cleanups/fixes and TODO updates.
Reformatted peak.running.clusters docstring to structured text for better HappyDoc output. Defined the rule for 'peak.running.cluster._filename' in peak.ini instead of in the code. Renamed PropSet to PropertySet, and made it possible to go from a PropertyName to a PropertySet by calling '.of()' (e.g. 'PropertyName("foo").of(anObj)'. PropertySets can now reproduce in various ways, e.g.: c = PropertyName('peak.running.cluster').of(None) # -> PropertySet c._host['two.baz.com'] # ('even','prime','weird') c._groups() # ('odd','even','prime','weird','qux') But none of this is documented yet and possibly subject to change. :) (Especially since we're probably going to change how the cluster namespace works anyhow!) Ideally, it should be easy to go from a property name to its value or to a property set, and to go from a property set to a value in some namespace. Of course, it's somewhat questionable whether we'll be doing this for that many properties in the first place! And this is all going to go "full circle" once properties have a naming context that can be used to look them up in. I worry a bit about creeping TMTOWTDI-ism in all this. :(
Reverted the ability to omit schemes/bodies from parsed URLs, since that might violate the IName interface contract for URLs! Fixed a problem with _defaultScheme support. Made some notes in TODO about issues in the naming system that need review/investigation.
Made peak.model StructuralFeatures use a uniform API for manipulating object attributes, which will make it easier to implement "lazy load" attributes later, and made it easier to implement _p_change support, which was also added. IBindingAPI now includes _getBinding, _setBinding, _delBinding, and _hasBinding methods, and model.Element sets _p_changed when a modifier method is called. Also did some more TODO reprioritizing; it now reflects the 0.5 priority order much better, even though it still lumps items together by package.
* Added 'binding.Constant(key, value)', which allows you to specify a constant value to be used as a property or utility in that component subtree. * Added storage.get/begin/commit/abortTransaction() APIs for ease of use in short scripts. Defined a default provider for ITransactionService in peak.ini that provides each component root with its own TransactionService instance. It's easily replaceable with other allocation strategies, if it should be needed. I may change this later to a per-root strategy, since the current strategy requires creating localConfigs for each component root. We'll see what actual use has to say about the best way of doing it. * Fixed a problem with local/global config object startup that could cause "phantom" configuration objects to appear via recursion of getLocal() or getGlobal(). * Got rid of binding.meta.assertInterfaces, which is no longer needed because the Interface package now correctly handles metaclass instances. * Got rid of Singleton, since it's not used for anything and I could neither think of any use cases nor remember why I added it in the first place! * Made it possible for CachingProviders to cache per-localConfig as well as per-object. This is handy for implementing per-hierarchy services, like the TransactionService provider mentioned above. * Misc. TODO updates.
Made Model.Element Persistent. There is still an unresolved issue relating to mixing Persistent with other metaclasses under Python 2.2, however. Be wary of mixing Persistent with *any* PEAK class until it's fixed. :(
Added error logging to basic txn error handler. Fixed a couple of bugs exposed by the newly added error logging. :) Reorganized TODO to better reflect priority of remaining items, although it's not completely prioritized yet.
Re-org/refactoring of many items from the TODO list for 0.5, including: * moved peak.binding.imports -> peak.util.imports, added importSuite() * Decided not to do binding.Acquire, it should just be a documented idiom * Moved LDAP and lockfile URLs to peak.storage.LDAP and peak.running.lockfiles, respectively * Moved factories.getObjectInstance -> spi, updated peak.ini to load naming.spi as the provider. * Consolidated naming.references into naming.names * Made ParsedURLs compile their pattern strings, and automatically make their 'fromX()' methods classmethods (and the same is true for other 'struct' types. * Refactored cursors and connections out into distinct SQLCursor/LDAPCursor types, based on a common AbstractCursor. * Added TooManyResults/TooFewResults errors to peak.exceptions
Completed configuration files refactoring. Configuration files now can have [Load Settings From] and [Provide Utilities] sections, and property sections can now define rules instead of just values. Property values are eval()'d at rule access time rather than configuration loading time, and they have access to 'propertyMap', 'propertyName', and 'targetObj' locals, as well as the full peak.api.* and config_components' globals. "Load Settings From" sections can access a potentially infinite variety of sources for loading configuration data; the sources are defined using the 'peak.config.loaders.*' property namespace, and thus can be meta-configured even in the same configuration file. Builtin loader types are 'file' and 'mapping'. GlobalConfig no longer has any hard-wired configuration steps; everything is now in the peak.ini file. Subclasses of GlobalConfig need only perform 'self.config_filenames.append(fname)' before calling GlobalConfig's 'setup()' method, to cause additional config files to be loaded after 'peak.ini'. Everything that is configurable in PEAK, is now (in principle) configurable via property files.
Added more docs and a test to the FileParsing framework. Refactored AbstractConfigParser to make it easier to define how differently-processed configuration sections will be handled. Misc. TODO additions.
Added detailed plan of attack for 0.5 release. It's getting closer...
A first pass at cleaning up the TODO file. Also, removed the Specialist class and associated interfaces altogether, since Racks can serve all the same functions in PEAK. (Perhaps Rack should be renamed to Specialist, but that's a matter for future debate.)
'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 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.
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.
Fixed the "reference to rebound class within another class" problem with module inheritance, as reported by (who else?) Ulrich Eck. :)
Added some notes on ideas for what might go into version 0.3.
Moved TODO.txt out of the docs directory so HappyDoc will make an HTML file for it in the reference docs.
Powered by ViewCVS 1.0-dev