Re: [Python-Dev] PEP 246: lossless and stateless
Guido van Rossum wrote: > Are there real-life uses of stateful adapters that would be thrown out > by this requirement? Here are two interfaces we're using in a project: http://just.letterror.com/ltrwiki/PenProtocol (aka "SegmentPen") http://just.letterror.com/ltrwiki/PointPen They're both abstractions for drawing glyphs (characters from a font). Sometimes the former is more practical and sometimes the latter. We really need both interfaces. Yet they can't be adapted without keeping some state in the adapter. Implicit adaptations may be dangerous here, but I'm not so sure I care. In my particular use case, it will be very rare that people want to do funcTakingPointPen(segmentPen) otherFuncTakingPointPen(segmentPen) I don't it will be a problem in general that my adapter carries a bit of state, and that if it _does_ become a problem, it's easy to work around. It's not dissimilar to file.readline() vs. file.next(): sure, it's not pretty that file iteration doesn't work nice with readline(), but all bug reports about that get closed as "won't fix" ;-). It's something you can easily learn to live with. That said, I don't think implicit adaptation from str to file is a good idea... Python (the std lib, really) shouldn't use "dangerous" adapters for implicit adaptation, but that doesn't mean it should be impossible to do so anyway. [ ... ] > But the solution IMO is not to weigh down adapt(), but to agree, as a > user community, not to create such "bad" adapters, period. OTOH there > may be specific cases where the conventions of a particular > application or domain make stateful or otherwise naughty adapters > useful, and everybody understands the consequences and limitations. > Sort of the way that NumPy defines slices as views on the original > data, even though lists define slices as copies of the original data; > you have to know what you are doing with the NumPy slices but the > NumPy users don't seem to have a problem with that. (I think.) [ ... ] > Guarantees again. I think it's hard to provide these, and it feels > unpythonic. [ ... ] > Or maybe we shouldn't try to guarantee so much and instead define > simple, "Pythonic" semantics and live with the warts, just as we do > with mutable defaults and a whole slew of other cases where Python > makes a choice rooted in what is easy to explain and implement (for > example allowing non-Liskovian subclasses). Adherence to a particular > theory about programming is not very Pythonic; doing something that > superficially resembles what other languages are doing but actually > uses a much more dynamic mechanism is (for example storing instance > variables in a dict, or defining assignment as name binding rather > than value copying). Yes, yes and yes! Just ___ 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: lossless and stateless
Hi Guido, On Thu, Jan 13, 2005 at 10:20:40PM -0800, Guido van Rossum wrote: > Hm. Maybe that post points out that adapters that add state are bad, > period. I have to say that the example of adapting a string to a file > using StringIO() is questionable. Another possible adaptation from a > string to a file would be open() I have some theory about why adapting a string to a file in any way is questionable, but why adapting some more specific class to some other class usually "feels right", and about what "lossy" means. In my opinion a user-defined class or interface mixes two notions: a "concept" meaningful for the programmer that the instances represent, and the "interface" provided to manipulate it. Adaptation works well at the "concept" level without all the hassles of information loss and surprizes of transitive adaptation. The problems show up in the cases where a single concrete interface doesn't obviously match to a single "concept". For example, strings "mean" very different concepts in various contexts, e.g. a file name, an url, the byte content a document, or the pickled representation of something. Containers have the similar problem. This suggests that only concrete objects which are expected to encode a *single* concept should be used for adaptation. Note that the theory -- for which I have an old draft at http://arigo.tunes.org/semantic_models.html -- suggests that it is possible to be more precise about various levels of concepts encoding each others, like a string standing for the name of a file itself encoding an image; but I'm not proposing anything similar here, just suggesting a way to realize what kind of adaptation is problematic. > may be specific cases where the conventions of a particular > application or domain make stateful or otherwise naughty adapters > useful, and everybody understands the consequences and limitations. Note that it may be useful to be able to register some adapaters in "local" registeries instead of the single global one, to avoid all kinds of unexpected global effects. For example something along the lines of (but nicer than) : my_registry = AdapterRegister() my_registry.register(...) my_registry.adapt(x, y) # direct use __adaptregistry__ = my_registry def f(x as y): # implicit use of the module-local registry stuff This would allow a module to provide the str->StringIO or str->file conversion locally. A bientot, Armin. ___ 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
On Fri, 14 Jan 2005 08:50:27 +0100, Alex Martelli <[EMAIL PROTECTED]> wrote: > Ooops -- sorry; I wouldn't have imagined Brazilian hits would swamp the > google hits to that extent, mostly qualifying post-grad courses and the > like... seems to be an idiom there for that. 'Lato sensu' is used to indicate short post-graduate level courses that don't give one any recognized degree such as 'MSc', or 'master'. It's pretty much like a specialization course on some specific area, usually offered by small private universities. It's like a fever around here - everyone does just to add something to the resume - and has spawned a entire branch in the educational industry (and yeah, 'industry' is the best word for it). Some schools refer to traditional post graduate courses as 'stricto sensu'. I don't have the slightest idea about where they did get this naming from. It's also amazing how many hits you'll get for the wrong spelling: 'latu sensu' & 'strictu sensu', mostly from Brazil, and also from some spanish-speaking countries. > Also, a reflection: taxonomy, the classification of things (living > beings, rocks, legal precedents, ...) into categories, is a discipline > with many, many centuries of experience behind it. I think it is > telling that taxonomists found out they require _two_ kinds of > ``inheritance'' to do their job (no doubt there are all kind of > _nuances_, but specialized technical wording exists for two kinds: > "strict-sense" and "broad-sense")... they need to be able to assert > that "A is a B _broadly speaking_" (or specifically "_strictly > speaking_") so often that they evolved specific terminology. Let's > hope it doesn't take OOP many centuries to accept that both "stricto > sensu inheritance" (Liskovianly-correct) AND "lato sensu inheritance" > are needed to do _our_ jobs!-) Good point! -- Carlos Ribeiro Consultoria em Projetos blog: http://rascunhosrotos.blogspot.com blog: http://pythonnotes.blogspot.com mail: [EMAIL PROTECTED] mail: [EMAIL PROTECTED] ___ 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] redux: fractional seconds in strptime
Brett> The problem I have always had with this proposal is that the Brett> value is worthless, time tuples do not have a slot for fractional Brett> seconds. Yes, it could possibly be changed to return a float for Brett> seconds, but that could possibly break things. Actually, time.strptime() returns a struct_time object. Would it be possible to extend %S to parse floats then add a microseconds (or whatever) field to struct_time objects that is available by attribute only? In Py3k it could worm its way into the tuple representation somehow (either as a new field or by returning seconds as a float). Brett> My vote is that if something is added it be like %N but without Brett> the optional optional digit count. This allows any separator to Brett> be used while still consuming the digits. It also doesn't Brett> suddenly add optional args which are not supported for any other Brett> directive. I realize the %4N notation is distasteful, but without it I think you will have trouble parsing something like 13:02:00.704 What would be the format string? %H:%M:%S.%N would be incorrect. It works if you allow the digit notation: %H:%M:%S.%3N I think that except for the logging module presentation of fractions of a second would almost always use the locale-specific decimal point, so if that problem is fixed, extending %S to understand floating point seconds would be reasonable. Skip ___ 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] redux: fractional seconds in strptime
On 2005 Jan 14, at 10:36, Skip Montanaro wrote: Brett> The problem I have always had with this proposal is that the Brett> value is worthless, time tuples do not have a slot for fractional Brett> seconds. Yes, it could possibly be changed to return a float for Brett> seconds, but that could possibly break things. Actually, time.strptime() returns a struct_time object. Would it be possible to extend %S to parse floats then add a microseconds (or whatever) field to struct_time objects that is available by attribute only? In Py3k it could worm its way into the tuple representation somehow (either as a new field or by returning seconds as a float). +1 -- I never liked the idea that 'time tuples' lost fractions of a second. On platforms where that's sensible and not too hard, time.time() could also -- unobtrusively and backwards compatibly -- set that same attribute. I wonder if, where the attribute's real value is unknown, it should be None (a correct indication of "I dunno") or 0.0 (maybe handier); instinctively, I would prefer None. "Available by attribute only" is probably sensible, overall, but maybe strftime should make available whatever formatting item[s] strptime may grow to support fractions of a second; and one such item (distinct from %S for guaranteed backwards compatibility) should be "seconds and fraction, with [[presumably, locale-specific]] decimal point inside". 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] redux: fractional seconds in strptime
On Fri, 2005-01-14 at 06:40, Alex Martelli wrote: > +1 -- I never liked the idea that 'time tuples' lost fractions of a > second. On platforms where that's sensible and not too hard, > time.time() could also -- unobtrusively and backwards compatibly -- set > that same attribute. I wonder if, where the attribute's real value is > unknown, it should be None (a correct indication of "I dunno") or 0.0 > (maybe handier); instinctively, I would prefer None. None feels better. I've always thought it was kind of icky for datetimes to use microseconds=0 to decide whether to print the fractional second part or not for isoformat(), e.g.: >>> import datetime >>> now = datetime.datetime.now() >>> now.isoformat() '2005-01-14T06:44:18.013832' >>> now.replace(microsecond=0).isoformat() '2005-01-14T06:44:18' -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] redux: fractional seconds in strptime
On Fri, 2005-01-14 at 09:36, Skip Montanaro wrote: > Actually, time.strptime() returns a struct_time object. Would it be > possible to extend %S to parse floats then add a microseconds (or whatever) > field to struct_time objects that is available by attribute only? +1 for adding a microseconds field to struct_time, but I'd also like to see an integer-only way of parsing fractional seconds in time.strptime. Using floating point makes it harder to support exact comparison of timestamps (an issue I recently ran into when writing unit tests for code storing timestamps in a database). My vote is for %N producing a microseconds field. Mark Russell ___ 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: lossless and stateless
On Thu, Jan 13, 2005 at 08:54:33PM -0500, Raymond Hettinger wrote: | > Since __conform__ and __adapt__ | > would sprout two new arguments, it would make those writing adapters | > think a bit more about the kind of adapter that they are providing. | | Using optional arguments may not be the most elegant or extensible | approach. Perhaps a registry table or adapter attributes would fare | better. I'm not sure how either of these would work since the adapt() function could return `self`. Adapter attributes wouldn't work in that case (or would they?), and since adapters could be given dynamically by __adapt__ or __conform__ a registry isn't all that appropriate. Perhaps we could just pass around a single **kwargs? Best, Clark ___ 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: lossless and stateless
On Fri, Jan 14, 2005 at 12:11:10AM -0500, Phillip J. Eby wrote: | Clark's proposal isn't going to solve this issue for PEP 246, alas. In | order to guarantee safety of adaptive type declarations, the | implementation strategy *must* be able to guarantee that 1) adapters do | not have state of their own, and 2) adapting an already-adapted object | re-adapts the original rather than creating a new adapter. 1. Following Raymond's idea for allowing adaption to reflect more arbitrary properties (which can be used to provide restrictions on the kinds of adapters expected): adapt(object, protocol, default = False, **properties) Request adaptation, where the result matches a set of properties, such as 'lossless', 'stateless'. __conform__(self, protocol, **properties) __adapt__(self, object, **properties) Conform/adapt but optionally parameterized by a set of restrictions. The **properties can be used to inform the adaptation. register(from, to, adapter = None, predicate = None) Register an adaptation path from one protocol to another, optionally providing an adapter. If no adapter is provided, then adapt(from,to,**properties) is used when adapting. If a predicate is provided, then the adaptation path is available only if predicate(**properties) returns True. 2. Perhaps if we just provide a mechanism for an adapter to specify that it's OK to be used "implicitly" via the declaration syntax? def fun(x: Y): ... is equivalent to, def fun(x): x = adapt(x, Y, declaration = True) On Thu, Jan 13, 2005 at 05:52:10PM -0800, Guido van Rossum wrote: | This may solve the current raging argument, but IMO it would | make the optional signature declaration less useful, because | there's no way to accept other kind of adapters. I'd be happier | if def f(X: Y) implied X = adapt(X, Y). Ideally, yes. However, some adapters may want to explicitly disable their usage in this context -- so some differentiation is warranted. This 'revised' proposal puts the burden on the adapter (or its registration) to specify that it shouldn't be used in this context. I'm carefully using 'declaration' as the restriction, not 'stateless'. One may have a stateful adapter which is most appropriate to be used in declarations (see Armin's insightful post). Furthermore, the 'full' version of adapt() where argument 'restrictions' can be specified could be done via a decorator syntax: @adapt(x, Y, **properties) I hope this helps. P.S. Clearly there is much of information to be captured in this thread and put into the PEP (mostly as appendix material); keep posting good ideas, problems, opinions, whatever -- I will summarize over this weekend. -- 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] frame.f_locals is writable
Shane Holloway (IEEE) wrote: For a little background, I'm working on making an edit and continue support in python a little more robust. So, in replacing references to unmodifiable types like tuples and bound-methods (instance or class), I iterate over gc.get_referrers. So, I'm working on frame types, and wrote this code:: def replaceFrame(self, ref, oldValue, newValue): for name, value in ref.f_locals.items(): if value is oldValue: ref.f_locals[name] = newValue assert ref.f_locals[name] is newValue FWIW, this should work: def replaceFrame(self, ref, oldValue, newValue): for name, value in ref.f_locals.items(): if value is oldValue: exec "ref.f_locals[name] = newValue" assert ref.f_locals[name] is newValue And, no, you don't have to tell me that this is an evil hack. I already know that, since I discovered it earlier this evening by poking around in the C source code for PyFrame_LocalsToFast and then looking to see what code calls that function :) Cheers, Nick -- Nick Coghlan | [EMAIL PROTECTED] | Brisbane, Australia --- http://boredomandlaziness.skystorm.net ___ 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: lossless and stateless
On Fri, Jan 14, 2005 at 09:47:15AM +, Armin Rigo wrote: | In my opinion a user-defined class or interface mixes two notions: a | "concept" meaningful for the programmer that the instances | represent, and the "interface" provided to manipulate it. ... | This suggests that only concrete objects which are expected to | encode a *single* concept should be used for adaptation. So, in this view of the world, the adapter from FileName to File _is_ appropriate, but the adapter from String to FileName isn't? def checkSecurity(filename: FileName): ... Hmm. I'd like to be able to pass in a String here, and use that String->FileName adapter. So, there isn't a problem yet; although String is vague in a sense, it doesn't hurt to specialize it in the context that I have in mind. def checkContent(file: File): ... look for well known viruses ... def checkSecurity(filename: FileName): ... look for nasty path information ... return checkContent(filename) Even this is _ok_ since the conceptual jump is specified by the programmer between the two stages. The problem happens when one does... checkContent("is-this-a-filename-or-is-this-content") This is where we run into issues. When an adapter which 'specializes' the content is used implicitly in a trasitive adaption chain. | Note that it may be useful to be able to register some adapaters | in "local" registeries instead of the single global one, to avoid | all kinds of unexpected global effects. Nice... 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: lossless and stateless
At 10:09 AM 1/14/05 +0100, Just van Rossum wrote: Guido van Rossum wrote: > Are there real-life uses of stateful adapters that would be thrown out > by this requirement? Here are two interfaces we're using in a project: http://just.letterror.com/ltrwiki/PenProtocol (aka "SegmentPen") http://just.letterror.com/ltrwiki/PointPen They're both abstractions for drawing glyphs (characters from a font). Sometimes the former is more practical and sometimes the latter. We really need both interfaces. Yet they can't be adapted without keeping some state in the adapter. Maybe I'm missing something, but for those interfaces, isn't it okay to keep the state in the *adapted* object here? In other words, if PointPen just added some private attributes to store the extra data? Implicit adaptations may be dangerous here, but I'm not so sure I care. In my particular use case, it will be very rare that people want to do funcTakingPointPen(segmentPen) otherFuncTakingPointPen(segmentPen) But if the extra state were stored on the segmentPen rather than the adapter, this would work correctly, wouldn't it? Whereas with it stored in an adapter, it wouldn't. ___ 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: lossless and stateless
At 09:47 AM 1/14/05 +, Armin Rigo wrote: For example, strings "mean" very different concepts in various contexts, e.g. a file name, an url, the byte content a document, or the pickled representation of something. Note that this is solvable in practice by the author of a method or framework choosing to define an interface that they accept, and then pre-defining the adaptation from string to that interface. So, what a string "means" in that context is pre-defined. The interpretation problem for strings comes only when a third party attempts to define adaptation from a string to a context that takes some more generic interface. This would allow a module to provide the str->StringIO or str->file conversion locally. It also works for the module to define a target interface and register an adapter to that, and introduces less complexity into the adaptation system. ___ 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: lossless and stateless
Phillip J. Eby wrote: > At 10:09 AM 1/14/05 +0100, Just van Rossum wrote: > >Guido van Rossum wrote: > > > > > Are there real-life uses of stateful adapters that would be > > > thrown out by this requirement? > > > >Here are two interfaces we're using in a project: > > > > http://just.letterror.com/ltrwiki/PenProtocol (aka "SegmentPen") > > http://just.letterror.com/ltrwiki/PointPen > > > >They're both abstractions for drawing glyphs (characters from a > >font). Sometimes the former is more practical and sometimes the > >latter. We really need both interfaces. Yet they can't be adapted > >without keeping some state in the adapter. > > Maybe I'm missing something, but for those interfaces, isn't it okay > to keep the state in the *adapted* object here? In other words, if > PointPen just added some private attributes to store the extra data? > > > >Implicit adaptations may be dangerous here, but I'm not so sure I > >care. In my particular use case, it will be very rare that people > >want to do > > > > funcTakingPointPen(segmentPen) > > otherFuncTakingPointPen(segmentPen) > > But if the extra state were stored on the segmentPen rather than the > adapter, this would work correctly, wouldn't it? Whereas with it > stored in an adapter, it wouldn't. Are you saying the adapter could just hijack some attrs on the adapted object? Or ore you saying the adapted object should be aware of the adapter? Both don't sound right, so I hope I'm misunderstanding... Just ___ 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: lossless and stateless
[Phillip] > Quick demo (strawman syntax) of declaring adapters... > > First, a type declaring that its 'read' method has the semantics of > 'file.read': > > class SomeKindOfStream: > def read(self, byteCount) like file.read: > ... [and more like this] Sorry, this is dead in the water. I have no desire to add syntax complexities like this to satisfy some kind of theoretically nice property. > Second, third-party code adapting a string iterator to a readable file: We need to pick a better example; I like Armin's hypothesis that adapting strings to more specific things is abuse of the adapter concept (paraphrased). > >Are there real-life uses of stateful adapters that would be thrown out > >by this requirement? > > Think about this: [...] No, I asked for a real-life example. Just provided one, and I'm satisfied that stateful adapters can be useful. ["proof" omitted] > Thus, stateful adapters *must* be explicitly adapted by the code that needs > to manage the state. This doesn't prove it at all to me. > This is why I say that PEP 246 is fine, but type declarations need a more > restrictive version. PEP 246 provides a nice way to *find* stateful > adapters, it just shouldn't do it for function arguments. You haven't proven that for me. The example quoted earlier involving print_next_line() does nothing to prove it, since it's a bad use of adaptation for a different reason: string -> file adaptation is abuse. > >But the solution IMO is not to weigh down adapt(), but to agree, as a > >user community, not to create such "bad" adapters, period. > > Maybe. The thing that inspired me to come up with a new approach is that > "bad" adapters are just *sooo* tempting; many of the adapters that we're > just beginning to realize are "bad", were ones that Alex and I both > initially thought were okay. One of my hesitations about adding adapt() and interfaces to the core language has always been that it would change the "flavor" of much of the Python programming we do and that we'd have to relearn how to write good code. There are other places in Python where it can be tempting to use its features in a way that can easily cause trouble (the extremely dynamic nature of the language is always tempting); we tend not to invent new syntax to fix this but instead develop idioms that avoid the issues. IOW, I don't want to make it syntactically impossible to write bad adapters, but we'll have to develop a set of guidelines for writing good adapters. I don't believe for a second that all stateful adapters are bad, even though I expect that stateless lossless adapters are always good. I like Armin's hypothesis better. -- --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] PEP 246: lossless and stateless
Hi Phillip, On Fri, Jan 14, 2005 at 10:22:36AM -0500, Phillip J. Eby wrote: > Note that this is solvable in practice by the author of a method or > framework choosing to define an interface that they accept, and then > pre-defining the adaptation from string to that interface. So, what a > string "means" in that context is pre-defined. I'm trying to reserve the usage of "interface" to something more concrete: the concrete ways we have to manipulate a given object (typically a set of methods including some unwritten expectations). We might be talking about the same thing, then, but just to check: I'm making sense of the above paragraph in two steps. First, I read it with "interface" replaced by "concept": the author of the method chooses what concepts the input arguments carry: a file or a file name, for example. Then he chooses which particular interface he'd like to access the input arguments through: if it's a file, then it's probably via the standard file-like methods; if it's a file name, then it's probably as a string. It's important to do it in two steps, even if in practice a lot of concepts typically comes with a single associated interface (both together, they are a "duck type"). The programmer using existing methods also goes through two steps: first, he considers the "intuitive" signature of the method, which includes a reasonable name and conceptual arguments. Then he traditionally has to care about the precise interface that the callee expects. For example, he knows that in some specific situation he wants to use marshal.load[s](something), but he has to check precisely which interface the function expects for 'something': a file name string, a file-like object, a real file, a content string? Adaptation should make the latter part more automatic, and nothing more. Ideally, both the caller and the callee know (and write down) that the function's argument is a "reference to some kind of file stuff", a very general concept; then they can independently specify which concrete object they expect and provide, e.g. "a string naming a file", "a file-like object", "a string containing the data". What I see in most arguments about adaptation/conversion/cast is some kind of confusion that would make us believe that the concrete interface (or even worse the formal one) fully defines what underlying concepts they represent. It is true only for end-user application-specific classes. > The interpretation problem for strings comes only when a third party > attempts to define adaptation from a string to a context that takes some > more generic interface. In the above example, there is nothing in the general concept that helps the caller to guess how a plain string will be interpreted, or symmetrically that helps the callee to guess what an incoming plain string means. In my opinion this should fail, in favor of something more explicit. It's already a problem without any third party. > >(...) conversion locally. > > It also works for the module to define a target interface and register an > adapter to that, and introduces less complexity into the adaptation system. Makes sense, but my fear is that people will soon register generic adapters all around... debugging nightmares! Armin ___ 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] frame.f_locals is writable
Brett C. wrote: Other option would be to add a function that either directly modified single values in f_localsplus, a function that takes a dict and propogates the values, or a function that just calls PyFrame_LocalsToFast() . Brett!! Thanks for looking this up! With a little help from ctypes, I was able to call PyFrame_LocalsToFast, and it works wonderfully! Maybe this method could be added to the frame type itself? Personally I am against this, but that is because you would single-handedly ruin my master's thesis and invalidate any possible type inferencing one can do in Python without some semantic change. But then again my thesis shows that amount of type inferencing is not worth the code complexity so it isn't totally devastating. =) Well, at least in theory this only allows the developer to replace a variable with a better (hopefully) version of a class that is very similar... > And you are right, "don't do that". =) I'm going to only remember this trick in the light of development tools. Really! This magic is WAY too deep for a library. The only use for it that I could really see is a smalltalk-like swap method. Thanks again for your help! -Shane ___ 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] frame.f_locals is writable
FWIW, this should work: def replaceFrame(self, ref, oldValue, newValue): for name, value in ref.f_locals.items(): if value is oldValue: exec "ref.f_locals[name] = newValue" assert ref.f_locals[name] is newValue And, no, you don't have to tell me that this is an evil hack. I already know that, since I discovered it earlier this evening by poking around in the C source code for PyFrame_LocalsToFast and then looking to see what code calls that function :) Yes. After poking around in Google with PyFrame_LocalsToFast, I found some other links to people doing that. I implemented a direct call using ctypes to make the code explicit about what's happening. I'm just glad it is possible now. Works fine in both 2.3 and 2.4. Thanks, -Shane ___ 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: lossless and stateless
At 08:32 AM 1/14/05 -0800, Guido van Rossum wrote: I have no desire to add syntax complexities like this to satisfy some kind of theoretically nice property. Whether it's syntax or a decorator, it allows you to create stateless adapters without needing to write individual adapter *classes*, or even having an explicit notion of an "interface" to adapt to. That is, it makes it very easy to write a "good" adapter; you can do it without even trying. The point isn't to make it impossible to write a "bad" adapter, it's to make it more attractive to write a good one. Also, btw, it's not a "theoretically nice" property. I just tried making PyProtocols 'Adapter' class immutable, and reran PEAK's unit tests, exercising over 100 adapter classes. *Three* had state. All were trivial caching, not per-adapter state. However, even had they *not* been trivial caching, this suggests that there are a *lot* of use cases for stateless adapters, and that means that a trivial 'like' decorator can make it very easy to write stateless adapters. What I'm suggesting is effectively replacing PEP 246's global registry with one that can generate a stateless adapter from individual operation declarations. But it can still fall back on __conform__ and __adapt__ if there aren't any declarations, and we could also require adapt() to return the same adapter instance if an adapter is stateful. No, I asked for a real-life example. Just provided one, and I'm satisfied that stateful adapters can be useful. But his example doesn't require *per-adapter* state, just per-original-object state. As long as there's a clean way to support that, his example still works -- and in fact it works *better*, because then that "rare" case he spoke of will work just fine without even thinking about it. Therefore, I think we should make it easy for stateful adapters to link their state to the adapted object, not the adapter instance. This better matches most people's intuitive mental model of adaptation, as judged by the comments of people in this discussion who were new to adaptation. If adapt() promised to return the same (stateful) adapter instance each time, then Just's "rare" example would work nicely, without a bug. One of my hesitations about adding adapt() and interfaces to the core language has always been that it would change the "flavor" of much of the Python programming we do and that we'd have to relearn how to write good code. Exactly! I came up with the monkey typing idea specifically to address this very issue, because the PEP discussion has shown that it is hard to learn to write good adapters, and very easy to be tempted to write bad ones. If there is a very easy way to write good adapters, then it will be more attractive to learn about it. If you have to do a little bit more to get per-object state, and then it's hardest of all to get per-adapter state, the model is a good match to the frequency of those use cases. Even better, it avoids creating the concept of an interface, except that you want something "like" a file or a dictionary. It's the first Python "interface" proposal I know of that can actually spell the loose notion of "file-like" in a concretely useful way! I think the concept can be extended slightly to work with stateful (per-object) adapters, though I'll have to give it some thought and prototyping. I don't believe for a second that all stateful adapters are bad, Neither do I. It's *per-adapter-instance* state that's bad, or at least that no good use cases have yet been shown for. If we can make it easy to have *per-adapted-object* state, or guarantee "same-adapter return", then that's even better. For example, if there were a weak reference dictionary mapping objects to their (stateful) adapters, then adapt() could always return the same adapter instance for a given source object, thus guaranteeing a single state. Of course, this would also imply that adapt() needs to know that an adapter is stateful, so that it doesn't keep around lots of trivial stateless adapters. Thus, there should be a little more effort required to create this kind of adapter (i.e., you need to say that it's stateful). By the way, I've encountered the need for *this* kind of stateful adapter more than once; PyProtocols has a notion of a StickyAdapter, that keeps per-adapted-object state, which is sometimes needed because you can't hold on to the "same adapter" for some reason. The StickyAdapter attaches itself to the original object, such that when you adapt that object again, you always get the same StickyAdapter instance. In basically all the use cases I found where there's a *really* stateful adapter, I'm using a StickyAdapter, not trying to have per-adapter-instance state. So, what I'm suggesting is that we make it ridiculously easy for somebody to create adapters that either have no state, or that have "sticky" state, and make it obscure at best to create one that ha
Re: [Python-Dev] PEP 246: lossless and stateless
At 04:39 PM 1/14/05 +, Armin Rigo wrote: Ideally, both the caller and the callee know (and write down) that the function's argument is a "reference to some kind of file stuff", a very general concept; then they can independently specify which concrete object they expect and provide, e.g. "a string naming a file", "a file-like object", "a string containing the data". Yes, exactly! That's what I mean by "one use case, one interface". But as you say, that's because we don't currently have a way to separate these ideas. So, in developing with PyProtocols, I create a new interface for each concept, possibly allowing adapters for some other interface to supply default implementations for that concept. But, for things like strings and such, I define direct adapters to the new concept, so that they override any "generic" adapters as you call them. So, I have a path that looks like: concreteType -> functionalInterface -> conceptInterface Except that there's also a shorter concreteType -> conceptInterface path for various types like string, thus providing context-sensitivity. (Interestingly, strings are the *most* common instance of this situation, as they're one of the most "open to interpretation" objects you can have!) > It also works for the module to define a target interface and register an > adapter to that, and introduces less complexity into the adaptation system. Makes sense, but my fear is that people will soon register generic adapters all around... debugging nightmares! Well, if you have "interface per concept", you *have* a context; the context is the concept itself. ___ 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: lossless and stateless
On Fri, Jan 14, 2005 at 04:39:00PM +, Armin Rigo wrote: | I'm trying to reserve the usage of "interface" to something more | concrete: the concrete ways we have to manipulate a given object | (typically a set of methods including some unwritten expectations). I'd say that a programmer interface intends to encapsulates both the 'concept' and the 'signature'. The concept is indicated by the names of the function delcarations and fields, the signature by the position and type of arguments. | Adaptation should make [passing data between conceptually equivalent | interfaces?] more automatic, and nothing more. Ideally, both the caller | and the callee know (and write down) that the function's argument is a | "reference to some kind of file stuff", a very general concept; then they | can independently specify which concrete object they expect and provide, | e.g. "a string naming a file", "a file-like object", "a string containing | the data". But it is quite difficult to know when two interfaces are conceptually equivalent... | What I see in most arguments about adaptation/conversion/cast is some kind | of confusion that would make us believe that the concrete interface (or | even worse the formal one) fully defines what underlying concepts they | represent. It is true only for end-user application-specific classes. It seems your distinction comes down to defining 'best pratice' for when you define an adapter... and when you don't. Perhaps we don't need to qualify the adapters that exist, as much as make them transparent to the programmer. A bad adapter will most likely be detected _after_ a weird bug has happened. Perhaps the adapt() framework can provide meaningful information in these cases. Imagine enhancing the stack-trace with additional information about what adaptations were made; Traceback (most recent call last): File "xxx", line 1, in foo Adapting x to File File "yyy", line 384, in bar Adapting x to FileName etc. | In the above example, there is nothing in the general concept that helps | the caller to guess how a plain string will be interpreted, or | symmetrically that helps the callee to guess what an incoming plain | string means. In my opinion this should fail, in favor of something | more explicit. It's already a problem without any third party. How can we express your thoughts so that they fit into a narrative describing how adapt() should and should not be used? If you could respond by re-posting your idea with the 'average python programmer' as your audience it would help me quite a bit when summarizing your contribution to the thread. Best, Clark ___ 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: lossless and stateless
On Fri, Jan 14, 2005 at 12:28:16PM -0500, Phillip J. Eby wrote: | At 08:32 AM 1/14/05 -0800, Guido van Rossum wrote: | >I have no desire to add syntax | >complexities like this to satisfy some kind of theoretically nice | >property. | | Whether it's syntax or a decorator, it allows you to create stateless | adapters without needing to write individual adapter *classes*, or even | having an explicit notion of an "interface" to adapt to. That is, it | makes it very easy to write a "good" adapter; you can do it without even | trying. The point isn't to make it impossible to write a "bad" adapter, | it's to make it more attractive to write a good one. Phillip, May I suggest that you write this up as a PEP? Being dead in the water isn't always fatal. Right now you're ideas are still very fuzzy and by forcing yourself to come up with a narrative, semantics section, minimal implementation, and examples, you will go along way to both refining your idea and also allowing others to better understand what you're proposing. Cheers, Clark ___ 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: lossless and stateless
Phillip J. Eby wrote: > For example, if there were a weak reference dictionary mapping > objects to their (stateful) adapters, then adapt() could always > return the same adapter instance for a given source object, thus > guaranteeing a single state. Wouldn't that tie the lifetime of the adapter object to that of the source object? Possibly naive question: is using adaptation to go from iterable to iterator abuse? That would be a clear example of per-adapter state. Just ___ 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] redux: fractional seconds in strptime
Skip Montanaro wrote: Brett> The problem I have always had with this proposal is that the Brett> value is worthless, time tuples do not have a slot for fractional Brett> seconds. Yes, it could possibly be changed to return a float for Brett> seconds, but that could possibly break things. Actually, time.strptime() returns a struct_time object. Would it be possible to extend %S to parse floats then add a microseconds (or whatever) field to struct_time objects that is available by attribute only? In Py3k it could worm its way into the tuple representation somehow (either as a new field or by returning seconds as a float). Right, it's a struct_time object; just force of habit to call it a time tuple. And I technically don't see why a fractional second attribute could not be added that is not represented in the tuple. But I personally would like to see struct_tm eliminated in Py3k and replaced with datetime usage. My wish is to have the 'time' module stripped down to only the bare essentials that just don't fit in datetime and push everyone to use datetime for most things. Brett> My vote is that if something is added it be like %N but without Brett> the optional optional digit count. This allows any separator to Brett> be used while still consuming the digits. It also doesn't Brett> suddenly add optional args which are not supported for any other Brett> directive. I realize the %4N notation is distasteful, but without it I think you will have trouble parsing something like 13:02:00.704 What would be the format string? %H:%M:%S.%N would be incorrect. Why is that incorrect? -Brett ___ 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] redux: fractional seconds in strptime
On Fri, Jan 14, 2005, Brett C. wrote: > > Right, it's a struct_time object; just force of habit to call it a time > tuple. > > And I technically don't see why a fractional second attribute could not be > added that is not represented in the tuple. But I personally would like to > see struct_tm eliminated in Py3k and replaced with datetime usage. My wish > is to have the 'time' module stripped down to only the bare essentials that > just don't fit in datetime and push everyone to use datetime for most > things. Because of people doing things like year, month, day, hour, min, sec, junk, junk, junk = time.localtime() -- Aahz ([EMAIL PROTECTED]) <*> http://www.pythoncraft.com/ "19. A language that doesn't affect the way you think about programming, is not worth knowing." --Alan Perlis ___ 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: lossless and stateless
> Date: Fri, 14 Jan 2005 02:38:05 -0500 > From: "Phillip J. Eby" <[EMAIL PROTECTED]> > Subject: Re: [Python-Dev] PEP 246: lossless and stateless > To: [EMAIL PROTECTED] > Cc: "Clark C. Evans" <[EMAIL PROTECTED]>, python-dev@python.org > Message-ID: <[EMAIL PROTECTED]> > Content-Type: text/plain; charset="us-ascii"; format=flowed > > Each of these examples registers the function as an implementation of the > "file.read" operation for the appropriate type. When you want to build an > adapter from SomeKindOfStream or from a string iterator to the "file" type, > you just access the 'file' type's descriptors, and look up the > implementation registered for that descriptor for the source type > (SomeKindOfStream or string-iter). If there is no implementation > registered for a particular descriptor of 'file', you leave the > corresponding attribute off of the adapter class, resulting in a class > representing the subset of 'file' that can be obtained for the source class. > > The result is that you generate a simple adapter class whose only state is > a read-only slot pointing to the adapted object, and descriptors that bind > the registered implementations to that object. That is, the descriptor > returns a bound instancemethod with an im_self of the original object, not > the adapter. (Thus the implementation never even gets a reference to the > adapter, unless 'self' in the method is declared of the same type as the > adapter, which would be the case for an abstract method like 'readline()' > being implemented in terms of 'read'.) > > Anyway, it's therefore trivially "guaranteed" to be stateless (in the same > way that an 'int' is "guaranteed" to be immutable), and the implementation > is also "guaranteed" to be able to always get back the "original" object. > > Defining adaptation in terms of adapting operations also solves another > common problem with interface mechanisms for Python: the dreaded "mapping > interface" and "file-like object" problem. Really, being able to > *incompletely* implement an interface is often quite useful in practice, so > this "monkey see, monkey do" typing ditches the whole concept of a complete > interface in favor of "explicit duck typing". You're just declaring "how > can X act 'like' a duck" -- emulating behaviors of another type rather than > converting structure. I get it! Your last description didn't quite sink in but this one does and I've been thinking about this quite a bit, and I like it. I'm starting to see how it nicely sidesteps the problems discussed in the thread so far. Partial implementation of interfaces (read, implementing only the operations you care about on a method by method basis instead of an entire interface) really is very useful and feels quite pythonic to me. After all, in most cases of substitutability in Pyhton (in my experience), it's not the *type* you do anything with, but that type's operations. Does anyone know of any other languages that take this "operational" aproach to solving the substitutability problem? There seem to be some downsides vs. interfaces (I think) the lack of "it's documentation too" aspect, I find zope 3 interfaces.py modules the best way to learn about it, but again the upside is, no complex interface relationships just to define the subtle variations of "mapping" and users can always just say help(file.read). Another thing I see used fairly commonly are marker interfaces. While I'm not sure of their overall usefullness I don't see how they can be done using your operational scheme. Maybe that means they were a bad idea in the first place. I also think this is easier for beginners to understand, instead of "you have to implement this interface, look at it over here, that's the "file" interface, now you implement that in your object and you better do it all right" you just tell them "call your method 'read' and say its 'like file.read' and your thing will work where any file can be read. -Michel ___ 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] redux: fractional seconds in strptime
>> I realize the %4N notation is distasteful, but without it I think you >> will have trouble parsing something like >> >> 13:02:00.704 >> >> What would be the format string? %H:%M:%S.%N would be incorrect. Brett> Why is that incorrect? Because "704" represents the number of milliseconds, not the number of nanoseconds. I'm sure that in some applications people are interested in extremely short time scales. Writing out hours, minutes and seconds when all you are concerned with are small fractions of seconds (think high energy physics) would be a waste. In those situations log entries like 704 saw proton 705 proton hit neutron 706 saw electron headed toward Saturn might make perfect sense. Parsing the time field entirely within time.strptime would be at least clumsy if you couldn't tell it the scale of the numbers you're dealing with. Parsing with %N, %3N or %6N would give different values (nanoseconds, milliseconds or microseconds). Skip ___ 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] redux: fractional seconds in strptime
On 2005 Jan 14, at 19:11, Aahz wrote: On Fri, Jan 14, 2005, Brett C. wrote: Right, it's a struct_time object; just force of habit to call it a time tuple. And I technically don't see why a fractional second attribute could not be added that is not represented in the tuple. But I personally would like to see struct_tm eliminated in Py3k and replaced with datetime usage. My wish is to have the 'time' module stripped down to only the bare essentials that just don't fit in datetime and push everyone to use datetime for most things. Because of people doing things like year, month, day, hour, min, sec, junk, junk, junk = time.localtime() And why would that be a problem? It would keep working just like today, assuming you're answering the "don't see why" part. From the start, we discussed fractional seconds being available only as an ATTRIBUTE of a struct_time, not an ITEM (==iteration on a struct_time will keep working just line now). 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] redux: fractional seconds in strptime
On Fri, Jan 14, 2005, Alex Martelli wrote: > On 2005 Jan 14, at 19:11, Aahz wrote: >>On Fri, Jan 14, 2005, Brett C. wrote: >>> >>>Right, it's a struct_time object; just force of habit to call it a >>>time tuple. >>> >>>And I technically don't see why a fractional second attribute could >>>not be added that is not represented in the tuple. But I personally >>>would like to see struct_tm eliminated in Py3k and replaced with >>>datetime usage. My wish is to have the 'time' module stripped down >>>to only the bare essentials that just don't fit in datetime and push >>>everyone to use datetime for most things. >> >>Because of people doing things like >> >>year, month, day, hour, min, sec, junk, junk, junk = time.localtime() > > And why would that be a problem? It would keep working just like > today, assuming you're answering the "don't see why" part. From the > start, we discussed fractional seconds being available only as an > ATTRIBUTE of a struct_time, not an ITEM (==iteration on a struct_time > will keep working just line now). Uh, I missed the second "not" in Brett's first sentence of second paragraph. Never mind! -- Aahz ([EMAIL PROTECTED]) <*> http://www.pythoncraft.com/ "19. A language that doesn't affect the way you think about programming, is not worth knowing." --Alan Perlis ___ 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: lossless and stateless
On Fri, Jan 14, 2005 at 10:02:39AM -0800, Michel Pelletier wrote: | Phillip J. Eby wrote: | > The result is that you generate a simple adapter class whose | > only state is a read-only slot pointing to the adapted object, | > and descriptors that bind the registered implementations to that object. it has only the functions in the interface, plus the adaptee; all requests through the functions are forwarded on to their equivalent in the adaptee; sounds alot like the adapter pattern ;) | I get it! Your last description didn't quite sink in but this one does | and I've been thinking about this quite a bit, and I like it. I'm | starting to see how it nicely sidesteps the problems discussed in | the thread so far. I'm not sure what else this mechanism provides; besides limiting adapters so that they cannot maintain their own state. | Does anyone know of any other languages that take this "operational" | aproach to solving the substitutability problem? Microsoft's COM? | I also think this is easier for beginners to understand, instead of | "you have to implement this interface, look at it over here, | that's the "file" interface, now you implement that in your object | and you better do it all right" you just tell them "call your | method 'read' and say its 'like file.read' and your thing will work | where any file can be read. A tangable example would perhaps better explain... Looking forward to the PEP, Clark ___ 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: lossless and stateless
On 2005 Jan 14, at 20:25, Clark C. Evans wrote: | Does anyone know of any other languages that take this "operational" | aproach to solving the substitutability problem? Microsoft's COM? I don't see the parallel: COM (QueryInterface) is strictly by-interface, not by-method, and has many other differences. 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: lossless and stateless
At 06:56 PM 1/14/05 +0100, Just van Rossum wrote: Phillip J. Eby wrote: > For example, if there were a weak reference dictionary mapping > objects to their (stateful) adapters, then adapt() could always > return the same adapter instance for a given source object, thus > guaranteeing a single state. Wouldn't that tie the lifetime of the adapter object to that of the source object? Well, you also need to keep the object alive if the adapter is still hanging around. I'll get to implementation details and alternatives in the PEP. Possibly naive question: is using adaptation to go from iterable to iterator abuse? That would be a clear example of per-adapter state. I don't know if it's abuse per se, but I do know that speciifying whether a routine takes an iterable or can accept an iterator is often something important to point out, and it's a requirement that back-propagates through code, forcing explicit management of the iterator's state. So, if you were going to do some kind of adaptation with iterators, it would be much more useful IMO to adapt the *other* way, to turn an iterator into a reiterable. Coincidentally, a reiterable would create per-object state. :) In other words, if you *did* consider iterators to be adaptation, it seems to me an example of wanting to be explicit about when the adapter gets created, if its state is per-adapter. And the reverse scenario (iterator->reiterable) is an example of adaptation where shared state could solve a problem for you if it's done implicitly. (E.g. by declaring that you take a reiterable, but allowing people to pass in iterators.) ___ 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: lossless and stateless
At 12:41 PM 1/14/05 -0500, Clark C. Evans wrote: May I suggest that you write this up as a PEP? Already committed to it for this weekend, but my statement was buried in a deep thread between Alex and I, so you might've missed 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: lossless and stateless
At 10:02 AM 1/14/05 -0800, Michel Pelletier wrote: I get it! Thanks for the positive feedback, I was getting worried that I had perhaps gone quite insane during the great debate. :) Your last description didn't quite sink in but this one does and I've been thinking about this quite a bit, and I like it. I'm starting to see how it nicely sidesteps the problems discussed in the thread so far. Good, I'll try to cherry-pick from that post when writing the PEP. Does anyone know of any other languages that take this "operational" aproach to solving the substitutability problem? This can be viewed as a straightforward extension of the COM or Java type models in two specific ways: 1) You can implement an interface incompletely, but still receive a partial adapter 2) Third parties can supply implementations of individual operations Everything else is pretty much like COM pointers to interfaces, or Java casting. Of course, as a consequence of #1, you also have to declare conformance per-operation rather than per-interface, but some syntactic sugar for declaring a block of methods would be helpful. But that's a detail; declaring support for an interface in COM or Java is just "like" automatically adding all the individual "like" declarations. Alternatively, you can look at this as a dumbed-down version of protocols or typeclasses in functional languages that use generic or polymorphic operations as the basis of their type system. E.g. in Haskell a "typeclass" categorizes types by common operations that are available to them. For example the 'Ord' typeclass represents types that have ordering via operations like <, >, and so forth. However, you don't go and declare that a type is in the 'Ord' typeclass, what you do is *implement* those operations (which may be by defining how to call some other operation the type has) and the type is automatically then considered to be in the typeclass. (At least, that's my understanding as a non-Haskell developer who's skimmed exactly one tutorial on the language! I could be totally misinterpreting what I read.) Anyway, all of these systems were inspirations, if that's what you're asking. There seem to be some downsides vs. interfaces (I think) the lack of "it's documentation too" aspect, I find zope 3 interfaces.py modules the best way to learn about it, but again the upside is, no complex interface relationships just to define the subtle variations of "mapping" and users can always just say help(file.read). It doesn't *stop* you from using interfaces of whatever stripe for documentation, though. The target type can be abstract. All that's required is that it *be* a type (and that restriction might be loosen-able via an adapter!) and that it have descriptors that will indicate the callable operations. So Zope interfaces still work; there's no requirement that the descriptor something is "like" can't be an empty function with a docstring, like it is in a Zope or PyProtocols interface. Another thing I see used fairly commonly are marker interfaces. While I'm not sure of their overall usefullness I don't see how they can be done using your operational scheme. Add an operation to them, or an attribute like 'isFoo'. Then declare an implementation that returns true, if the appropriate object state matches. (I presume you're talking about Zope's per-instance marker interfaces that come and go based on object state.) Maybe that means they were a bad idea in the first place. Probably so! But they can still be done, if you really need one. You just have to recast it in terms of some kind of operation or attribute. I also think this is easier for beginners to understand, instead of "you have to implement this interface, look at it over here, that's the "file" interface, now you implement that in your object and you better do it all right" you just tell them "call your method 'read' and say its 'like file.read' and your thing will work where any file can be read. You don't even need to call it read; you could use the word "read" in the non-English language of your choice; any code that wants a "file" will still be able to invoke it using "read". (And English speakers will at least know they're looking at code that's "like" file.read.) ___ 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: lossless and stateless
At 02:25 PM 1/14/05 -0500, Clark C. Evans wrote: I'm not sure what else this mechanism provides; besides limiting adapters so that they cannot maintain their own state. * No need to write adapter classes for stateless adapters; just declare methods * Allows partial adapters to be written for e.g. "file-like" objects without creating lots of mini-interfaces and somehow relating them all * No need to explain the concept of "interface" to somebody who just knows that the routine they're calling needs a "file" and they need to make their object "work like" a file in some way. (That is, more supportive of "programming for everybody") * Supports using either concrete or abstract types as effective interfaces * Doesn't require us to create explicit interfaces for the entire stdlib, if saying something's "like" an existing abstract or concrete type suffices! * Supports abstract operations like "dict.update" that can automatically flesh out partial adapters (i.e, if you have an object with an operation "like" dict.__setitem__, then a generic dict.update can be used to complete your adaptation) * Doesn't require anybody to write __conform__ or __adapt__ methods in order to get started with adaptation. This is really more of a replacement for PEP 245 than 246 in some ways, but of course it relates to 246 also, since the idea would basically be to integrate it with the "global registry" described in 246. In other words, "like" declarations should populate the global registry, and in such a way that state is unified for (per-object) stateful adapters. ___ 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] redux: fractional seconds in strptime
Skip Montanaro wrote: >> I realize the %4N notation is distasteful, but without it I think you >> will have trouble parsing something like >> >> 13:02:00.704 >> >> What would be the format string? %H:%M:%S.%N would be incorrect. Brett> Why is that incorrect? Because "704" represents the number of milliseconds, not the number of nanoseconds. I'm sure that in some applications people are interested in extremely short time scales. Writing out hours, minutes and seconds when all you are concerned with are small fractions of seconds (think high energy physics) would be a waste. In those situations log entries like 704 saw proton 705 proton hit neutron 706 saw electron headed toward Saturn might make perfect sense. Parsing the time field entirely within time.strptime would be at least clumsy if you couldn't tell it the scale of the numbers you're dealing with. Parsing with %N, %3N or %6N would give different values (nanoseconds, milliseconds or microseconds). Fine, but couldn't you also do a pass over the data after extraction to get to the actual result you want (so parse, and take the millisecond value and multiply by the proper scale)? This feels like it is YAGNI, or at least KISS. If you want to handle milliseconds because of the logging module, fine. But trying to deal with all possible time parsing possibilities is painful and usually not needed. Personally I am more inclined to add a new directive that acts as %S but allows for an optional decimal point, comma or the current locale's separator if it isn't one of those two which will handle the logging package's optional decimal output ('\d+([,.%s]\d+)?" % locale.localeconv()['decimal_point']). Also doesn't break any existing code. And an issue I forgot to mention for all of this is it will break symmetry with time.strftime(). If symmetry is kept then an extra step in strftime will need to be handled since whatever solution we do will not match the C spec anymore. -Brett ___ 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: lossless and stateless
On Fri, 2005-01-14 at 10:07 -0500, Phillip J. Eby wrote: > Maybe I'm missing something, but for those interfaces, isn't it okay to > keep the state in the *adapted* object here? In other words, if PointPen > just added some private attributes to store the extra data? I have been following this discussion with quite a lot of interest, and I have to confess that a lot of what's being discussed is confusing me. I use stateful adapters quite a bit - Twisted has long had a concept of "sticky" adapters (they are called "persistent" in Twisted, but I think I prefer "sticky"). Sometimes my persistent adapters are sticky, sometimes not. Just's example of iter() as an adaptation is a good example of a non-sticky stateful adaptation, but this example I found interesting, because it seems that the value-judgement of stateless adapters as "good" is distorting design practices to make other mistakes, just to remove state from adapters. I can't understand why PJE thinks - and why there seems to be a general consensus emerging - that stateless adapters are intrinsically better. For the sake of argument, let's say that SegmentPen is a C type, which does not have a __dict__, and that PointPen is a Python adapter for it, in a different project. Now, we have nowhere to hide PointPen's state on SegmentPen - and why were we trying to in the first place? It's a horrible breach of encapsulation. The whole *point* of adapters is to convert between *different* interfaces, not merely to rename methods on the same interface, or to add extra methods that work on the same data. To me, "different interfaces" means that the actual meaning of the operations is different - sometimes subtly, sometimes dramatically. There has to be enough information in one interface to get started on the implementation of another, but the fact that such information is necessary doesn't mean it is sufficient. It doesn't mean that there is enough information in the original object to provide a complete implementation of a different interface. If there were enough information, why not just implement all of your interfaces on the original class? In the case of our hypothetical cSegmentPen, we *already* have to modify the implementation of the original class to satisfy the needs of a "stateless" adapter. When you're modifying cSegmentPen, why not just add the methods that you wanted in the first place? Here's another example: I have a business logic class which lives in an object database, typically used for a web application. I convert this into a desktop application. Now, I want to adapt IBusinessThunk to IGtkUIPlug. In the process of doing so, I have to create a GTK widget, loaded out of some sort of resource file, and put it on the screen. I have to register event handlers which are associated with that adapter. The IBusinessThunk interface doesn't specify a __dict__ attribute as part of the interface, or the ability to set arbitrary attributes. And nor should it! It is stored in an indexed database where every attribute has to be declared, maybe, or perhaps it uses Pickle and sticking a GTK widget into its representation would make it un-pickleable. Maybe it's using an O/R mapper which loses state that is not explicitly declared or explicitly touch()ed. There are a variety of problems which using it in this unsupported way might create, but as the implementor of a IGtkUIPlug, I should be concerned *only* with what IBusinessThunk provides, which is .embezzle() and .checkFundsAvailable(). I am not writing an adapter from DBBusinessThunkImpl, after all, and perhaps I am receiving a test implementation that works entirely differently. This example gets to the heart of what makes interfaces useful to me - model/view separation. Although one might be hard pressed to call some of the things I use adaptation for "views", the idea of mediated access from a user, or from network protocol, or from some internal code acting on behalf of a user is the overwhelming majority of my use-cases. Most of the other use-cases I can think of are like the one James mentions, where we really are using adaptation to shuffle around some method names and provide simple glossing over totally isomorphic functionality to provide backwards (or sideways, in the case of almost-identical libraries provided on different platforms or environments) compatibility. For these reasons I would vastly prefer it if transitivity were declared as a property of the *adaptation*, not of the adapter or the registry or to be inferred from various vaguely-defined properties like "losslessness" or "statelessness". I am also concerned about any proposal which introduces transitivity-based errors at adaptation time rather than at registration time, because by then it is definitely too late to do anything about it. I wish I had a better suggestion, but I'm still struggling through the rest of the thread :). ___ Python-Dev mailing li
Re: [Python-Dev] PEP 246: lossless and stateless
On Jan 14, 2005, at 19:02, Glyph Lefkowitz wrote: On Fri, 2005-01-14 at 10:07 -0500, Phillip J. Eby wrote: Maybe I'm missing something, but for those interfaces, isn't it okay to keep the state in the *adapted* object here? In other words, if PointPen just added some private attributes to store the extra data? Here's another example: I have a business logic class which lives in an object database, typically used for a web application. I convert this into a desktop application. Now, I want to adapt IBusinessThunk to IGtkUIPlug. In the process of doing so, I have to create a GTK widget, loaded out of some sort of resource file, and put it on the screen. I have to register event handlers which are associated with that adapter. The IBusinessThunk interface doesn't specify a __dict__ attribute as part of the interface, or the ability to set arbitrary attributes. And nor should it! It is stored in an indexed database where every attribute has to be declared, maybe, or perhaps it uses Pickle and sticking a GTK widget into its representation would make it un-pickleable. Maybe it's using an O/R mapper which loses state that is not explicitly declared or explicitly touch()ed. There are a variety of problems which using it in this unsupported way might create, but as the implementor of a IGtkUIPlug, I should be concerned *only* with what IBusinessThunk provides, which is .embezzle() and .checkFundsAvailable(). I am not writing an adapter from DBBusinessThunkImpl, after all, and perhaps I am receiving a test implementation that works entirely differently. This example gets to the heart of what makes interfaces useful to me - model/view separation. Although one might be hard pressed to call some of the things I use adaptation for "views", the idea of mediated access from a user, or from network protocol, or from some internal code acting on behalf of a user is the overwhelming majority of my use-cases. I think the idea is that it's "better" to have an adapter from IBusinessThunk -> IGtkUIPlugFactory, which you can use to *create* a stateful object that complies with the IGtkUIPlug interface. This way, you are explicitly creating something entirely new (derived from something else) with its own lifecycle and state and it should be managed accordingly. This is clearly not simply putting a shell around an IBusinessThunk that says "act like this right now". -bob ___ 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: lossless and stateless
On Fri, 14 Jan 2005 19:02:52 -0500, Glyph Lefkowitz <[EMAIL PROTECTED]> wrote: > On Fri, 2005-01-14 at 10:07 -0500, Phillip J. Eby wrote: > > > Maybe I'm missing something, but for those interfaces, isn't it okay to > > keep the state in the *adapted* object here? In other words, if PointPen > > just added some private attributes to store the extra data? > > I have been following this discussion with quite a lot of interest, and > I have to confess that a lot of what's being discussed is confusing me. > I use stateful adapters quite a bit - Twisted has long had a concept of > "sticky" adapters (they are called "persistent" in Twisted, but I think > I prefer "sticky"). Sometimes my persistent adapters are sticky, > sometimes not. Just's example of iter() as an adaptation is a good > example of a non-sticky stateful adaptation, but this example I found > interesting, because it seems that the value-judgement of stateless > adapters as "good" is distorting design practices to make other > mistakes, just to remove state from adapters. I can't understand why > PJE thinks - and why there seems to be a general consensus emerging - > that stateless adapters are intrinsically better. My feeling here was not that people thought that stateless adapters were in general intrinsically better -- just when the adaptation was going to be done implicitly (e.g. by type declarations). When no state is involved, adapting an object multiple times can be guaranteed to produce the same adapted object, so if this happens implicitly, it's not a big deal. When state is involved, _some_ decisions have to be made, and it seems like those decisions should be made explicitly... Steve -- You can wordify anything if you just verb it. --- Bucky Katt, Get Fuzzy ___ 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: lossless and stateless
At 05:37 PM 1/14/05 -0700, Steven Bethard wrote: On Fri, 14 Jan 2005 19:02:52 -0500, Glyph Lefkowitz <[EMAIL PROTECTED]> wrote: > On Fri, 2005-01-14 at 10:07 -0500, Phillip J. Eby wrote: > > > Maybe I'm missing something, but for those interfaces, isn't it okay to > > keep the state in the *adapted* object here? In other words, if PointPen > > just added some private attributes to store the extra data? > > I have been following this discussion with quite a lot of interest, and > I have to confess that a lot of what's being discussed is confusing me. > I use stateful adapters quite a bit - Twisted has long had a concept of > "sticky" adapters (they are called "persistent" in Twisted, but I think > I prefer "sticky"). Sometimes my persistent adapters are sticky, > sometimes not. Just's example of iter() as an adaptation is a good > example of a non-sticky stateful adaptation, but this example I found > interesting, because it seems that the value-judgement of stateless > adapters as "good" is distorting design practices to make other > mistakes, just to remove state from adapters. I can't understand why > PJE thinks - and why there seems to be a general consensus emerging - > that stateless adapters are intrinsically better. My feeling here was not that people thought that stateless adapters were in general intrinsically better -- just when the adaptation was going to be done implicitly (e.g. by type declarations). Yes, exactly. :) When no state is involved, adapting an object multiple times can be guaranteed to produce the same adapted object, so if this happens implicitly, it's not a big deal. When state is involved, _some_ decisions have to be made, and it seems like those decisions should be made explicitly... At last someone has been able to produce a concise summary of my insane ramblings. :) Yes, this is precisely the key: implicit adaptation should always return an adapter with the "same" state (for some sensible meaning of "same"), because otherwise control of an important aspect of the system's behavior is too widely distributed to be able to easily tell for sure what's going on. It also produces the side-effect issue of possibly introducing transitive adaptation, and again, that property is widely distributed and hard to "see". Explicit adaptation to add per-adapter state is just fine; it's only *implicit* "non-sticky stateful" adaptation that creates issues. Thus, the PEP I'm working on focuses on making it super-easy to make stateless and sticky stateful adapters with a bare minimum of declarations and interfaces and such. ___ 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: lossless and stateless
At 07:02 PM 1/14/05 -0500, Glyph Lefkowitz wrote: For the sake of argument, let's say that SegmentPen is a C type, which does not have a __dict__, and that PointPen is a Python adapter for it, in a different project. There are multiple implementation alternatives possible here; it isn't necessary that the state be hidden there. The point is that, given the same SegmentPen, we want to get the same PointPen each time we *implicitly* adapt, in order to avoid violating the "naive" developer's mental model of what adaptation is -- i.e. an extension of the object's state, not a new object with independent state. One possible alternative implementation is to use a dictionary from object id to a 'weakref(ob),state' tuple, with the weakref set up to remove the entry when 'ob' goes away. Adapters would then have a pointer to their state object and a pointer to the adaptee. As long as an adapter lives, the adaptee lives, so the state remains valid. Or, if no adapters remain, but the adaptee still lives, then so does the state which can be resurrected when a new adapter is requested. It's too bad Python doesn't have some sort of deallocation hook you could use to get notified when an object goes away. Oh well. Anyway, as you and I have both pointed out, sticky adaptation is an important use case; when you need it, you really need it. This example gets to the heart of what makes interfaces useful to me - model/view separation. Although one might be hard pressed to call some of the things I use adaptation for "views", the idea of mediated access from a user, or from network protocol, or from some internal code acting on behalf of a user is the overwhelming majority of my use-cases. If every time you pass a "model" to something that expects a "view", you get a new "view" instance being created, things are going to get mighty confusing, mighty fast. In contrast, explicit adaptation with 'adapt(model,IView)' or 'IView(model)' allows you to explicitly control the lifecycle of the view (or views!) you want to create. Guido currently thinks that type declaration should be implemented as 'adapt(model,IView)'; I think that maybe it should be restricted (if only by considerations of "good style") to adapters that are sticky or stateless, reserving per-state adaptation for explicit creation via today's 'adapt()' or 'IFoo(ob)' APIs. I wish I had a better suggestion, but I'm still struggling through the rest of the thread :). I'll be starting work on the PEP soon, maybe I'll have a rough draft of at least the first few sections ready to post tonight so everybody can get started on ripping them to pieces. The sooner I know about the holes, the sooner I can fix 'em. Or alternatively, the sooner Guido shoots it down, the less work I have to do on the PEP. :) ___ 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] frame.f_locals is writable
Shane Holloway (IEEE) wrote: Yes. After poking around in Google with PyFrame_LocalsToFast, I found some other links to people doing that. I implemented a direct call using ctypes to make the code explicit about what's happening. I'm just glad it is possible now. Works fine in both 2.3 and 2.4. I realised after posting that the exec-based hack only works for poking values into the _current_ frame's locals, so my trick wouldn't have done what you needed, anyway. Cheers, Nick. -- Nick Coghlan | [EMAIL PROTECTED] | Brisbane, Australia --- http://boredomandlaziness.skystorm.net ___ 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: lossless and stateless
On Fri, 2005-01-14 at 19:14 -0500, Bob Ippolito wrote: > I think the idea is that it's "better" to have an adapter from > IBusinessThunk -> IGtkUIPlugFactory, which you can use to *create* a > stateful object that complies with the IGtkUIPlug interface. > > This way, you are explicitly creating something entirely new (derived > from something else) with its own lifecycle and state and it should be > managed accordingly. This is clearly not simply putting a shell around > an IBusinessThunk that says "act like this right now". Yes. This is exactly what I meant to say. Maybe there are 2 entirely different use-cases for adaptation, and we shouldn't be trying to confuse the two, or conflate them into one system? I am going to go have a look at PEAK next, to see why there are so many stateless adapters there. ___ 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