[Python-announce] CodraFT v2.1.1

2022-07-20 Thread Pierre Raybaut
Hi all,

CodraFT is an open-source generic signal and image processing software, based 
on Python, Qt, NumPy, SciPy and others:
https://codra-ingenierie-informatique.github.io/CodraFT/

I am pleased to announce that CodraFT v2.1.1 has been released.
This is the second public release of version 2, compatible with Python 3.7+.

CodraFT provides signal/image processing and visualisation features, and is 
available either as a stand-alone application or may be embedded in your own 
Python-Qt application thanks to advanced automation capabilities. CodraFT also 
has many I/O features, supporting a lot of images format as well as HDF5 (for 
saving/loading CodraFT workspace or importing any other data file).

Enjoy!

--
Always a pleasure to share with Python community, since 2008.
Pierre Raybaut
___
Python-announce-list mailing list -- python-announce-list@python.org
To unsubscribe send an email to python-announce-list-le...@python.org
https://mail.python.org/mailman3/lists/python-announce-list.python.org/
Member address: arch...@mail-archive.com


Re: list indices must be integers or slices, not str

2022-07-20 Thread Roel Schroeven

Frank Millman schreef op 20/07/2022 om 13:04:

>> On Wed, 20 Jul 2022 at 18:34, Frank Millman  wrote:
>>>   >>>
>>>   >>> x = list(range(10))
>>>   >>>
>>>   >>> '{x[1]}'.format(**vars())
>>> '1'
>>>   >>>
>>>   >>> '{x[-1]}'.format(**vars())
>>> Traceback (most recent call last):
>>>     File "", line 1, in 
>>> TypeError: list indices must be integers or slices, not str
>>>   >>>
>>>
>>> Can anyone explain this error? It seems that a negative index is deemed
>>> to be a string in this case.
>>>
>>
>> [...]
>>

"It seems to only want integer constants. x[2+2] and x[k] where k=2
don't work either.

I think the preferred style these days is f'{x[-1]}' which works."

Unfortunately the 'f' option does not work for me in this case, as I am
using a string object, not a string literal.

I've always found a bit dirty to pass indiscriminate symbol tables like 
the one from globals() or vars() or vars(some_object) to a formatting 
method, leaving the formatting string free to access any of it. I prefer 
to make things more explicit. Can't you make a dict with a selection of 
things you possible want to format?


In a sense I think you're looking for a more complete templating 
solution than what Python's formatting mechanisms are designed for. 
Maybe you should consider a full template engine, like Jinja?


--
"There is no cause so noble that it will not attract fuggheads."
-- Larry Niven

--
https://mail.python.org/mailman/listinfo/python-list


Re: exec() an locals() puzzle

2022-07-20 Thread Martin Di Paola

I did a few tests

# test 1
def f():
i = 1
print(locals())
exec('y = i; print(y); print(locals())')
print(locals())
a = eval('y')
print(locals())
u = a
print(u)
f()

{'i': 1}
1
{'i': 1, 'y': 1}
{'i': 1, 'y': 1}
{'i': 1, 'y': 1, 'a': 1}
1

# test 2
def f():
i = 1
print(locals())
exec('y = i; print(y); print(locals())')
print(locals())
a = eval('y')
print(locals())
y = a
print(y)
f()
{'i': 1}
1
{'i': 1, 'y': 1}
{'i': 1}
Traceback (most recent call last):
NameError: name 'y' is not defined


So test 1 and 2 are the same except that the variable 'y' is not
present/present in the f's code.

When it is not present, exec() modifies the f's locals and adds an 'y'
to it but when the variable 'y' is present in the code (even if not
present in the locals()), exec() does not add any 'y' (and the next
eval() then fails)

The interesting part is that if the 'y' variable is in the f's code
*and* it is defined in the f's locals, no error occur but once again the
exec() does not modify f's locals:

# test 3
def f():
i = 1
y = 42
print(locals())
exec('y = i; print(y); print(locals())')
print(locals())
a = eval('y')
print(locals())
y = a
print(y)
f()
{'i': 1, 'y': 42}
1
{'i': 1, 'y': 1}
{'i': 1, 'y': 42}
{'i': 1, 'y': 42, 'a': 42}
42

Why does this happen? No idea.

I may be related with this:

# test 4
def f():
i = 1
print(locals())
exec('y = i; print(y); print(locals())')
print(locals())
print(y)
f()
Traceback (most recent call last):
NameError: name 'y' is not defined

Despite exec() adds the 'y' variable to f's locals, the variable is not
accessible/visible from f's code.

So, a few observations (by no means this is how the vm works):

1) each function has a set of variables defined by the code (let's call
this "code-defined locals" or "cdef-locals").
2) each function also has a set of "runtime locals" accessible from
locals().
3) exec() can add variables to locals() (runtime) set but it cannot add
any to cdef-locals.
4) locals() may be a superset of cdef-locals (but entries in cdef-locals
which value is still undefined are not shown in locals())
5) due rule 4, exec() cannot add a variable to locals() if it is already
 present in the in cdef-locals.
6) when eval() runs, it uses locals() set for lookup

Perhaps rule 5 is to prevent exec() to modify any arbitrary variable of
the caller...

Anyways, nice food for our brains.

On Wed, Jul 20, 2022 at 04:56:02PM +, george trojan wrote:

I wish I could understand the following behaviour:

1. This works as I expect it to work:

def f():
   i = 1
   print(locals())
   exec('y = i; print(y); print(locals())')
   print(locals())
   exec('y *= 2')
   print('ok:', eval('y'))
f()

{'i': 1}
1
{'i': 1, 'y': 1}
{'i': 1, 'y': 1}
ok: 2

2. I can access the value of y with eval() too:

def f():
   i = 1
   print(locals())
   exec('y = i; print(y); print(locals())')
   print(locals())
   u = eval('y')
   print(u)
f()

{'i': 1}
1
{'i': 1, 'y': 1}
{'i': 1, 'y': 1}
1

3. When I change variable name u -> y, somehow locals() in the body of
the function loses an entry:

def f():
   i = 1
   print(locals())
   exec('y = i; print(y); print(locals())')
   print(locals())
   y = eval('y')
   print(y)
f()

{'i': 1}
1
{'i': 1, 'y': 1}
{'i': 1}

---NameError
   Traceback (most recent call last)
Input In [1], in ()  7 print(y)  8 # y
= eval('y')  9 #print('ok:', eval('y'))---> 10 f()

Input In [1], in f()  4 exec('y = i; print(y); print(locals())')
  5 print(locals())> 6 y = eval('y')  7 print(y)

File :1, in 
NameError: name 'y' is not defined1.

Another thing: within the first exec(), the print order seems
reversed. What is going on?

BTW, I am using python 3.8.13.

George
--
https://mail.python.org/mailman/listinfo/python-list

--
https://mail.python.org/mailman/listinfo/python-list


Re: list indices must be integers or slices, not str

2022-07-20 Thread Martin Di Paola

offtopic

If you want a pure-python but definitely a more hacky implementation,
you can play around with inspect.stack() and get the variables from
the outer frames.


# code:
x = 32
y = 42
printf("Hello x={x}, y={y}", x=27)

# output:
Hello x=27, y=42


The implementation of printf() was never released in PyPI (I guess I never saw
it as more than a challenge).

But the implementation is quite simple (I did a post about it):
https://book-of-gehn.github.io/articles/2021/07/11/Home-Made-Python-F-String.html

Thanks,
Martin.
On Wed, Jul 20, 2022 at 10:46:35AM -0600, Mats Wichmann wrote:

On 7/20/22 05:04, Frank Millman wrote:


I think the preferred style these days is f'{x[-1]}' which works."

Unfortunately the 'f' option does not work for me in this case, as I am
using a string object, not a string literal.


For that you could consider

https://pypi.org/project/f-yeah/

(straying a bit off thread subject by now, admittedly)
--
https://mail.python.org/mailman/listinfo/python-list

--
https://mail.python.org/mailman/listinfo/python-list


Re: exec() an locals() puzzle

2022-07-20 Thread Eryk Sun
On 7/20/22, george trojan  wrote:
>
> 1. This works as I expect it to work:
>
> def f():
> i = 1
> print(locals())
> exec('y = i; print(y); print(locals())')
> print(locals())
> exec('y *= 2')
> print('ok:', eval('y'))
> f()

In CPython, the locals of a function scope (as opposed to a class
scope or module scope) are optimized by storing them in an array in
the current frame. locals(), however, always returns the non-optimized
locals mapping of the current frame, i.e. the value of
sys._getframe(0).f_locals. In the case of optimized locals, the
locals() call first updates this dict with a snapshot of the current
values of local variables. This is useful for introspection, but
modifying the snapshot cannot extend or modify the optimized local
variables of the function scope.

exec() and eval() default to using the global and local variable
mappings that are returned by globals() and locals(). This allows them
to access the snapshot of the containing function's optimized locals,
but they can't extend or modify the function's optimized locals. At
most they can add dynamic locals to the snapshot, as used by
subsequent calls to locals(), exec() and eval().
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Are there any benefits of a shared build python, compared to a static build python?

2022-07-20 Thread Barry


> On 20 Jul 2022, at 18:09, Tianhe  wrote:
> 
> Python by default builds the library `libpythonMAJOR.MINOR.a` and
> statically links it into the interpreter. Also it has an `--enable-shared`,
> (https://docs.python.org/3/using/configure.html#cmdoption-enable-shared)
> flag, which will build a shared library `libpythonMAJOR.MINOR.so.1.0`, and
> dynamically link it to the interpreter.
> 
> Are there any benefits of a shared build python, compared to a static build
> python? Is there any performance difference?

What appears to be important is being able to do link time optimisation of 
python code.
I think Debian starting doing this first and other distro followed after seeing 
the big
performance improvement Debian got.

Barry

> 
> I found a related question on SO and is it like he said (
> https://stackoverflow.com/a/73035776/5983841), shared built vs statically
> built python only affects the "Embedding Python in Another Application"
> scenario ?
> 
> --
> 
> Regards,
> 
> Micky
> -- 
> https://mail.python.org/mailman/listinfo/python-list
> 

-- 
https://mail.python.org/mailman/listinfo/python-list


exec() an locals() puzzle

2022-07-20 Thread george trojan
I wish I could understand the following behaviour:

1. This works as I expect it to work:

def f():
i = 1
print(locals())
exec('y = i; print(y); print(locals())')
print(locals())
exec('y *= 2')
print('ok:', eval('y'))
f()

{'i': 1}
1
{'i': 1, 'y': 1}
{'i': 1, 'y': 1}
ok: 2

2. I can access the value of y with eval() too:

def f():
i = 1
print(locals())
exec('y = i; print(y); print(locals())')
print(locals())
u = eval('y')
print(u)
f()

{'i': 1}
1
{'i': 1, 'y': 1}
{'i': 1, 'y': 1}
1

3. When I change variable name u -> y, somehow locals() in the body of
the function loses an entry:

def f():
i = 1
print(locals())
exec('y = i; print(y); print(locals())')
print(locals())
y = eval('y')
print(y)
f()

{'i': 1}
1
{'i': 1, 'y': 1}
{'i': 1}

---NameError
Traceback (most recent call last)
Input In [1], in ()  7 print(y)  8 # y
= eval('y')  9 #print('ok:', eval('y'))---> 10 f()

Input In [1], in f()  4 exec('y = i; print(y); print(locals())')
   5 print(locals())> 6 y = eval('y')  7 print(y)

File :1, in 
NameError: name 'y' is not defined1.

Another thing: within the first exec(), the print order seems
reversed. What is going on?

BTW, I am using python 3.8.13.

George
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: list indices must be integers or slices, not str

2022-07-20 Thread Mats Wichmann
On 7/20/22 05:04, Frank Millman wrote:

> I think the preferred style these days is f'{x[-1]}' which works."
> 
> Unfortunately the 'f' option does not work for me in this case, as I am
> using a string object, not a string literal.

For that you could consider

https://pypi.org/project/f-yeah/

(straying a bit off thread subject by now, admittedly)
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: list indices must be integers or slices, not str

2022-07-20 Thread Chris Angelico
On Wed, 20 Jul 2022 at 23:50, Peter Otten <__pete...@web.de> wrote:
>
> I found
>
> https://peps.python.org/pep-3101/
>
> """
> PEP 3101 – Advanced String Formatting
> ...
> An example of the ‘getitem’ syntax:
>
> "My name is {0[name]}".format(dict(name='Fred'))
>
> It should be noted that the use of ‘getitem’ within a format string is
> much more limited than its conventional usage. In the above example, the
> string ‘name’ really is the literal string ‘name’, not a variable named
> ‘name’. The rules for parsing an item key are very simple. If it starts
> with a digit, then it is treated as a number, otherwise it is used as a
> string.
>

Cool. I think this is a good justification for a docs patch, since
that really should be mentioned somewhere other than a historical
document.

ChrisA
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: list indices must be integers or slices, not str

2022-07-20 Thread MRAB

On 20/07/2022 12:08, Chris Angelico wrote:

On Wed, 20 Jul 2022 at 20:55, Frank Millman  wrote:


On 2022-07-20 11:37 AM, Chris Angelico wrote:
> On Wed, 20 Jul 2022 at 18:34, Frank Millman  wrote:
>>
>> Hi all
>>
>> C:\Users\E7280>python
>> Python 3.9.7 (tags/v3.9.7:1016ef3, Aug 30 2021, 20:19:38) [MSC v.1929 64
>> bit (AMD64)] on win32
>> Type "help", "copyright", "credits" or "license" for more information.
>>   >>>
>>   >>> x = list(range(10))
>>   >>>
>>   >>> '{x[1]}'.format(**vars())
>> '1'
>>   >>>
>>   >>> '{x[-1]}'.format(**vars())
>> Traceback (most recent call last):
>> File "", line 1, in 
>> TypeError: list indices must be integers or slices, not str
>>   >>>
>>
>> Can anyone explain this error? It seems that a negative index is deemed
>> to be a string in this case.
>>
>
> Yeah, that does seem a little odd. What you're seeing is the same as
> this phenomenon:
>
 "{x[1]} {x[spam]}".format(x={1: 42, "spam": "ham"})
> '42 ham'
 "{x[1]} {x[spam]}".format(x={"1": 42, "spam": "ham"})
> Traceback (most recent call last):
>File "", line 1, in 
> KeyError: 1
>
> But I can't find it documented anywhere that digits-only means
> numeric. The best I can find is:
>
> https://docs.python.org/3/library/string.html#formatstrings
> """The arg_name can be followed by any number of index or attribute
> expressions. An expression of the form '.name' selects the named
> attribute using getattr(), while an expression of the form '[index]'
> does an index lookup using __getitem__()."""
>
> and in the corresponding grammar:
>
> field_name::=  arg_name ("." attribute_name | "[" element_index "]")*
> index_string  ::=   +
>
> In other words, any sequence of characters counts as an argument, as
> long as it's not ambiguous. It doesn't seem to say that "all digits is
> interpreted as an integer, everything else is interpreted as a
> string". ISTM that a negative number should be interpreted as an
> integer too, but that might be a backward compatibility break.
>

Thanks for investigating this further. I agree it seems odd.

As quoted above, an expression of the form '[index]' does an index
lookup using __getitem()__.

The only __getitem__() that I can find is in the operator module, and
that handles negative numbers just fine.


In general, __getitem__ is the method used to handle those sorts of lookups:

class X:
 def __getitem__(self, item):
 print("Get item", type(item), item)

"{x[0]} {x[1]} {x[-1]} {x[spam]} {x[1.0]}".format(x=X())

Outside of a format directive, you'd need to quote those:

x[0], x[1], x["spam"]

The distinction is that unquoted bare numbers are interpreted as
integers, not as strings. I'm unable to find the exact definition of
that documented.


Do you think it is worth me raising an issue, if only to find out the
rationale if there is one?



I'd wait for other people's responses first, there may be a better
insight to be found than what I was able to come across.


It's mentioned in PEP 3101 (Advanced String Formatting):

"""
The rules for parsing an item key are very simple. If it starts with a 
digit, then it is treated as a number, otherwise it is used as a string.

"""

I have a vague memory of it being discussed on python-dev, but it was a 
long time ago.

--
https://mail.python.org/mailman/listinfo/python-list


Re: list indices must be integers or slices, not str

2022-07-20 Thread Peter Otten

On 20/07/2022 11:37, Chris Angelico wrote:

On Wed, 20 Jul 2022 at 18:34, Frank Millman  wrote:


Hi all

C:\Users\E7280>python
Python 3.9.7 (tags/v3.9.7:1016ef3, Aug 30 2021, 20:19:38) [MSC v.1929 64
bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
  >>>
  >>> x = list(range(10))
  >>>
  >>> '{x[1]}'.format(**vars())
'1'
  >>>
  >>> '{x[-1]}'.format(**vars())
Traceback (most recent call last):
File "", line 1, in 
TypeError: list indices must be integers or slices, not str
  >>>

Can anyone explain this error? It seems that a negative index is deemed
to be a string in this case.



Yeah, that does seem a little odd. What you're seeing is the same as
this phenomenon:


"{x[1]} {x[spam]}".format(x={1: 42, "spam": "ham"})

'42 ham'

"{x[1]} {x[spam]}".format(x={"1": 42, "spam": "ham"})

Traceback (most recent call last):
   File "", line 1, in 
KeyError: 1

But I can't find it documented anywhere that digits-only means
numeric.



I found

https://peps.python.org/pep-3101/

"""
PEP 3101 – Advanced String Formatting
...
An example of the ‘getitem’ syntax:

"My name is {0[name]}".format(dict(name='Fred'))

It should be noted that the use of ‘getitem’ within a format string is
much more limited than its conventional usage. In the above example, the
string ‘name’ really is the literal string ‘name’, not a variable named
‘name’. The rules for parsing an item key are very simple. If it starts
with a digit, then it is treated as a number, otherwise it is used as a
string.

Because keys are not quote-delimited, it is not possible to specify
arbitrary dictionary keys (e.g., the strings “10” or “:-]”) from within
a format string.
"""
--
https://mail.python.org/mailman/listinfo/python-list


[Python-announce] structlog 22.1.0

2022-07-20 Thread Hynek Schlawack
I’m happy to announce a new release of structlog!

With more than 4 million downloads per month, structlog is the most popular 
solution for structured logging in Python. It doesn’t just allow you to log 
key-value pairs in a structured manner, it also makes it EASIER and FASTER. 
Check out  if you’re intrigued 
but not convinced!

My heartfelt thanks go to:

- My generous GitHub sponsors ,
- companies subscribing to structlog on Tidelift 
,
- and people who buy me coffees on !

That's the support that made me maintain structlog for almost a decade with no 
end in sight! <3



(alternatively, see  
for a richer-formatted version of the following)

Highlights

This is a (too) big release, so it has many highlights!

Firstly, rendering exceptions in machine-readable logs (usually JSON) got a big 
upgrade: thanks to structlog.processors.dict_tracebacks you can now have fully 
structured exceptions in your logs!

To ease getting started with structlog, we're now shipping 
structlog.stdlib.recreate_defaults() that recreates structlog's default 
behavior, but on top of standard library's logging. The output looks the same, 
but it runs through logging's machinery and integrates itself easier. The 
default configuration now also merges your contextvars-based context, so enjoy 
structlog.contextvars.bind_contextvars() without configuring anything!

Another request wish that kept coming up is naming the message key differently 
than event. We're aware that nowadays keys like msg are more common, but 
structlog pre-dates the software that introduced and popularized it. To allow 
for more consistency across your platforms, structlog now ships 
structlog.processors.EventRenamer that allows you to rename the default event 
key to something else and additionally also allows you to rename another key to 
event.

Full Changelog

Removed

-   Python 3.6 is not supported anymore.
-   Pickling is now only possible with protocol version 3 and newer.

Deprecated

-   The entire structlog.threadlocal module is deprecated. Please use the 
primitives from structlog.contextvars instead.

If you're using the modern APIs (bind_threadlocal() / merge_threadlocal()) 
it's enough to replace them 1:1 with their contextvars counterparts. The old 
approach around wrap_dict() has been discouraged for a while.

Currently there are no concrete plans to remove the module, but no patches 
against it will be accepted from now on. #409

Added

-   structlog.processors.StackInfoRenderer now has an additional_ignores 
parameter that allows you to filter out your own logging layer. #396
-   Added structlog.WriteLogger, a faster – but more low-level – alternative to 
structlog.PrintLogger. It works the way PrintLogger used to work in previous 
versions. #403 #404
-   structlog.make_filtering_bound_logger()-returned loggers now also have a 
log() method to match the structlog.stdlib.BoundLogger signature closer. #413
-   Added structured logging of tracebacks via the structlog.tracebacks module, 
and most notably the structlog.tracebacks.ExceptionDictTransformer which can be 
used with the new structlog.processors.ExceptionRenderer to render JSON 
tracebacks. #407
-   structlog.stdlib.recreate_defaults(log_level=logging.NOTSET) that recreates 
structlog's defaults on top of standard library's logging. It optionally also 
configures logging to log to standard out at the passed log level. #428
-   structlog.processors.EventRenamer allows you to rename the hitherto 
hard-coded event dict key event to something else. Optionally, you can rename 
another key to event at the same time, too. So adding EventRenamer(to="msg", 
replace_by="_event") to your processor pipeline will rename the standard event 
key to msg and then rename the _event key to event. This allows you to use the 
event key in your own log files and to have consistent log message keys across 
languages.
-   structlog.dev.ConsoleRenderer(event_key="event") now allows to customize 
the name of the key that is used for the log message.

Changed

-   structlog.make_filtering_bound_logger() now returns a method with the same 
signature for all log levels, whether they are active or not. This ensures that 
invalid calls to inactive log levels are caught immediately and don't explode 
once the log level changes. #401
-   structlog.PrintLogger – that is used by default – now uses print() for 
printing, making it a better citizen for interactive terminal applications. #399
-   structlog.testing.capture_logs now works for already initialized bound 
loggers. #408
-   structlog.processors.format_exc_info() is no longer a function, but an 
instance of structlog.processors.ExceptionRenderer. Its behavior has 

Re: list indices must be integers or slices, not str

2022-07-20 Thread Chris Angelico
On Wed, 20 Jul 2022 at 21:06, Frank Millman  wrote:
> I saw this from Paul Rubin - for some reason his posts appear in google
> groups, but not python-list.
>
> "It seems to only want integer constants. x[2+2] and x[k] where k=2
> don't work either.

Yes, that's for the same reason that x[spam] can be used usefully with
a dictionary. Otherwise you'd need to use quotes. It makes perfect
sense that both 2+2 and k are treated as strings.

> I think the preferred style these days is f'{x[-1]}' which works."

Not true; there's no single "preferred style", and f-strings are
absolutely NOT replacements for everything else. They have their
place, as do the others. Yes, including percent formatting, it is not
deprecated, and it's really tiresome when people claim that it is.

> Unfortunately the 'f' option does not work for me in this case, as I am
> using a string object, not a string literal.

Right. An f-string uses the exact syntax of a Python expression, which
is often too powerful, but also restricts it to the string literal
style (since it's actual code, not a method call). For other purposes,
.format() is a better choice.

ChrisA
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: list indices must be integers or slices, not str

2022-07-20 Thread Chris Angelico
On Wed, 20 Jul 2022 at 20:55, Frank Millman  wrote:
>
> On 2022-07-20 11:37 AM, Chris Angelico wrote:
> > On Wed, 20 Jul 2022 at 18:34, Frank Millman  wrote:
> >>
> >> Hi all
> >>
> >> C:\Users\E7280>python
> >> Python 3.9.7 (tags/v3.9.7:1016ef3, Aug 30 2021, 20:19:38) [MSC v.1929 64
> >> bit (AMD64)] on win32
> >> Type "help", "copyright", "credits" or "license" for more information.
> >>   >>>
> >>   >>> x = list(range(10))
> >>   >>>
> >>   >>> '{x[1]}'.format(**vars())
> >> '1'
> >>   >>>
> >>   >>> '{x[-1]}'.format(**vars())
> >> Traceback (most recent call last):
> >> File "", line 1, in 
> >> TypeError: list indices must be integers or slices, not str
> >>   >>>
> >>
> >> Can anyone explain this error? It seems that a negative index is deemed
> >> to be a string in this case.
> >>
> >
> > Yeah, that does seem a little odd. What you're seeing is the same as
> > this phenomenon:
> >
>  "{x[1]} {x[spam]}".format(x={1: 42, "spam": "ham"})
> > '42 ham'
>  "{x[1]} {x[spam]}".format(x={"1": 42, "spam": "ham"})
> > Traceback (most recent call last):
> >File "", line 1, in 
> > KeyError: 1
> >
> > But I can't find it documented anywhere that digits-only means
> > numeric. The best I can find is:
> >
> > https://docs.python.org/3/library/string.html#formatstrings
> > """The arg_name can be followed by any number of index or attribute
> > expressions. An expression of the form '.name' selects the named
> > attribute using getattr(), while an expression of the form '[index]'
> > does an index lookup using __getitem__()."""
> >
> > and in the corresponding grammar:
> >
> > field_name::=  arg_name ("." attribute_name | "[" element_index 
> > "]")*
> > index_string  ::=   +
> >
> > In other words, any sequence of characters counts as an argument, as
> > long as it's not ambiguous. It doesn't seem to say that "all digits is
> > interpreted as an integer, everything else is interpreted as a
> > string". ISTM that a negative number should be interpreted as an
> > integer too, but that might be a backward compatibility break.
> >
>
> Thanks for investigating this further. I agree it seems odd.
>
> As quoted above, an expression of the form '[index]' does an index
> lookup using __getitem()__.
>
> The only __getitem__() that I can find is in the operator module, and
> that handles negative numbers just fine.

In general, __getitem__ is the method used to handle those sorts of lookups:

class X:
def __getitem__(self, item):
print("Get item", type(item), item)

"{x[0]} {x[1]} {x[-1]} {x[spam]} {x[1.0]}".format(x=X())

Outside of a format directive, you'd need to quote those:

x[0], x[1], x["spam"]

The distinction is that unquoted bare numbers are interpreted as
integers, not as strings. I'm unable to find the exact definition of
that documented.

> Do you think it is worth me raising an issue, if only to find out the
> rationale if there is one?
>

I'd wait for other people's responses first, there may be a better
insight to be found than what I was able to come across.

ChrisA
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: list indices must be integers or slices, not str

2022-07-20 Thread Frank Millman



On 2022-07-20 12:31 PM, Frank Millman wrote:

On 2022-07-20 11:37 AM, Chris Angelico wrote:

On Wed, 20 Jul 2022 at 18:34, Frank Millman  wrote:


Hi all

C:\Users\E7280>python
Python 3.9.7 (tags/v3.9.7:1016ef3, Aug 30 2021, 20:19:38) [MSC v.1929 64
bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
  >>>
  >>> x = list(range(10))
  >>>
  >>> '{x[1]}'.format(**vars())
'1'
  >>>
  >>> '{x[-1]}'.format(**vars())
Traceback (most recent call last):
    File "", line 1, in 
TypeError: list indices must be integers or slices, not str
  >>>

Can anyone explain this error? It seems that a negative index is deemed
to be a string in this case.



Yeah, that does seem a little odd. What you're seeing is the same as
this phenomenon:


"{x[1]} {x[spam]}".format(x={1: 42, "spam": "ham"})

'42 ham'

"{x[1]} {x[spam]}".format(x={"1": 42, "spam": "ham"})

Traceback (most recent call last):
   File "", line 1, in 
KeyError: 1

But I can't find it documented anywhere that digits-only means
numeric. The best I can find is:

https://docs.python.org/3/library/string.html#formatstrings
"""The arg_name can be followed by any number of index or attribute
expressions. An expression of the form '.name' selects the named
attribute using getattr(), while an expression of the form '[index]'
does an index lookup using __getitem__()."""

and in the corresponding grammar:

field_name    ::=  arg_name ("." attribute_name | "[" 
element_index "]")*

index_string  ::=   +

In other words, any sequence of characters counts as an argument, as
long as it's not ambiguous. It doesn't seem to say that "all digits is
interpreted as an integer, everything else is interpreted as a
string". ISTM that a negative number should be interpreted as an
integer too, but that might be a backward compatibility break.



Thanks for investigating this further. I agree it seems odd.

As quoted above, an expression of the form '[index]' does an index 
lookup using __getitem()__.


The only __getitem__() that I can find is in the operator module, and 
that handles negative numbers just fine.


Do you think it is worth me raising an issue, if only to find out the 
rationale if there is one?


Frank


I saw this from Paul Rubin - for some reason his posts appear in google 
groups, but not python-list.


"It seems to only want integer constants. x[2+2] and x[k] where k=2
don't work either.

I think the preferred style these days is f'{x[-1]}' which works."

Unfortunately the 'f' option does not work for me in this case, as I am 
using a string object, not a string literal.


Frank
--
https://mail.python.org/mailman/listinfo/python-list


Re: list indices must be integers or slices, not str

2022-07-20 Thread Frank Millman

On 2022-07-20 11:37 AM, Chris Angelico wrote:

On Wed, 20 Jul 2022 at 18:34, Frank Millman  wrote:


Hi all

C:\Users\E7280>python
Python 3.9.7 (tags/v3.9.7:1016ef3, Aug 30 2021, 20:19:38) [MSC v.1929 64
bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
  >>>
  >>> x = list(range(10))
  >>>
  >>> '{x[1]}'.format(**vars())
'1'
  >>>
  >>> '{x[-1]}'.format(**vars())
Traceback (most recent call last):
File "", line 1, in 
TypeError: list indices must be integers or slices, not str
  >>>

Can anyone explain this error? It seems that a negative index is deemed
to be a string in this case.



Yeah, that does seem a little odd. What you're seeing is the same as
this phenomenon:


"{x[1]} {x[spam]}".format(x={1: 42, "spam": "ham"})

'42 ham'

"{x[1]} {x[spam]}".format(x={"1": 42, "spam": "ham"})

Traceback (most recent call last):
   File "", line 1, in 
KeyError: 1

But I can't find it documented anywhere that digits-only means
numeric. The best I can find is:

https://docs.python.org/3/library/string.html#formatstrings
"""The arg_name can be followed by any number of index or attribute
expressions. An expression of the form '.name' selects the named
attribute using getattr(), while an expression of the form '[index]'
does an index lookup using __getitem__()."""

and in the corresponding grammar:

field_name::=  arg_name ("." attribute_name | "[" element_index "]")*
index_string  ::=   +

In other words, any sequence of characters counts as an argument, as
long as it's not ambiguous. It doesn't seem to say that "all digits is
interpreted as an integer, everything else is interpreted as a
string". ISTM that a negative number should be interpreted as an
integer too, but that might be a backward compatibility break.



Thanks for investigating this further. I agree it seems odd.

As quoted above, an expression of the form '[index]' does an index 
lookup using __getitem()__.


The only __getitem__() that I can find is in the operator module, and 
that handles negative numbers just fine.


Do you think it is worth me raising an issue, if only to find out the 
rationale if there is one?


Frank
--
https://mail.python.org/mailman/listinfo/python-list


Re: Pip upgrade causing issues in 3.10

2022-07-20 Thread Eryk Sun
On 7/20/22, Mike Dewhirst  wrote:
> On 20/07/2022 4:43 am, David Raymond wrote:
>> C:\Program Files\Python310\Scripts>..\python.exe -m pip install --upgrade
>> pip
>> ERROR: Could not install packages due to an OSError: [WinError 32] The
>> process cannot access the file because it is being used by another
>> process: 'c:\\program files\\python310\\scripts\\'
> There's your problem. The 'other' process is your cmd.exe within which
> you are typing etc.
>
> Python scripts dir should be on the path so you don't have to execute
> anything from within it. Windows is obviously tripping over its own toes
> trying to delete and install something in the same dir while you also
> have your foot in it.

This should only occur if uninstalling pip deletes all of the files in
the "Scripts" directory. In this case, pip will 'compress' the
individual delete operations to remove the entire directory. It begins
by trying to 'stash' the "Scripts" directory, i.e. by renaming it to a
temporary adjacent name. It uses shutil.move() for this, which tries
os.rename() and falls back on shutil.copytree() and shutil.rmtree().

Of course this fails with a sharing violation if the directory is open
as the working directory in any process, including the current Python
process, because an open for a working directory doesn't share
delete/rename access. pip fails to handle this error. It crashes and
leaves a mess. The empty "Scripts" directory and the copytree() copy
aren't rolled back properly, and neither are the stashed (renamed)
"pip" and "pip*dist-info" directories in site packages.

This is not user error. It is a bug in pip. It should be able to
recover gracefully from failing to delete the directory. Moreover, it
shouldn't even have to roll back the operations if it deleted the
directory due to compression of explicit removals from the install
"RECORD". In particular there is no reason to delete the "Scripts"
directory, even if it's left empty.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: list indices must be integers or slices, not str

2022-07-20 Thread Chris Angelico
On Wed, 20 Jul 2022 at 18:34, Frank Millman  wrote:
>
> Hi all
>
> C:\Users\E7280>python
> Python 3.9.7 (tags/v3.9.7:1016ef3, Aug 30 2021, 20:19:38) [MSC v.1929 64
> bit (AMD64)] on win32
> Type "help", "copyright", "credits" or "license" for more information.
>  >>>
>  >>> x = list(range(10))
>  >>>
>  >>> '{x[1]}'.format(**vars())
> '1'
>  >>>
>  >>> '{x[-1]}'.format(**vars())
> Traceback (most recent call last):
>File "", line 1, in 
> TypeError: list indices must be integers or slices, not str
>  >>>
>
> Can anyone explain this error? It seems that a negative index is deemed
> to be a string in this case.
>

Yeah, that does seem a little odd. What you're seeing is the same as
this phenomenon:

>>> "{x[1]} {x[spam]}".format(x={1: 42, "spam": "ham"})
'42 ham'
>>> "{x[1]} {x[spam]}".format(x={"1": 42, "spam": "ham"})
Traceback (most recent call last):
  File "", line 1, in 
KeyError: 1

But I can't find it documented anywhere that digits-only means
numeric. The best I can find is:

https://docs.python.org/3/library/string.html#formatstrings
"""The arg_name can be followed by any number of index or attribute
expressions. An expression of the form '.name' selects the named
attribute using getattr(), while an expression of the form '[index]'
does an index lookup using __getitem__()."""

and in the corresponding grammar:

field_name::=  arg_name ("." attribute_name | "[" element_index "]")*
index_string  ::=   +

In other words, any sequence of characters counts as an argument, as
long as it's not ambiguous. It doesn't seem to say that "all digits is
interpreted as an integer, everything else is interpreted as a
string". ISTM that a negative number should be interpreted as an
integer too, but that might be a backward compatibility break.

ChrisA
-- 
https://mail.python.org/mailman/listinfo/python-list


list indices must be integers or slices, not str

2022-07-20 Thread Frank Millman

Hi all

C:\Users\E7280>python
Python 3.9.7 (tags/v3.9.7:1016ef3, Aug 30 2021, 20:19:38) [MSC v.1929 64 
bit (AMD64)] on win32

Type "help", "copyright", "credits" or "license" for more information.
>>>
>>> x = list(range(10))
>>>
>>> '{x[1]}'.format(**vars())
'1'
>>>
>>> '{x[-1]}'.format(**vars())
Traceback (most recent call last):
  File "", line 1, in 
TypeError: list indices must be integers or slices, not str
>>>

Can anyone explain this error? It seems that a negative index is deemed 
to be a string in this case.


Thanks

Frank Millman
--
https://mail.python.org/mailman/listinfo/python-list


Re: Pip upgrade causing issues in 3.10

2022-07-20 Thread Mike Dewhirst

On 20/07/2022 4:43 am, David Raymond wrote:

C:\Program Files\Python310\Scripts>..\python.exe -m pip install --upgrade pip
ERROR: Could not install packages due to an OSError: [WinError 32] The process 
cannot access the file because it is being used by another process: 
'c:\\program files\\python310\\scripts\\'
There's your problem. The 'other' process is your cmd.exe within which 
you are typing etc.


Python scripts dir should be on the path so you don't have to execute 
anything from within it. Windows is obviously tripping over its own toes 
trying to delete and install something in the same dir while you also 
have your foot in it.


M

--
Signed email is an absolute defence against phishing. This email has
been signed with my private key. If you import my public key you can
automatically decrypt my signature and be sure it came from me. Just
ask and I'll send it to you. Your email software can handle signing.



OpenPGP_signature
Description: OpenPGP digital signature
-- 
https://mail.python.org/mailman/listinfo/python-list