Re: [ZODB-Dev] API question
On 16/01/2013 18:01, Tres Seaver wrote: 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. What Tres said ;-) - - 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. Yeah, easy, good coverage reporting and intergration with Jenkins' test reporting, coverage reporting and various other plugins to nose are the reasons I've moved all my stuff over.. cheers, Chris -- Simplistix - Content Management, Batch Processing Python Consulting - http://www.simplistix.co.uk ___ For more information about ZODB, see http://zodb.org/ ZODB-Dev mailing list - ZODB-Dev@zope.org https://mail.zope.org/mailman/listinfo/zodb-dev
Re: [ZODB-Dev] API question
-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 tsea...@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
Re: [ZODB-Dev] API question
On Mon, Jan 14, 2013 at 1:32 PM, Tres Seaver tsea...@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 ___ For more information about ZODB, see http://zodb.org/ ZODB-Dev mailing list - ZODB-Dev@zope.org https://mail.zope.org/mailman/listinfo/zodb-dev
Re: [ZODB-Dev] API question
On Mon, Jan 14, 2013 at 7:20 PM, Tres Seaver tsea...@palladion.com wrote: ... I'm tempted to rename the 'DB.py' module 'db.py', and jam in a BBB entry in sys.modules for 'ZODB.DB'; likewise, I am tempted to rename the 'FileStorage.py' package 'filestorage', its same-named module '_filestorage.py', and jam in BBB entries for the old names. +.9 if done without backward-incompatiblke breakage. This would be a 4.1 thing. +1 if you used zodb.filestorage.filestorage rather than zodb.filestorage._filestorage. Those renames would make the preferred API: from ZODB import DB # convenience alias for the class from ZODB import db # the moodule from ZODB.db import DB # my preferred speling from ZDOB.filestorage imoprt FileStorage # conv. alias for class from ZODB import filestorage # the package from ZODB.filestorage import FileStorage # my preferred speling This is the same as one earlier. I suspect you meant: from ZODB.filestorage._filestorage import FileStorage but couldn't type the underware. I don't think the packagification of the FileStorage module was a win, but it's too hard to fix it now. Some day, I'd like to work on a filestorage2, but fear I won't ever find the time. :( from ZODB.filestorage import _filestorage # if needed We shouldn't design an API where we expected people to grab underware. Aside from not liking from imports and the _filestorage nit, +1 For extra bonus fun, we could rename 'ZODB' to 'zodb' :) In that case, we might switch to a namespace package, oodb, which I've already reserved: http://pypi.python.org/pypi/oodb But I doubt we're up for this much disruption. Jim -- Jim Fulton http://www.linkedin.com/in/jimfulton Jerky is better than bacon! http://zo.pe/Kqm ___ For more information about ZODB, see http://zodb.org/ ZODB-Dev mailing list - ZODB-Dev@zope.org https://mail.zope.org/mailman/listinfo/zodb-dev
[ZODB-Dev] API question
-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')) or use the module as a facade :: import ZODB db = ZODB.DB(ZODB.FileStorage.FileStorage('/path/to/Data.fs')) 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')) or even better:: from ZDOB.DB import DB # This one can even be ambiguous now 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. Tres. - -- === Tres Seaver +1 540-429-0999 tsea...@palladion.com Palladion Software Excellence by Designhttp://palladion.com -BEGIN PGP SIGNATURE- Version: GnuPG v1.4.11 (GNU/Linux) Comment: Using GnuPG with undefined - http://www.enigmail.net/ iEYEARECAAYFAlD0TycACgkQ+gerLs4ltQ4AgACg3MCYrEOga5KF8goWyu2OxjWe H7QAoLEyHTShzBc9ZkMENWbG+hqzrpTg =nBoy -END PGP SIGNATURE- ___ For more information about ZODB, see http://zodb.org/ ZODB-Dev mailing list - ZODB-Dev@zope.org https://mail.zope.org/mailman/listinfo/zodb-dev
Re: [ZODB-Dev] API question
On Mon, Jan 14, 2013 at 01:32:07PM -0500, Tres Seaver wrote: 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')) ZODB.FileStorage is a module, you can't call it. ZODB.DB, much to my surprise, refers to the ZODB.DB.DB class. A backwards compatibility thing maybe? or use the module as a facade :: import ZODB db = ZODB.DB(ZODB.FileStorage.FileStorage('/path/to/Data.fs')) This rings warning bells in my mind: if you're using the ZODB.FileStorage module, you should import it directly: import ZODB import ZODB.FileStorage db = ZODB.DB(ZODB.FileStorage.FileStorage('/path/to/Data.fs')) 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')) (I'm not a fan of this style, but never mind that.) or even better:: from ZDOB.DB import DB # This one can even be ambiguous now from ZODB.FileStorage import FileStorage db = DB(FileStorage('/path/to/Data.fs')) This is what I usually do. I don't get the ambiguous comment. ZODB.DB is (currently) always the class[1]. ZODB.FileStorage is always the module. [1] I think (currently) the only way to refer to the ZODB.DB module is to use sys.modules['ZODB.DB']: import ZODB ZODB.DB class 'ZODB.DB.DB' from ZODB import DB DB class 'ZODB.DB.DB' import ZODB.DB ZODB.DB class 'ZODB.DB.DB' 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. Can you demonstrate the ambiguity? As I've shown before, I was unable to find it, at least with Python 2.x. Marius Gedminas -- We don't really understand it, so we'll give it to the programmers. signature.asc Description: Digital signature ___ For more information about ZODB, see http://zodb.org/ ZODB-Dev mailing list - ZODB-Dev@zope.org https://mail.zope.org/mailman/listinfo/zodb-dev
Re: [ZODB-Dev] API question
-BEGIN PGP SIGNED MESSAGE- Hash: SHA1 On 01/14/2013 03:33 PM, Marius Gedminas wrote: Can you demonstrate the ambiguity? As I've shown before, I was unable to find it, at least with Python 2.x. On the filesystem: $ find src/ZODB/FileStorage/ -name *.py src/ZODB/FileStorage/fspack.py src/ZODB/FileStorage/__init__.py src/ZODB/FileStorage/fsdump.py src/ZODB/FileStorage/fsoids.py src/ZODB/FileStorage/format.py src/ZODB/FileStorage/interfaces.py src/ZODB/FileStorage/tests.py src/ZODB/FileStorage/FileStorage.py So, 'ZODB.FileStorage.FilesStorage' could logically be either the 'Filestorage' module inside the 'ZODB.FileStorage' package, or else the same-named class. As with ZODB.DB, getting to the actual module is tricky, because both thses imports give you the class:: from ZODB.FileStorage import FileStorage and:: From ZODB.FileStorage.FileStorage import FileStorage I'm tempted to rename the 'DB.py' module 'db.py', and jam in a BBB entry in sys.modules for 'ZODB.DB'; likewise, I am tempted to rename the 'FileStorage.py' package 'filestorage', its same-named module '_filestorage.py', and jam in BBB entries for the old names. Those renames would make the preferred API: from ZODB import DB # convenience alias for the class from ZODB import db # the moodule from ZODB.db import DB # my preferred speling from ZDOB.filestorage imoprt FileStorage # conv. alias for class from ZODB import filestorage # the package from ZODB.filestorage import FileStorage # my preferred speling from ZODB.filestorage import _filestorage # if needed For extra bonus fun, we could rename 'ZODB' to 'zodb' :) Tres. - -- === Tres Seaver +1 540-429-0999 tsea...@palladion.com Palladion Software Excellence by Designhttp://palladion.com -BEGIN PGP SIGNATURE- Version: GnuPG v1.4.11 (GNU/Linux) Comment: Using GnuPG with undefined - http://www.enigmail.net/ iEYEARECAAYFAlD0oOgACgkQ+gerLs4ltQ4LOwCgu3VSRklLjFMdkuWLkUNV4h2S m/MAoKMI+ZrTqFUnXkgGNSw7Gq2yYN0V =67De -END PGP SIGNATURE- ___ For more information about ZODB, see http://zodb.org/ ZODB-Dev mailing list - ZODB-Dev@zope.org https://mail.zope.org/mailman/listinfo/zodb-dev