[Python-Dev] Re: Delayed evaluation of f-strings?
> On 24 Jun 2021, at 10:28, micro codery wrote: > > As pointed out already, f-strings and format are subtly different (not > counting that one can eval and the other cannot). Besides quoting, the > f-sting mini language has diverged from format's spam="Spam" f"{spam=}" > "spam='Spam'" "{spam=}".format(spam=spam) > Traceback (most recent call last): > File "", line 1, in > KeyError: 'spam=' > > I created a package some time ago to do exactly this > https://pypi.org/project/f-yeah/ Lovely! Thanks. —eric ___ Python-Dev mailing list -- python-dev@python.org To unsubscribe send an email to python-dev-le...@python.org https://mail.python.org/mailman3/lists/python-dev.python.org/ Message archived at https://mail.python.org/archives/list/python-dev@python.org/message/RIWZ6ABBMQXB32QVUCJU43QZM3HNZ74R/ Code of Conduct: http://python.org/psf/codeofconduct/
[Python-Dev] Re: Delayed evaluation of f-strings?
Except I like the mini-language of f-strings much better than format()’s. And there is a performance difference between f-strings and format(). > On 24 Jun 2021, at 19:03, Luciano Ramalho wrote: > > I don't think that would be a good idea since we already have > .format() which covers that use case and is more flexible than > f-strings (it supports positional arguments, as well as *args and > **kwargs). > > I think keeping f-strings simple is a better idea. > > Best, > > Luciano > > On Thu, Jun 24, 2021 at 1:30 PM Eric Nieuwland > wrote: >> >> In a recent discussion with a colleague we wondered if it would be possible >> to postpone the evaluation of an f-string so we could use it like a regular >> string and .format() or ‘%’. >> >> I found >> https://stackoverflow.com/questions/42497625/how-to-postpone-defer-the-evaluation-of-f-strings >> and tweaked it a bit to: >> >> import inspect >> >> class DelayedFString(str): >>def __str__(self): >>vars = inspect.currentframe().f_back.f_globals.copy() >>vars.update(inspect.currentframe().f_back.f_locals) >>return self.format(**vars) >> >> delayed_fstring = DelayedFString("The current name is {name}") >> >> # use it inside a function to demonstrate it gets the scoping right >> def new_scope(): >>names = ["foo", "bar"] >>for name in names: >>print(delayed_fstring) >> >> new_scope() >> >> >> While this does what it should it is very slow. >> So I wondered whether it would be an idea to introduce d-strings (delayed >> f-strings) and make f-strings syntactic sugar for >> >> f"The current name is {name}" = str(d"The current name is {name}") >> >> >> And perhaps access to the variables and conversions specified in the >> d-string. >> >> ___ >> Python-Dev mailing list -- python-dev@python.org >> To unsubscribe send an email to python-dev-le...@python.org >> https://mail.python.org/mailman3/lists/python-dev.python.org/ >> Message archived at >> https://mail.python.org/archives/list/python-dev@python.org/message/GT5DNA7RKRLFWE3V42OTWB7X5ER7KNSL/ >> Code of Conduct: http://python.org/psf/codeofconduct/ > > > > -- > Luciano Ramalho > | Author of Fluent Python (O'Reilly, 2015) > | http://shop.oreilly.com/product/0636920032519.do > | Technical Principal at ThoughtWorks > | Twitter: @ramalhoorg ___ Python-Dev mailing list -- python-dev@python.org To unsubscribe send an email to python-dev-le...@python.org https://mail.python.org/mailman3/lists/python-dev.python.org/ Message archived at https://mail.python.org/archives/list/python-dev@python.org/message/YJQDXGTFX7G2P6OLYT3QF3IFN7Z65FSG/ Code of Conduct: http://python.org/psf/codeofconduct/
[Python-Dev] Re: Delayed evaluation of f-strings?
I didn’t make myself clear, sorry. The code example was just to give an initial what I was suggesting. The errors you show demonstrate the example is incomplete. I’d like them to work. > On 24 Jun 2021, at 18:37, Martin (gzlist) wrote: > > On Thu, 24 Jun 2021 at 17:25, Eric Nieuwland wrote: >> >> class DelayedFString(str): >>def __str__(self): >>vars = inspect.currentframe().f_back.f_globals.copy() >>vars.update(inspect.currentframe().f_back.f_locals) >>return self.format(**vars) > > This isn't quite right as the semantics between f-strings and > str.format() are not actually the same (though this isn't well > documented): > >>>> f'{1 + 2}' >'3' >>>> str(DelayedFString('{1 + 2}')) >Traceback (most recent call last): > File "", line 1, in > File "", line 5, in __str__ >KeyError: '1 + 2' > >>>> d = dict(a=1) >>>> f'{d["a"]}' >'1' >>>> str(DelayedFString('{d["a"]}')) >Traceback (most recent call last): > File "", line 1, in > File "", line 5, in __str__ >KeyError: '"a"' > > Basically, f-strings rely on eval-like semantics. > > Martin ___ Python-Dev mailing list -- python-dev@python.org To unsubscribe send an email to python-dev-le...@python.org https://mail.python.org/mailman3/lists/python-dev.python.org/ Message archived at https://mail.python.org/archives/list/python-dev@python.org/message/L5U7ES6PS5LW532PAP62CD4PU55WEBAI/ Code of Conduct: http://python.org/psf/codeofconduct/
[Python-Dev] Delayed evaluation of f-strings?
In a recent discussion with a colleague we wondered if it would be possible to postpone the evaluation of an f-string so we could use it like a regular string and .format() or ‘%’. I found https://stackoverflow.com/questions/42497625/how-to-postpone-defer-the-evaluation-of-f-strings and tweaked it a bit to: import inspect class DelayedFString(str): def __str__(self): vars = inspect.currentframe().f_back.f_globals.copy() vars.update(inspect.currentframe().f_back.f_locals) return self.format(**vars) delayed_fstring = DelayedFString("The current name is {name}") # use it inside a function to demonstrate it gets the scoping right def new_scope(): names = ["foo", "bar"] for name in names: print(delayed_fstring) new_scope() While this does what it should it is very slow. So I wondered whether it would be an idea to introduce d-strings (delayed f-strings) and make f-strings syntactic sugar for f"The current name is {name}" = str(d"The current name is {name}") And perhaps access to the variables and conversions specified in the d-string. ___ Python-Dev mailing list -- python-dev@python.org To unsubscribe send an email to python-dev-le...@python.org https://mail.python.org/mailman3/lists/python-dev.python.org/ Message archived at https://mail.python.org/archives/list/python-dev@python.org/message/GT5DNA7RKRLFWE3V42OTWB7X5ER7KNSL/ Code of Conduct: http://python.org/psf/codeofconduct/
[Python-Dev] Re: The repr of a sentinel
To add to the suggestions already given in this thread I dug into code I wrote some time ago. Offered as an inspiration. === missing.py === from typing import Any def MISSING(klass: Any) -> Any: """ create a sentinel to indicate a missing instance of a class :param klass: the class of which an instance is missing :return: missing class object """ g = globals() missing_klass_name = f"_MISSING_{klass.__module__}_{klass.__name__}_MISSING_" if missing_klass_name not in g: g[missing_klass_name] = type( missing_klass_name, (klass,), { "__repr__": lambda x: f"MISSING({klass.__name__})", } ) return g[missing_klass_name]() === and as a demo: === demo_missing.py === import pickle from missing import MISSING x = MISSING(str) y = "bar" print(f"{x!r} == {y!r}: {x == y}") print(f"{x!r} is {y!r}: {x is y}") # MISSING(str) == 'bar': False # MISSING(str) is 'bar': False with open("object.pickled", "wb") as f: pickle.dump(x, f) with open("object.pickled", "rb") as f: y = pickle.load(f) print(f"{x!r} == {y!r}: {x == y}") print(f"{x!r} is {y!r}: {x is y}") # MISSING(str) == MISSING(str): True # MISSING(str) is MISSING(str): False def foo(a: int = MISSING(int), b: int = MISSING(int)): print(f"{a=} {isinstance(a, int)}") print(f"{b=} {isinstance(b, int)}") print(f"{a!r} == {b!r}: {a == b}") print(f"{a!r} is {b!r}: {a is b}") foo() # a=MISSING(int) True # b=MISSING(int) True # MISSING(int) == MISSING(int): True # MISSING(int) is MISSING(int): False foo(1) # a=1 True # b=MISSING(int) True # 1 == MISSING(int): False # 1 is MISSING(int): False class Test: ... t = MISSING(Test) print(f"{t=}") # t=MISSING(Test) ===___ Python-Dev mailing list -- python-dev@python.org To unsubscribe send an email to python-dev-le...@python.org https://mail.python.org/mailman3/lists/python-dev.python.org/ Message archived at https://mail.python.org/archives/list/python-dev@python.org/message/NABTH4G5IZZYCFSH2RBQNLQL3BKEUFKQ/ Code of Conduct: http://python.org/psf/codeofconduct/
[Python-Dev] Re: The repr of a sentinel
To add to the suggestions already given in this thread I dug into code I wrote some time ago. Offered as an inspiration. === missing.py === from typing import Any def MISSING(klass: Any) -> Any: """ create a sentinel to indicate a missing instance of a class :param klass: the class of which an instance is missing :return: missing class object """ g = globals() missing_klass_name = f"_MISSING_{klass.__module__}_{klass.__name__}_MISSING_" if missing_klass_name not in g: g[missing_klass_name] = type( missing_klass_name, (klass,), { "__repr__": lambda x: f"MISSING({klass.__name__})", } ) return g[missing_klass_name]() === and as a demo: === demo_missing.py === import pickle from missing import MISSING x = MISSING(str) y = "bar" print(f"{x!r} == {y!r}: {x == y}") print(f"{x!r} is {y!r}: {x is y}") # MISSING(str) == 'bar': False # MISSING(str) is 'bar': False with open("object.pickled", "wb") as f: pickle.dump(x, f) with open("object.pickled", "rb") as f: y = pickle.load(f) print(f"{x!r} == {y!r}: {x == y}") print(f"{x!r} is {y!r}: {x is y}") # MISSING(str) == MISSING(str): True # MISSING(str) is MISSING(str): False def foo(a: int = MISSING(int), b: int = MISSING(int)): print(f"{a=} {isinstance(a, int)}") print(f"{b=} {isinstance(b, int)}") print(f"{a!r} == {b!r}: {a == b}") print(f"{a!r} is {b!r}: {a is b}") foo() # a=MISSING(int) True # b=MISSING(int) True # MISSING(int) == MISSING(int): True # MISSING(int) is MISSING(int): False foo(1) # a=1 True # b=MISSING(int) True # 1 == MISSING(int): False # 1 is MISSING(int): False class Test: ... t = MISSING(Test) print(f"{t=}") # t=MISSING(Test) === ___ Python-Dev mailing list -- python-dev@python.org To unsubscribe send an email to python-dev-le...@python.org https://mail.python.org/mailman3/lists/python-dev.python.org/ Message archived at https://mail.python.org/archives/list/python-dev@python.org/message/42O33BFRJLDFVKX4XSKMZ6VLR7H7GXKP/ Code of Conduct: http://python.org/psf/codeofconduct/
[Python-Dev] Matching syntax and semantics
Hi all, Some days back Mark Shannon posted his view/proposal pattern matching on github. While reading it I realised an intermediate step between matching and variable assignment might do away with part of the discussion. I wrote it in an issue with the view/proposal (https://github.com/markshannon/pattern-matching/issues/1) Thinking about it a bit longer, it really might be worth exploring the idea more, so let me repeat it here: 1. In a pattern the values to match are marked with a special symbol (‘$’, ‘!’ or ‘?’ seem candidates). 2. A matching case produces a tuple of matched values. The tuple may be nested to reflect the matched structure. 3. The tuple may be deconstructed according to the usual rules. As an example: example_value = Example("bar", Embedded(None, "foo"), 42, "baz") match example_value: case Example($, Embedded($, "foo"), 42, $) as t: # t = ("bar”, (None, ), "baz”) pass case Example($, Embedded($, "foo"), 42, $) as pre, *rest: # pre = "bar", rest = ((None, ), "baz”) pass alternatively: match example_value: case pre, *rest = t = Example($, Embedded($, "foo"), 42, $): # pre = "bar", rest = ((None, ), "baz”) # t = ("bar”, (None, ), "baz”) pass Just my $0.02 —eric ___ Python-Dev mailing list -- python-dev@python.org To unsubscribe send an email to python-dev-le...@python.org https://mail.python.org/mailman3/lists/python-dev.python.org/ Message archived at https://mail.python.org/archives/list/python-dev@python.org/message/XSRGCA6L3GYKKHQHZYKMPOM3KTI72STC/ Code of Conduct: http://python.org/psf/codeofconduct/
[Python-Dev] Re: PEP 622: Arrow for capture patterns
On 5 Sep 2020 Ram Rachum wrote: > > Hi everyone, > > Sorry if this was proposed already. I looked here > https://www.python.org/dev/peps/pep-0622/#alternatives-for-constant-value-pattern, > search for "idea to make lookup semantics the default". I saw that a few > symbols like $ and ? were proposed, and I thought that maybe the annotation > syntax -> could indicate a capture expression, like so: > >case x: >match Point(-> a, -> b): >... >match -> whatever: >do_something(whatever) > > I like the arrow because it's easy to imagine the value "entering" the > variable. What do you think? > > > Thanks, > Ram. Nice! :) Combined with keywords that could become: Point(x -> a, y -> b) or, mixed with providing values: Point(x -> a, y=42) And we wouldn’t need match -> whatever: because we already have x, and if x is an expression I’d prefer case x as whatever: ___ Python-Dev mailing list -- python-dev@python.org To unsubscribe send an email to python-dev-le...@python.org https://mail.python.org/mailman3/lists/python-dev.python.org/ Message archived at https://mail.python.org/archives/list/python-dev@python.org/message/AFTPEB5R2JMGVLIOOYDCGMMX2QNSTAWJ/ Code of Conduct: http://python.org/psf/codeofconduct/
[Python-Dev] Re: Pattern matching (alternative to PEP 622)
> On 4 Aug 2020, at 14:38, Koos Zevenhoven wrote: > > Hi everyone, > > [ … analysis of design goals and possible solutions, including … ] > > Point3D(x=pi, y=SIX, z=value) It suddenly struck me that Point3D(x=pi, y=SIX, z into value) would quite accurately describe what is being established here. > [ … goes on … ] > > matches > > and that would evaluate to a boolean-like value. Yes. I’d like that as it separates functionality (pattern matching) from the control structure (match statement). > [ … ] > > Similarly, also > point matches main_diagonal_point(pos?) > should only match if x == y == z — and then bind that value to pos. > However, one might expect to be able to write the same thing inline as > point matches Point3D(pos?, pos?, pos?) > , so based on that, multiple occurrences of the same binding target should > ensure equality. > > > What about wildcards? If ? were the wildcard, that would mean that > point matches main_diagonal_point(?) > should NOT mean the same as > point matches Point3D(?,?,?) > > [ … ] Clever observations! > —Koos —eric ___ Python-Dev mailing list -- python-dev@python.org To unsubscribe send an email to python-dev-le...@python.org https://mail.python.org/mailman3/lists/python-dev.python.org/ Message archived at https://mail.python.org/archives/list/python-dev@python.org/message/4YPDAYTSJW3AV6FO7PCWXJ74FQST4JLC/ Code of Conduct: http://python.org/psf/codeofconduct/
[Python-Dev] PEP 622: Structural Pattern Matching -- followup
On 24/06/2020 20:38, Guido van Rossum wrote: > Everyone, > > If you've commented and you're worried you haven't been heard, please=20 > add your issue *concisely* to this new thread. Note that the following=20 > issues are already open and will be responded to separately; please=20 > don't bother commenting on these until we've done so: > > - Alternative spellings for '|' > - Whether to add an 'else' clause (and how to indent it) > - A different token for wildcards instead of '_' > - What to do about the footgun of 'case foo' vs. 'case .foo' > > (Note that the last two could be combined, e.g. '?foo' or 'foo?' to=20 > mark a variable binding and '?' for a wildcard.) Can we extend the syntax for the match statement from match_stmt: "match" expression ':' NEWLINE INDENT case_block+ DEDENT to match_stmt: "match" expression ['as' NAME] ':' NEWLINE INDENT case_block+ DEDENT with the same meaning as in "with"? So the variable with the NAME assumes the value of the expression. That way I won’t have to use the walrus at every case where I need the full result of the expression. It could even be used to get rid of the walrus_pattern entirely. Example: match nested_data[index].attribute as foo: ... case SomeClass(…): bar(foo) … case AnotherClass(…): baz(foo) … ___ Python-Dev mailing list -- python-dev@python.org To unsubscribe send an email to python-dev-le...@python.org https://mail.python.org/mailman3/lists/python-dev.python.org/ Message archived at https://mail.python.org/archives/list/python-dev@python.org/message/N7DWR5ZNF23HSBRPEPP2GWWKQSYM32AM/ Code of Conduct: http://python.org/psf/codeofconduct/
[Python-Dev] PEP 622: Structural Pattern Matching -- followup
> On 25 Jul 2020, at 03:44, Rob Cliffe wrote: > > Without arguing for or against allowing a capture variable, IMO rather > than syntax like >match into : > it would be far better (and not require a new keyword) to write this as >with as match : > > On 24/06/2020 20:38, Guido van Rossum wrote: >> Everyone, >> >> If you've commented and you're worried you haven't been heard, please=20 >> add your issue *concisely* to this new thread. Note that the following=20 >> issues are already open and will be responded to separately; please=20 >> don't bother commenting on these until we've done so: >> >> - Alternative spellings for '|' >> - Whether to add an 'else' clause (and how to indent it) >> - A different token for wildcards instead of '_' >> - What to do about the footgun of 'case foo' vs. 'case .foo' >> >> (Note that the last two could be combined, e.g. '?foo' or 'foo?' to=20 >> mark a variable binding and '?' for a wildcard.) >> We already have 'with' for contexts. We already have patterns with 'as': - except expression "as" identifier ":" - "import" module "as" identifier - "with" expression "as" target So I think this would be quite confusing. ___ Python-Dev mailing list -- python-dev@python.org To unsubscribe send an email to python-dev-le...@python.org https://mail.python.org/mailman3/lists/python-dev.python.org/ Message archived at https://mail.python.org/archives/list/python-dev@python.org/message/PDVN3D3FCIM34VGNTEUYTFKYPA57B3Z6/ Code of Conduct: http://python.org/psf/codeofconduct/
[Python-Dev] Re: Python-Dev Digest, Vol 204, Issue 129
On 24/06/2020 20:38, Guido van Rossum wrote: > Everyone, > > If you've commented and you're worried you haven't been heard, please=20 > add your issue *concisely* to this new thread. Note that the following=20 > issues are already open and will be responded to separately; please=20 > don't bother commenting on these until we've done so: > > - Alternative spellings for '|' > - Whether to add an 'else' clause (and how to indent it) > - A different token for wildcards instead of '_' > - What to do about the footgun of 'case foo' vs. 'case .foo' > > (Note that the last two could be combined, e.g. '?foo' or 'foo?' to=20 > mark a variable binding and '?' for a wildcard.) Can we extend the syntax for the match statement from match_stmt: "match" expression ':' NEWLINE INDENT case_block+ DEDENT to match_stmt: "match" expression ['as' NAME] ':' NEWLINE INDENT case_block+ DEDENT with the same meaning as in "with"? So the variable with the NAME assumes the value of the expression. That way I won’t have to use the walrus at every case where I need the full result of the expression. It could even be used to get rid of the walrus_pattern entirely. Example: match nested_data[index].attribute as foo: ... case SomeClass(…): bar(foo) … case AnotherClass(…): baz(foo) … ___ Python-Dev mailing list -- python-dev@python.org To unsubscribe send an email to python-dev-le...@python.org https://mail.python.org/mailman3/lists/python-dev.python.org/ Message archived at https://mail.python.org/archives/list/python-dev@python.org/message/IJCTESGMZF6NI7ZTSGLRIXLPA7EN4TF2/ Code of Conduct: http://python.org/psf/codeofconduct/
[Python-Dev] Re: Python-Dev Digest, Vol 204, Issue 129
> On 25 Jul 2020, at 03:44, Rob Cliffe wrote: > > Without arguing for or against allowing a capture variable, IMO rather > than syntax like > match into : > it would be far better (and not require a new keyword) to write this as > with as match : > > On 24/06/2020 20:38, Guido van Rossum wrote: >> Everyone, >> >> If you've commented and you're worried you haven't been heard, please=20 >> add your issue *concisely* to this new thread. Note that the following=20 >> issues are already open and will be responded to separately; please=20 >> don't bother commenting on these until we've done so: >> >> - Alternative spellings for '|' >> - Whether to add an 'else' clause (and how to indent it) >> - A different token for wildcards instead of '_' >> - What to do about the footgun of 'case foo' vs. 'case .foo' >> >> (Note that the last two could be combined, e.g. '?foo' or 'foo?' to=20 >> mark a variable binding and '?' for a wildcard.) >> We already have 'with' for contexts. We already have patterns with 'as': - except expression "as" identifier ":" - "import" module "as" identifier - "with" expression "as" target So I think this would be quite confusing. ___ Python-Dev mailing list -- python-dev@python.org To unsubscribe send an email to python-dev-le...@python.org https://mail.python.org/mailman3/lists/python-dev.python.org/ Message archived at https://mail.python.org/archives/list/python-dev@python.org/message/U27FYK4U34M7FGDIUTDQZCNAU2MV7UNW/ Code of Conduct: http://python.org/psf/codeofconduct/
[Python-Dev] Re: PEP 622 constant value syntax idea
> From: Baptiste Carvello > Subject: [Python-Dev] Re: PEP 622 constant value syntax idea > > What about simply "is", which is already a keyword? > > AFAIK "is" has no meaning as a prefix operator as of now, so hopefully > it would not make the grammar ambiguous (how can one check that for sure?). > > match color: >case is RED: >print("red") >case is BLUE: >print("blue") >case other: >print(f"unknown color {other}") > > or with Rhodri James' example: > > match value: >case is x: >print("value matches") >case Point(is x, y): >print("value matches x, y captured") >case Line(Point(is x1, y1), Point(x2, is y2)): >print("wouldn't call that pretty, but not ugly either") > > > Cheers, > Baptiste > > P.S.: granted, it could mislead some users into thinking that the > comparison is done with "is" instead of "=="; but then, patterns are > special in many ways, users will have to just learn them… That is exactly why I think you should make the special things special and keep the familiar things as you know them. So constants and variables like they are in other uses and matched values/patterns using a special construction/syntax. And we don’t need the catch all case if we would have the IMHO more familiar: match Color(…) as color: case RED: print(f”{color} is red") case BLUE: print(f”{color} is blue”) else: print(f"unknown color {color}”) thus eliminating the whole ‘case ’ issue. ___ Python-Dev mailing list -- python-dev@python.org To unsubscribe send an email to python-dev-le...@python.org https://mail.python.org/mailman3/lists/python-dev.python.org/ Message archived at https://mail.python.org/archives/list/python-dev@python.org/message/4NTH5H6RX2KTVVJFJUF53UWESJIBCLYS/ Code of Conduct: http://python.org/psf/codeofconduct/
[Python-Dev] Re: PEP 622 version 2 (Structural Pattern Matching)
Rhodri James wrote: > Eric Nieuwland wrote: > >> Just after I hit ‘send’ it dawned on me it might be preferable to make that >> >> match poly: >> p0 = Point(x0, y0) >> p1 = Point(x1, y1) >> p2 = Point(x2, y2) >> case Polygon(p0, p1, p2): >> … >> >> so the part preceded by ‘match’ is the preparation phase for matching. >> > Are you intending p0, p1 and p2 to be subpatterns rather than object > instantiations? That makes me a little twitchy; the difference between what > you wrote and: > > match poly: > p0 = Point(x0, y0) > p1 = Point(x1, y1) > case Polygon(p0, p1, p2): > ... > is very easy to miss. > You are perfectly right. That is why I prefer explicit marking of variables to be bound by matching. Your example could then become: match poly: p0 = Point(x0, \y0) p1 = Point(\x1, y1) case Polygon(p0, p1, \p2): … and IMHO it would be very clear what to expect. An alternative would be to ‘declare’ variables that are to be bound to make things even more explicit, like: match poly: x1 = to_be_bound_by_matching y0 = to_be_bound_by_matching p2 = to_be_bound_by_matching p0 = Point(x0, y0) p1 = Point(x1, y1) case Polygon(p0, p1, p2): … where a better name than ‘to_be_bound_by_matching’ would certainly be needed. —eric ___ Python-Dev mailing list -- python-dev@python.org To unsubscribe send an email to python-dev-le...@python.org https://mail.python.org/mailman3/lists/python-dev.python.org/ Message archived at https://mail.python.org/archives/list/python-dev@python.org/message/W6VILFGBO4HJLEAUTSW6SJMNZN352KTJ/ Code of Conduct: http://python.org/psf/codeofconduct/
[Python-Dev] Re: PEP 622 version 2 (Structural Pattern Matching)
Greg Ewing wrote: > Eric Nieuwland wrote: > >> ... >> match poly: >> p0 = Point(x0, y0) >> p1 = Point(x1, y1) >> p2 = Point(x2, y2) >> case Polygon(p0, p1, p2): >> … >> > > Interesting idea, but what happens if you don't > need any setup? > Do you have to write > > > match poly: > pass > case ... > > ? Yes, that would be the idea. Unless you would need to setup variables to be bound in the cases, of course. Without that an if … elif … elif … else structure would be equivalent and possibly preferable. ___ Python-Dev mailing list -- python-dev@python.org To unsubscribe send an email to python-dev-le...@python.org https://mail.python.org/mailman3/lists/python-dev.python.org/ Message archived at https://mail.python.org/archives/list/python-dev@python.org/message/CMDHKH3YPLIQ4WGI4MEL2BQKKVU6DGDE/ Code of Conduct: http://python.org/psf/codeofconduct/
[Python-Dev] Re: PEP 622 version 2 (Structural Pattern Matching)
On 11 Jul 2020, at 21:03, Eric Nieuwland wrote: > What I meant to say is that as I read the current PEP text there would be a > confusing difference between > > match poly: > case Polygon(Point(x0, y0), Point(x1, y1), Point(x2, y2)): > ... > > and > > p0 = Point(x0, y0) > p1 = Point(x1, y1) > p2 = Point(x2, y2) > match poly: > case Polygon(p0, p1, p2): > ... > > This would be especially clumsy if I need to match parts in a deep structure. > It would require me to either write the whole construction as part of the > ‘match’ or use ‘match’ nested to drill down to the parts I need. > Just after I hit ‘send’ it dawned on me it might be preferable to make that match poly: p0 = Point(x0, y0) p1 = Point(x1, y1) p2 = Point(x2, y2) case Polygon(p0, p1, p2): … so the part preceded by ‘match’ is the preparation phase for matching. This could also resolve the discussion on indentation of the ‘case’ parts and the placement of the default matching: match [as ]: case []: … [else: ] within the preparation statements it would then be allowed to use undefined variables as receivers of matched parts. ___ Python-Dev mailing list -- python-dev@python.org To unsubscribe send an email to python-dev-le...@python.org https://mail.python.org/mailman3/lists/python-dev.python.org/ Message archived at https://mail.python.org/archives/list/python-dev@python.org/message/DOGIGJRL2RBHNGXXH2LZG6QMWTPLHU5J/ Code of Conduct: http://python.org/psf/codeofconduct/
[Python-Dev] Re: PEP 622 version 2 (Structural Pattern Matching)
> On 10 Jul 2020, at 18:28, Jim Baker wrote: > > On Fri, Jul 10, 2020, 9:16 AM Eric Nieuwland wrote: > >> On 10 Jul 2020, at 01:51, Jim Baker wrote: >> ... >> Explicit namespacing (if a constant) or using a guard (if a variable) seems >> to be the right solution, as Ethan demonstrated earlier. No need for . or ^ >> or \ or ... to disambiguate. Also it seems to me that structural pattern >> matching will build on two common usages of namespaces for constants: >> >> 1. Constants used from other modules are almost always used in the module >> namespace. Eg, socket.AF_UNIX or signal.SIGTERM. >> 2. New code often tends to use constants defined within an Enum namespace. >> Hopefully we will see more of this convention in usage. >> >> (Very much an aside: Interestingly with the socket module we see both used - >> it defines its constants with IntEnum and exports them traditionally. The >> namespace specifics it uses with IntEnum._convert_ to make this happen -- >> strictly speaking EnumMeta._convert, not documented, and a bit hard to >> follow -- might be possibly debatable, but it works out quite well in >> practice in providing backwards compatibility while continuing to work with >> a C source of these constants.) >> >> This would also mean >> case Point(x=\x, y=\y): >> should be used to obtain x and y from the Point instance. > > This approach makes deeper nesting of the structure much more cumbersome, I > think. > > How to match Polygon(Point(x0,y0), Point(x1, y1), Point(x2, y2)) based on its > structure? > And Polygon(Point(x0,y0), p1, Point(x2, y2))? > > > I'm just trying to describe what v2 of the PEP is trying to do and how it > then corresponds to a reasonable usage model. Sorry for any confusion. Yes, I understood. Thank you for that. No apology needed. > So in your scenario above, Polygon and Point are used as class patterns > (https://www.python.org/dev/peps/pep-0622/#class-patterns). Consequently they > are treated accordingly and have that nice structural pattern matching > quality! What I meant to say is that as I read the current PEP text there would be a confusing difference between match poly: case Polygon(Point(x0, y0), Point(x1, y1), Point(x2, y2)): ... and p0 = Point(x0, y0) p1 = Point(x1, y1) p2 = Point(x2, y2) match poly: case Polygon(p0, p1, p2): ... This would be especially clumsy if I need to match parts in a deep structure. It would require me to either write the whole construction as part of the ‘match’ or use ‘match’ nested to drill down to the parts I need. > Earlier I was discussing constant patterns > (https://www.python.org/dev/peps/pep-0622/#constant-value-patterns), which > require they be namespaced in some way (a qualified name as it is described > in the PEP). Indeed. My point is this would be - as far as I know - the first time you need to create a namespace to use the value of an already known variable. This only to allow assignment to variables which I find counterintuitive and which IMHO leads to clumsy constructions, as shown above. So I hope the new and special thing here (i.e. assign matched parts of the structure to variables) will not interfere with how we read expressions in Python. A special indicator for the special use case to me seems far easier to understand and to teach. —eric ___ Python-Dev mailing list -- python-dev@python.org To unsubscribe send an email to python-dev-le...@python.org https://mail.python.org/mailman3/lists/python-dev.python.org/ Message archived at https://mail.python.org/archives/list/python-dev@python.org/message/ZXYKO57S6U5UNQG6Y5IUXIXI54RBV2QD/ Code of Conduct: http://python.org/psf/codeofconduct/
[Python-Dev] Re: PEP 622 version 2 (Structural Pattern Matching)
> On 10 Jul 2020, at 01:51, Jim Baker wrote: > > > On Thu, Jul 9, 2020 at 1:42 PM Eric Nieuwland <mailto:eric.nieuwl...@gmail.com>> wrote: > Much of the discussion seems to focus on how to distinguish between a > variable as a provider of a value and a variable as receiver of a matched > value. > > In normal Python syntax a variable in an expression provides a value, please > let’s keep that unchanged. > > For patterns, these are no different than parameters for a function (either a > lambda expression or with `def`); or target assignments in unpacking > assignments. So just like I wouldn't wonder where `a` and `b` materialized in > the parameters for the function definition below > > def sum2(a, b): > return a + b > > I think it will be straightforward to understand this in the context of a > `case` using a capture pattern: > > match x: > case (a, b): > return a + b >... > > (This commonality between cases and function definitions is further used in > Scala for example, but I don't see that approach for defining an idea of > partial functions -- not like functools.partial functions! -- as being that > useful in Python.) > > > So it seems to me we should explicitly mark a variable to receive a matched > value. > I have seen ‘?’ suggested as a prefix to do this, ‘\’ would also do fine. > > This would solve the single variable issue, too: > case foo: > matches the value of ‘foo’, while > case \foo: > matches anything and stores it in ‘foo’. > > > Explicit namespacing (if a constant) or using a guard (if a variable) seems > to be the right solution, as Ethan demonstrated earlier. No need for . or ^ > or \ or ... to disambiguate. Also it seems to me that structural pattern > matching will build on two common usages of namespaces for constants: > > 1. Constants used from other modules are almost always used in the module > namespace. Eg, socket.AF_UNIX or signal.SIGTERM. > 2. New code often tends to use constants defined within an Enum namespace. > Hopefully we will see more of this convention in usage. > > (Very much an aside: Interestingly with the socket module we see both used - > it defines its constants with IntEnum and exports them traditionally. The > namespace specifics it uses with IntEnum._convert_ to make this happen -- > strictly speaking EnumMeta._convert, not documented, and a bit hard to follow > -- might be possibly debatable, but it works out quite well in practice in > providing backwards compatibility while continuing to work with a C source of > these constants.) > > This would also mean > case Point(x=\x, y=\y): > should be used to obtain x and y from the Point instance. This approach makes deeper nesting of the structure much more cumbersome, I think. How to match Polygon(Point(x0,y0), Point(x1, y1), Point(x2, y2)) based on its structure? And Polygon(Point(x0,y0), p1, Point(x2, y2))? ___ Python-Dev mailing list -- python-dev@python.org To unsubscribe send an email to python-dev-le...@python.org https://mail.python.org/mailman3/lists/python-dev.python.org/ Message archived at https://mail.python.org/archives/list/python-dev@python.org/message/VQ25KUKTGWABHK6DYIC6ZEXFSZ2IX7JR/ Code of Conduct: http://python.org/psf/codeofconduct/
[Python-Dev] Re: PEP 622 version 2 (Structural Pattern Matching)
> On 10 Jul 2020, Stefano Borini wrote: > > Just my 2 cents, I find it kind of annoying that the whole structure > requires two levels of indentation to actually reach the operational > code. > This would be a first in python. > > I would prefer an option akin to if elif elif else where each block is > only one level deep. It very much depends on how you read it. To me the proposed structure is like with as : if : … elif : … and thus not really different ___ Python-Dev mailing list -- python-dev@python.org To unsubscribe send an email to python-dev-le...@python.org https://mail.python.org/mailman3/lists/python-dev.python.org/ Message archived at https://mail.python.org/archives/list/python-dev@python.org/message/3LCHUK3IV4CXWSFHNROREJQ3WTS2JZ7L/ Code of Conduct: http://python.org/psf/codeofconduct/
[Python-Dev] Re: PEP 622 version 2 (Structural Pattern Matching)
Much of the discussion seems to focus on how to distinguish between a variable as a provider of a value and a variable as receiver of a matched value. In normal Python syntax a variable in an expression provides a value, please let’s keep that unchanged. So it seems to me we should explicitly mark a variable to receive a matched value. I have seen ‘?’ suggested as a prefix to do this, ‘\’ would also do fine. This would solve the single variable issue, too: case foo: matches the value of ‘foo’, while case \foo: matches anything and stores it in ‘foo’. This would also mean case Point(x=\x, y=\y): should be used to obtain x and y from the Point instance. ___ Python-Dev mailing list -- python-dev@python.org To unsubscribe send an email to python-dev-le...@python.org https://mail.python.org/mailman3/lists/python-dev.python.org/ Message archived at https://mail.python.org/archives/list/python-dev@python.org/message/3MC2ZKDVRSDYRBZSYSFDR4M6GKQXITO2/ Code of Conduct: http://python.org/psf/codeofconduct/
[Python-Dev] Re: PEP 622: Structural Pattern Matching - followup
I wrote: > > Guido van Rossum wrote: > >> Eric Nieuwland wrote: >> >>> I have some doubt about the keyword: ‘match' seems to be at odds with >>> 'for', 'while', 'with', 'if' as it is more of an action. >>> It's more like 'try' but that statement has a completely different >>> structure. >> >> Well, 'try' is also an action. :-) Many people have tried to come up with a >> different keyword here, but nothing has been found that comes even close to >> the simplicity of match. Plus, several other languages (Scala, Rust) use it >> too (which is further evidence that it's a natural fit). > > It may also be evidence for not being able to come up with a more accurate > keyword. > > Reading through the PEP once more I noticed I was understanding > > match X: > case Y: > Z > > as > > when X: > matches Y: > Z > > which also to me seems to reflect the close relation to an if-elif-elif… > construction. > > This would almost naturally imply the possibility of: > > when X: > matches Y: > Z > ... > else: > Q > > And maybe also an additional operator: > > if X matches Y: > Z > > >>> Not a native speaker I don't have a reasonable alternative, though. >> >> Me neither, but I speak it quite fluently now, and 'match' really feels >> like it fits well here. > > Trying ;-) Thinking of this over the weekend, I think the following might be even more flexible and powerful: when X: Y1: Z1 Y2: Z2 … else: Q which would be the same as: if X Y1: Z1 elif X Y2: Z2 … else: Q Furthermore when X: Y1 if C1: Z1 Y2 if C2: Z2 … else: Q would be the same as: if X Y1 and C1: Z1 elif X Y2 and C2: Z2 … else: Q and so the PEP would need to define: - the 'when’ keyword - the 'matches' comparison ___ Python-Dev mailing list -- python-dev@python.org To unsubscribe send an email to python-dev-le...@python.org https://mail.python.org/mailman3/lists/python-dev.python.org/ Message archived at https://mail.python.org/archives/list/python-dev@python.org/message/Q3GZ3YSI5MDP7DNRWW452STZ6KF6EMBT/ Code of Conduct: http://python.org/psf/codeofconduct/
[Python-Dev] Re: PEP 622: Structural Pattern Matching
Guido van Rossum wrote: > Eric Nieuwland wrote: > >> I have some doubt about the keyword: ‘match' seems to be at odds with >> 'for', 'while', 'with', 'if' as it is more of an action. >> It's more like 'try' but that statement has a completely different >> structure. > > Well, 'try' is also an action. :-) Many people have tried to come up with a > different keyword here, but nothing has been found that comes even close to > the simplicity of match. Plus, several other languages (Scala, Rust) use it > too (which is further evidence that it's a natural fit). It may also be evidence for not being able to come up with a more accurate keyword. Reading through the PEP once more I noticed I was understanding match X: case Y: Z as when X: matches Y: Z which also to me seems to reflect the close relation to an if-elif-elif… construction. This would almost naturally imply the possibility of: when X: matches Y: Z ... else: Q And maybe also an additional operator: if X matches Y: Z >> Not a native speaker I don't have a reasonable alternative, though. > > Me neither, but I speak it quite fluently now, and 'match' really feels > like it fits well here. Trying ;-)___ Python-Dev mailing list -- python-dev@python.org To unsubscribe send an email to python-dev-le...@python.org https://mail.python.org/mailman3/lists/python-dev.python.org/ Message archived at https://mail.python.org/archives/list/python-dev@python.org/message/MN3TP6UL2QUO6VYIEPUGDGLIREZHYLI2/ Code of Conduct: http://python.org/psf/codeofconduct/
[Python-Dev] Re: PEP 622: Structural Pattern Matching
Great PEP! I have some doubt about the keyword: ‘match’ seems to be at odds with ‘for’, ‘while’, ‘with’, ‘if’ as it is more of an action. It’s more like ‘try’ but that statement has a completely different structure. Not a native speaker I don’t have a reasonable alternative, though. ___ Python-Dev mailing list -- python-dev@python.org To unsubscribe send an email to python-dev-le...@python.org https://mail.python.org/mailman3/lists/python-dev.python.org/ Message archived at https://mail.python.org/archives/list/python-dev@python.org/message/TDWDDAROGWNSARY6AS4O52XAZ44CQDGW/ Code of Conduct: http://python.org/psf/codeofconduct/
Re: [Python-Dev] PEP for adding an sq_index slot so that any object, a or b, can be used in X[a:b] notation
Travis Oliphant wrote: PEP: ### Title: Allowing any object to be used for slicing [...] Rationale Currently integers and long integers play a special role in slice notation in that they are the only objects allowed in slice syntax. In other words, if X is an object implementing the sequence protocol, then X[obj1:obj2] is only valid if obj1 and obj2 are both integers or long integers. There is no way for obj1 and obj2 to tell Python that they could be reasonably used as indexes into a sequence. This is an unnecessary limitation. [...] I like the general idea from an academic point of view. Just one question: could you explain what I should expect from x[ slicer('spam') : slicer('eggs') ] when slicer implements this protocol? Specifically, I'd like to known how you want to define the interval between two objects. Or is that for the sliced/indexed object to decide? --eric ___ 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] Let's just *keep* lambda
On 5 feb 2006, at 18:43, Guido van Rossum wrote: After so many attempts to come up with an alternative for lambda, perhaps we should admit defeat. I've not had the time to follow the most recent rounds, but I propose that we keep lambda, so as to stop wasting everybody's talent and time on an impossible quest. -- --Guido van Rossum (home page: http://www.python.org/~guido/) +1 And let's add Wise t the BDFL's title: WBDFL. ;-) --eric ___ 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] any support for a methodcaller HOF?
Nick Coghlan wrote: That's like saying it's not the same because '(x*x def (x)' creates a function while '(x*x for x in seq)' creates a generator-iterator. Well, naturally - if the expression didn't do something different, what would be the point in having it? ;-) Naturally. I just wanted to point out it's a beast of another kind, so like syntax may not be a good idea. The parallel I'm trying to draw is at the syntactic level, not the semantic. I'm quite aware that the semantics will be very different ;) Yours is f = lambda x: x*x and it will die by Guido hand... In the short term, probably. I'm hoping that the progressive accumulation of workarounds like itemgetter, attrgetter and partial (and Alex's suggestion of 'methodcaller') and the increasing use of function arguments for things like sorting and the itertools module will eventually convince Guido that deferring expressions is a feature that needs to be *fixed* rather than discarded entirely. Then how about nameless function/method definition: def (x): ... usual body ... produces an unnamed method object and def spam(x): is just spam = def (x): ... while our beloved eggs(lambda x: x*x) would become eggs(def(x): return x*x) --eric ___ 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] any support for a methodcaller HOF?
Martin v. Löwis wrote: I believe that usage of a keyword with the name of a Greek letter also contributes to people considering something broken. QOTW! ;-) --eric ___ 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] any support for a methodcaller HOF?
Nick Coghlan wrote: I believe that usage of a keyword with the name of a Greek letter also contributes to people considering something broken. Aye, I agree there are serious problems with the current syntax. All I'm trying to say above is that I don't believe the functionality itself is broken. Lambda is not broken, it's restricted to single calculation and therefore of limited use. Although I wasn't too serious (should had added more signs of that), an anonymous 'def' would allow to use the full power of method definition. At last count, Guido's stated preference was to ditch the functionality entirely for Py3k, so unless he says something to indicate he's changed his mind, we'll simply need to continue with proposing functions like methodcaller() as workarounds for its absence... Yep, we'll just have to learn to live without it. :-( / ;-) --eric ___ 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] any support for a methodcaller HOF?
On 4 feb 2006, at 3:18, Nick Coghlan wrote: All I'm suggesting is that a similarly inspired syntax is worth considering when it comes to deferred expressions: def f(x): return x*x = f = (x*x def (x)) It's not the same, as x remains free whereas in g = [x*x for x in seq] x is bound. Yours is f = lambda x: x*x and it will die by Guido hand... --eric ___ 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] The path module PEP
On 1 feb 2006, at 19:14, BJörn Lindqvist wrote: I've submitted an updated version of the PEP. The only major change is that instead of the method atime and property getatime() there is now only one method named atime(). Also some information about the string inheritance problem in Open Issues. I still have no idea what to do about it though. The current PEP still contains some redundancy between properties and methods under Specifications: basename() - name basename(), stripext() - namebase splitpath() - parent, name (documented) I would like to suggest to use only properties and use splitall() to obtain a tuple with the complete breakdown of the path. And may be splitall() could then be renamed to split(). The directory methods mkdir()/makedirs() and rmdir()/removedirs() could be unified. To me it seems they only exist because of Un*x details. my $0.005 --eric ___ 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] Small any/all enhancement
I wrote: all() can be terminated at the first false element. For very long sequences this has important performance benefits. Besides, it makes all(seq,pred) the equivalent of pred(seq[0]) and pred(seq[1]) and pred(seq[2]) and ... then, Martin v. Löwis wrote: And so does the version with generator expressions: Alex' expression will also terminate with the first false statement; it is equivalent to some_objects[0]==0 and some_objects[1]==0 and ... and Alex Martelli wrote: Of course it can -- in both formulations. genexp's are also computed as needed, only one item at a time: you appear to imply they don't, maybe you're confusing them with list comprehensions. What I'm asking is, what are the ADVANTAGES of the pred form, that make it worth paying the conceptual cost of having two obvious ways to do one task. all(seq,pred) the equivalent of pred(seq[0]) and pred(seq[1]) and pred(seq[2]) and ... ...and also the equivalent of all(pred(s) for s in seq) -- which is exactly my problem: I don't like redundant good ways of expressing identical tasks. The genexp will often be more compact, whenever the 'pred' requires a def, a lambda, or something like operator.attrgetter, anyway. Oops! Right you are. I was a bit too quick after seeing the use of map() proposed. --eric ___ 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] Small any/all enhancement
Alex Martelli wrote: On Dec 27, 2005, at 12:45 PM, Valentino Volonghi aka Dialtone wrote: ... any(iterable, test=bool) and all(iterable, test=bool) ... any(some_objects, test=operator.attrgetter('some_attribute')) Why would that be better than any(o.some_attribute for o in some_objects) ? def zerop(x): return x==0 all(some_objects, zerop) and why would that be better than all(o==0 for o in some_objects) ? all() can be terminated at the first false element. For very long sequences this has important performance benefits. Besides, it makes all(seq,pred) the equivalent of pred(seq[0]) and pred(seq[1]) and pred(seq[2]) and ... ___ 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] Proposed resolutions for open PEP 343 issues
Michael Chermside wrote: Guido writes: I find AttributeError: __exit__ just as informative. Eric Nieuwland responds: I see. Then why don't we unify *Error into Error? Just read the message and know what it means. And we could then drop the burden of exception classes and only use the message. A sense of deja-vu comes over me somehow ;-) The answer (and there _IS_ an answer) is that using different exception types allows the user some flexibility in CATCHING the exceptions. The discussion you have been following obscures that point somewhat because there's little meaningful difference between TypeError and AttributeError (at least in well-written code that doesn't have unnecessary typechecks in it). Yep. I too would like to have 'SOME flexibility in catching the exceptions' meaning I'd like to be able to catch TypeErrors and AttributeErrors while not catching what I call ProtocolErrors. The simple reason is that in most of my apps TypeErrors and AttributeErrors will depend on the runtime situation, while ProtocolErrors will mostly be static. So I'll debug for ProtocolErrors and I'll handle runtime stuff. If there were a significant difference between TypeError and AttributeError then Nick and Guido would have immediately chosen the appropriate error type based on functionality rather than style, and there wouldn't have been any need for discussion. I got that already. To me it means one of them may be a candidate for removal/redefinition. Oh yeah, and you can also put extra info into an exception object besides just the error message. (We don't do that as often as we should... it's a powerful technique.) Perhaps that needs for propaganda then. I won't dare to suggest syntactic sugar ;-) --eric ___ 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] Proposed resolutions for open PEP 343 issues
Guido van Rossum wrote: [Eric are all your pets called Eric? Nieuwland] Hmmm... Would it be reasonable to introduce a ProtocolError exception? [Guido] And which perceived problem would that solve? [Eric] It was meant to be a bit more informative about what is wrong. ProtocolError: lacks __enter__ or __exit__ That's exactly what I'm trying to avoid. :) I find AttributeError: __exit__ just as informative. In either case, if you know what __exit__ means, you'll know what you did wrong. And if you don't know what it means, you'll have to look it up anyway. And searching for ProtocolError doesn't do you any good -- you'll have to learn about what __exit__ is and where it is required. I see. Then why don't we unify *Error into Error? Just read the message and know what it means. And we could then drop the burden of exception classes and only use the message. A sense of deja-vu comes over me somehow ;-) ___ 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] Proposed resolutions for open PEP 343 issues
Guido van Rossum wrote: It is true though that AttributeError is somewhat special. There are lots of places (perhaps too many?) where an operation is defined using something like if the object has attribute __foo__, use it, otherwise use some other approach. Some operations explicitly check for AttributeError in their attribute check, and let a different exception bubble up the stack. Presumably this is done so that a bug in somebody's __getattr__ implementation doesn't get masked by the otherwise use some other approach branch. But this is relatively rare; most calls to PyObject_GetAttr just clear the error if they have a different approach available. In any case, I don't see any of this as supporting the position that TypeError is somehow more appropriate. An AttributeError complaining about a missing __enter__, __exit__ or __context__ method sounds just fine. (Oh, and please don't go checking for the existence of __exit__ before calling __enter__. That kind of bug is found with even the most cursory testing.) Hmmm... Would it be reasonable to introduce a ProtocolError exception? --eric ___ 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] Proposed resolutions for open PEP 343 issues
Guido van Rossum wrote: On 10/25/05, Eric Nieuwland [EMAIL PROTECTED] wrote: Hmmm... Would it be reasonable to introduce a ProtocolError exception? And which perceived problem would that solve? The problem of Nick Guido disagreeing in public? ;-) No, that will go on in other fields, I guess. It was meant to be a bit more informative about what is wrong. ProtocolError: lacks __enter__ or __exit__ --eric ___ 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] Proposed changes to PEP 343
Nick Coghlan wrote: 1. Amend the statement specification such that: with EXPR as VAR: BLOCK is translated as: abc = (EXPR).__with__() exc = (None, None, None) VAR = abc.__enter__() try: try: BLOCK except: exc = sys.exc_info() raise finally: abc.__exit__(*exc) Is this correct? What happens to with 40*13+2 as X: print X ? --eric ___ 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] Proposed changes to PEP 343
Nick Coghlan wrote: Eric Nieuwland wrote: What happens to with 40*13+2 as X: print X It would fail with a TypeError because the relevant slot in the type object was NULL - the TypeError checks aren't shown for simplicity's sake. This behaviour isn't really any different from the existing PEP 343 - the only difference is that the statement looks for a __with__ slot on the original EXPR, rather than looking directly for an __enter__ slot. Hmmm I hadn't noticed that. In my memory a partial implementation of the protocol was possible. Thus, __enter__/__exit__ would only be called if they exist. Oh well, I'll just add some empty methods. --eric ___ 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] partition() (was: Remove str.find in 3.0?)
Raymond Hettinger wrote: I think it's convenient but also rather odd that split() with a static string argument was moved from module string to a method in class str, while split() with a regexp has remained in module re. I don't see what you find odd. With str and unicode objects being builtin, you don't need a separate module. In contrast, re is a stand-alone extension which, of course, requires an import. That's an implementation oriented view. IMHO it is all a match-and-cut operation with fixed strings the simplest form of match expressions. From that point of view the distinction between the two is quite arbitrary. Of course, when turning from principles to daily practice again it is quite clear the distinction is useful. --eric ___ 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] partition() (was: Remove str.find in 3.0?)
Pierre Barbier de Reuille wrote: Or you want to have some partition method which accept regular expressions: head, sep, tail = some_str.partition(re.compile(sep+'.'*offset)) Neat! +1 on regexps as an argument to partition(). --eric ___ 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] partition() (was: Remove str.find in 3.0?)
On 30 aug 2005, at 17:40, Antoine Pitrou wrote: Neat! +1 on regexps as an argument to partition(). It sounds better to have a separate function and call it re.partition, doesn't it ? By the way, re.partition() is *really* useful compared to re.split() because with the latter you don't which string precisely matched the pattern (it isn't an issue with str.split() since matching is exact). Nice, too. BUT, spam! and eggs.partition(re.compile(!.*d)) more closely resembles xyz.split(), and that is the way things have evolved up-to now. --eric ___ 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 348 and ControlFlow
Dear all, Sorry to bring this up again, but I think there is an inconsistency in PEP 348 in its current formulation. From PEP: In Python 2.4, a bare except clause will catch any and all exceptions. Typically, though, this is not what is truly desired. More often than not one wants to catch all error exceptions that do not signify a bad interpreter state. In the new exception hierarchy this is condition is embodied by Exception. Thus bare except clauses will catch only exceptions inheriting from Exception. So, bare except will catch anything that is an Exception. This includes GeneratorExit and StopIteration, which contradicts: It has been suggested that ControlFlowException should inherit from Exception. This idea has been rejected based on the thinking that control flow exceptions typically should not be caught by bare except clauses, whereas Exception subclasses should be. To me this means GeneratorExit and StopIteration are to be taken out of the Exception subtree. It seems to me rather awkward to put them at the same level as Exception and TerminatingException. So there comes the old (yeah, I know REJECTED) idea of a ControlFlowException class, right next to Exception and TerminatingException: BaseException +TerminatingException + ... + Exception + ... + ControlFlowException + GeneratorExit + StopIteration Is my logic flawed (again ;-)? --eric Eric Nieuwland ___ 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] Terminology for PEP 343
Raymond Hettinger wrote: With 343 accepted, we can now add __enter__() and __exit__() methods to objects. What term should describe those objects in the documentation? Witty objects? ___ 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] Wishlist: dowhile
Nick Coghlan wrote: With PEP 315, a do-while loop would look like: do: body while cond: pass But then, I'm reasonably happy with the 'break out of an infinite loop' approach, so *shrug*. From Programming Languages 101 I remember this construct in Algol 68. It was then claimed to be *the* universal loop construct. If that is true __and__ it is easy to implement, I'd say +INF for PEP 315. --eric ___ 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] Wishlist: dowhile
Guido van Rossum wrote: On 6/14/05, Eric Nieuwland [EMAIL PROTECTED] wrote: From Programming Languages 101 I remember this construct in Algol 68. It was then claimed to be *the* universal loop construct. If that is true __and__ it is easy to implement, I'd say +INF for PEP 315. It's true, but this both dates you (A68 has been dead for several decades) and locates you: it was said that A68's popularity was inversely proportional to (the square of?) the distance from Amsterdam. It also dates and locates me. :-) Lucky me ;-) ___ 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] Thoughts on stdlib evolvement
Skip Montanaro wrote: The main technical challenge seems to be backward compatibility. You need to support both flat (import urllib) and packaged namespaces (from www import urllib), possibly within the same application. That is, postulating a www package, if I execute import urllib from www.urllib import urlopen the module-level code should only be executed once, and urlopen == urllib.urlopen should evaluate to True. Unless from __future__ import new_std_library and we don't allow mixed use within the same module. --eric ___ 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 343 rewrite complete
Phillip J. Eby wrote: At 10:00 PM 6/1/2005 +0200, Eric Nieuwland wrote: Phillip J. Eby wrote: -1, too confusing. A matter of taste, I guess. IMHO 'with' secretly handling exceptions is confusing. It doesn't secretly handle them; it simply gets access to them, which is an entirely different thing. By confusing, I mean that it is not clear from your construct what exceptions are caught by the 'except' clause, due to its structural layout. It's also not clear whether the __enter__/__exit__ of EXPR wrap BLOCK1 only, or both BLOCK1 and BLOCK2. These aspects are confusing because whatever decision you make about the semantics, someone will have to *remember* them, as opposed to being unambiguously represented by the block structure. By contrast, if you remove the except: clause from your construct, it is clear that BLOCK1 is what is wrapped, and there is no possible confusion about who sees what exceptions. Exceptions inside the block are communicated to __exit__, exceptions outside (including those in the 'with' statement itself) are not. OK. This forwarding (is that the proper expression here?) of an exception to __exit__ is what I meant by 'secretly handling'. If everybody agrees I'll write with EXPR as VAR: try: BLOCK1 except EXCEPTION: BLOCK2 instead. Seems a waiste to me, though. I was thinking about 'try EXPR [as VAR]:' as a 'try' that handles uncaught exceptions by forwarding it to EXPR's __exit__ method. No confusion with me. --eric ___ 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 343 rewrite complete
On 2 jun 2005, at 22:12, Phillip J. Eby wrote: At 10:04 PM 6/2/2005 +0200, Eric Nieuwland wrote: I was thinking about 'try EXPR [as VAR]:' as a 'try' that handles uncaught exceptions by forwarding it to EXPR's __exit__ method. No confusion with me. No doubt. However, it's not obvious what happens to an exception in EXPR; surely it can't be passed to EXPR's __exit__ method. So, is it handled by the try, or does it pass out of the block? Whichever answer you give, there is somebody who will think the opposite. And this is precisely the ambiguity I've been talking about. In contrast, a 'with' unmixed with 'try' is absolutely unambiguous as to which except: clauses handle what exceptions where. slap forehead I never thought of that! Now I see what you mean. I could only save my idea by stating the scope of 'try' only starts after the ':', but that seems too artificial. --eric ___ 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 343 rewrite complete
Nice going! But ... Could we extend the 'try' syntax for this instead of introducing 'with'? If I look at the translation it an augmented 'try'. with EXPR as VAR: BLOCK1 except EXCEPTION: BLOCK2 could then be translated to abc = EXPR exc = (None, None, None) VAR = abc.__enter__() try: try: BLOCK1 except EXCEPTION: BLOCK2 except: exc = sys.exc_info() raise finally: abc.__exit__(*exc) Can the 'throw()' method be renamed 'raise()'? IMHO that makes much clearer what happens. Same thing with 'GeneratorExit', 'StopGeneration' more closely matches 'StopIteration'. --eric ___ 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 343 rewrite complete
Eric Nieuwland wrote: If I look at the translation it an augmented 'try'. with EXPR as VAR: BLOCK1 except EXCEPTION: BLOCK2 Oops, that should read: try EXPR as VAR: BLOCK1 except EXCEPTION: BLOCK2 --eric ___ 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 343 rewrite complete
Phillip J. Eby wrote: At 08:46 PM 6/1/2005 +0200, Eric Nieuwland wrote: If I look at the translation it an augmented 'try'. with EXPR as VAR: BLOCK1 except EXCEPTION: BLOCK2 could then be translated to -1, too confusing. A matter of taste, I guess. IMHO 'with' secretly handling exceptions is confusing. Can the 'throw()' method be renamed 'raise()'? IMHO that makes much clearer what happens. No, 'raise' is a reserved word. It would have to be 'raise_()'. -0. My bad. Should have thought about that. Same thing with 'GeneratorExit', 'StopGeneration' more closely matches 'StopIteration'. StopIteration is raised the *other* way, so closely matching isn't really a benefit. -1. Yep! Misread that one. --eric ___ 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 344: Exception Chaining and Embedded Tracebacks
Guido van Rossum wrote: Consider try: BLOCK except EXCEPTION, VAR: HANDLER I'd like to see this translated into try: BLOCK except EXCEPTION, VAR: __context = VAR try: HANDLER except Exception, __error: __error.__context__ = __context raise If I interpret the above translation correctly, then: try: BLOCK1 except EXCEPTION1, VAR1: try: BLOCK2 except EXCEPTION2, VAR2: HANDLER with exceptions occuring in BLOCK1, BLOCK2 and HANDLER would result in HANDLER's exception with __context__ set to BLOCK1's exception and BLOCK2's exception would be lost. --eric ___ 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 343 - Abstract Block Redux
Shane Hathaway wrote: Here is example A, a non-looping block statement using try: text = 'diamond' for fn in filenames: try opening(fn) as f: if text in f.read(): print 'I found the text in %s' % fn break That's a pretty way to write it! Would it be possible to extend the 'try' syntax in this way? It would certainly stress the fact that this construct includes exception handling. --eric ___ 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] Merging PEP 310 and PEP 340-redux?
Guido van Rossum wrote: class locking: def __init__(self, lock): self.lock = lock def __enter__(self): self.lock.acquire() def __exit__(self, *args): self.lock.release() class opening: def __init__(self, filename): self.filename = filename def __enter__(self): self.f = open(self.filename); return self.f def __exit__(self, *args): self.f.close()\ And do EXPR as VAR: BLOCK would mentally be translated into itr = EXPR VAR = itr.__enter__() try: BLOCK finally: itr.__exit__(*sys.exc_info()) # Except sys.exc_info() isn't defined by finally In this example locking's __enter__ does not return anything. Would do EXPR: BLOCK also be legal syntax? -eric ___ 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 340: Deterministic Finalisation (new PEP draft, either a competitor or update to PEP 340)
Greg Ewing wrote: Ron Adam wrote: There seems to be some confusion as to weather or not 'for's will do finalizing. So I was trying to stress I think regular 'for' loops should not finalize. They should probably give an error if an object with an try-finally in them or an __exit__ method. But if the for-loop can tell whether the iterator needs finalizing or not, why not have it finalize the ones that need it and not finalize the ones that don't? That would be backwards compatible, since old for-loops working on old iterators would work as before. That's why I suggested to have the behaviour depend on what is passed in as EXPR. for VAR in EXPR: BLOCK could be translated to: __cleanup = False __itr = EXPR if not isinstance(__itr,iterator): __itr = iter(__itr) __cleanup = True while True: try: VAR = __itr.next() except StopIteration: break BLOCK if __cleanup: __itr.__exit__() Which would require isinstance(__itr,iterator) or equivalent to act as a robust test on iterators. I'll leave 'for' with an 'else' clause as an exercise to the reader. --eric ___ 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 340: Deterministic Finalisation (new PEP draft, either a competitor or update to PEP 340)
Josiah Carlson wrote: Eric Nieuwland [EMAIL PROTECTED] wrote: I don't know. Using 'del' in that place seems ackward to me. Why not use the following rule: for [VAR in] EXPR: SUITE If EXPR is an iterator, no finalisation is done. If EXPR is not an iterator, it is created at the start and destroyed at the end of the loop. You should know why that can't work. If I pass a list, is a list an iterator? No, but it should neither be created nor destroyed before or after. I suggested to create AN ITERATOR FOR THE LIST and destroy that at the end. The list itself remains untouched. --eric ___ 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 340: Deterministic Finalisation (new PEP draft, either a competitor or update to PEP 340)
Josiah Carlson wrote: The argument over whether blocks should loop, I believe has been had; they should. The various use cases involve multi-part transactions and such. Then it is not so much looping but more pushing forward the state of the state of the block's life-cycle? This might by a good moment to consider life-cycle support a la PROCOL. --eric ___ 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 340: Deterministic Finalisation (new PEP draft, either a competitor or update to PEP 340)
Nick Coghlan wrote: [...] The whole PEP draft can be found here: http://members.iinet.net.au/~ncoghlan/public/pep-3XX.html [...] Used as follows:: for del auto_retry(3, IOError): f = urllib.urlopen(http://python.org/;) print f.read() I don't know. Using 'del' in that place seems ackward to me. Why not use the following rule: for [VAR in] EXPR: SUITE If EXPR is an iterator, no finalisation is done. If EXPR is not an iterator, it is created at the start and destroyed at the end of the loop. --eric ___ 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] Pre-PEP: Unifying try-except and try-finally
Guido van Rossum wrote: try_stmt: 'try' ':' suite ( except_clause ':' suite)+ ['else' ':' suite] ['finally' ':' suite] | 'finally' ':' suite ) There is no real complexity in this grammar, it's unambiguous, it's an easy enough job for the code generator, and it catches a certain class of mistakes (like mis-indenting some code). Fair enough. Always nice to have some assistence from the system. --eric ___ 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 340: Breaking out.
Ronald Oussoren wrote: What's bothering me about the proposed semantics is that block statement behaves like a loop while most use cases do no looping whatsoever. Furthermore the it doesn't feel like loop either. In all three examples on this page I'd assume that the break would break out of the for loop. I'm bothered the same way. IMHO control constructs should be very clear. No implicit looping, conditionals etc. Especially since the main reason to have this whole discussion is about resource management. The main pattern of use I have in mind is: resource = grab/allocate/open/whatever(...) try: do something possibly with the resource except ...: ... finally: ... resource.release/deallocate/close/whatever() This is linear. No looping whatsoever. And easily translated to a simple language construct and a protocol: class resource(object): def __init__(self,...): # store resource parameters def __acquire__(self): # whatever it takes to grab the resource def __release__(self): # free the resource res = resource(...) acquire res: do something possibly with the resource except ...: ... finally: ... The resource is automagically released at the end of the 'acquire' block (keyword up for other proposals :-) An alternative syntax could also be allowed: acquire resource(...) as res: ...etc... Then 'res' would be undefined after the 'acquire' block. --eric ___ 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] anonymous blocks
Guido van Rossum wrote: tri = self.subcalculation(The quick brown fox jumps over the lazy dog) self.disentangle(0x40, tri, self.indent+1) IMO this is clearer, and even shorter! But it clutters the namespace with objects you don't need. So the complete equivalent would be more close to: tri = self.subcalculation(The quick brown fox jumps over the lazy dog) self.disentangle(0x40, tri, self.indent+1) del tri which seems a bit odd to me. If we apply this to the anonymous block problem, we may end up finding lambda the ultimate compromise -- like a gentleman in the back of my talk last week at baypiggies observed (unfortunately I don't know his name). It wasn't me ;-) It seems this keeps getting back at you. Wish I had thought of this argument before. --eric ___ 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] @decoration of classes
Given the ideas so far, would it possible to: def meta(cls): ... @meta class X(...): ... ?? --eric ___ 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] @decoration of classes
On 26 mrt 2005, at 21:36, Josiah Carlson wrote: Eric Nieuwland [EMAIL PROTECTED] wrote: Given the ideas so far, would it possible to: def meta(cls): ... @meta class X(...): ... It is not implemented in Python 2.4. From what I understand, making it happen in Python 2.5 would not be terribly difficult. The question is about a compelling use case. Is there a use where this syntax is significantly better, easier, etc., than an equivalent metaclass? Would people use the above syntax if it were available? What would you use the above syntax to do? Well, I can imagine using @meta(MyMetaClass) class MyClass(...): ... instead of class MyClass(...): __metaclass__ = MyMetaClass ... Somehow, it seems more aesthetic to me. --eric ___ 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
Fwd: [Python-Dev] docstring before function declaration
Nicholas Jacobson wrote: IIRC, Guido once mentioned that he regretted not setting function docstrings to come before the function declaration line, instead of after. [ examples deleted ] I think that commenting the function before its declaration, at the same tabbed point, increases the code's readability. What do you think about making this change at some point (e.g. Python 3000)? Or if not, then having the option to toggle to this layout? Please don't. All class attributes are declared within the class. Pulling out the docstring would make it an exception. The current situation is very clear and easy to explain to newbies. If you feel the current position of the docstring may be the first attribute's docstring, insert a newline at the proper positions to separate the two. It works for me. --eric ___ 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] comprehension abbreviation (was: Adding any() and all())
Martin v. Löwis wrote: That's not the full syntax. The full syntax is [ test for exprlist in testlist list-iter-opt ] where test can be an arbitrary expression: and, or, lambda, +, -, ... exprlist can be a list of expression, except for boolean and relational expressions (but I think this is further constrained semantically) testlist list a list of tests list-iter-opt is optional, and can be another for or if block Aren't these names a bit mixed up w.r.t. what's in that position? As far as I know test is not a test but a function as it produces any value not just True/False exprlst is a list of names, not arbitrary expressions testlist is anything which will produce an iterator Or so I've understood so far. So a more complex example is [ lambda a: a[x]+y*z for x,y in A for z in B if x z] I'm schocked ;-) --eric ___ 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] func.update_meta (was: @deprecated)
Neat! But please add something to the __doc__ so we can also see it was changed. E.g. self.__doc__ = other.__doc__ + os.linesep + *** deprecated *** On 12 mrt 2005, at 5:25, Nick Coghlan wrote: I like update_meta Patch against current CVS added to SF with the behaviour: def update_meta(self, other): self.__name__ = other.__name__ self.__doc__ = other.__doc__ self.__dict__.update(other.__dict__) ___ 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] comprehension abbreviation (was: Adding any() and all())
Gareth McCaughan wrote: I'd like it, and my reason isn't just to save typing. There are two reasons. 1 Some bit of my brain is convinced that [x in stuff if condition] is the Right Syntax and keeps making me type it even though I know it doesn't work. 2 Seeing [x for x in stuff if condition] triggers my internal duplicated-stuff alarm, and it's distracting, in the same sort of way as it's distracting in C or C++ seeing The full syntax is: [ f(x) for x in seq if pred(x) ] being allowed to write 'x' instead of 'identity(x)' is already a shortcut, just as dropping the conditional part. Remember we're doing set theory stuff here. IMHO we should follow its notation conventions as much as we can. --eric ___ 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] Rationale for sum()'s design?
Guido van Rossum wrote: I think the conclusion should be that sum() is sufficiently constrained by backwards compatibility to make fixing it impossible before 3.0. But in 3.0 I'd like to fix it so that the 2nd argument is only used for empty lists. Which is not unlike the get() method of dicts. So may be the default should be None? ___ 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: [Pythonmac-SIG] The versioning question...
Martin v. Löwis wrote: Eric Nieuwland wrote: Would it be an idea to submit a PEP for extending the 'import' keyword? No. Normally, packages should aim for backwards compatibility, so that applications would only want to specify a minimum version, such as import xml assert xml.version_info (0,8,2) If you really want side-by-side installation of different versions, and a mechanism to select between them, the package could support import xml_0_8_2 as xml IOW, import-as should be sufficient for what you want to achieve. Unless you are doing comparison tests, where it would be nice to be able to state in a generic way that the new implementation should not change answers. May be something like: import spam[1] as spamnext # next version import spam[0] as spamnow # current version assert spamnow.Ni() == spamnext.Ni() --eric ___ 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: [Pythonmac-SIG] The versioning question...
Hi all, On 27 dec 2004, at 19:27, Chris Barker wrote: Robin has added versioning to the latest wxPython, and I. for one am ecstatic. It works great for me. I am generally using 2.5.3, but have 2.4.2 installed, and a number of my apps depend on it (on Linux anyway, it's pretty useless on OS-X) It's great to be able to put: import wxversion wxversion.select(2.4) At the top of my apps, and know that they'll use the version of wxPython I tested against. Would it be an idea to submit a PEP for extending the 'import' keyword? I can imagine it to be like: import spam version 1 import foo version 2, 4 import bar version 7, 1, 6 with version numbers consisting of some fixed maximum of parts and the version number parts not given might be wildcards. We could then have a per module version system like: .../ spam/ 1.0.1/ ... [version 1.0.1 stuff in here] 1.5.7/ ... [version 1.5.7 stuff in here] there should be nothing else in the module directory, except for a mechanism to further support versioning. Default behaviour of 'import spam' would be to select the most recent version. We might want to override that by pointing to some other version. This might be achieved using a symbolic link/alias/shortcut to the directory of that version (spam/current - spam/1.0.1). More like the directory/module method would be to allow for a __version__.py file in 'spam'. Content of this file is to be determined, but I think it should at least something like __current__ or __version__ to act as the pointer to the current version. --eric ___ 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