[Python-ideas] Re: Extract variable name from itself
Do you mean something like C# nameof()? https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/operators/nameof ___ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-le...@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/USPQDMEA7ACWH2T56ZYTWBGG7SMT3RIF/ Code of Conduct: http://python.org/psf/codeofconduct/
[Python-ideas] Re: New Ideas for Python - Oregon State University Open Source Software Course
> add multi-line commenting to the Python programming language Python uses docstrings for multi-line comments. > add capability to optimize for database access and usage Do you have an example of a concrete "capability to optimize for database access and usage"? What does that mean? How would it improve upon existing libraries like SQLAlchemy? > add functionality for mobile application development to the Python > programming language Most programming languages don't come with mobile development toolkits out of the box because they're expensive to maintain, and it's better for mobile sdks to have their own release cycle tied to the platform they're targeting instead of tied to specific language versions. You can use Kivy, the BeeWare project, and possibly other projects with their own set of tradeoffs to develop mobile apps using python. ___ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-le...@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/ZTXL3E5NSA43KLJ6MNXBIMM55D42QATE/ Code of Conduct: http://python.org/psf/codeofconduct/
[Python-ideas] Re: Ampersand operator for strings
I'm -1 on this. You can easily make a helper that achieves the desired syntax. Presenting "human readable data" isn't just about collapsing spaces, and having your own helper means that you can adjust the formatting to your specific use case if needed (for example with a different separator). from typing import Self class StripJoin: def __init__(self, value: str = "") -> None: self.value = value def __and__(self, other: str) -> Self: other = other.strip() separator = bool(self.value and other) * " " return StripJoin(f"{self.value}{separator}{other}") def __str__(self) -> str: return self.value j = StripJoin() print(j & " foo " & " bar " & " something ") # Output: "foo bar something" The example above is more efficient than a possible implementation directly on the str builtin as it doesn't strip the left side over and over. However it still incurs repeated allocations and encourages a pattern that performs badly in loops. With a lot of input you should probably accumulate the stripped strings in a list and join them all at once. In any case I recommend reaching out for a library like Rich (https://github.com/Textualize/rich) if you care about formatting the output of your program nicely. ___ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-le...@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/A7RPR3FSBXEMRYAUXJVYYROCHVHL7DVP/ Code of Conduct: http://python.org/psf/codeofconduct/
[Python-ideas] Re: Variadic patterns
I really like this. One problem though is that it's not immediately obvious what happens with binding patterns and "as" clauses. In the code inside the case statement, should these identifiers refer to the last value matched, or should they accumulate all the matches in a list? ___ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-le...@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/U6TBMZXATDAYKYUVK7B3JNHJH3XCPO76/ Code of Conduct: http://python.org/psf/codeofconduct/
[Python-ideas] Re: Time to relax some restrictions on the walrus operator?
Yeah you can technically craft such pathological edge cases but this is already heavily discouraged. Libraries that change the usual semantics of python's object model are rare. The only exception I can think of would be numpy which disallows truthiness checks because of the ambiguity of arrays being both scalars and containers. However, this means that the "if x := get_some_array():" construct is already ill-formed so nothing would change by generalizing the left side to arbitrary patterns. And since numpy arrays aren't proper Sequence types you can't use them with the current implementation of pattern matching anyway. So besides carefully crafted pathological edge-cases the "if (...) is not None" construct would be completely redundant. ___ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-le...@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/332DUWASBGXRPUHQN2AVEKTV2ASILKLB/ Code of Conduct: http://python.org/psf/codeofconduct/
[Python-ideas] Re: Time to relax some restrictions on the walrus operator?
> Yes, but what if you're testing for something that could *potentially* match > one of these empty objects? The right side can absolutely be falsy but to be able to conflate the falsy return value with the None emitted when the pattern doesn't match, the left side has to be one of the dubious patterns I listed. > I'm worried that this will end up being a bug magnet, or conversely, that > people will have to work around it with "if ([x] := foo()) is not None:", > which is way too clunky. In your example "if ([x] := foo()) is not None:" there is no possible value returned by foo() that could be both falsy and match the [x] pattern at the same time. All patterns besides the ones I listed can only be matched by truthy values so the work-around would only be needed for those dubious patterns. I think I'll experiment with a prototype when I have more time. ___ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-le...@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/VFRVYISEETRVZE6ODA72L7I3V63M6KY7/ Code of Conduct: http://python.org/psf/codeofconduct/
[Python-ideas] Re: Time to relax some restrictions on the walrus operator?
> What if it does match, though? The walrus operator returns the value on the right side so this wouldn't change. In your example the original dict would get printed. some_dict = {"x": 1, "y": 2} print({"x": x} := some_dict) # {"x": 1, "y": 2} The only pattern where it's not possible to know if the pattern was matched by looking at the return value is the None pattern: print(None := x) If the pattern matches this will print the value of x, None, and if the pattern doesn't match this will also print None because the walrus operator evaluates to None instead of the value on the right side when the pattern doesn't match. This is not a problem since testing for None is normally done with the is operator: x is None The only patterns where it's not possible to know if the pattern was matched by looking at the truthiness of the return values are the following: print(None := x) print(False := x) print(0 := x) print(0.0 := x) print("" := x) print([] := x) print({} := x) This is not a problem since in all of these cases testing for truthiness is normally done with bool() or by testing the value directly in an if statement. In my opinion the behavior is fairly unsurprising: return the right side if the pattern matches or None otherwise. We can even explain the current restricted behavior in terms of pattern matching: the name on the left side is an "irrefutable" pattern which will always match and therefore always return the right side of the expression. ___ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-le...@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/YQRKWVCEAQ7D67ODF74IVBDLVXAQGQOL/ Code of Conduct: http://python.org/psf/codeofconduct/
[Python-ideas] Re: Time to relax some restrictions on the walrus operator?
A while ago there was a discussion about allowing "match" patterns for the walrus operator. This would cover iterable unpacking as you suggested along with all the patterns allowed in match statements. if [x, y, z] := re.match(r"...").groups(): print(x, y, z) The walrus expression would evaluate to None if the pattern on the left can't be matched. print(x := 42) # 42 print(1 := 42) # None This would make it really useful in if statements and list comprehensions. Here are a couple motivating examples: # Buy every pizza on the menu cost_for_all_pizzas = sum( price for food in menu if ({"type": "pizza", "price": price} := food) ) # Monitor service health while Response(status=200, json={"stats": stats}) := health_check(): print(stats) time.sleep(5) ___ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-le...@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/HC7TAUYFTDMP52KAGDJFIB27KFSSI6C3/ Code of Conduct: http://python.org/psf/codeofconduct/
[Python-ideas] Re: Regex pattern matching
I see. I guess the ambiguity would stem from trying to force match objects into the sequence protocol even though the custom __getitem__() means that they're essentially a mixed mapping: Mapping[int | str, str | None] If we avoid any sort of "smart" length derived from only mo.groups() or mo.groupdict(), there's nothing stopping match objects from acting as proper mappings. We would need __iter__() which would simply yield all the available keys, including group 0 and all the named groups, and __len__() which would return the total number of keys. My point is that the match object doesn't need to masquerade as something else to be useful, just implement the protocol to describe the available keys. m = re.match(r"(a) (?Pb)(x)?", "a b") list(m) # [0, 1, 2, 3, 'foo'] dict(m) # {0: 'a b', 1: 'a', 2: 'b', 3: None, 'foo': 'b'} This means that pattern matching with mapping patterns would work automatically. The first example I shared would look like this: match re.match(r"(v|f) (\d+) (\d+) (\d+)", line): case {1: "v", 2: x, 3: y, 4: z}: print("Handle vertex") case {1: "f", 2: a, 3: b, 4: c}: print("Handle face") The second example would work without any changes: match re.match(r"(?P\d+)|(?P+)|(?P*)", line): case {"number": str(value)}: return Token(type="number", value=int(value)) case {"add": str()}: return Token(type="add") case {"mul": str()}: return Token(type="mul") ___ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-le...@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/FUB4CD2DKPJV5QVKZEFJ6XBAFKIP4EZ6/ Code of Conduct: http://python.org/psf/codeofconduct/
[Python-ideas] Regex pattern matching
Hi, I've been thinking that it would be nice if regex match objects could be deconstructed with pattern matching. For example, a simple .obj parser could use it like this: match re.match(r"(v|f) (\d+) (\d+) (\d+)", line): case ["v", x, y, z]: print("Handle vertex") case ["f", a, b, c]: print("Handle face") Sequence patterns would extract groups directly. Mapping patterns could be used to extract named groups, which would be nice for simple parsers/tokenizers: match re.match(r"(?P\d+)|(?P\+)|(?P\*)", line): case {"number": str(value)}: return Token(type="number", value=int(value)) case {"add": str()}: return Token(type="add") case {"mul": str()}: return Token(type="mul") Right now, match objects aren't proper sequence or mapping types though, but that doesn't seem too complicated to achieve. If this is something that enough people would consider useful I'm willing to look into how to implement this. ___ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-le...@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/EKMIJCSJGHJR36W2CNJE4CKO3S5MW3U4/ Code of Conduct: http://python.org/psf/codeofconduct/
[Python-ideas] Re: Python standard library TOML module
Yes. This is desperately needed. Usually I'm not a big fan of adding new standard library modules but in this case since toml is becoming such a critical part of packaging it seems like a no-brainer. ___ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-le...@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/B5T6TMAK2MSCQ4IV3VLRSFS6FBVGHRVN/ Code of Conduct: http://python.org/psf/codeofconduct/
[Python-ideas] Re: Unpacking in tuple/list/set/dict comprehensions
+1 I think this is a very sensible proposal and I encountered the use-cases you mentioned several times. ___ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-le...@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/5ILYEOUJY7U2RZ6CFVVFHUZD2UFUNUCE/ Code of Conduct: http://python.org/psf/codeofconduct/
[Python-ideas] Re: Typing Callable Ellipsis -- support for type hints a la Callable[[int, float, ...], None]
You can do that with a custom protocol https://docs.python.org/3/library/typing.html#typing.Protocol ___ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-le...@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/OHODQQX2TREFRTOVRIFYVQSLKGB2MVZI/ Code of Conduct: http://python.org/psf/codeofconduct/
[Python-ideas] Re: Otherwise clause in for statement to run when a empty iterable is used
I find that when I run into a similar scenario the reason why I need the iterable to be non-empty is because I'm trying to find something in it, and for this the `else` clause works pretty well: for item in get_items(): if check(item): do_thing(item) break else: raise ValueError() Early returns can also be useful: for item in get_items(): if check(item): return do_thing(item) raise ValueError() ___ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-le...@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/7PJDRJ6ESY5KT4VECU57P4PEPPOH4LK5/ Code of Conduct: http://python.org/psf/codeofconduct/
[Python-ideas] Re: We should have an explicit concept of emptiness for collections
> (len(collection) == 0) is True bool((len(collection) == 0) is True) == True ___ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-le...@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/MAPJNXHXGE64QJWLZ27HDPU4NMTI52W5/ Code of Conduct: http://python.org/psf/codeofconduct/
[Python-ideas] Re: A __decoration_call__ method for Callable objects (WAS: Decorators on variables)
Now this is a really interesting proposal. Something wasn't right in the other discussion, I didn't think making variable decorators inconsistent with the current class and function decorators by providing the variable name was particularly good. I've always felt like that something like __decoration_call__ was missing, so I'm really grateful that someone took the time to think about it. I'd say this looks pretty promising, and I can't see any specific downside compared to the alternative proposals. ___ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-le...@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/KX5ZOTCYLGLUT365VKE6U45HAISKI7ZC/ Code of Conduct: http://python.org/psf/codeofconduct/
[Python-ideas] Re: match expressions in python 3.10
On the other hand I think extending the walrus operator would make the change less intrusive and the syntax more easily discoverable: if match := re.match(r"...", some_string): print(match[1], match[2]) if [_, a, b] := re.match(r"...", some_string): print(a, b) # Assuming match objects would then be made into proper sequences Also, since it's not a new operator there's no need to worry about operator precedence. And since the current behavior of the walrus operator would already implement a subset of the proposed changes, I think it would reduce friction when deciding whether or not to adopt it. One last point is that the new operator would lead to two equivalent constructs: if thing.value matches foo: ... if foo := thing.value: ... I think using the "matches" operator like this would probably be frowned upon but that's yet another thing you would need to explain when teaching the language. Also, I can easily imagine some codestyle where the walrus operator would be considered obsolete as it would overlap with the "matches" operator while only providing a subset of the functionality, thus leading to fragmentation in the ecosystem. ___ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-le...@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/6YUVCSL23YKSCKRDJXVUZW2XSGXAYCJM/ Code of Conduct: http://python.org/psf/codeofconduct/
[Python-ideas] Re: match expressions in python 3.10
There was a discussion about this a couple months ago but instead of adding a new keyword the idea was that the walrus operator could be upgraded from simply being a binding operator to matching patterns supported by the match statement. if ["example", *files] := variable: print(files) If the pattern doesn't match the expression would evaluate to None instead of the right hand side value. The current syntax would still work the same as it would be interpreted as an unconditional name binding pattern. foo = [1, 2, 3] assert ([] := foo) is None assert ([a, b, c] := foo) is foo assert (bar := foo) is foo # No special case needed for the current behavior ___ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-le...@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/67C6OWL5YOFYKXJGY6XI34JKJC6WBUGT/ Code of Conduct: http://python.org/psf/codeofconduct/
[Python-ideas] Re: Comprehensions within f-strings
I didn't even realize f'{n for n in row}' was already valid syntax. Since generator expressions can usually only appear within parentheses, I assumed the syntax wouldn't conflict with anything because you would need to parenthesize the generator to make it work. Anyway, now I see that the better option is to leave the interpolation as-is but introduce a conversion flag that can unroll any iterable, so the current behavior actually works in our favor here. This would indeed be more powerful than any specialized comprehension syntax. print(''.join(f'{n:>8.3f}' for n in row) + f' | {sum(row):>8.3f}') print(f'{row!u:>8.3f} | {sum(row):>8.3f}') Now the second option is even more attractive in my opinion. I'm using !u for "unroll". The good news is that implementing a conversion flag is a much less intrusive change. ___ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-le...@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/YBTB5WMSBZQPCIUPPMRLTYITPSSRPQRK/ Code of Conduct: http://python.org/psf/codeofconduct/
[Python-ideas] Comprehensions within f-strings
Recently there's been some discussion around string comprehensions, and I wanted to look at a specific variant of the proposal in a bit more detail. Original thread: https://mail.python.org/archives/list/python-ideas@python.org/thread/MVQGP4GGTIWQRJTSY5S6SDYES6JVOOGK/ Let's say i have a matrix of numbers: matrix = [[randint(7, 50) / randint(1, 3) for _ in range(4)] for _ in range(4)] I want to format and display each row so that the columns are nicely lined up. Maybe also display the sum of the row at the end of each line: for row in matrix: print(''.join(f'{n:>8.3f}' for n in row) + f' | {sum(row):>8.3f}') This gives me a nicely formatted table. Now with the proposal: for row in matrix: print(f'{n for n in row:>8.3f} | {sum(row):>8.3f}') The idea is that you would be able to embed a comprehension in f-string interpolations, and that the format specifier at the end would be applied to all the generated items. This has a few advantages compared to the first version. It's a bit shorter and I find it easier to see what kind of shape the output will look like. It would also be faster since the interpreter would be able to append the formatted numbers directly to the final string. The first version needs to create a temporary string object for each number and then feed it into the iterator protocol before joining them together. ___ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-le...@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/HSTXKN7OUUR34IXLVMXR65XVPNWPVEL5/ Code of Conduct: http://python.org/psf/codeofconduct/
[Python-ideas] Re: String comprehension
> But that was not the primary motivator for adding them to the language. I don't think the original author thinks that way either about string comprehensions. I was asked about the kind of speed benefits that string comprehensions would have over using a generator with "".join() and I used f-strings as an example because the benefits would be similar. By the way now that i think about it, comprehensions would fit into f-string interpolation pretty nicely. f""" Guest list ({len(people)} people): {person.name + '\n' for person in people} """ > Which massively reduces the possible kinds of comprehensions one might write, > and I suspect most of those are already covered by string methods. I actually replied to David Mertz about this. String comprehensions can derive substrings from any iterable. Just like the only requirement for using a generator expression in "".join() is that it produces strings. Comprehensions can also have nested loops which can come in handy at times. And of course this doesn't mean I'm going to advocate for using them with complex predicates. ___ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-le...@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/J4UNAY3QY7M34UU5OIMZJCZR5XV7O676/ Code of Conduct: http://python.org/psf/codeofconduct/
[Python-ideas] Re: String comprehension
> you talked about builtin *iterables* My mistake, I reused the terminology used by the original author to make it easier to follow. > The point of iterators like map, zip and filter is to *avoid* performing the > computation until it is required. Of course. Maybe I wasn't clear enough. I don't know why we're bringing up these operators in a discussion about comprehensions. And what would a "range" comprehension even look like? To me the fact that there's no comprehensions for enumerate, filter, map, range, reversed and zip doesn't contribute to making dict, list and set exceptional cases. As I said we're left with bytearray, frozenset and memoryview. These are much less frequently used and don't even have a literal form so expecting comprehensions for them would be a bit nonsensical. On the other hand strings, bytes, lists, dicts and sets all have literal forms but only lists, dicts and sets have comprehensions. Three out of five doesn't make them exceptional cases so it's only logical to at least consider the idea of adding comprehensions for strings (and bytes) too. ___ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-le...@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/MU5CMPQJ2REDMDOKHFJTJCF2B3F5LIPN/ Code of Conduct: http://python.org/psf/codeofconduct/
[Python-ideas] Re: String comprehension
> The builtin interables bytearray, bytes, enumerate, filter frozenset, map, > memoryview, range, reversed, tuple and zip suggest differently. enumerate, filter, map, range, reversed and zip don't apply because they're not collections, you wouldn't be able to store the result of the computation anywhere. bytes comprehensions would make sense if string comprehensions are added. This leaves us with bytearray, frozenset and memoryview. How often are these used compared to strings, dicts, and lists? > If we were re-designing Python from scratch today, it is quite likely that we > would have only generator comprehensions I don't know about this, but unless everything besides generator expressions get deprecated the current comprehensions are here to stay and string comprehensions would fit perfectly alongside them (this is my opinion). ___ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-le...@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/JAGVQPSYUJAMVH4LCMLA6GJDH55ET2JJ/ Code of Conduct: http://python.org/psf/codeofconduct/
[Python-ideas] Re: String comprehension
> c"f(c) for c in some_string if g(c)" Even this example would allow the interpreter to skip building the generator object and having to feed the result of every f(c) back into the iterator protocol. This is similar to f-strings vs str.format. You could say that f-strings are redundant because they can't do anything that str.format can't, but they make it possible to shave off the static overhead of going through python's protocols and enable additional optimizations. ___ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-le...@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/UPXU2CNCACBAO7EV4XI3MMKZDAFSHTAA/ Code of Conduct: http://python.org/psf/codeofconduct/
[Python-ideas] Re: String comprehension
> the ONLY predicate that can be expressed about a single character is it being > a member of a subset of all Unicode characters You seem to be assuming that the comprehension would be purposefully restricted to iterating over strings. The original author already provided examples with predicates that don't involve checking for a subset of characters. old = [0, 1, None, 2] new = c"str(x + 1) for x in old if isinstance(x, int)" The existing "".join() idiom isn't restricted to iterating over an existing string. You also have to account for nested comprehensions. There's nothing that would prevent you from having arbitrary complexity in string comprehension predicates, just like nothing prevents you from having arbitrary predicates when you join a generator expression. ___ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-le...@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/6T7NQT5HFVYSI3RHUCBDDCEWKJ7HDPZG/ Code of Conduct: http://python.org/psf/codeofconduct/
[Python-ideas] Re: String comprehension
It's kind of weird that people seem to be missing the point about this. Python already has comprehensions for all the iterable builtins except strings. The proposed syntax doesn't introduce any new concept and would simply make strings more consistent with the rest of the builtins. The argument that we can already do this with the "".join() idiom is backwards. It's something we have to do _because_ there's no way to write a string comprehensions directly. Comprehensions express intent. Joining a generator expression with an empty string doesn't convey the intent that you're building a string where each character is derived from another iterable. Also I haven't seen anyone acknowledge the potential performance benefits of string comprehensions. The "".join() idiom needs to go through the entire generator machinery to assemble the final string, whereas a decent implementation of string comprehensions would enable some pretty significant optimizations. ___ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-le...@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/CYCM35RAKL7PMPGE2VYQ2ZPKK5RSMEZM/ Code of Conduct: http://python.org/psf/codeofconduct/
[Python-ideas] Re: Add venv activate command to the venv modules
To get around the fact that activating a virtualenv requires setting environment variables in the current shell poetry has a shell command that simply spawns a new shell with the appropriate environment variables: https://python-poetry.org/docs/cli/#shell So a cross-platform `activate` command wouldn't be possible but something like this could: $ python -m venv venv_name shell (venv_name) $ # the virtualenv is now active (venv_name) $ exit $ # back into the parent shell ___ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-le...@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/AOUNEH6HA6QC7KE7WRRYXSP6FSVOTJ5P/ Code of Conduct: http://python.org/psf/codeofconduct/
[Python-ideas] Re: Function for fetching what months between two dates
Hi. Bundling this into the standard library doesn't seem to provide any real advantage over defining it as a free-standing utility function in your own code. And if it's in your own code you can easily tweak it if you need to :) ___ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-le...@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/26U3IAZ4IBNL7KKKCV7O5Q6KOSEJZLXQ/ Code of Conduct: http://python.org/psf/codeofconduct/
[Python-ideas] Re: Make for/while loops nameable.
I think this is the kind of feature that can very easily be abused. Whenever I want to break out of a nested loop I take this as an opportunity to extract the loop into its own function and use the return statement to break out of the loop. IMO this is a lot better than having named or indexed loop control because a proper function can later be reusable, and it lets you explain why you need to return early in the docstring. ___ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-le...@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/SMU7CAFHWQROQYLWK3HEL5XDDRXKU46Z/ Code of Conduct: http://python.org/psf/codeofconduct/
[Python-ideas] Re: [RFC] Built-in shorthand b() for breakpoint()
Single-letter variables are common. If your use-case is inserting breakpoints into arbitrary library code there's no way to guarantee that the builtin won't be shadowed by some arguments or other local variables, making your alias extremely unreliable. def add(a, b): """Arbitrary library code.""" b() # This will fail because the argument shadows the builtin return a + b Sure you could argue that the `breakpoint` builtin is affected by shadowing too, but it's much less common to have a variable named `breakpoint` than `b`. I think an even worse consequence would be the cryptic error message that beginners would be likely to encounter in programming tutorials. Quick example: def add(a): # Assuming some kind of tutorial about functions return a + b NameError: name 'b' is not defined Let's imagine that the beginner made a mistake and forgot to declare the second argument. The error message is clear, but with your `breakpoint` alias this is what the interpreter will print out: TypeError: unsupported operand type(s) for +: 'int' and 'builtin_function_or_method' Really confusing. I highly oppose this. ___ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-le...@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/4VB2TQRS5DLSYN3UVXL7PPTFWMC3ZPB4/ Code of Conduct: http://python.org/psf/codeofconduct/
[Python-ideas] Re: Move semantics
The C++ example specifically shows that if you're talking about ownership and lifetimes, you're not talking about move semantics. As you pointed out, the example wouldn't work in Rust specifically because Rust has a borrow checker, and not just move semantics. A compiler with a borrow checker will perform move optimizations, which at runtime result in behavior similar to C++ move semantics. So I'm pointing out that in this thread, we're really talking about borrow checking with declarative lifetimes more than move semantics. ___ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-le...@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/DNZP5Z372TFTT2QDXHQYQ7SM5OGDTAZQ/ Code of Conduct: http://python.org/psf/codeofconduct/
[Python-ideas] Re: Move semantics
This thread is a mess. Move semantics is nothing more than creating a shallow copy that steals the inner state of a previous instance. It's an optimization, and moving out of a variable never makes the previous instance unusable: void f1(std::vector&& vec); void f2() { std::vector vec; f1(std::move(vec)); vec.push_back(2); // This compiles just fine } Since move semantics are a pass-by-value optimization, they can't exist in python where calling any kind of function simply shares bindings. In python no matter how hard you try you'll never run into the "hollow" instances that move semantics leave behind. Some of the use-cases described in this thread are actually about borrow checking: making it possible to terminate the semantic lifetime of a variable by passing it to a function. Manually propagating lifetime restrictions through type annotations is definitely possible, and could be supported with a mypy plugin, but it will be very verbose, and without any kind of "constness" in the language the added safety will be pretty limited. ___ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-le...@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/XFLGRVBLGD7P2TLT6Z55QK6356676A5H/ Code of Conduct: http://python.org/psf/codeofconduct/
[Python-ideas] Re: PEP 634-636: Mapping patterns and extra keys
I'm in favor of keeping the PEP as it currently is. Mappings are naturally structural subtypes of one another, therefore mapping patterns should be consistent with class patterns. car = Car(...) match car: case Vehicle(): pass case Car(): # will never match pass This example is analogous to the first one in the discussion. If Car is a subclass of Vehicle, then Vehicle() is a more general pattern than Car() and will always match despite the instance not being exactly of type Vehicle. With mapping patterns it's exactly the same thing. You need to match the more specific patterns first. Matching x and y is more general than matching x, y and z. One more thing. If we compare the proposed behavior to other languages the most relevant example would be object destructuring in javascript: const { 'x': x, 'y': y } = { 'x': 1, 'y': 2, 'z': 3 }; const { x, y } = { x: 1, y: 2, z: 3 }; // more common short form Object destructuring only matches the specified fields. You can also match the remaining fields but it's always explicit: const { x, y, ...rest } = { x: 1, y: 2, z: 3 }; console.log(rest); // { z: 3 } The pattern is widely adopted and the behavior generally lines up with people's expectations. ___ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-le...@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/52L3EQ5FUBXDZRFAU4D4PESMZ6GUGIHC/ Code of Conduct: http://python.org/psf/codeofconduct/
[Python-ideas] Re: PEP 634-636: Mapping patterns and extra keys
I'm in favor of keeping the PEP as it currently is. Mappings are naturally structural subtypes of one another, therefore mapping patterns should be consistent with class patterns. car = Car(...) match car: case Vehicle(): pass case Car(): # will never match pass This example is analogous to the first one in the discussion. If Car is a subclass of Vehicle, then Vehicle() is a more general pattern than Car() and will always match despite the instance not being exactly of type Vehicle. With mapping patterns it's exactly the same thing. You need to match the more specific patterns first. Matching x and y is more general than matching x, y and z. One more thing. If we compare the proposed behavior to other languages the most relevant example would be object destructuring in javascript: const { 'x': x, 'y': y } = { 'x': 1, 'y': 2, 'z': 3 }; const { x, y } = { x: 1, y: 2, z: 3 }; // more common short form Object destructuring only matches the specified fields. You can also match the remaining fields but it's always explicit: const { x, y, ...rest } = { x: 1, y: 2, z: 3 }; console.log(rest); // { z: 3 } The pattern is widely adopted and the behavior generally lines up with people's expectations. ___ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-le...@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/I65QIOZNEIMJSE6YP2VNJGAXM3KOFM56/ Code of Conduct: http://python.org/psf/codeofconduct/
[Python-ideas] Re: Dict unpacking assignment
I think that instead of dict unpacking specifically, what we need is to come up with a way to use the pattern-matching proposed in PEP 634 outside of match statements. This would make it possible to unpack any pattern. My opinion is that the walrus operator is practically waiting to support pattern-matching: if Response(status=200, json={"title": title}) := get('/posts/42'): print(title) I wrote a few more examples here: - https://mail.python.org/archives/list/python-ideas@python.org/thread/MJ7JHYKHKB2T4SCFV4TX4IMKUANUAF5B/ -- Valentin ___ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-le...@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/ZWFMZH7QCOQHXPFGHAWOI74OSUAPCWGL/ Code of Conduct: http://python.org/psf/codeofconduct/
[Python-ideas] Re: Extrapolating PEP 634: The walrus was waiting for patmat all along
> Why should a failed match return None? That's not helpful if it matches > but the value itself is None. The only pattern that would match `None` is this one: print(None := get_value()) # Always None Here, the walrus operator would always return `None`. Either because the function returned `None` or the function returned something else and the pattern didn't match. The behavior is consistent, this particular pattern is just not that useful. Pattern-matching shouldn't exempt you from checking for `None` with the `is` operator anyway: print(get_value() is None) # True or False The proposed semantics don't get in the way of idiomatic python. Most of the time you only care about the truthiness of the value returned by the walrus operator. The most common example would be with regular expressions: price_tag = "Price: $7" if match := re.match(r".*(\d+).*", price_tag): print(match[1]) By the way I'm hoping that with PEP 634 `Match` objects can become proper `collections.abc.Sequence` instances. This would allow regex destructuring: if [_, amount] := re.match(r".*(\d+).*", price_tag): print(amount) -- Valentin ___ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-le...@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/7GWNFOLPAASUZCXAXAAUWFX7APVGNM4X/ Code of Conduct: http://python.org/psf/codeofconduct/
[Python-ideas] Re: Extrapolating PEP 634: The walrus was waiting for patmat all along
> If you look in PEP 622 you'll see that there was a rejected idea `if > match ...` that's pretty similar. We nixed it because it just made the > PEP larger. For 3.11 we can consider something like this. Of course I understand the PEP is already pretty big. But if it goes through and we start thinking about extending it with `if match` statements, my point is that it would be worth considering extending the walrus operator instead :) ___ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-le...@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/EEJ27EVCQJTAPTWO6SRRHOOARRLSJJVT/ Code of Conduct: http://python.org/psf/codeofconduct/
[Python-ideas] Extrapolating PEP 634: The walrus was waiting for patmat all along
Pattern-matching is great. I think PEP 634 is on the right track, but it would be a waste to only use pattern-matching for choosing a branch in a match statement. Let’s look at Rust: if let [x, y] = my_array { ... } Rust "if let" constructs are an alternative to full-blown match statements that make it less verbose to match a single pattern. We have a similar problem. The syntax proposed by PEP 634 is pretty verbose for matching a single pattern: match my_list: case [x, y]: ... Two keywords and two indentation levels. We can do better: if [x, y] := my_list: ... Yes, your first intuition is right. This looks similar to the Rust version but would work completely differently. But hear me out. Let's look past my terrible example and focus on the idea. 1. The walrus operator was purposefully designed to create bindings and not to perform assignments to arbitrary lvalues. 2. Matching a pattern only introduces bindings as well, no assignments. 3. The current behavior of the walrus operator is equivalent to matching the right-side operand to an "irrefutable" capture pattern. Allowing the walrus operator to do pattern-matching would simply make the returned value conditional. If the pattern doesn't match, the walrus operator returns None. print(x := 42) # 42 print(1 := 42) # None The current PEG parser would backtrack when encountering the walrus operator to interpret the left-side as a pattern. Finally, more examples: # Buy every pizza on the menu sum( price for food in menu if ({"type": "pizza", "price": price} := food) ) # Download all images from document {url: download(url) for tag in html if (Img(src=url) := tag)} # Monitor service health while Response(status=200, json={"stats": stats}) := health_check(): print(stats) time.sleep(5) I'm convinced that making the walrus operator a pattern-matching operator would turn it into the perfect companion for PEP 634. What do you think? References: - PEP 634: https://www.python.org/dev/peps/pep-0634/ - Rust "if let": https://doc.rust-lang.org/book/ch06-03-if-let.html -- Valentin ___ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-le...@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/MJ7JHYKHKB2T4SCFV4TX4IMKUANUAF5B/ Code of Conduct: http://python.org/psf/codeofconduct/