
On Fri, Oct 15, 2021 at 2:53 PM Chris Angelico <rosuav@gmail.com> wrote:
On Sat, Oct 16, 2021 at 8:22 AM Jeremiah Paige <ucodery@gmail.com> wrote:
Here is a pseudo-program showing where I would like to use this token in my own code if it existed. I think besides the cases where one is forced
to
always repeat the variable name as a string (namedtuple, NewType) this is an easy way to express clear intent to link the variable name to either its value or original source.
REGION = os.getenv(<<<) db_url = config[REGION][<<<]
name = arguments.get(<<<)
con = connect(db_url) knights = <<< horse = <<< con.execute(f"SELECT * FROM {knights} WHERE {horse}=?", (name,))
Toys like this often don't sell the idea very well, because there's a solid criticism of every example:
1) The environment variable REGION shouldn't be assigned to a variable named REGION, because it's not a constant. In real-world code, I'd be more likely to write >> region = os.getenv('REGION') << which wouldn't work with this magic token. 2) I'd be much more likely to put the entire config block into a variable >> cfg = config[os.getenv("REGION")] << and then use cfg.db_url for all config variables, so they also wouldn't be doubling up the names. 3) Not sure what you're doing with arguments.get(), but if that's command line args, it's way easier to wrap everything up and make them into function parameters. 4) I've no idea why you'd be setting knights to the string literal "knights" outside of a toy. If it's for the purpose of customizing the table name in the query, wouldn't it be something like >> table = "knights" << ?
I'm sure there are better examples than these, but these ones really aren't a great advertisement.
I'll admit I don't really have any further examples. After this idea came up I found myself occasionally typing out code where I tried to reach for it and wishing it was already implemented. But saying "I literally had to type T = TypeVar("T") four times!" is not in itself a compelling example. Even though I know I will have to type it again, and will again feel weird that there is no better way to write this in python. I don't really write factory functions this way myself, I just use them with what sounds like more regularity than some. I would absolutely use this syntax to gather some env vars, or declare string flags, like in tix.py. My real world example that got me to circle back to this idea was writing a scraper that would collect as much metadata as possible from a package. This meant walking many different static config files that have lots of optional branches, or branches that can hold many different kinds of data. This is the short bit that reads in a package's long description from pyproject.
if readme := project.get("readme"): if isinstance(readme, str): self.readme = self._read_file(readme, "utf-8") elif text := readme.get("text"): if "file" in readme: raise CorruptPackage() self.readme = text else: charset = readme.get("charset", "utf-8") self.readme = self._read_file(readme["file"], charset)
A lot of lines in this example block are creating very short lived variables based on the key name in the file read. I want the names to be kept in sync with the config file, even though I have no fear of this specific standard changing. However you already said that unpacking in expression assignment is not selling the new syntax. And I see no one else sticking their head up to say this is of interest. Regards, ~ Jeremiah