.__html__() is a convention used for smart escaping. String-like
objects should return self to indicate that they're preformatted and
should not be escaped further. Other objects can define .__html__() to
indicate their preferred HTML format. This convention is used by
literal() in webhelpers.html, and by the render functions that ship
with Pylons (render_mako, etc). I didn't know WebOb itself also did
it.
Previous implementations of smart escaping (Quixote, Genshi) required
preformatted objects to be a certain class. This made it impossible
for third-party libraries to mark their objects preformatted, because
they'd have to depend on the package with the special class, which
they'd refuse to do or wouldn't know about. Worse, they would be tied
to one specific template library rather than supporting all of them.
The .__html__ strategy allows third-party packages to define their own
string subclass with an .__html__ method rather than having to depend
on a special class in a foreign package.
So in this case, is the object yours or somebody else's? If it's
yours, define an .__html__ method that returns unicode. If it's
somebody else's, well, what does it think .__html__ is supposed to be?
Or is it just returning something for all .__getattr__ calls
regardless of value?
callable() has been deprecated by Guido and is not in Python 3. He
says rather than using it, just call the d**n thing and see if you get
an exception or not.
--
Mike Orr <slugg...@gmail.com>
If it's displaying the environment in an error message, it has to
escape it to avoid security vulnerabilities. Otherwise a cracker can
force an exception and put malicious Javascript in the query string
(which would be displayed as part of the environment).
>> Or is it just returning something for all .__getattr__ calls
>> regardless of value?
>
> pymongo.database instance always returns a collection object,
> regardless of the attr name. The collection object is not callable,
> (well actually it defines __call__, but its implementation throws an
> exception immediately on purpose). The pymongo database __getattr__
> looks like this
>
> # in pymongo database
> def __getattr__(self, name):
> return Collection(self.db, name)
>
>
> Ok, good to know about the callable deprecation. It looks like I may
> just subclass pymongo.database and override its __getattr__ to check
> for __html__. That doesn't feel very clean, but it'll work.
It sounds like the best solution. Sometimes you have to make kludges
like this when two unrelated libraries make contradictory assumptions.
Fortunately pymongo.database is overridable.
Why does pymongo.database return a useless value for unknown
attributes? Perhaps this is a bug in PyMongo. I'm not sure what
``Collection(self.db, name)`` means, but if a property is not
specifically defined it should raise AttributeError. Otherwise it
will throw off not only WebOb but all analysis/introspection tools.
--
Mike Orr <slugg...@gmail.com>
There are all kinds of special names that can trip you up, in various
places. I've found that it's safest to add
if name.startswith('_'):
raise AttributeError(name)
to such magic __getattr__ methods.
If you actually use collection names starting with an underscore, you
could make a stricter check and look for __..., or __...__.
Marius Gedminas
--
There's a special hell 4 people who replace words with numbers.
-- Ben "Yahtzee" Croshaw