On Jan 19, 2020, at 22:22, Soni L. <fakedme...@gmail.com> wrote:
> 
> 
>> >> > or maybe:
>> >> > > foo = f"{from foo.bar import 'foo.txt'}"  # string imports
>> >> > bbar = fb"{from foo.bar import 'bar.txt'}"  # bytes imports
>> >> >> This version would require turning import from a statement into an 
>> >> >> expression, which seems like a pretty big change.
>> > > It would not. Equivalently, ''!r isn't an expression and yet you can do 
>> > > f"{''!r}", because it's special syntax of fstrings.
>> 
>> That’s not even remotely equivalent. A format replacement_field has an 
>> expression and optional conversion and type specifiers. The fact that 
>> conversion and type specifiers aren’t expressions doesn’t mean the 
>> expression isn’t an expression. That’s like arguing that digits don’t have 
>> to have numeric values because you can put a - at the start of a number and 
>> - doesn’t have a numeric value.
>> 
>> Plus, you’re clearly trying to use the value of the import, which inherently 
>> means it’s an expression. Statements don’t have values. Neither do 
>> conversion specifiers, or random fragments of syntax. Only expressions have 
>> values.
> 
> It wouldn't be an expression in itself, it would be an expression *in a 
> fstring*. fstrings *do not follow normal python syntax*

Yes they do. Look at the grammar in the library docs:

f_string          ::=  (literal_char | "{{" | "}}" | replacement_field)*
replacement_field ::=  "{" f_expression ["!" conversion] [":" format_spec] "}"
f_expression      ::=  (conditional_expression | "*" or_expr)
                         ("," conditional_expression | "," "*" or_expr)* [","]
                       | yield_expression
conversion        ::=  "s" | "r" | "a"
format_spec       ::=  (literal_char | NULL | replacement_field)*
literal_char      ::=  <any code point except
The f_expression is a subset of the same expression used by the main syntax. 
All those alternate productions it links to are the ones in the main syntax. 
The syntax for the expression part of an f-string is an expression. And look at 
the semantics. What it formats is the result of evaluating that expression (as 
normal Python code in the relevant scope).

> so we can literally add a rule that says "if you see '{from $NAME import 
> $STR}' in an fstring, do this"
> to the syntax. it doesn't need to become an expression, it just needs to turn 
> the '{...}' part into the desired value. oh and, for that reason, no 
> modifiers or whatnot would be applicable.

So instead of adding a new expression to Python, you want to change f-strings 
from being a subset of Python to being a subset of Python plus a new import 
expression that isn’t in Python but looks confusingly similar to something that 
is.

> you do not have to turn it into an expression or define it as an expression. 
> besides, you get different behaviour for unicode fstrings and bytes fstrings 
> which should further help to drive the point home that it's not an expression 
> within an fstring,

There are no bytes f-strings. I think there are rejected PEPs for both the 
obvious ways of doing things (add a __bfformat__ protocol, or don’t allow 
format specs), but they’re both rejected.

But even if there were binary f-strings, it wouldn’t show any such thing 
anyway. The whole reason bytes format makes sense is that string format works 
by evaluating an expression to get an ordinary value and then calling a method 
on the result. A bytes format would do the same thing, but call a different 
method (presumably __bformat__ falling back to __bytes__ instead of __format__ 
falling back to __str__, although you might also want to add the C buffer 
protocol as a fallback) on that value.

>> > And the point is that you shouldn't have to import stuff to be able to 
>> > import stuff, If even if the latter stuff is resources. It should be built 
>> > into the language just like importing modules is built into the language.
>> 
>> Why?
>> 
>> You could make this same claim about anything: you shouldn’t have to import 
>> stuff to be able to deserialize stuff with JSON or to do elementwise 
>> operations on arrays or whatever. You need some argument for why reading 
>> text files is so much more important than all the other things you use a 
>> module for that it needs to be builtin.
>> 
>> The reason importing modules is special is the obvious bootstrapping 
>> problem: if you had to import a module to import modules, there would be no 
>> way to import that first module. That obviously isn’t true for loading text 
>> files.
>> 
>> And even then, import could just be a builtin function (the way it is in 
>> many other languages); the reason it needs special syntax is that it needs 
>> to bind things in the outer scope.
> 
> if import was a function then we wouldn't have "from foo import *" and we 
> wouldn't be having this argument. it's not a function tho ;)

I’m sorry, but this doesn’t even make sense as a reply to what I said. 

I explained why import can’t be a function. But your resource import-expression 
(or import-not-an-expression-but-f-strings-treat-them-as-if-they-we’re) can be 
a function, because it doesn’t need to bind any names or do anything else with 
the containing scope. So you have to explain why it needs custom syntax instead 
of just being a function.

You also need to explain why it even needs to be builtin rather than imported, 
even though being imported is fine for tons of other useful stuff that people 
do even more often.

If you can’t explain either of those things, and if imporlib.reaources already 
does everything you want, the answer is to just import it and use it.
_______________________________________________
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/ZP5KQKJM7B6337R4JJ7ELMERKG4PYN6L/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to