[Python-ideas] Re: 'Infinity' constant in Python

2020-09-04 Thread Steven D'Aprano
On Sat, Sep 05, 2020 at 12:44:47AM -0400, Cade Brown wrote:

> First of all, you're comparing immutable value types to dynamic objects
> which are predicated and processed based on the memory address (e.g. for
> equality testing, by default). Of course they're going to have different
> semantics, especially when converting to a unique string representation.

Um, yes?

What's your point here? There is no guarantee that `eval(repr(x))` must 
always return something equal to x, and one reason that isn't a 
guarantee is the difference between value types (whether mutable or not) 
and identity types. That's not the only acceptable reason though.


> A better question to ask is why does it work for *almost* all values of
> 'float' , but not infinite ones... This is a glaring hole in my opinion.

That is a better question, but it's not a great question. Nor is it a 
glaring hole: Python is 30 years old, if this was an obvious lack that 
people need regularly, it would have been fixed years ago.

Unless you have thought of something new that none of the tens or 
hundreds of thousands of Python users over the decades have thought of, 
I think we can be fairly confident that this is at best a minor feature.

Python is a mature and popular language. Any "glaring hole" in the 
language is likely to be:

- a matter of personal preference or taste;

- something that has been ruled out due to backwards compatibility 
  or because it doesn't fit the execution model;

- or something of such minor importance that nobody noticed or cared.

In the last case, it's not exactly *glaring* then.


> Why do you think having 'inf' is better than something that means something
> to the python interpreter?

Not everything has to be a builtin constant.

If it's a keyword, there is the *very large* cost that it will break any 
code that uses Infinity as a name.

There's the opportunity cost: once we create an Infinity or Inf 
constant, then we're stuck with it forever, even if a better use for 
that name comes along.

There is the development cost: somebody has to do the work, write the 
tests, write the documentation.

There's the on-going bloating cost: every new feature increases the size 
of the language, the interpreter, the documentation, the time it takes 
to compile the interpreter, etc. A few milliseconds here, a few bytes 
there, it all adds up.

There's the cost to users: one more builtin that you have to learn, one 
more thing to know, one more choice to make, more questions for 
beginners to ask:

"What's the difference between float('inf') and Infinity?"

"Why is it Infinity not Inf?"

"Why is there no builtin NAN constant?"

You can argue that these are all *small* costs, and I agree. (Other than 
the backwards-compatibility breaking use of a new keyword, which alone 
would almost certainly rule this out.)

But, based on the discussion so far, the benefit is even smaller. If the 
costs are greater than the benefit, then adding an Infinity constant 
will make the language worse, not better.

Come up with an important, interesting use-case, and that balance could 
change. But consistency with other floats alone is not a very 
interesting or important reason.

There's no NAN constant either. Do you want that?


> I've had countless times where I've had to
> Google how to create an infinite float, and second guessed myself because
> it is very unintuitive to have to call a string conversion to get what
> amounts to a constant.

x = Decimal('0.1')
p = Path('/home/user/file')
regex = re.compile(r'spam.*')

Does this mean that we need to have constants for Decimals, Paths, 
regexes, etc too?
 
I guess we need an infinite number of builtin named constants.

No? Then what makes infinity important enough to be an exception?


I'm sorry that you can't remember the basic idiom `float('inf')` or that 
you can import it from the math lib, even after googling it "countless" 
times. Perhaps you should write it on a postit note and stick it on your 
monitor?

I'm not being sarcastic. I've literally done that for other things I had 
trouble remembering.



> The 'use case' is being able to specify a number which is constant, by a
> constant, and not requiring me to execute a function call.

That's not a use-case. That's a personal preference that literally boils 
down to "But I don't want to use a function call!".

But okay, you can get this by monkey-patching the builtins. Stick this 
in your PYTHONSTARTUP file, or the entry point to your Python 
applications:

import builtins
builtins.inf = float('inf')

and now you can use `inf` as a builtin name everywhere.

It's not a keyword, but making Infinity a keyword would be even more 
costly, breaking backwards compatibility for very little benefit.


> Further, keeping
> it the way it is harbors readability. Every time I parse code that contains
> `float('inf')` I ask myself why it is having to do this, because it seems
> like code shouldn't have to.


I think you mean "hi

[Python-ideas] Re: 'Infinity' constant in Python

2020-09-04 Thread Cade Brown
Also, I've seen multiple people say I suggested 'inf' as the name when I've
specifically said at least twice that it would not be my choice for the
identifier. I clearly have said 'Infinity' is the far superior choice for
Python. My comments were that currently, Python displays 'inf' as the
string representation, and that the repr function would be changed to
return the new identifier (i.e. `repr(float('inf')) == 'Infinity'`)

And, I am undecided on 'nan' semantics (`NaN` would be my choice of
identifier, in any situation), since it is (by definition) not a number.
It's kind of odd that Python has it, especially since it has 'none'. I
guess it's good for interfacing with C APIs and lower level functions that
require a float and not a generic object, but I digress. In any case, it
would be very similar to 'Infinity' constants (some differences: `float('nan')
is float('nan')` is False, whereas `NaN is NaN` would be True, but of
course `NaN == NaN` is still False)

Thanks,

*Cade Brown*
Research Assistant @ ICL (Innovative Computing Laboratory)
Personal Email: brown.c...@gmail.com
ICL/College Email: c...@utk.edu




On Sat, Sep 5, 2020 at 12:44 AM Cade Brown  wrote:

> First of all, you're comparing immutable value types to dynamic objects
> which are predicated and processed based on the memory address (e.g. for
> equality testing, by default). Of course they're going to have different
> semantics, especially when converting to a unique string representation.
> A better question to ask is why does it work for *almost* all values of
> 'float' , but not infinite ones... This is a glaring hole in my opinion.
>
> Why do you think having 'inf' is better than something that means
> something to the python interpreter? I've had countless times where I've
> had to Google how to create an infinite float, and second guessed myself
> because it is very unintuitive to have to call a string conversion to get
> what amounts to a constant.
>
> The 'use case' is being able to specify a number which is constant, by a
> constant, and not requiring me to execute a function call. Further, keeping
> it the way it is harbors readability. Every time I parse code that contains
> `float('inf')` I ask myself why it is having to do this, because it seems
> like code shouldn't have to.
>
> Your argument seems to stem from the least possible Python can do (i.e. it
> doesn't HAVE to do anything more than it does currently). This mailing list
> is python-ideas, which is for ideas currently not in Python. I am aware
> that nothing *has* to be done, I am merely suggesting why it would make
> sense to add, and why it would make Python a more complete, predictable and
> frankly 'prettier' language (albeit subjective). I don't see how any of
> your points address those concerns
>
>
> On Fri, Sep 4, 2020, 10:14 PM Steven D'Aprano  wrote:
>
>> On Fri, Sep 04, 2020 at 09:40:55PM -0400, Cade Brown wrote:
>> > The `eval(repr(x)) == x` is not a segment of my code; rather it is part
>> of
>> > Python's description of what 'repr' should do:
>> >
>> > https://docs.python.org/3.4/library/functions.html?highlight=repr#repr
>> >
>> >
>> > Specifically: ` For many types, this function makes an attempt to
>> return a
>> > string that would yield an object with the same value when passed to
>> eval()`
>> > > >
>>
>> "For many types" and "makes an attempt".
>>
>> There has never been, and never will be, a guarantee that all objects
>> will obey that invariant. As I said, it is a Nice To Have, and it is
>> designed for convenience at the interactive interpreter.
>>
>>
>> > So everyone in this thread can stop mentioning security concerns; I'm
>> sure
>> > we're all aware of those and we should instead focus on what repr
>> should do
>> > and shouldn't do.
>>
>> You specifically said that math.inf doesn't solve your problem *because*
>> `eval(repr(x))` doesn't work. Now you are backpeddling and saying that
>> this is not your actual problem.
>>
>> (In fact it does work, if you do it correctly.)
>>
>> There are a million other objects that don't obey that invariant:
>>
>> py> x = object()
>> py> eval(repr(x)) == x
>> SyntaxError: invalid syntax
>>
>>
>> Why is float infinity so special that it needs to obey the
>> invariant?
>>
>> What's the actual problem, or problems, in your code that you are trying
>> to solve by making an infinity builtin? If there is no actual problem
>> being solved, and the only reason you want this is because:
>>
>>
>> > I think it's weird to not fulfill this promise
>>
>>
>> you don't have any sympathy from me:
>>
>> - `eval(repr(x))` is not a promise, it is a mere suggestion
>>   that *some* types *try* to provide.
>>
>> - Adding a special built-in constant Infinity just to satisfy
>>   this Nice To Have feature is overkill.
>>
>> - It would require float infinities to change their repr from
>>   'inf' to 'Infinity', and that will break doctests.
>

[Python-ideas] Re: 'Infinity' constant in Python

2020-09-04 Thread Cade Brown
First of all, you're comparing immutable value types to dynamic objects
which are predicated and processed based on the memory address (e.g. for
equality testing, by default). Of course they're going to have different
semantics, especially when converting to a unique string representation.
A better question to ask is why does it work for *almost* all values of
'float' , but not infinite ones... This is a glaring hole in my opinion.

Why do you think having 'inf' is better than something that means something
to the python interpreter? I've had countless times where I've had to
Google how to create an infinite float, and second guessed myself because
it is very unintuitive to have to call a string conversion to get what
amounts to a constant.

The 'use case' is being able to specify a number which is constant, by a
constant, and not requiring me to execute a function call. Further, keeping
it the way it is harbors readability. Every time I parse code that contains
`float('inf')` I ask myself why it is having to do this, because it seems
like code shouldn't have to.

Your argument seems to stem from the least possible Python can do (i.e. it
doesn't HAVE to do anything more than it does currently). This mailing list
is python-ideas, which is for ideas currently not in Python. I am aware
that nothing *has* to be done, I am merely suggesting why it would make
sense to add, and why it would make Python a more complete, predictable and
frankly 'prettier' language (albeit subjective). I don't see how any of
your points address those concerns


On Fri, Sep 4, 2020, 10:14 PM Steven D'Aprano  wrote:

> On Fri, Sep 04, 2020 at 09:40:55PM -0400, Cade Brown wrote:
> > The `eval(repr(x)) == x` is not a segment of my code; rather it is part
> of
> > Python's description of what 'repr' should do:
> >
> > https://docs.python.org/3.4/library/functions.html?highlight=repr#repr
> >
> >
> > Specifically: ` For many types, this function makes an attempt to return
> a
> > string that would yield an object with the same value when passed to
> eval()`
> > 
>
> "For many types" and "makes an attempt".
>
> There has never been, and never will be, a guarantee that all objects
> will obey that invariant. As I said, it is a Nice To Have, and it is
> designed for convenience at the interactive interpreter.
>
>
> > So everyone in this thread can stop mentioning security concerns; I'm
> sure
> > we're all aware of those and we should instead focus on what repr should
> do
> > and shouldn't do.
>
> You specifically said that math.inf doesn't solve your problem *because*
> `eval(repr(x))` doesn't work. Now you are backpeddling and saying that
> this is not your actual problem.
>
> (In fact it does work, if you do it correctly.)
>
> There are a million other objects that don't obey that invariant:
>
> py> x = object()
> py> eval(repr(x)) == x
> SyntaxError: invalid syntax
>
>
> Why is float infinity so special that it needs to obey the
> invariant?
>
> What's the actual problem, or problems, in your code that you are trying
> to solve by making an infinity builtin? If there is no actual problem
> being solved, and the only reason you want this is because:
>
>
> > I think it's weird to not fulfill this promise
>
>
> you don't have any sympathy from me:
>
> - `eval(repr(x))` is not a promise, it is a mere suggestion
>   that *some* types *try* to provide.
>
> - Adding a special built-in constant Infinity just to satisfy
>   this Nice To Have feature is overkill.
>
> - It would require float infinities to change their repr from
>   'inf' to 'Infinity', and that will break doctests.
>
> - And even if that feature were satisfied by infinity, it
>   couldn't be satisfied by float NANs by their very definition:
>
> py> from math import nan
> py> nan == nan
> False
>
> So while the cost of adding a new Infinity builtin is small, the benefit
> is even smaller.
>
>
> --
> Steve
> ___
> 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/AHJETD7PM6M6IKERP7NYNGYWAJBZDS27/
> Code of Conduct: http://python.org/psf/codeofconduct/
>
___
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/7LJZKX2HM65UCQUPU2WEWS6EN6V6SOMB/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: 'Infinity' constant in Python

2020-09-04 Thread Steven D'Aprano
On Fri, Sep 04, 2020 at 08:52:22PM -0700, Christopher Barker wrote:
> I am a -0 on this, but I think it was Greg Ewing that presented a real use
> case:
> 
> There is no way to use literal_eval that gets you an inf (or NaN value).
> 
> Which is a real, though maybe not important, use case.

That's not a *use-case*. A use-case is practical problem you are trying 
to solve.

Without a use-case for why you need literal_value to return an inf, 
that's merely an observation, no different from the observation that 
there is no way to use zip or list to get an inf. It's true, but so 
what?

That's not a rhetorical question. It might be that there is a good 
use-case for using literal_eval and needing to generate infinities.

But there are many objects that you can't construct with literal_eval. 
Because they aren't literals, or even semi-literals like tuple displays 
and complex numbers. It's not clear to me that we should care about
infs and NANs in literal_eval.

But if we should care, making inf (and NAN?) a builtin constant is 
probably not the best solution.


-- 
Steve
___
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/BEI3OLMGUPGKEWX2YWEVGIEARQOCLCGK/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: 'Infinity' constant in Python

2020-09-04 Thread Christopher Barker
I am a -0 on this, but I think it was Greg Ewing that presented a real use
case:

There is no way to use literal_eval that gets you an inf (or NaN value).

Which is a real, though maybe not important, use case.

-CHB

On Fri, Sep 4, 2020 at 7:15 PM Steven D'Aprano  wrote:

> On Fri, Sep 04, 2020 at 09:40:55PM -0400, Cade Brown wrote:
>
> > The `eval(repr(x)) == x` is not a segment of my code; rather it is part
> of
>
> > Python's description of what 'repr' should do:
>
> >
>
> > https://docs.python.org/3.4/library/functions.html?highlight=repr#repr
>
> >
>
> >
>
> > Specifically: ` For many types, this function makes an attempt to return
> a
>
> > string that would yield an object with the same value when passed to
> eval()`
>
> > 
>
>
>
> "For many types" and "makes an attempt".
>
>
>
> There has never been, and never will be, a guarantee that all objects
>
> will obey that invariant. As I said, it is a Nice To Have, and it is
>
> designed for convenience at the interactive interpreter.
>
>
>
>
>
> > So everyone in this thread can stop mentioning security concerns; I'm
> sure
>
> > we're all aware of those and we should instead focus on what repr should
> do
>
> > and shouldn't do.
>
>
>
> You specifically said that math.inf doesn't solve your problem *because*
>
> `eval(repr(x))` doesn't work. Now you are backpeddling and saying that
>
> this is not your actual problem.
>
>
>
> (In fact it does work, if you do it correctly.)
>
>
>
> There are a million other objects that don't obey that invariant:
>
>
>
> py> x = object()
>
> py> eval(repr(x)) == x
>
> SyntaxError: invalid syntax
>
>
>
>
>
> Why is float infinity so special that it needs to obey the
>
> invariant?
>
>
>
> What's the actual problem, or problems, in your code that you are trying
>
> to solve by making an infinity builtin? If there is no actual problem
>
> being solved, and the only reason you want this is because:
>
>
>
>
>
> > I think it's weird to not fulfill this promise
>
>
>
>
>
> you don't have any sympathy from me:
>
>
>
> - `eval(repr(x))` is not a promise, it is a mere suggestion
>
>   that *some* types *try* to provide.
>
>
>
> - Adding a special built-in constant Infinity just to satisfy
>
>   this Nice To Have feature is overkill.
>
>
>
> - It would require float infinities to change their repr from
>
>   'inf' to 'Infinity', and that will break doctests.
>
>
>
> - And even if that feature were satisfied by infinity, it
>
>   couldn't be satisfied by float NANs by their very definition:
>
>
>
> py> from math import nan
>
> py> nan == nan
>
> False
>
>
>
> So while the cost of adding a new Infinity builtin is small, the benefit
>
> is even smaller.
>
>
>
>
>
> --
>
> Steve
>
> ___
>
> 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/AHJETD7PM6M6IKERP7NYNGYWAJBZDS27/
>
> Code of Conduct: http://python.org/psf/codeofconduct/
>
> --
Christopher Barker, PhD

Python Language Consulting
  - Teaching
  - Scientific Software Development
  - Desktop GUI and Web Development
  - wxPython, numpy, scipy, Cython
___
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/QIGOPPNQS3PJUHB3RFJ3FXAJWPVVDWDF/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: 'Infinity' constant in Python

2020-09-04 Thread Jeffrey Kintscher
"from foo import *" is a really lazy programming practice that assumes 
there are no symbol clashes between the module's namespace and the 
current namespace.  It makes production code harder to maintain because 
the reader has to figure out whether a given function or class name is 
defined in the current namespace or merely mapped there from another 
module for convenience.


I know it is common in tutorials (especially C++ tutorials mapping 'std' 
into global) to make example code shorter and somehow easier to read 
(especially in books).  Unfortunately, the reason namespaces exist is 
rarely emphasized, which gives the impression that it is a common 
acceptable practice.  Everyplace I have worked has had the hard rule 
that modules are never mapped into the global namespace in production 
code (for both C++ and Python).


Restricting symbols in the global namespace to prevent clashes in module 
namespaces seems like backward reasoning to accommodate bad practices.  
The fact that pylab takes care to allow mapping all of the numpy symbols 
into its namespace to make pylab a super namespace of the two has 
nothing to do with mapping the symbols into the global namespace.


//Jeff


On 9/4/20 3:30 PM, Todd wrote:
On Fri, Sep 4, 2020, 12:48 Cade Brown > wrote:


I am positing that Python should contain a constant (similar to
True, False, None), called Infinity.

It would be equivalent to `float('inf')`, i.e. a floating point
value representing a non-fininte value. It would be the positive
constant; negative infinity could retrieved via `-Infinity`

Or, to keep float representation the same, the name `inf` could be
used, but that does not fit Python's normal choice for such
identifiers (but indeed, this is what C uses which is the desired
behavior of string conversion)

I think there are a number of good reasons for this constant. For
example:
  * It is also a fundamental constant (similar to True, False, and
None), and should be representable as such in the language
  * Requiring a cast from float to string is messy, and also
obviously less efficient (but this performance difference is
likely insignificant)
  * Further, having a function call for something that should
be a constant is a code-smell; in general str -> float conversion
may throw an error or anything else and I'd rather not worry about
that.
  * It would make the useful property that `eval(repr(x)) == x`
for floating point numbers (currently, `NameError: name 'inf' is
not defined`)

This makes it difficult to, for example, naively serialize a list
of floats. For example:

```
>>> x = [1, 2, 3, 4]
>>> repr(x)
'[1, 2, 3, 4]'
>>> eval(repr(x)) == x
True
>>> x = [1, 2, 3, float('inf')]
>>> repr(x)
'[1, 2, 3, inf]'
>>> eval(repr(x)) == x
Traceback (most recent call last):
  File "", line 1, in 
  File "", line 1, in 
NameError: name 'inf' is not defined
```

To me, this is problematic; I would expect it to work seamlessly
as it does with other floating point constants.

A few rebuttals/claims against:
  - Creating a new constant (Infinity) which is unassignable may
break existing code


It will break an ENORMOUS amount of code.  Numpy has its own top-level 
"inf" variable.  So all code that uses "from numpy import *" will 
break.  Pylab imports numpy in that way, so "from pylab import *" will 
also break.  Whether you think this is a good approach or not, a ton 
of tutorials recommend doing this.  All of those tutorials will break 
in a way that is very hard to fix.



___
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/GTPEHRE7VZCQD5CMCMGQ54XUBUQDUH6D/
Code of Conduct: http://python.org/psf/codeofconduct/


--
-
From there to here, from here to there,
funny things are everywhere.
   -- Theodore Geisel

___
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/V4XU3FCQ6P3GV5T4CG4APRLLZMDSAOIC/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: 'Infinity' constant in Python

2020-09-04 Thread Steven D'Aprano
On Fri, Sep 04, 2020 at 09:40:55PM -0400, Cade Brown wrote:
> The `eval(repr(x)) == x` is not a segment of my code; rather it is part of
> Python's description of what 'repr' should do:
> 
> https://docs.python.org/3.4/library/functions.html?highlight=repr#repr
> 
> 
> Specifically: ` For many types, this function makes an attempt to return a
> string that would yield an object with the same value when passed to eval()`
> 

"For many types" and "makes an attempt".

There has never been, and never will be, a guarantee that all objects 
will obey that invariant. As I said, it is a Nice To Have, and it is 
designed for convenience at the interactive interpreter.


> So everyone in this thread can stop mentioning security concerns; I'm sure
> we're all aware of those and we should instead focus on what repr should do
> and shouldn't do.

You specifically said that math.inf doesn't solve your problem *because* 
`eval(repr(x))` doesn't work. Now you are backpeddling and saying that 
this is not your actual problem.

(In fact it does work, if you do it correctly.)

There are a million other objects that don't obey that invariant:

py> x = object()
py> eval(repr(x)) == x
SyntaxError: invalid syntax


Why is float infinity so special that it needs to obey the 
invariant?

What's the actual problem, or problems, in your code that you are trying 
to solve by making an infinity builtin? If there is no actual problem 
being solved, and the only reason you want this is because:


> I think it's weird to not fulfill this promise


you don't have any sympathy from me:

- `eval(repr(x))` is not a promise, it is a mere suggestion
  that *some* types *try* to provide.

- Adding a special built-in constant Infinity just to satisfy 
  this Nice To Have feature is overkill.

- It would require float infinities to change their repr from
  'inf' to 'Infinity', and that will break doctests.

- And even if that feature were satisfied by infinity, it 
  couldn't be satisfied by float NANs by their very definition:

py> from math import nan
py> nan == nan
False

So while the cost of adding a new Infinity builtin is small, the benefit 
is even smaller.


-- 
Steve
___
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/AHJETD7PM6M6IKERP7NYNGYWAJBZDS27/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: 'Infinity' constant in Python

2020-09-04 Thread Cade Brown
The `eval(repr(x)) == x` is not a segment of my code; rather it is part of
Python's description of what 'repr' should do:

https://docs.python.org/3.4/library/functions.html?highlight=repr#repr


Specifically: ` For many types, this function makes an attempt to return a
string that would yield an object with the same value when passed to eval()`


So everyone in this thread can stop mentioning security concerns; I'm sure
we're all aware of those and we should instead focus on what repr should do
and shouldn't do.

I think it's weird to not fulfill this promise, when it should be easy to
do. Further, I agree that 'inf' is:
  1. Too backwards incompatible
  2. Not the right format for Python (Python likes pascalcase, like `None`,
`True`, `False`)

So again, I'd like to not focus on arguing whether a particular codebase
should be using 'eval' on strings generated by repr.
Rather, my point was that the current behavior does not follow what Python
suggests and says 'repr' should do.



*Cade Brown*
Research Assistant @ ICL (Innovative Computing Laboratory)
Personal Email: brown.c...@gmail.com
ICL/College Email: c...@utk.edu




On Fri, Sep 4, 2020 at 9:31 PM Greg Ewing 
wrote:

> On 5/09/20 10:51 am, Chris Angelico wrote:
> > If you make "inf" a keyword, then even the Python
> > standard library is broken.
>
> The OP didn't suggest that, he suggested adding a new name
> such as Infinity that reprs could use.
>
> --
> Greg
> ___
> 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/TTFTEBD437MK4BCVET7SGUEVJYS6ZET6/
> Code of Conduct: http://python.org/psf/codeofconduct/
>
___
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/TWVKMN55OSMI6YC5OODAXU4O7ECWZG2Q/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: 'Infinity' constant in Python

2020-09-04 Thread Chris Angelico
On Sat, Sep 5, 2020 at 11:30 AM Greg Ewing  wrote:
>
> On 5/09/20 10:51 am, Chris Angelico wrote:
> > If you make "inf" a keyword, then even the Python
> > standard library is broken.
>
> The OP didn't suggest that, he suggested adding a new name
> such as Infinity that reprs could use.
>

Suggested both, actually. But IMO neither is necessary, both can break
stuff, and the value of it is low. Not everything has to be a keyword.

ChrisA
___
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/N5BZQFTS7PAJSDUT3ZS6RF3VLPGTV45A/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: 'Infinity' constant in Python

2020-09-04 Thread Greg Ewing

On 5/09/20 10:51 am, Chris Angelico wrote:

If you make "inf" a keyword, then even the Python
standard library is broken.


The OP didn't suggest that, he suggested adding a new name
such as Infinity that reprs could use.

--
Greg
___
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/TTFTEBD437MK4BCVET7SGUEVJYS6ZET6/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: 'Infinity' constant in Python

2020-09-04 Thread Chris Angelico
On Sat, Sep 5, 2020 at 10:11 AM Steven D'Aprano  wrote:
>
> On Fri, Sep 04, 2020 at 06:10:23PM -0400, Cade Brown wrote:
>
> > I mentioned that in my post; however it doesn't satisfy the problems I have
> > (mainly being that eval(repr(x))==x)
>
> Further to my previous comment, if you *absolutely must* use eval, you
> can mitigate some (but not all) security threats and solve your
> eval(repr) issue:
>
> # evaluate string `s` a little bit less dangerously
> if '_' in s:
> raise ValueError('underscore prohibited')
> else:
> eval(s, {'inf': math.inf, '__builtins__': None})
>

But don't expect that to actually be secure. It mitigates SOME security threats.

I think Python would do very well to have a "restricted evaluation"
function. Looking at the source code for literal_eval, it doesn't seem
too hard to add a check alongside the Constant handler to say "if it's
Name, context Load, look up the name in the provided dict".

ChrisA
___
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/JLZLEPLVT36IF62QKDQTQRAXQTUGBWP3/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: 'Infinity' constant in Python

2020-09-04 Thread Steven D'Aprano
On Fri, Sep 04, 2020 at 06:10:23PM -0400, Cade Brown wrote:

> I mentioned that in my post; however it doesn't satisfy the problems I have
> (mainly being that eval(repr(x))==x)

Further to my previous comment, if you *absolutely must* use eval, you 
can mitigate some (but not all) security threats and solve your 
eval(repr) issue:

# evaluate string `s` a little bit less dangerously
if '_' in s:
raise ValueError('underscore prohibited')
else:
eval(s, {'inf': math.inf, '__builtins__': None})


-- 
Steve
___
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/TGPIOEG6RL6SDOZOMBVDFKZBYLDIVLX7/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: 'Infinity' constant in Python

2020-09-04 Thread Steven D'Aprano
On Fri, Sep 04, 2020 at 06:10:23PM -0400, Cade Brown wrote:
> I mentioned that in my post; however it doesn't satisfy the problems I have
> (mainly being that eval(repr(x))==x)

I'm not very sympathetic to that problem. `eval(repr(x))` is a Nice To 
Have convenience for the interactive interpreter, it is not a guarantee, 
and it is not best practice when coding -- especially not if your x 
values are objects that come from a third party.

`float(repr(x))` works fine and avoids both the security and performance 
issues with eval:

py> from math import inf
py> nums = [1.2, -8.9e-50, inf]
py> all([float(repr(x)) == x for x in nums])
True

So I'm going to climb out on a limb here and say that if you're 
calling eval on the repr of floats, you're probably doing the wrong 
thing. In fact, if you know that they are certainly floats, and never 
any other kind of object, then you are *certainly* doing the wrong thing 
because of performance:

$ python3 -m timeit "eval('1.2575')"
10 loops, best of 5: 3.21 usec per loop
$ python3 -m timeit "float('1.2575')"
200 loops, best of 5: 113 nsec per loop

And if you *don't* know what sort of objects they are, then you're 
leaving yourself open to a world of hurt if there is any possibility you 
might get them from an untrusted third-party.



-- 
Steve
___
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/6DKETUBLVANL737YW3E7KYI5DT2ST5H3/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: 'Infinity' constant in Python

2020-09-04 Thread Joao S. O. Bueno
On Fri, 4 Sep 2020 at 19:12, Cade Brown  wrote:

> I mentioned that in my post; however it doesn't satisfy the problems I
> have (mainly being that eval(repr(x))==x)
>

In [1]: from math import inf


In [2]: eval(repr(inf)) == inf

Out[2]: True

"works for me"

>
> I still think unifying it as a constant is better because then the repr of
> a float gives a string which, if evaluated, gives the float back exactly.
> Using math.inf or string conversion throws an error if you try to evaluate
> it
>
>
> On Fri, Sep 4, 2020, 6:05 PM Christopher Barker 
> wrote:
>
>> This is in the math module already, along with NaN:
>>
>> In [1]: import math
>>
>>
>> In [2]: math.inf
>>
>> Out[2]: inf
>>
>> In [3]: math.nan
>>
>> Out[3]: nan
>>
>> The same value
>>
>> In [4]: math.inf == float('inf')
>>
>> Out[4]: True
>>
>> but not the same object -- i.e. it's not a singleton.
>>
>> In [5]: math.inf is float('inf')
>>
>> Out[5]: False
>>
>> -CHB
>>
>>
>>
>> On Fri, Sep 4, 2020 at 9:49 AM Cade Brown  wrote:
>>
>>> I am positing that Python should contain a constant (similar to True,
>>> False, None), called Infinity.
>>>
>>> It would be equivalent to `float('inf')`, i.e. a floating point value
>>> representing a non-fininte value. It would be the positive constant;
>>> negative infinity could retrieved via `-Infinity`
>>>
>>> Or, to keep float representation the same, the name `inf` could be used,
>>> but that does not fit Python's normal choice for such identifiers (but
>>> indeed, this is what C uses which is the desired behavior of string
>>> conversion)
>>>
>>> I think there are a number of good reasons for this constant. For
>>> example:
>>>   * It is also a fundamental constant (similar to True, False, and
>>> None), and should be representable as such in the language
>>>   * Requiring a cast from float to string is messy, and also obviously
>>> less efficient (but this performance difference is likely insignificant)
>>>   * Further, having a function call for something that should be a
>>> constant is a code-smell; in general str -> float conversion may throw an
>>> error or anything else and I'd rather not worry about that.
>>>   * It would make the useful property that `eval(repr(x)) == x` for
>>> floating point numbers (currently, `NameError: name 'inf' is not defined
>>> `)
>>>
>>> This makes it difficult to, for example, naively serialize a list of
>>> floats. For example:
>>>
>>> ```
>>> >>> x = [1, 2, 3, 4]
>>> >>> repr(x)
>>> '[1, 2, 3, 4]'
>>> >>> eval(repr(x)) == x
>>> True
>>> >>> x = [1, 2, 3, float('inf')]
>>> >>> repr(x)
>>> '[1, 2, 3, inf]'
>>> >>> eval(repr(x)) == x
>>> Traceback (most recent call last):
>>>   File "", line 1, in 
>>>   File "", line 1, in 
>>> NameError: name 'inf' is not defined
>>> ```
>>>
>>> To me, this is problematic; I would expect it to work seamlessly as it
>>> does with other floating point constants.
>>>
>>> A few rebuttals/claims against:
>>>   - Creating a new constant (Infinity) which is unassignable may break
>>> existing code
>>>   - Converting a float to string is not the same as it is in C. Whil
>>>
>>> I also realize that there is `math.inf`, but I argue that the constant
>>> is more fundamental than that, and it still doesn't solve the problem with
>>> `repr()` I described
>>>
>>> Thanks,
>>> 
>>> *Cade Brown*
>>> Research Assistant @ ICL (Innovative Computing Laboratory)
>>> Personal Email: brown.c...@gmail.com
>>> ICL/College Email: c...@utk.edu
>>>
>>>
>>> ___
>>> 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/XMA6KOBLPABV7EL5GV2BIRC2ESYKXMVV/
>>> Code of Conduct: http://python.org/psf/codeofconduct/
>>>
>>
>>
>> --
>> Christopher Barker, PhD
>>
>> Python Language Consulting
>>   - Teaching
>>   - Scientific Software Development
>>   - Desktop GUI and Web Development
>>   - wxPython, numpy, scipy, Cython
>>
> ___
> 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/QHOV45S2QN33KLHC5UZH33HA7VJQBXXO/
> Code of Conduct: http://python.org/psf/codeofconduct/
>
___
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/MT3JOHWCV4FOW6QNREBMVQLO4MN4LJIO/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: 'Infinity' constant in Python

2020-09-04 Thread Alex Hall
On Sat, Sep 5, 2020 at 12:43 AM Greg Ewing 
wrote:

> On 5/09/20 10:15 am, Chris Angelico wrote:
> > Remember that if this matters to you, you can "from math import inf".
>
> But you still need to use full eval on your repr, which could
> be a serious security problem in some contexts. If it were a
> built-in constant, ast.literal_eval could be used instead.
>

In most such cases you could use Python's json module which supports
Infinity.
___
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/GTGMKE3ZTWX2T33CHFMLGA2UVXUQKB5J/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: 'Infinity' constant in Python

2020-09-04 Thread Chris Angelico
On Sat, Sep 5, 2020 at 8:45 AM Greg Ewing  wrote:
>
> On 5/09/20 10:15 am, Chris Angelico wrote:
> > Remember that if this matters to you, you can "from math import inf".
>
> But you still need to use full eval on your repr, which could
> be a serious security problem in some contexts. If it were a
> built-in constant, ast.literal_eval could be used instead.
>

Perhaps the real solution is for literal_eval to be given a specific
set of names that it's allowed to reference. Most things don't have to
be keywords - it's normally fine for them to be builtins. (Or, in many
cases, importables.) If you make "inf" a keyword, then even the Python
standard library is broken.

ChrisA
___
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/ZKCQV452ICTQNMG7TLTRHDYRWL2UHA4C/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: 'Infinity' constant in Python

2020-09-04 Thread Greg Ewing

On 5/09/20 10:15 am, Chris Angelico wrote:

Remember that if this matters to you, you can "from math import inf".


But you still need to use full eval on your repr, which could
be a serious security problem in some contexts. If it were a
built-in constant, ast.literal_eval could be used instead.

--
Greg
___
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/6QT2OGBO6HIIJ2LGHAABYCHTG2PV4XHY/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: 'Infinity' constant in Python

2020-09-04 Thread Todd
On Fri, Sep 4, 2020, 12:48 Cade Brown  wrote:

> I am positing that Python should contain a constant (similar to True,
> False, None), called Infinity.
>
> It would be equivalent to `float('inf')`, i.e. a floating point value
> representing a non-fininte value. It would be the positive constant;
> negative infinity could retrieved via `-Infinity`
>
> Or, to keep float representation the same, the name `inf` could be used,
> but that does not fit Python's normal choice for such identifiers (but
> indeed, this is what C uses which is the desired behavior of string
> conversion)
>
> I think there are a number of good reasons for this constant. For example:
>   * It is also a fundamental constant (similar to True, False, and None),
> and should be representable as such in the language
>   * Requiring a cast from float to string is messy, and also obviously
> less efficient (but this performance difference is likely insignificant)
>   * Further, having a function call for something that should be a
> constant is a code-smell; in general str -> float conversion may throw an
> error or anything else and I'd rather not worry about that.
>   * It would make the useful property that `eval(repr(x)) == x` for
> floating point numbers (currently, `NameError: name 'inf' is not defined`)
>
> This makes it difficult to, for example, naively serialize a list of
> floats. For example:
>
> ```
> >>> x = [1, 2, 3, 4]
> >>> repr(x)
> '[1, 2, 3, 4]'
> >>> eval(repr(x)) == x
> True
> >>> x = [1, 2, 3, float('inf')]
> >>> repr(x)
> '[1, 2, 3, inf]'
> >>> eval(repr(x)) == x
> Traceback (most recent call last):
>   File "", line 1, in 
>   File "", line 1, in 
> NameError: name 'inf' is not defined
> ```
>
> To me, this is problematic; I would expect it to work seamlessly as it
> does with other floating point constants.
>
> A few rebuttals/claims against:
>   - Creating a new constant (Infinity) which is unassignable may break
> existing code
>


It will break an ENORMOUS amount of code.  Numpy has its own top-level
"inf" variable.  So all code that uses "from numpy import *" will break.
Pylab imports numpy in that way, so "from pylab import *" will also break.
Whether you think this is a good approach or not, a ton of tutorials
recommend doing this.  All of those tutorials will break in a way that is
very hard to fix.

>
___
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/GTPEHRE7VZCQD5CMCMGQ54XUBUQDUH6D/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: 'Infinity' constant in Python

2020-09-04 Thread Chris Angelico
On Sat, Sep 5, 2020 at 8:12 AM Cade Brown  wrote:
>
> I mentioned that in my post; however it doesn't satisfy the problems I have 
> (mainly being that eval(repr(x))==x)
>
> I still think unifying it as a constant is better because then the repr of a 
> float gives a string which, if evaluated, gives the float back exactly. Using 
> math.inf or string conversion throws an error if you try to evaluate it
>

Remember that if this matters to you, you can "from math import inf".
So your proposal is to, in effect, do this by default. I'm -0 on it
because it's so easy to do if you want it.

ChrisA
___
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/JUWHTO5J4AJWPFMH7HTNRMHNAX5HCLER/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: 'Infinity' constant in Python

2020-09-04 Thread Christopher Barker
This is in the math module already, along with NaN:

In [1]: import math


In [2]: math.inf

Out[2]: inf

In [3]: math.nan

Out[3]: nan

The same value

In [4]: math.inf == float('inf')

Out[4]: True

but not the same object -- i.e. it's not a singleton.

In [5]: math.inf is float('inf')

Out[5]: False

-CHB



On Fri, Sep 4, 2020 at 9:49 AM Cade Brown  wrote:

> I am positing that Python should contain a constant (similar to True,
> False, None), called Infinity.
>
> It would be equivalent to `float('inf')`, i.e. a floating point value
> representing a non-fininte value. It would be the positive constant;
> negative infinity could retrieved via `-Infinity`
>
> Or, to keep float representation the same, the name `inf` could be used,
> but that does not fit Python's normal choice for such identifiers (but
> indeed, this is what C uses which is the desired behavior of string
> conversion)
>
> I think there are a number of good reasons for this constant. For example:
>   * It is also a fundamental constant (similar to True, False, and None),
> and should be representable as such in the language
>   * Requiring a cast from float to string is messy, and also obviously
> less efficient (but this performance difference is likely insignificant)
>   * Further, having a function call for something that should be a
> constant is a code-smell; in general str -> float conversion may throw an
> error or anything else and I'd rather not worry about that.
>   * It would make the useful property that `eval(repr(x)) == x` for
> floating point numbers (currently, `NameError: name 'inf' is not defined`)
>
> This makes it difficult to, for example, naively serialize a list of
> floats. For example:
>
> ```
> >>> x = [1, 2, 3, 4]
> >>> repr(x)
> '[1, 2, 3, 4]'
> >>> eval(repr(x)) == x
> True
> >>> x = [1, 2, 3, float('inf')]
> >>> repr(x)
> '[1, 2, 3, inf]'
> >>> eval(repr(x)) == x
> Traceback (most recent call last):
>   File "", line 1, in 
>   File "", line 1, in 
> NameError: name 'inf' is not defined
> ```
>
> To me, this is problematic; I would expect it to work seamlessly as it
> does with other floating point constants.
>
> A few rebuttals/claims against:
>   - Creating a new constant (Infinity) which is unassignable may break
> existing code
>   - Converting a float to string is not the same as it is in C. Whil
>
> I also realize that there is `math.inf`, but I argue that the constant is
> more fundamental than that, and it still doesn't solve the problem with
> `repr()` I described
>
> Thanks,
> 
> *Cade Brown*
> Research Assistant @ ICL (Innovative Computing Laboratory)
> Personal Email: brown.c...@gmail.com
> ICL/College Email: c...@utk.edu
>
>
> ___
> 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/XMA6KOBLPABV7EL5GV2BIRC2ESYKXMVV/
> Code of Conduct: http://python.org/psf/codeofconduct/
>


-- 
Christopher Barker, PhD

Python Language Consulting
  - Teaching
  - Scientific Software Development
  - Desktop GUI and Web Development
  - wxPython, numpy, scipy, Cython
___
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/SN77STXZCJK37VMCIGUXVLPT26UJ2WQS/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: 'Infinity' constant in Python

2020-09-04 Thread Cade Brown
I mentioned that in my post; however it doesn't satisfy the problems I have
(mainly being that eval(repr(x))==x)

I still think unifying it as a constant is better because then the repr of
a float gives a string which, if evaluated, gives the float back exactly.
Using math.inf or string conversion throws an error if you try to evaluate
it


On Fri, Sep 4, 2020, 6:05 PM Christopher Barker  wrote:

> This is in the math module already, along with NaN:
>
> In [1]: import math
>
>
> In [2]: math.inf
>
> Out[2]: inf
>
> In [3]: math.nan
>
> Out[3]: nan
>
> The same value
>
> In [4]: math.inf == float('inf')
>
> Out[4]: True
>
> but not the same object -- i.e. it's not a singleton.
>
> In [5]: math.inf is float('inf')
>
> Out[5]: False
>
> -CHB
>
>
>
> On Fri, Sep 4, 2020 at 9:49 AM Cade Brown  wrote:
>
>> I am positing that Python should contain a constant (similar to True,
>> False, None), called Infinity.
>>
>> It would be equivalent to `float('inf')`, i.e. a floating point value
>> representing a non-fininte value. It would be the positive constant;
>> negative infinity could retrieved via `-Infinity`
>>
>> Or, to keep float representation the same, the name `inf` could be used,
>> but that does not fit Python's normal choice for such identifiers (but
>> indeed, this is what C uses which is the desired behavior of string
>> conversion)
>>
>> I think there are a number of good reasons for this constant. For example:
>>   * It is also a fundamental constant (similar to True, False, and None),
>> and should be representable as such in the language
>>   * Requiring a cast from float to string is messy, and also obviously
>> less efficient (but this performance difference is likely insignificant)
>>   * Further, having a function call for something that should be a
>> constant is a code-smell; in general str -> float conversion may throw an
>> error or anything else and I'd rather not worry about that.
>>   * It would make the useful property that `eval(repr(x)) == x` for
>> floating point numbers (currently, `NameError: name 'inf' is not defined
>> `)
>>
>> This makes it difficult to, for example, naively serialize a list of
>> floats. For example:
>>
>> ```
>> >>> x = [1, 2, 3, 4]
>> >>> repr(x)
>> '[1, 2, 3, 4]'
>> >>> eval(repr(x)) == x
>> True
>> >>> x = [1, 2, 3, float('inf')]
>> >>> repr(x)
>> '[1, 2, 3, inf]'
>> >>> eval(repr(x)) == x
>> Traceback (most recent call last):
>>   File "", line 1, in 
>>   File "", line 1, in 
>> NameError: name 'inf' is not defined
>> ```
>>
>> To me, this is problematic; I would expect it to work seamlessly as it
>> does with other floating point constants.
>>
>> A few rebuttals/claims against:
>>   - Creating a new constant (Infinity) which is unassignable may break
>> existing code
>>   - Converting a float to string is not the same as it is in C. Whil
>>
>> I also realize that there is `math.inf`, but I argue that the constant is
>> more fundamental than that, and it still doesn't solve the problem with
>> `repr()` I described
>>
>> Thanks,
>> 
>> *Cade Brown*
>> Research Assistant @ ICL (Innovative Computing Laboratory)
>> Personal Email: brown.c...@gmail.com
>> ICL/College Email: c...@utk.edu
>>
>>
>> ___
>> 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/XMA6KOBLPABV7EL5GV2BIRC2ESYKXMVV/
>> Code of Conduct: http://python.org/psf/codeofconduct/
>>
>
>
> --
> Christopher Barker, PhD
>
> Python Language Consulting
>   - Teaching
>   - Scientific Software Development
>   - Desktop GUI and Web Development
>   - wxPython, numpy, scipy, Cython
>
___
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/QHOV45S2QN33KLHC5UZH33HA7VJQBXXO/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] 'Infinity' constant in Python

2020-09-04 Thread Cade Brown
I am positing that Python should contain a constant (similar to True,
False, None), called Infinity.

It would be equivalent to `float('inf')`, i.e. a floating point value
representing a non-fininte value. It would be the positive constant;
negative infinity could retrieved via `-Infinity`

Or, to keep float representation the same, the name `inf` could be used,
but that does not fit Python's normal choice for such identifiers (but
indeed, this is what C uses which is the desired behavior of string
conversion)

I think there are a number of good reasons for this constant. For example:
  * It is also a fundamental constant (similar to True, False, and None),
and should be representable as such in the language
  * Requiring a cast from float to string is messy, and also obviously less
efficient (but this performance difference is likely insignificant)
  * Further, having a function call for something that should be a
constant is a code-smell; in general str -> float conversion may throw an
error or anything else and I'd rather not worry about that.
  * It would make the useful property that `eval(repr(x)) == x` for
floating point numbers (currently, `NameError: name 'inf' is not defined`)

This makes it difficult to, for example, naively serialize a list of
floats. For example:

```
>>> x = [1, 2, 3, 4]
>>> repr(x)
'[1, 2, 3, 4]'
>>> eval(repr(x)) == x
True
>>> x = [1, 2, 3, float('inf')]
>>> repr(x)
'[1, 2, 3, inf]'
>>> eval(repr(x)) == x
Traceback (most recent call last):
  File "", line 1, in 
  File "", line 1, in 
NameError: name 'inf' is not defined
```

To me, this is problematic; I would expect it to work seamlessly as it does
with other floating point constants.

A few rebuttals/claims against:
  - Creating a new constant (Infinity) which is unassignable may break
existing code
  - Converting a float to string is not the same as it is in C. Whil

I also realize that there is `math.inf`, but I argue that the constant is
more fundamental than that, and it still doesn't solve the problem with
`repr()` I described

Thanks,

*Cade Brown*
Research Assistant @ ICL (Innovative Computing Laboratory)
Personal Email: brown.c...@gmail.com
ICL/College Email: c...@utk.edu
___
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/XMA6KOBLPABV7EL5GV2BIRC2ESYKXMVV/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Python logging with a custom clock

2020-09-04 Thread N. Benes
Dear list,

log records in the Python logging library always use timestamps provided
by `time.time()`, i.e. the usual system clock (UTC, CLOCK_REALTIME).

This time is used as absolute timestamp in log records and for
timestamps relative to the load of the library (Lib/logging/__init__.py:
`_startTime`).

I would like to receive feedback to and propose the attached (and
possibly incomplete) patch that allows the programmer to provide a
custom callable to get the time instead of `time.time()`.
For example, this could be:

clock = lambda: time.clock_gettime(time.CLOCK_TAI)
or
def clock(): return time.clock_gettime(time.CLOCK_TAI)

and the callable could be provided during initial logging setup

logging.basicConfig(clock=clock, ...)

There is a similar approach in log4j to specify a custom clock [0].


This change enables the use of non-UTC clocks, e.g. `CLOCK_TAI` or
`CLOCK_MONOTONIC`, which are unaffected by leap seconds and count SI
seconds. (In fact, logging's use of differences of UTC timestamps could
make users believe that the obtained duration reflects SI seconds, which
it doesn't in all cases.)

Combining a custom absolute clock such as `CLOCK_TAI` with custom log
formatters allows users to /store or transfer/ log records with TAI
timestamps, and /display/ them with UTC timestamps (e.g. properly
converted from TAI to UTC with a "60" second during active leap second).
This resolves the ambiguity when analysing and correlating logs from
different machines also during leap seconds.


Attached is a simple example showing the different timestamps based on
UTC and TAI (assuming the current offset of +37 seconds [1] is properly
configured on the host, e.g. through PTP or `adjtimex()` with `ADJ_TAI`).

$ export TZ=GMT
$ date --iso-8601=seconds  && python3 example.py
2020-09-02T14:34:14+00:00
2020-09-02T14:34:51+ INFO message

According to the documentation `time.CLOCK_TAI` was introduced in Python
3.9 [2], but already today the system constant can be used (e.g. on
Debian Buster, Linux 4.19.0, Python 3.7.3 it is 11).

The two patches provided are for Python 3.7.3 (Debian Buster) and Python
3.8.5 (python.org). In the latter case, it may need to be considered how
changing the Python logging clock works: it probably should fail if
handlers are already configured, unless `force` is also provided and
handlers are reset.

Kind regards,
-- nicolas benes


[0] `log4j.Clock` in
https://logging.apache.org/log4j/log4j-2.8/manual/configuration.html
[1] https://www.timeanddate.com/worldclock/other/tai
[2] https://docs.python.org/dev/library/time.html#time.CLOCK_TAI


--
Nicolas Benes   nbe...@eso.org
   +Software Engineer
 +E S+  European Southern Observatory  https://www.eso.org
   OKarl-Schwarzschild-Strasse 2
   +D-85748 Garching b. Muenchen
Germany
--


>From e19413a025d7807f68fc83f17cbb5da147d869f5 Mon Sep 17 00:00:00 2001
From: Nicolas Benes 
Date: Tue, 1 Sep 2020 18:33:38 +0200
Subject: [PATCH] Logging with custom clock

---
 Lib/logging/__init__.py | 20 
 1 file changed, 16 insertions(+), 4 deletions(-)

diff --git a/Lib/logging/__init__.py b/Lib/logging/__init__.py
index 2761509..54ccf9e 100644
--- a/Lib/logging/__init__.py
+++ b/Lib/logging/__init__.py
@@ -49,10 +49,15 @@ __date__= "07 February 2010"
 #   Miscellaneous module data
 #---
 
+#
+#_clock_gettime is a callable to get the current time in seconds
+#
+_clock_gettime = time.time
+
 #
 #_startTime is used as the base when calculating the relative time of events
 #
-_startTime = time.time()
+_startTime = _clock_gettime()
 
 #
 #raiseExceptions is used to see if exceptions during handling should be
@@ -295,7 +300,7 @@ class LogRecord(object):
 """
 Initialize a logging record with interesting information.
 """
-ct = time.time()
+ct = _clock_gettime()
 self.name = name
 self.msg = msg
 #
@@ -494,8 +499,8 @@ class Formatter(object):
 %(lineno)d  Source line number where the logging call was issued
 (if available)
 %(funcName)sFunction name
-%(created)f Time when the LogRecord was created (time.time()
-return value)
+%(created)f Time when the LogRecord was created (by default
+time.time() return value)
 %(asctime)s Textual time when the LogRecord was created
 %(msecs)d   Millisecond portion of the creation time
 %(relativeCreated)d Time in milliseconds when the LogRecord was created,
@@ -1862,6 +1867,8 @@ def basicConfig(**kwargs):
   handlers, which will be added to the root handler. Any handler
   in the list which does not have a formatter

[Python-ideas] Re: Pickle improvement: global qualnames for local classes

2020-09-04 Thread Chris Angelico
On Fri, Sep 4, 2020 at 7:19 PM haael  wrote:
>
> Yes, but that could also be said about ordinary global classes.

(Please don't top-post, it makes it very difficult to usefully quote
multiple people.)

>
>  if sys.args[1] == "a":
>  class A:
> pass
>
>  a = A()
>
>  print(pickle.dumps(a))
>  else:
>  a = pickle.loads(input()) # no definition of class A in this run
>
>  > Apologies if I'm misunderstanding your point here, but it feels like
>  > what you're proposing would only work if you pickled and unpickled the
>  > data in the *same* running instance of the program.

Of course you COULD do that, but generally, any run of the program
will create equivalent classes with the same name. What you're
proposing would have some sort of unique ID generated for every class,
so how do you ensure that the correct class has the same ID?

If you're able to correctly match a class to its identifier, you could
far better do this yourself - or alternatively, have them all be the
SAME class with some sort of parameterization.

ChrisA
___
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/AIDFNUGUH4H6YVPCWDZHKKZQPWCLPO4A/
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Re: Pickle improvement: global qualnames for local classes

2020-09-04 Thread haael




Yes, but that could also be said about ordinary global classes.


if sys.args[1] == "a":
class A:
   pass

a = A()

print(pickle.dumps(a))
else:
a = pickle.loads(input()) # no definition of class A in this run






> I'm not sure that would work in practice. If I pickle Local_here, then
> run a new instance of the program that loads in the pickle file, but
> has never even run f() in the new instance, then the class Local
> doesn't exist. So you can't unpikcle an instance of it, as you don't
> know how to create the class...
>
> Apologies if I'm misunderstanding your point here, but it feels like
> what you're proposing would only work if you pickled and unpickled the
> data in the *same* running instance of the program.
>
> Paul
>



On Thu, 3 Sep 2020 at 18:06, haael  wrote:


Only objects of globally defined classes are picklable:

  class Global:
  pass

  picklable = Global()

  def f():
  class Local:
  pass
  return Local

  Local_here = f()
  unpicklable = Local_here()


However, instances become picklable if we assign the local class to some
globally reachable identifier.

  Local_here.__qualname__ = 'Local_here'
  now_picklable = Local_here()


Why not make it a feature? Let's define module level global identifier,
for instance `__local_classes__`. It will be a weak dictionary of class
objects. Whenever a local class is created, a weak ref is made and
reflected in the new classes' qualname.

  def f():
  class Local:
  pass
  # weak ref is created with some unique id
  return Local

  Local_here = f()

  print(Local_here.__qualname__) # '__local_classes__["uniqueidxxx"]'
  assert Local_here is __local_classes__["uniqueidxxx"]


Likewise for local functions.

This would make many objects picklable, which also positively affects
modules that rely on `pickle`, like `multiprocessing`.



___
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/KJY74GM24SS7S7ZAWYJTSTLAUL2SCJVC/
Code of Conduct: http://python.org/psf/codeofconduct/