I'm glad to hear this, as I think every project undergoes this at some
point anyway (magic-removal, anyone?), and it's probably better to
plan for it now that you already know you need to.
> Documentation
>
> I personally dislike lots of inline commenting. Sorry, but that's
> old-school thinking. If the function is so long or complex that it can't be
> understood by a decent programmer, then it is too long and should be
> refactored.
>
> However, I do agree that we are missing tons of method/class documentation.
> For my own projects, I like to use restructured text documentation for all
> classes and methods. Also, I'd like to see a standard license/copyright
> block at the top of all modules. I think also a call-out to the primary
> authors would be appropriate.
>
> I suspect that most people who are talking about documentation are really
> looking for better use/setup/extension documentation. That's a different
> beast entirely. Perhaps we should have a person who loves that kind of work
> head up that front? It won't be me.
I think your last point here is indeed the key. I've been talking
about integrating Satchmo into a project for a while now, but I've
found the documentation to be lacking in the area of integrating it
into an otherwise non-store site. That may be me, since I'm looking to
do some non-standard stuff, but I still found it very difficult to
even figure out where to begin.
Unfortunately, I'm much better about writing bland reference
documentation than installation docs and tutorials.
> Tests
>
> I think we should get more aggressive about requiring tests. With all the
> refactoring I've been doing lately, the existing tests have been literally
> invaluable. As we step up to 2.0 work, they'll be absolutely essential.
>
> Personally, I dislike doctests, but they're still much better than nothing.
> Yes UnitTests are a bit more of a pain to set up, but they are so much
> easier to casually extend once in place.
I'm glad to see a focus on tests, especially if you end up changing
the underlying implementation of things while maintaining an existing
API. As for doctests vs. unittests, I think it depends a lot on the
nature of the feature being tested. Doctests, in my mind, tend to work
best when developers will have to interact with the feature directly
in their own Python code. In these cases, doctests are great at
doubling as documentation, since they can quickly and easily convey
how Python code can use the feature. That's not an essential
requirement, of course, since you can document it elsewhere anyway,
but it makes it easy if you can do it all in one place.
On the other hand, things like Configuration are largely untouched by
external developers. Sure, they can define their own config options,
but they don't do so by calling many of the internal functions. In
those cases, unittests are probably better, since they're more
flexible, easier to isolate individual tests, and as you mention,
they're very easy to extend. They just don't have that documentation
feature, but for those cases where it doesn't make sense anyway, this
is hands-down the best option.
> Pluggability
>
> We already have *some* pluggability. The payment, shipping and tax systems
> all are pluggable. But that was all done "by hand", and isn't completely
> the same from subsystem to subsystem. Nor is the API/contract for extension
> clearly defined.
>
> We do not have good pluggability in the Product model/subsystem. This is
> our greatest weakness at the moment. There is far too much code which tests
> "is this an xxx-type product" scattered around. To use a Fowler phrase, it
> is starting to smell a bit.
>
> I spent some time looking at the Trac extension system. It is solid, even
> beautiful in many ways. I think we could use the Trac component system (
> http://trac.edgewall.org/wiki/TracDev/ComponentArchitecture)
> almost as-is to provide a much richer and more well-defined pluggable
> system.
>
> I'm not completely sure at this point how we'd marry Django and Trac at the
> model level for things like pluggable product models, but I think that it is
> quite possible to do and to do elegantly. I already see how we could extend
> the trac idea of an "ExtensionOption" to automatically provide satchmo
> Configuration registration.
>
> I'd love to hear any other ideas people have for modularization or pluggable
> architectures.
I admit, I haven't delved quite enough into Satchmo's internals to
know what tactics to suggest, but I can say that what i've seen of
Trac so far doesn't sit very well with me. It's probably just a
personal thing, since I can't really put my finger on any technical
*problems* with it, but it just seems like an over-engineered system
that makes Python do too much error-checking at run-time. The whole
idea of interfaces seems like a way to programmatically enforce that
programmers don't screw up. While screwups generally aren't good, I'm
just not convinced that such things should be handled at run-time.
But, like I said, that's really more just personal preference and
philosophy, so I don't have any real convincing reasons for stating
one way or another. Trac-style componentization isn't very
Django-esque, and maybe I'm just too much of a Django fanboy to
appreciate it. I do think you'd be able to marry it with Django, it
just seems like doing so might be unnecessary added time and energy.
My jury's still out on this one, so I might have a stronger opinion at
some other point.
> Refactoring
>
> I'd like to move around some components and make them more generic. For
> example, caching and configuration. They should be top-level apps, not
> imported from under a satchmo tree. Probably these (or at least caching)
> should be made pluggable via the newly-revamped pluggable architecture.
>
> Some apps should merge, for example accounts and contact. Some apps should
> have functionality moved to the appropriate place. Order and friends should
> leave Contact and move to Shop or Payment.
>
> All templates should live in their apps, not in one master template tree.
> For example, templates/product should move to product/templates/product.
> This is a wart and it encourages app spaghetti, imho.
I think this is a great idea. In working on one of my more sizable
projects, I found a variety of needs that I thought could be factored
out in a way that didn't depend on the project itself, and I was able
to release those and maintain them as separate apps. I wouldn't
necessary tell anyone they should do this, but as long as you're
already consider it, I'll certainly agree with the idea.
As for merging, I think that would help non-store projects integrate a
Satchmo store, since it would likely involve fewer additions to
INSTALLED_APPS, and the process could be documented much more easily.
Pluggability is good even for some internal things, such as Contacts,
since people might want to integrate their own existing Contact system
into their Satchmo installation. I don't know how easily that could be
done, but I'd certainly support any move that tries to make that
possible.
> Configuration
>
> I admit bias, since I wrote it, but I love the Configuration system. One
> major problem with it, however, is that some config options won't take
> effect until the store is restarted. Either we need to fix that so that
> when those items are changed, the appropriate systems are reloaded, or we
> need to have some global flag "needs restart", and a system for restarting
> the store from the admin.
As we've discussed before, I very much enjoyed seeing the work you did
on the Configuration system. I'm still not 100% thrilled about the
public API for it, but so far I haven't come up with anything better,
so that's a minor issue that's really just a matter of my own
preference.
The biggest thing I'll say here (and I'm sure you're expecting it) is
that I think you should break the Configuration system into its own
app, so that it can be maintained separately from Satchmo itself, and
can be used in non-Satchmo apps.
I say this because I'm not fond of having Satchmo's configuration and
dbsettings filling such similar roles in fairly different ways, with
different feature sets. I'd very much like to see a single
Configuration system that's available to all Django apps, and can
fulfill the needs of a variety of different types of sites. I've mused
in the past about where dbsettings is headed, after seeing the work
you've done, and I'd like to see us work together to make something
that can serve a greater audience.
I should note that I'm *not* suggesting that your Configuration system
be folded into dbsettings. dbsettings has something of a flawed
history, and since you've already done such a good job at overcoming
many of its pitfalls, I think it'd be better to start an all-new app,
based on your work, that we can refine to make it as good as possible.
> NewForms Admin
>
> I think we may as well move to NewFormsAdmin almost immediately. 2.0 won't
> be ready before the official release, and it looks so nice ... We'll be
> avoiding so much rework if we start sooner rather than later.
I haven't worked enough with newforms-admin to have much of an opinion
yet, but I do agree with you that if you're going to deal with it
eventually, it might as well be now, where you're already touching a
significant amount of Satchmo anyway.
I can't promise much in the way of time or code, but I'd be happy to
contribute wherever I can, especially if you do decide to break out
your Configuration work into a separate app. Keep up the good work!
-Gul
I suspect that most people who are talking about documentation are really looking for better use/setup/extension documentation. That's a different beast entirely. Perhaps we should have a person who loves that kind of work head up that front? It won't be me.
Tests
Personally, I dislike doctests, but they're still much better than nothing. Yes UnitTests are a bit more of a pain to set up, but they are so much easier to casually extend once in place.
Pluggability
We already have *some* pluggability. The payment, shipping and tax systems all are pluggable. But that was all done "by hand", and isn't completely the same from subsystem to subsystem. Nor is the API/contract for extension clearly defined.
We do not have good pluggability in the Product model/subsystem. This is our greatest weakness at the moment. There is far too much code which tests "is this an xxx-type product" scattered around. To use a Fowler phrase, it is starting to smell a bit.
Refactoring
I'd like to move around some components and make them more generic. For example, caching and configuration. They should be top-level apps, not imported from under a satchmo tree. Probably these (or at least caching) should be made pluggable via the newly-revamped pluggable architecture.
Configuration
I admit bias, since I wrote it, but I love the Configuration system. One major problem with it, however, is that some config options won't take effect until the store is restarted. Either we need to fix that so that when those items are changed, the appropriate systems are reloaded, or we need to have some global flag "needs restart", and a system for restarting the store from the admin.
NewForms Admin
I think we may as well move to NewFormsAdmin almost immediately. 2.0 won't be ready before the official release, and it looks so nice ... We'll be avoiding so much rework if we start sooner rather than later.
> Refactoring
To me it would make more sense
to have a couple of separate applications (contact, products, cart,
checkout/payment) that work together in a more loosely coupled and
clearly defined way.
Preferrably making it possible to put custom
modules in and affecting behaviour through different hooks. For
example it should be possible to use the checkout module without the
regular cart and use an existing user/contact database for buyer
information.
Anyway, I agree with the things you mention. Only question is: Can I
help out here? As I'm about to build a webshop it would be nice to
build it on Satchmo, but since I haven't followed the development I'm
not sure where to go.
> NewForms Admin
This is another main issue why I'm not already using Satchmo. Just
seems like waste of time to develop anything for oldforms-admin. And
it feels a bit difficult as a newbie to port it over to newforms.
> Pluggability
For adapters and interfaces you might want to look at Zope interfaces
as well. It seems well accepted; for example the the Twisted framework
replaced their own interface code with it and it seems to work well.
Btw, as this topic is "Post 1.0". How far into the future are these
things?
On the other hand, I distinctly remember a discussion where several
Django developers expressed displeasure with Zope interfaces, seeing
them as overkill.
Unfortunately I can't seem to find the discussion on django-developers
right now, but I mean to try again.
--
Nicola Larosa - http://www.tekNico.net/
We should take our cue from what happens when we fall in love: time
stops, goes away. We are there in the moment, and it lasts almost
forever. So the change over this infinite time is so gradual it is
no noticeable change at all. Love change, embrace it, slow it down,
make it last, and the stress disappears. -- Dave Pollard, August 2007
I don't know if I've spoken up on this, but I'm one of the Django
developers who extremely dislikes Zope interfaces. I just did some
more thinking about it today, actually, and I think I know the biggest
issue I have with it: what we're really after are components, not
interfaces (going by Zope terminology), but with Zope, components
require the use of interfaces. At least, as far as I've been able to
tell. So to get one potentially useful feature, we're stuck with an
extremely useless feature and a painful API.
So, what would be optimal is if we could implement a pluggable
component system without the overhead of interfaces. I did that this
afternoon in about 35 lines of code. I still want to look it over a
few more times before I'm sure that it'll actually do the job as well
as it needs to, but I think it should be quite possible to implement a
much simpler "framework" for dealing with pluggability in a much more
Django-friendly manner.
I'll write it up tomorrow if it looks promising, but regardless of
whether it's my code or not, I think there's a lot of potential for
coming up with something that doesnt rely on Zope's interface system.
-Gul
On 1/9/08, Nicola Larosa <nicola...@gmail.com> wrote:
>
> Bruce Kroeze wrote:
> > I guess the interfaces are worth looking at.
>
> On the other hand, I distinctly remember a discussion where several
> Django developers expressed displeasure with Zope interfaces, seeing
> them as overkill.
I don't know if I've spoken up on this, but I'm one of the Django
developers who extremely dislikes Zope interfaces.
So, what would be optimal is if we could implement a pluggable
component system without the overhead of interfaces. I did that this
afternoon in about 35 lines of code.
I'll write it up tomorrow if it looks promising, but regardless of
whether it's my code or not, I think there's a lot of potential for
coming up with something that doesnt rely on Zope's interface system.
I've written it up on my blog[1], and I've added it to
djangosnippets[2] as well, since it ended up being just 6 lines for
the essentials. It's not much, but it does exactly what needs to be
done, without any of the unnecessary overhead. You're welcome to add
utilities to it, of course, but ultimately, anything added to it would
just be helper utilities. There's nothing essential missing (that I
can see, anyway). Feedback is welcome!
-Gul
[1] http://gulopine.gamemusic.org/2008/jan/10/simple-plugin-framework/
[2] http://www.djangosnippets.org/snippets/542/
On Jan 9, 2008 6:35 PM, Bruce Kroeze <bkr...@gmail.com> wrote:
> On Jan 9, 2008 2:52 PM, Marty Alchin < gulo...@gamemusic.org> wrote:> > I'll write it up tomorrow if it looks promising, but regardless ofI've written it up on my blog[1], and I've added it to
> > whether it's my code or not, I think there's a lot of potential for
> > coming up with something that doesnt rely on Zope's interface system.
>
> I'd *love* to see that. I am quite suspicious of these straitjacket,
> overkill interfaces when really I just want a way of declaratively stating a
> contract. In fact, that's why I like signals so much. No overkill (though
> some do argue differently), ignore them if you like, but they provide useful
> features in a clear and straightforward manner.
djangosnippets[2] as well, since it ended up being just 6 lines for
the essentials. It's not much, but it does exactly what needs to be
done, without any of the unnecessary overhead.
I'm curious to see what other Satchmo devs think about it. Should we use Marty's minimal framework?
Ok. The example helped me out a lot. I think we would need to think through a couple of things:
- Where do we place the plugin calls? (I realize this isn't necessarily difficult but it should be thought out)
- Do we have any limits to what a plugin could do? If we have a plugin to do some contact updating, what if we have another plugin that interacts negatively with another one in the stream? This might just be another documentation issue but we need to be clear about it.
- Finally, is there a performance (speed/memory) ramification of sprinkling plugin calls all over the place? I thought that signals were relatively expensive, do we have similar concerns here?
I wouldn't call signals "slow" on their own, exaclty, but there is
definite concern. As you mention, Django by default makes extensive
use of signals, so any speed concerns there might be are greatly
amplified. The real problem, though, is how PyDispatcher locates
listeners to call. It has a fairly complicated data structure it has
to look through, containing all listeners registered for all signals
(even though you're only dispatching one) and then it has to inspect
each listener to figure out which arguments to send it.
That all adds flexibility, of course, since you can register a
listener for *any* signal, or for *any* sender (or theoretically
both). So PyDispatcher really doesn't know which listeners to call
under the call itself is made. That whole location process takes time.
It's not earth-shattering for most projects, but for some, that time
really adds up. There are some enhancements being considered, since
Django doesn't really make use of the "any signal" dispatch, but those
haven't been finalized yet.
But you're right, the time it takes to cycle through plugins is
directly related to how many are registered for that particular mount
point. If there aren't any, it's an empty list; very, very quick. Even
if there are dozens though, a single list can be traversed much more
quickly than the dispatcher's nested dictionary structure. And since
there's no need to inspect arguments or anything, it's all that much
quicker still.
-Gul