Re: [ZODB-Dev] API question

2013-01-25 Thread Chris Withers

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

2013-01-16 Thread Tres Seaver
-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

2013-01-15 Thread Jim Fulton
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

2013-01-15 Thread Jim Fulton
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

2013-01-14 Thread Tres Seaver
-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

2013-01-14 Thread Marius Gedminas
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

2013-01-14 Thread Tres Seaver
-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