Re: [PyPerSyst-Devel] API documentation
Brought to you by:
pobrien
From: <po...@or...> - 2003-09-30 23:17:45
|
Donnal Walter <don...@ya...> writes: > Patrick O'Brien: > > Donnal Walter <don...@ya...> writes: > > > This page is not intended to be official in any way, but is > > > provided for discussion purposes only: > > > > > > http://mindwrapper.org/pps/ppsapi.html > > > > > > 1. Is the basic API as I have documented it accurate? What > > > changes are needed to make it so? > > > > I didn't scrutinize it, but for the most part it looks right. I > > did notice a couple of errors and omissions. First, you might > > want to mention the Entity oid attribute, as well as the root > > and extent attributes. > > Done. Please see if they look correct now. Looking good. > > Also, Extent.match is not an alias for search. Look at the > > Python re module docs for the differences between match and > > search. > > Yes, I see that now. Sorry I missed it before. No need to apologize. The search and match methods should refer to "The patterns parameter," not "The criteria parameter." > > > 2. Is the basic API stable? Are there any sections that might > > > be considered unstable? > > > > The basic stuff is pretty stable. The entity package is mostly > > stable, though I'm thinking of a way to make oid, attrs, links, > > extent, and root more separate from user-defined attributes, > > either by giving them a prefix, perhaps "sys_", or by putting > > them in their own namespace, perhaps as attributes of a "sys" > > object: entity.sys.oid, entity.sys.attrs, etc. > > What about putting the user-defined attributes in their own > dictionary, sort of like Root._branches? I've thought about that. The basic issue is not so much partitioning the information within the class, but, rather, minimizing the public api of the base class in order to maximize the potential public api defined by subclasses in a schema. So I need something that gives me internal expansion space and guarantees that exposing another attribute from the base class won't conflict with schema-defined attributes. Either a reserved attribute prefix, like "sys_" or reserved attribute name, like "sys" that is actually a reference to an object to which I can add additional attributes, like self.sys.links and self.sys.attrs. I think the second is more elegant. I want to look at what Matt has been working on before I decide. > > The field stuff is completely unstable and needs attention. > > Please keep me informed. I am quite interested in this. (And I will > follow CVS.) I will. Matt has really been doing a lot of work on this in his sandbox. You might want to look at what he's come up with. > > > 3. There appears to be a private (or semi-public) attribute in > > > Transaction (_time) that is accessed directly by methods in the > > > Engine class. Is this intended to be part of the public API? > > > Should it be made a public property? > > > > It should not be part of the public API. If you need to > > timestamp, you should import clock, as in this example: > > > > from pypersyst.clock import Clock > > # clock.time() is used for timestamping all changes to entities. > > clock = Clock() > > time = clock.time() > > Yes, I understand that the programmer should use Clock.time() to > get a timestamp. Furthermore I *think* I understand that the > programmer should not timestamp transactions directly, but instead > should go through Engine.execute() via Engine._log(). Correct? Is > this the only only method that accesses transaction._time directly? > And if one were to write a new Engine (sub)class, would it ever be > necessary to override this (private) method (_log)? That's correct. Only an engine or storage writer should have to worry about these details. As far as what a new Engine might override, it all depends on what the new Engine wants to do differently. > > > 4. Have you thought about applying different Storage classes as > > > "mixin" classes to Engine as a way to avoid the need for > > > passing the callback method as a parameter? > > > > Hadn't thought about it. I tend not to use mixins very much. > > Are you troubled by the callback parameter? > > "Troubled" may be too strong a word, but when I was going through > the source code, it did take some effort to follow the trail from > Engine to Storage and back again. No big deal if the number of > engine and/or storage subclasses is small, but if you start adding > new subclasses, the callback approach might be somewhat more > difficult to maintain. Just a thought. And it really is not that > important to me. It's sort of one of those "personal preference" > things. I agree that the code is not quite as simple as I would like. So the engine and storage code might need to be refactored at some point. Most users won't need to touch it, however, or even understand it. > > > 5. The abstract Root class is a "dictionary-like" object. Have > > > you thought about actually making it a subclass of dict? > > > > Subclassing from dict is rarely a good idea, unless you really > > want something that is only slightly different from a dict. Root > > comes close, but since Root isn't meant to be used as a general > > purpose substitute for dict, I don't see the benefit of > > inheriting from dict. There would probably be just as much effort > > put into overriding dict behavior that didn't apply to Root, ... > > What dict behavior would need to be overridden? Some subset of these: >>> dir({}) ['__class__', '__cmp__', '__contains__', '__delattr__', '__delitem__', '__doc__', '__eq__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__init__', '__iter__', '__le__', '__len__', '__lt__', '__ne__', '__new__', '__reduce__', '__repr__', '__setattr__', '__setitem__', '__str__', 'clear', 'copy', 'get', 'has_key', 'items', 'iteritems', 'iterkeys', 'itervalues', 'keys', 'popitem', 'setdefault', 'update', 'values'] >>> > > as there would be in exposing some of Root's dict-like behavior. > > I'd have to see some benefits. Are there specific benefits to be > > gained by inheriting from dict? > > Hmmmm. Upon further review, the play stands. I've been thinking > about it, and now I tend to agree with your approach. All the > benefits I can think of for subclassing dict can be had by adding a > few methods as you have done. Good. :-) > > > 6. The only public method of the Root class (other than the > > > implied dictionary-like methods) appears to be _branch(). Is > > > this intended to be a public method? If so, why the leading > > > underscore? If not, from where is this method called? > > > > It's meant to be private, and it is called by the subclass in > > entity.root. > > Changed. I assume that other subclasses of root.Root might be > expected (or allowed) to call this method as well? Definitely. As I'm deciding what is private and what is public, I'm looking at things from the point of a user of PyPerSyst, who will create schemas and database applications. If something is private, they should not touch it unless they really, truly know what they are doing. But internally, private attributes are referenced directly by other modules in the framework and I consider that perfectly acceptable. I try not to be too strict and am mostly making things private in order to simplify things for users. > > Thanks for all your work on this! > > Sure thing. I did it to learn, and I am happy to share. > > One more question. In an earlier post you suggested (off-handedly) > that there is a specialized subclass of Database for entity, > > > So the entity package provides relational-like classes > > - Entity, Extent, as well as a specialized Root, Database, etc. > > but I cannot find it. Am I looking in the wrong place? I think I lied. Or maybe I meant to say transactions, rather than Database. Actually, there is a specialized Database in schevo.schevo. I think that's what I meant to point out. -- Patrick K. O'Brien Orbtech http://www.orbtech.com/web/pobrien ----------------------------------------------- "Your source for Python programming expertise." ----------------------------------------------- |