[ZODB-Dev] API question

Tres Seaver tseaver at palladion.com
Wed Jan 16 18:01:51 UTC 2013


-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On 01/15/2013 06:11 AM, Jim Fulton wrote:
> 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.

Sure.  I don't like using APIs via long, multi-dotted paths.

>> 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 have a couple of goals:

- - I want 'python setup.py develop test' to work on a fresh checkout, mostly
  because it makes doing multi-Python tests with tox simple.

- - Nose gives us easy access to Ned Batchelder's coverage package, which
  allows me to get seriously good test coverage in place before trying to
  port code to the "straddle" dialect.

- - I mean to keep the buildout + testrunner stuff working, too.

> 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.

Likely so.  I will give it a stab on the branch I'm working with.

> 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.

I'd like to see ZODB ported to Py3k ASAP, in a single codebase (as with
the ported 'zope.*' packages, 'persistent', 'transaction', and 'BTrees').
 Trying to get there with doctests has seemed way too hard to me:
doctests are really fragile to cross-platform changes (especially various
'repr' changes).

In the case of the already-ported packages, I migrated most of their
doctests out of the software into testsed snippets inside Sphinx docs.
That move seems like a reasonable tradeoff:  the examples still get
exercised as part of the docs, but they don't carry the weight of testing
the package.

> 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

OK, let's keep DB-the-class at top-level scope, and rename the packages
(w/ BBB aliases).



Tres.
- -- 
===================================================================
Tres Seaver          +1 540-429-0999          tseaver at palladion.com
Palladion Software   "Excellence by Design"    http://palladion.com
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.11 (GNU/Linux)
Comment: Using GnuPG with undefined - http://www.enigmail.net/

iEYEARECAAYFAlD26w8ACgkQ+gerLs4ltQ6QuwCcDoLmBnlXVhP4kDFPO1LseXf1
BbMAniOfRZ8Vvd+8JTRTjSPKxG2AWmSY
=o32e
-----END PGP SIGNATURE-----



More information about the ZODB-Dev mailing list