[ZODB-Dev] API question

Jim Fulton jim at zope.com
Tue Jan 15 11:11:52 UTC 2013


On Mon, Jan 14, 2013 at 1:32 PM, Tres Seaver <tseaver at palladion.com> wrote:
> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
>
> While working on preparation for a Py3k port, I've stumbled across a
> fundamental issue with how ZODB structures its API.  Do we intend that
> client code do the following::
>
>   from ZDOB import DB, FileStorage
>   db = DB(FileStorage('/path/to/Data.fs'))

As Marius points out, this doesn't work.

>
> or use the module as a facade ::
>
>   import ZODB
>   db = ZODB.DB(ZODB.FileStorage.FileStorage('/path/to/Data.fs'))

This doesn't work either. You haven't imported FileStorage.

WRT ZODB.DB, ZODB.DB is an age-old convenience. It's unfortunate that
ZODB.DB (the class) shadows the module, ZODB.DB, just like the class
ZODB.FileStorage.FileStorage shadows the modules
ZODB.FileStorage.FileStorage.FileStorage. (Of course, it's also
unfortunate that there's a ZODB.FileStorage.FileStorage.FileStorage
module. :)

If we had a do-over, we'd use ZODB.db.DB and
ZODB.filestorage.FileStorage, and ZODB.DB would be a convenience for
ZODB.db.DB.

>
> I would actually prefer that clients explicitly import the intermediate
> modules::
>
>   from ZDOB import DB, FileStorage
>   db = DB.DB(FileStorage.FileStorage('/path/to/Data.fs'))

So you don't mind shadowing FileStorage.FileStorage.FileStorage. ;)

> or even better::
>
>   from ZDOB.DB import DB
>   # This one can even be ambiguous now

FTR, I don't like this style.  Somewhat a matter of taste.


>   from ZODB.FileStorage import FileStorage
>   db = DB(FileStorage('/path/to/Data.fs'))
>
> The driver for the question is getting the tests to pass under both
> 'nosetests' and 'setup.py test', where the order of module imports etc.
> can make the ambiguous cases problematic.  It would be a good time to do
> whatever BBB stuff we need to (I would guess figuring out how to emit
> deprecation warnings for whichever variants) before releasing 4.0.0.

I'm pretty happy with the Zope test runner and I don't think using
nosetests is a good reason to cause backward-incompatibility. The zope
test runner works just fine with Python 3. Why do you feel compelled
to introduce nose?

I'm sort of in favor of moving to nose to follow the crowd, although
otherwise, nose is far too implicit for my taste. It doesn't hande
doctest well at all.

Having said that, if I was going to do something like this, I'd
rename the modules, ZODB.DB and ZODB.FileStorage to ZODB.db and
ZODB.filestorage and add module aliases for backward compatibility. I
don't know if that would be enough to satisfy nose.

I'm not up for doing any of this for 4.0.  I'm not alergic to a 5.0 in
the not too distant future.  I'm guessing that a switch to nose would
also make you rewrite all of the doctests as unittests. As the
prrimary maintainer of ZODB, I'm -0.8 on that.

Back to APIs, I think 90% of users don't import the APIs but set up
ZODB via ZConfig (or probably should, if they don't).  For Python use,
I think the ZODB.DB class short-cut us useful.  Over the last few
years, ZODB has grown some additional shortcuts that I think are also
useful. Among them:

ZODB.DB(filename)         -> DB with a file storage
ZODB.DB(None)             -> DB with a mapping storage
ZODB.connection(filename) -> connection to DB with file storage
ZODB.connection(None)     -> connection to DB with mapping storage

More importantly:

ZEO.client us a shortcut for ZEO.ClientStorage.ClientStorage
ZEO.DB(addr or port)         -> DB with a ZEO client
ZEO.connection(addr or port) -> connection to DB with a ZEO client

Jim

--
Jim Fulton
http://www.linkedin.com/in/jimfulton
Jerky is better than bacon! http://zo.pe/Kqm


More information about the ZODB-Dev mailing list