Re: [Python-Dev] PEP 246, redux

2005-01-11 Thread Alex Martelli
On 2005 Jan 11, at 11:01, Alex Martelli wrote:
On 2005 Jan 10, at 18:59, Phillip J. Eby wrote:
At 12:43 PM 1/10/05 -0500, Phillip J. Eby wrote:
As a practical matter, all of the existing interface systems (Zope, 
PyProtocols, and even the defunct Twisted implementation) treat 
interface inheritance as guaranteeing substitutability for the base 
interface, and do so transitively.
An additional data point, by the way: the Eclipse Java IDE has an 
adaptation system that works very much like PEP 246 does, and it 
appears that in a future release they intend to support automatic 
adapter transitivity, so as to avoid requiring each provider of an 
interface to provide O(n^2) adapters when writing the nth version of 
an interface.  IOW, their current release is transitive only for 
interface inheritance ala Zope or Twisted; their future release will 
be transitive for adapter chains ala PyProtocols.
This is definitely relevant prior art, so thanks for pointing it out.  
If interfaces change so often that 'n' can become worryingly high, 
this is a valid concern.  In my world, though, published interfaces do 
NOT change as often as to require such remedies;-).
...that was a bit too flippant -- I apologize.  It DOES happen that 
interfaces keep changing, and other situations where adapter-chain 
transitivity is quite handy do, absolutely!, occur, too.  Reflecting 
on Microsoft's QI (QueryInterface), based on a very strong injunction 
against changing interfaces and yet mandating transitivity, points that 
out -- that's prior art, too, and a LOT more of it than Eclipse can 
accumulate any time soon, considering how long COM has been at the 
heart of Microsoft's components strategy, how many millions of 
programmers have used or abused it.  Still, QI's set of constraints, 
amounting to a full-fledged equivalence relationship among all the 
adapters for a single underlying object, is, I fear, stronger than 
we can impose (so it may be that Eclipse is a better parallel, but I 
know little of it while COM is in my bones, so that's what I keep 
thinking of;-).

So, I see transitivity as a nice thing to have _IF_ it's something that 
gets explicitly asserted for a certain adapter -- if the adapter has to 
explicitly state to the system that it isn't lossy (maybe), or isn't 
noisy (perhaps more useful), or something like that... some amount of 
reassurance about the adapter that makes it fully safe to use in such a 
chain.

Maybe it might suffice to let an adapter which IS 'lossy' (or, more 
likely, one that is 'noisy') state the fact.  I'm always reluctant by 
instinct to default to convenient but risky behavior, trusting 
programmers to explicitly assert otherwise when needed; but in many 
ways this kind of design is a part of Python and works fine (_with_ the 
BDFL's fine nose/instinct for making the right compromise between 
convenience and safety in each case, of course).

I'm still pondering the don't adapt an adapter suggestion, which 
seems a sound one, and yet also seems to be, intrinsically, what 
transitivity-by-chaining does.  Note that QI does not suffer from this, 
because it lets you get the underlying object identity (IUnknown) from 
any interface adapter.  Maybe, just maybe, we should also consider that 
-- a distinguished protocol bereft of any real substance but acting as 
a flag for real unadapted object identity.  Perhaps we could use 
'object' for that, at least if the flow of logic in 'adapt' stays as in 
the current PEP 246 draft (i.e., __conform__ is given a chance before 
isinstance triggers -- so, all adapters could __conform__ to object by 
returning the underlying object being adapted, while other objects 
without such a feature in __conform__ would end up with 'adapt(x, 
object) is x').  Or, if object in this role turns out to be confusing, 
IDentity (;-) or some other specially designed protocol.

If we had this ability to get at the underlying object we could at 
least write clearer axioms about what transitivity must mean, as well 
as, help out with the adapting an adapter problems.  E.g., imagine:

def f(x: IFoo, y: IFoo):
if x is y: ...
that wouldn't work if adapt(x, IFoo) returns a separate adapter each 
time, which is the most likely situation (think, again, of str-file 
adaptation by StringIO wrapping); but recovering underlying identities 
by adapt(x, object) is adapt(y, object) would work.

I don't think that IUnknown or an equivalent, per se, can do *instead* 
of the need to have an adapter explicitly state it's non-noisy (or VV). 
 Besides the need to check for object identity, which is pretty rare 
except when writing axioms, invariants or pre/post-conds;-), the 
IUnknown equivalent would perhaps be more of a conceptual/philosophical 
'prop' than a practically useful feature -- while I see the ability to 
block unintended consequences of inheritance and transitivity (or even 
better, state explicitly when those consequences are wanted, even if 
that should be 90% of the 

Re: [Python-Dev] PEP 246, redux

2005-01-11 Thread Alex Martelli
On 2005 Jan 11, at 16:34, Phillip J. Eby wrote:
   ...
Anyway, I agree that your version of the code should be used to form 
the reference implementation, since the purpose of the reference 
implementation is to show the complete required semantics.
Great, one point at last on which we fully agree -- thanks Armin!-)
I was waiting for BDFL feedback before editing the PEP again, but if 
none is forthcoming I guess at some point I'll go ahead and at least to 
the edits that are apparently not controversial, like this one.  I'd 
like to have a summary of controversial points and short pro and con 
args, too, but I'm not unbiased enough to write it all by myself...;-)

Alex
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


RE: [Python-Dev] PEP 246, redux

2005-01-11 Thread Michael Chermside
Phillip:

I think you must inhabit a far more perfect world than I do.

You say, for instance, that:
 ...-1 if this introduces a performance penalty [...] just to
 support people who want to create deliberate Liskov violations.
 I personally don't think that we should pander to Liskov
 violators

... but in my world, people violate Liskov all the time, even
in languages that attempt (unsuccessfully) to enforce it. [1]

You say that:
 I think one should adapt primarily to interfaces, and
 interface-to-interface adaptation should be reserved for
 non-lossy, non-noisy adapters.

... but in my world, half the time I'm using adaptation to
correct for the fact that someone else's poorly-written
code requests some class where it should have just used
an interface.

You seem to inhabit a world in which transitivity of adaptation
can be enforced. But in my world, people occasionally misuse
adaptation because they think they know what they're doing
or because they're in a big hurry and it's the most convenient
tool at hand.

I wish I lived in your world, but I don't.

-- Michael Chermside

[1] - Except for Eiffel. Eiffel seems to do a pretty good job
   of enforcing it.

___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


RE: [Python-Dev] logging class submission

2005-01-11 Thread Batista, Facundo
Title: RE: [Python-Dev] logging class submission





[Stephan Stapel]


#-  There's a license issue here? 
#- 
#- I was given the advise to use this license. If this license 
#- prohibts inclusion into Python, how should I re-license the code?


I just was asking. Who gave you the advise?


. Facundo


Bitácora De Vuelo: http://www.taniquetil.com.ar/plog
PyAr - Python Argentina: http://pyar.decode.com.ar/



  . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

ADVERTENCIA.


La información contenida en este mensaje y cualquier archivo anexo al mismo, son para uso exclusivo del destinatario y pueden contener información confidencial o propietaria, cuya divulgación es sancionada por la ley.

Si Ud. No es uno de los destinatarios consignados o la persona responsable de hacer llegar este mensaje a los destinatarios consignados, no está autorizado a divulgar, copiar, distribuir o retener información (o parte de ella) contenida en este mensaje. Por favor notifíquenos respondiendo al remitente, borre el mensaje original y borre las copias (impresas o grabadas en cualquier medio magnético) que pueda haber realizado del mismo.

Todas las opiniones contenidas en este mail son propias del autor del mensaje y no necesariamente coinciden con las de Telefónica Comunicaciones Personales S.A. o alguna empresa asociada.

Los mensajes electrónicos pueden ser alterados, motivo por el cual Telefónica Comunicaciones Personales S.A. no aceptará ninguna obligación cualquiera sea el resultante de este mensaje.

Muchas Gracias.



___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


RE: [Python-Dev] logging class submission

2005-01-11 Thread Barry Warsaw
On Tue, 2005-01-11 at 12:58, Batista, Facundo wrote:
 [Stephan Stapel]
 
 #-  There's a license issue here? 
 #- 
 #- I was given the advise to use this license. If this license 
 #- prohibts inclusion into Python, how should I re-license the code?
 
 I just was asking. Who gave you the advise?

Here's a link to the PSF contribution form:

http://www.python.org/psf/contrib.html

This contains links to the recommended licenses for software that might
be included in Python.

-Barry



signature.asc
Description: This is a digitally signed message part
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


RE: [Python-Dev] logging class submission

2005-01-11 Thread Stephan Stapel
 I just was asking. Who gave you the advise?

someon in a german python forum. I'll change the license asap.

I'm just curious, but do I really have to use the contributor agreement etc.? I 
mean I'm just trying to submit a small class, no big framework.

cheers,

Stephan

Verschicken Sie romantische, coole und witzige Bilder per SMS!
Jetzt neu bei WEB.DE FreeMail: http://freemail.web.de/?mc=021193

___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


RE: [Python-Dev] PEP 246, redux

2005-01-11 Thread Phillip J. Eby
At 09:27 AM 1/11/05 -0800, Michael Chermside wrote:
Phillip:
I think you must inhabit a far more perfect world than I do.
You say, for instance, that:
 ...-1 if this introduces a performance penalty [...] just to
 support people who want to create deliberate Liskov violations.
 I personally don't think that we should pander to Liskov
 violators
I've since dropped both the performance objection and the objection to 
supporting Liskov violation; in a more recent post I've proposed an 
alternative algorithm for allowing it, that has a simpler implementation.


You say that:
 I think one should adapt primarily to interfaces, and
 interface-to-interface adaptation should be reserved for
 non-lossy, non-noisy adapters.
... but in my world, half the time I'm using adaptation to
correct for the fact that someone else's poorly-written
code requests some class where it should have just used
an interface.
PEP 246 adaptation?  Or are you talking about some other language?  (I ask 
out of curiosity.)

I agree that if it's possible to adapt to concrete types, people will do 
so.  However, I think we all agree that this isn't a great idea and should 
still be considered bad style.  That's not the same thing as saying it 
should be forbidden, and I haven't said it should be forbidden.


You seem to inhabit a world in which transitivity of adaptation
can be enforced. But in my world, people occasionally misuse
adaptation because they think they know what they're doing
or because they're in a big hurry and it's the most convenient
tool at hand.
How is this different from abuse of *any* language feature that you're then 
forced to work around?  Are you saying we should not provide a feature 
because *some* people will abuse the feature?  I don't understand.

If you allow interface inheritance, you're just as susceptible to an 
invalid adaptation path, and in my experience this is more likely to bite 
you unintentionally, mainly because interface inheritance works differently 
than class inheritance (which of course is used more often).  Do you want 
to prohibit interface inheritance, too?

___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] PEP 246, redux

2005-01-11 Thread Clark C. Evans
On Tue, Jan 11, 2005 at 12:54:36PM -0500, Phillip J. Eby wrote:
| * Replacing LiskovViolation is possible by dropping type/isinstance 
| checks from adapt(), and adding an isinstance check to 
| object.__conform__; Liskov violators then override __conform__ in their 
| class to return None when asked to conform to a protocol they wish to 
| reject, and return super().__conform__ for all other cases.  This 
| achieves your use case while simplifying both the implementation and the 
| usage.

I'd rather not assume that class inheritance implies substitutability,
unless the class is marked as an interface (assuming that one 
doesn't have interfaces).  I'd like it to be explicit -- a bit of a
nudge to remind a developer to verify substitutability is a good
thing. In this scenerio, a LiskovViolation exception isn't needed
(aside, I don't see the rationale for the exception: to prevent
third party adapters?). Could we make a boilerplate __conform__
which enables class-based substitutability a well-known decorator?

| * In my experience, incorrectly deriving an interface from another is the 
| most common source of unintended adaptation side-effects, not adapter 
| composition

It'd be nice if interfaces had a way to specify a test-suite that
could be run against a component which claims to be compliant.   For
example, it could provide invalid inputs and assert that the proper
errors are returned, etc.

Best,

Clark


-- 
Clark C. Evans  Prometheus Research, LLC.
http://www.prometheusresearch.com/
o   office: +1.203.777.2550 
  ~/ ,  mobile: +1.203.444.0557 
 //
((   Prometheus Research: Transforming Data Into Knowledge
 \\  ,
   \/- Research Exchange Database
   /\- Survey  Assessment Technologies
   ` \   - Software Tools for Researchers
~ *
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] PEP 246, redux

2005-01-11 Thread Michael Chermside
David Ascher writes:
 Terminology point: I know that LiskovViolation is technically correct,
 but I'd really prefer it if exception names (which are sometimes all
 users get to see) were more informative for people w/o deep technical
 background.  Would that be possible?

I don't see how. Googling on Liskov immediately brings up clear
and understandable descriptions of the principle that's being violated.
I can't imagine summarizing the issue more concisely than that! What
would you suggest? Including better explanations in the documentation
is a must, but LiskovViolation in the exception name seems unbeatably
clear and concise.

-- Michael Chermside

___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] PEP 246, redux

2005-01-11 Thread Phillip J. Eby
At 01:50 PM 1/11/05 -0500, Clark C. Evans wrote:
On Tue, Jan 11, 2005 at 12:54:36PM -0500, Phillip J. Eby wrote:
| * Replacing LiskovViolation is possible by dropping type/isinstance
| checks from adapt(), and adding an isinstance check to
| object.__conform__; Liskov violators then override __conform__ in their
| class to return None when asked to conform to a protocol they wish to
| reject, and return super().__conform__ for all other cases.  This
| achieves your use case while simplifying both the implementation and the
| usage.
I'd rather not assume that class inheritance implies substitutability,
Hm, you should take that up with Alex then, since that is what his current 
PEP 246 draft does.  :)  Actually, the earlier drafts did that too, so I'm 
not sure why you want to change this now.

What I've actually suggested here actually allows for 
inheritance=substitutability as the default, but also makes it trivially 
changeable for any given inheritance hierarchy by overriding __conform__ at 
the base of that hierarchy, and without introducing a special exception 
class to do it.

___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] PEP 246, redux

2005-01-11 Thread Phillip J. Eby
At 09:23 PM 1/11/05 +0100, Alex Martelli wrote:
Is the concept of *PRAGMATICS* so deucedly HARD for all of your eggheads?!
Hmm.  Pot, meet kettle.  :)

Yes, you're ALLOWED to stuff with NULL any field that isn't explicitly 
specified as NOT NULL.

But you should ONLY do so when the information is REALLY missing, NOT when 
you've lost it along the way because you've implemented adapter-chain 
transitivity: dropping information which you COULD have preserved with a 
bit more care (==without transitivity) is a violation of PRAGMATICS, of 
the BEST-EFFORT implication, just as it would be to drop packets once in a 
while in a TCP/IP stack due to some silly programming bug which was passed 
silently.
This is again a misleading analogy.  You are comparing end-to-end with 
point-to-point.  I am saying that if you have a point-to-point connection 
that drops all packets of a particular kind, you should not put it into 
your network, unless you know that an alternate route exists that can 
ensure those packets get through.  Otherwise, you are breaking the network.

Thus, I am saying that PRAGMATICALLY, it is silly to create a cable that 
drops all ACK packets, for example, and then plug it into your 
network.  And especially, it's silly to turn around that as a reason that 
one should only use end-to-end leased lines, because that packet forwarding 
business is dangerously unreliable!

As far as I can tell, you are arguing that you should never use packet 
forwarding for communication, because somebody might have a router 
somewhere that drops packets.  While I am arguing that if a router is known 
to drop packets incorrectly, the router is broken and should be removed 
from the network, or else bypassed via another route.  And, in the cases 
where you have a leased line direct from point A to point B, your routers 
should be smart enough to use that route in place of forwarding from A to C 
to D to B, or whatever.

___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] copy confusion

2005-01-11 Thread Alex Martelli
On 2005 Jan 11, at 23:20, Fredrik Lundh wrote:
back in Python 2.1 (and before), an object could define how copy.copy 
should
work simply by definining a __copy__ method.  here's the relevant 
portion:

...
try:
copierfunction = _copy_dispatch[type(x)]
except KeyError:
try:
copier = x.__copy__
except AttributeError:
raise error, \
  un(shallow)copyable object of type %s % type(x)
y = copier()
...
I recently discovered that this feature has disappeared in 2.3 and 
2.4.  in-
stead of looking for an instance method, the code now looks at the 
object's
type:
Hmmm, yes, we were discussing this general issue as part of the huge 
recent thread about pep 246.  In the new-style object model, special 
methods are supposed to be looked up on the type, not on the object; 
otherwise, having a class with special methods would be a problem -- 
are the methods meant to apply to the class object itself, or to its 
instances?

However, apparently, the code you quote is doing it wrong:
cls = type(x)
copier = _copy_dispatch.get(cls)
if copier:
return copier(x)
copier = getattr(cls, __copy__, None)
if copier:
return copier(x)
...because getattr is apparently the wrong way to go about it (e.g., it 
could get the '__copy__' from type(cls), which would be mistaken).  
Please see Armin Rigo's only recent post to Python-Dev for the way it 
should apparently be done instead -- assuming Armin is right (he 
generally is), there should be plenty of bugs in copy.py (ones that 
emerge when you're using custom metaclasses c -- are you doing that?).

Still, if you're using an instance of an old-style class, the lookup in 
_copy_dispatch should be on types.InstanceType -- is that what you're 
trying to copy, an instance of an old-style class?


(copy.deepcopy still seems to be able to use __deepcopy__ hooks, 
though)
It starts with a peek into a dispatch dictionary for the type of the 
object, too, just like shallow copy does.  What's the type of what 
you're trying to copy?


is this a bug, or a feature of the revised copy/pickle design?   (the 
code in
copy_reg/copy/pickle might be among the more convoluted pieces of 
python
coding that I ever seen...  and what's that smiley doing in copy.py?)

and if it's a bug, does the fact that nobody reported this for 2.3 
indicate that
I'm the only one using this feature?  is there a better way to control 
copying
that I should use instead?
When I can, I use __getstate__ and __setstate__, simply because they 
seem clear and flexible to be (usable for copying, deep copying, 
pickling).  But that doesn't mean __copy__ or __deepcopy__ should be 
left broken, of course.

Although there are features of design intent here, it does appear to me 
there may be bugs too (if the getattr on the type is wrong); in this 
case it's worrisome, not just that nobody else reported problems, but 
also that the unit tests didn't catch them...:-(

Alex
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] Re: PEP 246: LiskovViolation as a name

2005-01-11 Thread Guido van Rossum
 My point is that it'd be nice if we could come up with an exception name
 which could be grokkable without requiring 1) Google, 2) relatively
 high-level understanding of type theory.

How about SubstitutabilityError?

 The point is broader, though -- when I get my turn in the time machine,
 I'll lobby for replacing NameError with UndefinedVariable or something
 similar (or more useful still).  The former is confusing to novices, and
 while it can be learned, that's yet another bit of learning which is,
 IMO, unnecessary, even though it may be technically more correct.

We did that for UnboundLocalError, which subclasses NameError. Perhaps
we can rename NameError to UnboundVariableError (and add NameError as
an alias for b/w compat).

-- 
--Guido van Rossum (home page: http://www.python.org/~guido/)
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] copy confusion

2005-01-11 Thread Phillip J. Eby
At 11:56 PM 1/11/05 +0100, Alex Martelli wrote:
What both issues?  There's only one issue, it seems to me -- one of 
metaconfusion.
I was relying on Fredrik's report of a problem with the code; that is the 
other issue I referred to.

___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] PEP 246, redux

2005-01-11 Thread Alex Martelli
On 2005 Jan 11, at 22:08, Phillip J. Eby wrote:
   ...
Yes, you're ALLOWED to stuff with NULL any field that isn't 
explicitly specified as NOT NULL.

But you should ONLY do so when the information is REALLY missing, NOT 
when you've lost it along the way because you've implemented 
adapter-chain transitivity: dropping information which you COULD have 
preserved with a bit more care (==without transitivity) is a 
violation of PRAGMATICS, of the BEST-EFFORT implication, just as it 
would be to drop packets once in a while in a TCP/IP stack due to 
some silly programming bug which was passed silently.
This is again a misleading analogy.  You are comparing end-to-end with 
point-to-point.  I am saying that if you have a point-to-point 
connection that drops all packets of a particular kind, you should not 
put it into your network, unless you know that an alternate route 
exists that can ensure those packets get through.  Otherwise, you are 
breaking the network.
But adaptation is not transmission!  It's PERFECTLY acceptable for an 
adapter to facade: to show LESS information in the adapted object than 
was in the original.  It's PERFECTLY acceptable for an adapter to say 
this piece information is not known when it's adapting an object for 
which that information, indeed, is not known.  It's only CONJOINING the 
two perfectly acceptable adapters, as transitivity by adapter chain 
would do automatically, that you end up with a situation that is 
pragmatically undesirable: asserting that some piece of information is 
not known, when the information IS indeed available -- just not by the 
route automatically taken by the transitivity-system.

What happened here is not that either of the adapters registered is 
wrong: each does its job in the best way it can.  The programming 
error, which transitivity hides (degrading the quality of information 
resulting from the system -- a subtle kind of degradation that will be 
VERY hard to unearth), is simply that the programmer forgot to register 
the direct adapter.  Without transitivity, the programmer's mistake 
emerges easily and immediately; transitivity hides the mistake.

By imposing transitivity, you're essentially asserting that, if a 
programmer forgets to code and register an A - C direct adapter, this 
is never a problem, as long as A - B and B - C adapters are 
registered, because A - B - C will give results just as good as the 
direct A - C would have, so there's absolutely no reason to trouble 
the programmer about the trivial detail that transitivity is being 
used.

At the same time, if I understand correctly, you're ALSO saying that if 
two other adapters exist, A - Z and Z - C, *THEN* it's an error, 
because you don't know when adapting A - C whether to go via B or via 
Z.  Well, if you consistently believe what I state in the previous 
paragraph, then this is just weird: since you're implicitly asserting 
that any old A-?-C transitive adaptation is just as good as a direct 
A-C, why should you worry about there being more than one such 2-step 
adaptation available?  Roll the dice to pick one and just proceed.

Please note that in the last paragraph I'm mostly trying to reason by 
absurd: I do NOT believe one can sensibly assert in the general case 
that A-?-C is just as good as A-C, without imposing FAR stronger 
constraints on adaptation that we possibly can (QI gets away with it 
because, designed from scratch, it can and does impose such 
constraints, essentially that all interfaces belong to ONE single 
object -- no independent 3rd party adaptation, which may be a bigger 
loss than the constraints gain, actually).

I'm willing to compromise to the extent of letting any given adaptation 
somehow STATE, EXPLICITLY, this adaptation is lossless and perfect, 
and can be used as a part of transitive chains of adaptation without 
any cost whatsoever.  If we do that, though, the adaptation system 
should trust this assertion, so if there are two possibilities of equal 
minimal length, such as A-B-C or A-Z-C, with all the steps being 
declared lossless and perfect, then it SHOULD just pick one by whatever 
criterion, since both will be equally perfect anyway -- so maybe my 
reasoning by absurd wasn't totally absurd after all;-).

Would this compromise be acceptable to you?
Alex
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] PEP 246, redux

2005-01-11 Thread Clark C. Evans
On Tue, Jan 11, 2005 at 03:30:19PM -0500, Phillip J. Eby wrote:
| Clark said he didn't want to assume substitutability; I was pointing out 
| that he could choose to not assume that, if he wished, by implementing an 
| appropriate __conform__ at the base of his hierarchy. 

Oh, that's sufficient.  If someone making a base class wants to assert
that derived classes should check compliance (rather than having it
automagic), then they can do this.  Good enough!

| I don't agree with Clark's use case, but my 
| proposal supports it as a possibility, and yours does not.

It was a straw-man; and I admit, not a particularly compelling one.

| To implement a Liskov violation with my proposal, you do exactly the same 
| as with your proposal, *except* that you can simply return None instead 
| of raising an exception, and the logic for adapt() is more 
| straightforward.

I think I prefer just returning None rather than raising a
specific exception.  The semantics are different: None implies that
other adaptation mechanisms (like a registry) could be tried, while
LiskovException implies that processing halts and no further 
adaptation techniques are to be used.  In this case, None is 
the better choice for this particular case since it would enable
third-parties to register a wrapper.

Overall, I think both you and Alex are now proposing essentially
the same thing... no?

Best,

Clark

-- 
Clark C. Evans  Prometheus Research, LLC.
http://www.prometheusresearch.com/
o   office: +1.203.777.2550 
  ~/ ,  mobile: +1.203.444.0557 
 //
((   Prometheus Research: Transforming Data Into Knowledge
 \\  ,
   \/- Research Exchange Database
   /\- Survey  Assessment Technologies
   ` \   - Software Tools for Researchers
~ *
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] copy confusion

2005-01-11 Thread Phillip J. Eby
At 02:58 PM 1/11/05 -0800, Guido van Rossum wrote:
[Phillip]
 Looks like a bug to me; it breaks the behavior of classic classes, since
 type(classicInstance) returns InstanceType.
I'm not so sure. I can't seem to break this for classic classes.
Sorry; I was extrapolating from what I thought was Fredrik's description of 
this behavior as a bug, and examining of the history of the code that he 
referenced.  I saw that the current version of that code had evolved 
directly from a version that was retrieving instance.__copy__; I therefore 
assumed that the loss-of-feature Fredrik was reporting was that.

That is, I thought that the problem he was experiencing was that classic 
classes no longer supported __copy__ because this code had changed.  I 
guess I should have looked at other lines of code besides the ones he 
pointed out; sorry about that.  :(


The only thing this intends to break, and then only for new-style
classes, is the ability to have __copy__ be an instance variable
(whose value should be a callable without arguments) -- it must be a
method on the class. This is the same thing that I've done for all
built-in operations (__add__, __getitem__ etc.).
Presumably, this is the actual feature loss that Fredrik's describing; i.e. 
lack of per-instance __copy__ on new-style classes.  That would make more 
sense.


 However, it also looks like it might have been introduced to fix the
 possibility that calling '__copy__' on a new-style class with a custom
 metaclass would result in ending up with an unbound method.  (Similar to
 the metaconfusion issue being recently discussed for PEP 246.)
Sorry, my head just exploded. :-(
The issue is that for special attributes (like __copy__, __conform__, etc.) 
that do not have a corresponding type slot, using getattr() is not 
sufficient to obtain slot-like behavior.  This is because 
'aType.__special__' may refer to a __special__ intended for *instances* of 
'aType', instead of the __special__ for aType.

As Armin points out, the only way to fully emulate type slot behavior for 
unslotted special attributes is to perform a search of the __dict__ of each 
type in the MRO of the type of the object for which you wish to obtain the 
special attribute.

So, in this specific case, __copy__ does not have a type slot, so it is 
impossible using getattr (or simple attribute access) to guarantee that you 
are retrieving the correct version of __copy__ in the presence of metaclasses.

This is what Alex and I dubbed metaconfusion in discussion of the same 
issue for PEP 246's __adapt__ and __conform__ methods; until they have 
tp_adapt and tp_conform slots, they can have this same problem.

Alex and I also just speculated that perhaps the stdlib should include a 
function that can do this, so that stdlib modules that define unslotted 
special attributes (such as __copy__) can ensure they work correctly in the 
presence of metaclasses.

___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] PEP 246, redux

2005-01-11 Thread Phillip J. Eby
At 06:38 PM 1/11/05 -0500, Clark C. Evans wrote:
| To implement a Liskov violation with my proposal, you do exactly the same
| as with your proposal, *except* that you can simply return None instead
| of raising an exception, and the logic for adapt() is more
| straightforward.
I think I prefer just returning None rather than raising a
specific exception.  The semantics are different: None implies that
other adaptation mechanisms (like a registry) could be tried, while
LiskovException implies that processing halts and no further
adaptation techniques are to be used.  In this case, None is
the better choice for this particular case since it would enable
third-parties to register a wrapper.
Overall, I think both you and Alex are now proposing essentially
the same thing... no?
Yes; I'm just proposing shuffling the invocation of things around a bit in 
order to avoid the need for an exception, and in the process increasing the 
number of possible customizations a bit.

Not that I care about those customizations as such; I just would like to 
simplify the protocol.  I suppose there's some educational benefit in 
making somebody explicitly declare that they're a Liskov violator, but it 
seems that if we're going to support it, it should be simple.

___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


[Python-Dev] copy confusion

2005-01-11 Thread Fredrik Lundh
back in Python 2.1 (and before), an object could define how copy.copy should
work simply by definining a __copy__ method.  here's the relevant portion:

...
try:
copierfunction = _copy_dispatch[type(x)]
except KeyError:
try:
copier = x.__copy__
except AttributeError:
raise error, \
  un(shallow)copyable object of type %s % type(x)
y = copier()
...

I recently discovered that this feature has disappeared in 2.3 and 2.4.  in-
stead of looking for an instance method, the code now looks at the object's
type:

...

cls = type(x)

copier = _copy_dispatch.get(cls)
if copier:
return copier(x)

copier = getattr(cls, __copy__, None)
if copier:
return copier(x)

...

(copy.deepcopy still seems to be able to use __deepcopy__ hooks, though)

is this a bug, or a feature of the revised copy/pickle design?   (the code in
copy_reg/copy/pickle might be among the more convoluted pieces of python
coding that I ever seen...  and what's that smiley doing in copy.py?)

and if it's a bug, does the fact that nobody reported this for 2.3 indicate that
I'm the only one using this feature?  is there a better way to control copying
that I should use instead?

/F 



___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


[Python-Dev] Re: copy confusion

2005-01-11 Thread Fredrik Lundh
Guido van Rossum wrote:

 The only thing this intends to break /.../

it breaks classic C types:

 import cElementTree
 x = cElementTree.Element(tag)
 x
Element 'tag' at 00B4BA30
 x.__copy__
built-in method __copy__ of Element object at 0x00B4BA30
 x.__copy__()
Element 'tag' at 00B4BA68
 import copy
 y = copy.copy(x)
Traceback (most recent call last):
  File stdin, line 1, in ?
  File C:\python24\lib\copy.py, line 93, in copy
raise Error(un(shallow)copyable object of type %s % cls)
copy.Error: un(shallow)copyable object of type type 'Element'
 dir(x)
['__copy__', '__deepcopy__', 'append', 'clear', 'find', 'findall', 'findtext',
'get', 'getchildren', 'getiterator', 'insert', 'items', 'keys', 'makeelement', 
'set']
 dir(type(x))
['__class__', '__delattr__', '__delitem__', '__delslice__', '__doc__',
'__getattribute__', '__getitem__', '__getslice__', '__hash__', '__init__',
'__len__', '__new__', '__reduce__', '__reduce_ex__', '__repr__',
'__setattr__', '__setitem__', '__setslice__', '__str__']

(and of course,  custom C types is the only case where I've ever used
__copy__; the default behavior has worked just fine for all other cases)

for cElementTree, I've worked around this with an ugly __reduce__ hack,
but that doesn't feel right...

/F 



___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


RE: [Python-Dev] PEP 246, redux

2005-01-11 Thread Raymond Hettinger
 Thus, my argument is that an adapter like this should never be made
part
 of
 the adapter system, even if there's no transitivity.  However, if you
 agree
 that such an adapter shouldn't be implicit, then it logically follows
that
 there is no problem with allowing transitivity, except of course that
 people may sometimes break the rule.

At some point, the PEP should be extended to include a list of best
practices and anti-patterns for using adapters.  I don't find issues of
transitivity and implicit conversion to be immediately obvious.

Also, it is not clear to me how or if existing manual adaption practices
should change.  For example, if I need a file-like interface to a
string, I currently wrap it with StringIO.  How will that change it the
future?  By an explicit adapt/conform pair?  Or by strings knowing how
to conform to file-like requests?


Raymond Hettinger

___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] Re: [Csv] csv module TODO list

2005-01-11 Thread Andrew McNamara
Would the csv module be a good place to add a DBF reader and writer?  

I would have thought it would make sense as it's own module (in the same
way that we have separate modules that present a common interface for
the different databases), or am I missing something?

I'd certainly like to see a DBF parser in python - reading and writing odd
file formats is bread-and-butter for us contractors... 8-)

-- 
Andrew McNamara, Senior Developer, Object Craft
http://www.object-craft.com.au/
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


[Python-Dev] PEP 246, redux

2005-01-11 Thread Roeland Rengelink
I'm trying to understand the relation between Guido's posts on optional 
 static typing and PEP 245 (interfaces) and 246 (adaptation). I have a 
 couple of questions

PEP 245 proposes to introduce a fundamental distinction between type and 
 interface. However, 245 only introduces a syntax for interfaces, and 
says very little about the semantics of interfaces. (Basically only that 
 if X implements Y then implements(X, Y) will return True). The 
semantics of interfaces are currently only implied by PEP 246, and by 
Guido's  posts referring to 246.

Unfortunately PEP 246 explicitly refuses to decide that protocols are 
245-style interfaces. Therefore, it is not clear to me how acceptance of 
 245 would impact on 246?  Specifically, what would be the difference 
between:

x = adapt(obj, a_245_style_interface)
x = adapt(obj, a_protocol_type)
and, if there is no difference, what would the use-case of interfaces be?
Put another way: explicit interfaces and adaptation based typing seem to 
 be about introducing rigor (dynamic, not static) to Python. Yet, PEP 
245 and 246 seems to go out of their way to give interfaces and 
adaptation as little baggage as possible. So, where is the rigor going 
to come from?

On the one hand this seems very Pythonic - introduce a new feature with 
as little baggage as possible, and see where it evolves from there. Let 
the rigor flow, not from the restrictions of the language, but from the 
 expressive power of the language.

On the other hand: why not, at least:
- explore in 245 how the semantics of interfaces might introduce rigor 
into the language. It would be particularly illuminating to find out in 
what way implementing an interface differs from deriving from an ABC 
and  in what way an interface hierarchy differs semantically from a 
hierarchy  of ABCs

- rewrite 246 under the assumption that 245 (including semantics) has 
been accepted

I would volunteer, but, for those of you who hadn't noticed yet, I don't 
know what I'm talking about.

Cheers,
Roeland Rengelink

___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


RE: [Python-Dev] PEP 246, redux

2005-01-11 Thread Phillip J. Eby
At 07:52 PM 1/11/05 -0500, Raymond Hettinger wrote:
Also, it is not clear to me how or if existing manual adaption practices
should change.  For example, if I need a file-like interface to a
string, I currently wrap it with StringIO.  How will that change it the
future?  By an explicit adapt/conform pair?  Or by strings knowing how
to conform to file-like requests?
The goal here is to be able to specify that a function parameter takes, 
e.g. a readable stream, and that you should be able to either explicitly 
wrap in a StringIO to satisfy this, or *possibly* that you be able to just 
pass a string and have it work automatically.

If the latter is the case, there are a variety of possible ways it might 
work.  str.__conform__ might recognize the readable stream interface, or 
the __adapt__ method of the readable stream interface could recognize 
'str'.  Or, Alex's new proposed global type registry might contain an entry 
for 'str,readableStream'.  Which of these is the preferred scenario very 
much depends on a lot of things, like who defined the readable stream 
interface, and whether anybody has registered an adapter for it!

PyProtocols tries to answer this question by allowing you to register 
adapters with interfaces, and then the interface's __adapt__ method will do 
the actual adaptation.  Zope does something similar, at least in that it 
uses the interface's __adapt__ method, but that method actually uses a 
global registry.

Neither PyProtocols nor Zope make much use of actually implementing 
hand-coded __conform__ or __adapt__ methods, as it's too much trouble for 
something that's so inherently declarative anyway, and only the creator of 
the object class or the interface's type have any ability to define 
adapters that way.  Given that built-in types are often handy sources of 
adaptation (e.g. str-to-StringIO in your example), it isn't practical in 
present-day Python to add a __conform__ method to the str type!

Thus, in the general case it just seems easier to use a per-interface or 
global registry for most normal adaptation, rather than using 
__conform__.  However, having __conform__ exist is a nice out for 
implementing unusual custom requirements (like easy dynamic conformance), 
so I don't think it should be removed.

___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com