Thanks Chuck, all of your points seem valid to me. But someone (I can't
even remember who started this thread :-)) is using a Delegation technique
to write his servlets and could only get it to work by removing the check
for Servlet as a base class.
Perhaps that someone could explain the technique in a bit more detail? Why
are you using delegation instead of inheritance? How exactly are you doing
it?
Maybe we can collectively find a way to accomplish your goals without having
to remove Servlet as a required base class.
- Geoff
> -----Original Message-----
> From: Chuck Esterbrook [mailto:ChuckEsterbrook@...]
> Sent: Wednesday, April 10, 2002 6:26 PM
> To: Geoffrey Talvola; webware-discuss@...
> Subject: Re: [Webware-discuss] Allowing delegation in servlets
>
>
> On Wednesday 10 April 2002 01:53 pm, Geoffrey Talvola wrote:
> > I would propose using "hasattr" to check for the existence of awake,
> > respond, and sleep, and removing the assert statement. The
> > RuntimeError that results could have a much better error
> message than
> > the assert would give us, anyhow.
> >
> > But I'm curious on Chuck's take on removing the assert statement. I
> > somehow have a feeling that he has an opinion on this, maybe because
> > it was discussed before?
> >
> > - Geoff
>
> Yes, this was discussed and decided before. Here are the points:
>
> - By requiring subclasses of Servlet, we can put methods in Servlet
> that other parts of WebKit (like the AppServer and Application) can
> make use of.
>
> Otherwise, if we decide to add some method like "serverSidePath" in a
> version 0.4 then we basically break every WebKit application that
> wasn't subclassing Servlet.
>
> We would either get breakage every time we added something
> (when there
> is often a reasonable default implementation), or we could
> have to make
> these methods into global functions (that would presumably check
> hasattr() first to see if the servlet wanted to "override them").
>
> There is a "myth" among the Python community that requiring
> inheritance
> is _always_ bad. It is bad if you only rely on one or two methods and
> don't plan on beefing up the de facto base class. It is also bad with
> builtin types in Py <= 2.2 because they couldn't be subclassed.
>
> - There are probably more required methods than you might think. I
> doubt that it's only awake, respond and sleep.
>
> - Since you are already using WebKit, inheriting from Servlet (or a
> subclass is extremely easy):
>
> from WebKit.HTTPServlet import HTTPServlet
> class Foo(HTTPServlet):
> pass
>
> - Python provides multiple inheritance so you're not locked into just
> inheriting from WebKit.
>
> - Invoking hasattr() multiple times will be more expensive than one
> isinstance().
>
> - Checking isinstance() guards against the "duplicate module" bug we
> experienced earlier.
>
>
>
> It sounds like the assert should be changed to an "if: raise" to be
> more clear and avoid being "optimized out".
>
> -Chuck
>
>
> >
> > > -----Original Message-----
> > > From: iron@... [mailto:iron@...]
> > > Sent: Monday, April 08, 2002 3:31 PM
> > > To: webware-discuss@...
> > > Subject: Re: [Webware-discuss] Allowing delegation in servlets
> > >
> > > On Mon, Apr 08, 2002 at 02:43:37PM -0400, Geoffrey Talvola wrote:
> > > > > My first attempt failed because line 183 of ServletFactory is:
> > > > >
> > > > > assert issubclass(theClass, Servlet)
> > > > >
> > > > > Anyway, I'd like to argue for the removal of the assertion in
> > > > > ServletFactory, since it is denying use of a very powerful,
> > > > > and arguably
> > > > > better technique than inheritance. In any case, assertions
> > > > > can be optimized
> > > > > away in .pyo files, so that the presence of the assertion
> > > > > statement is of
> > > > > questionable value...
> > > >
> > > > I think the assertion is there to help out the Webware user
> > >
> > > who forgets to
> > >
> > > > have their servlet inherit from Servlet. I assume that
> > >
> > > mistake happens
> > >
> > > > relatively frequently. I know I've done it once or twice.
> > >
> > > Without the
> > >
> > > > assertion (which pinpoints the problem pretty clearly),
> > >
> > > presumably you would
> > >
> > > > wind up with a traceback somewhere else in the guts of
> > >
> > > Appliction.py that
> > >
> > > > would be less obvious to track down, especially for a casual
> > > > user.
> > > >
> > > > Now you've identified a legitimate use for a servlet not
> > >
> > > derived from
> > >
> > > > Servlet. So you want to remove the assertion, but that
> > >
> > > would hurt casual
> > >
> > > > Webware users hwo might forget the base class. So maybe
> > >
> > > there should be an
> > >
> > > > option "AllowServletsNotDerivedFromServlet" that defaults
> > >
> > > to 0, but you can
> > >
> > > > just flip the switch and it skips the assertion? I would
> > >
> > > imagine this to be
> > >
> > > > documented as "for experts".
> > >
> > > If a servlet must always subclass Servlet, or at least we pretend
> > > to require that for the default case, the exception should be
> > > changed from
> > > AssertionError to something else. AssertionError mean "I" made an
> > > error. Other exceptions mean "you" made an error.
> > >
> > > But perhaps we need to rethink what are the requirements for
> > > servlets. At minimum, awake/respond/sleep methods. This sounds
> > > like an interface.
> > > Since Python doesn't have interfaces (yet), we've been using
> > > "must be a
> > > subclass of Servlet" as a substitute.
> > >
> > > The simplest way to avoid the issubclass test and yet not
> introduce
> > > an esoteric option like
> AllowServletsNotDerivedFromServlet would be
> > > to test explicitly for the required features:
> > >
> > > if not hasattr(theClass, 'respond'): raise RuntimeError(...)
> > >
> > > try:
> > > theClass.respond
> > > except AttributeError:
> > > raise RuntimeError(...)
> > >
> > > if not hasattr(theClass, 'respond') or \
> > > type(theClass.respond) != types.MethodType:
> > > raise RuntimeError(...)
> > >
> > > requiredMethods = 'awake', 'respond', 'sleep'
> > > for methMame in requiredMethods:
> > > try:
> > > meth = getattr(theClass, methName)
> > > if type(meth) != types.MethodType:
> > > raise RuntimeError("not a method...")
> > > except AttributeError:
> > > raise RuntimeError("method doesn't exist...")
> > >
> > >
> > > --
> > > -Mike (Iron) Orr, iron@... (if mail problems: mso@...)
> > > http://iron.cx/ English * Esperanto * Russkiy *
> > > Deutsch * Espan~ol
> > >
> > > _______________________________________________
> > > Webware-discuss mailing list
> > > Webware-discuss@...
> > > https://lists.sourceforge.net/lists/listinfo/webware-discuss
>
|