Re: f-string syntax deficiency?

2023-06-06 Thread Roel Schroeven via Python-list

Op 6/06/2023 om 16:48 schreef Chris Angelico via Python-list:

On Wed, 7 Jun 2023 at 00:42, Roel Schroeven  wrote:
> (Recently there has been an effort to provide clearer and more useful
> error messages; this seems to be a case where there is still room for
> improvement: "SyntaxError: invalid syntax" doesn't immediately remind me
> of that fact that 'return' is a keyword and therefor can't be used as an
> attribute.)

That's true, but depending on exactly how you're seeing the error, it
might highlight the exact part that's a problem:

>>> opt.return
   File "", line 1
 opt.return
 ^^
SyntaxError: invalid syntax

It's extremely hard to guess what the programmer might have intended
in these situations, as the error might not be the word "return" but
perhaps the punctuation (maybe that was supposed to be a semicolon, or
something). So Python does the best it can, and points out that the
"return" keyword in this context doesn't make syntactic sense.

Ah yes, good point.

--
"Don't Panic."
-- Douglas Adams, The Hitchhiker's Guide to the Galaxy

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


Re: File system path annotations

2023-06-19 Thread Roel Schroeven via Python-list

Op 19/06/2023 om 10:43 schreef Peter Slížik via Python-list:

Hello,

what is the preferred way of annotating file system paths?

This StackOverflow answer 
(and a few others) recommend using the

str | os.PathLike

union.

However, byte arrays can be used as paths too, and including them
would make the annotation quite long.

You don't have to type out the whole thing every time. Define it somewhere:

PathLike = str | bytes | os.PathLike

and then you can use PathLike everywhere.

I also believe that str confirms to the PathLike definition. Please,
correct me if I'm wrong.
I don't think so: os.PathLike instances must have a __fspath__() method, 
which str and bytes don't have.

And finally - using paths in Python programs is so common, that one
would expect to have a special type (or type alias) in typing. Am I
missing something?
I agree there should be something like that. This StackOverflow answer 
(https://stackoverflow.com/a/68027757/59122) talks about something like 
that: _typeshed.AnyPath. It is used in the standard library, but 
apparently it doesn't exist at runtime and you need a trick to make it 
work. I would expect something better to exist, but as far as I can find 
out there isn't.


PEP 519 has a little section on the topic 
(https://peps.python.org/pep-0519/#provide-specific-type-hinting-support):


> Provide specific type hinting support
>
> There was some consideration to providing a generic typing.PathLike 
class which would allow for e.g. typing.PathLike[str] to specify a type 
hint for a path object which returned a string representation.
> While potentially beneficial, the usefulness was deemed too small to 
bother adding the type hint class.

>
> This also removed any desire to have a class in the typing module 
which represented the union of all acceptable path-representing types as 
that can be represented with typing.Union[str, bytes,
> os.PathLike] easily enough and the hope is users will slowly 
gravitate to path objects only.


--

"This planet has - or rather had - a problem, which was this: most of the
people living on it were unhappy for pretty much of the time. Many solutions
were suggested for this problem, but most of these were largely concerned with
the movement of small green pieces of paper, which was odd because on the whole
it wasn't the small green pieces of paper that were unhappy."
-- Douglas Adams

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


Re: File system path annotations

2023-06-19 Thread Roel Schroeven via Python-list

Op 19/06/2023 om 11:44 schreef Peter Slížik:

Thank you, Roel. You've answered all my questions.

> [PEP 519]: ...as that can be represented with typing.Union[str, 
bytes, os.PathLike] easily enough and the hope is users

> will slowly gravitate to path objects only.

I read a lot on Python and, frankly, I don't see this happening. 
People on the Internet keep using /str/ as their path representation 
choice. Presumably, programmers don't feel the need to bother with a 
complex solution if the simplest option works just fine.
I agree, I don't see that happening either. I often find myself using 
str for paths: often simple filenames are all that's needed, and then I 
don't see much point in importing pathlib and wrapping the filenames in 
Path() constructors. I do tend to switch to path objects when I start 
needing to do operations on the paths, though.


--
"Your scientists were so preoccupied with whether they could, they didn't
stop to think if they should"
-- Dr. Ian Malcolm
--
https://mail.python.org/mailman/listinfo/python-list


Re: Should NoneType be iterable?

2023-06-20 Thread Roel Schroeven via Python-list

Op 20/06/2023 om 2:50 schreef Greg Ewing via Python-list:

I would question the wisdom of designing an API that
can return either a sequence or None. If it normally
returns a sequence, and there are no items to return,
it should return an empty sequence.
I guess it depends on the reason why there are no items. If it is simply 
because there are no items, then yes, I agree it should return an empty 
sequence. But if it is because of some kind of error condition, I don't 
think it should. But in that case I don't think the API should return 
None either: I feel it should raise an exception.


--
"Je ne suis pas d’accord avec ce que vous dites, mais je me battrai jusqu’à
la mort pour que vous ayez le droit de le dire."
-- Attribué à Voltaire
"I disapprove of what you say, but I will defend to the death your right to
say it."
-- Attributed to Voltaire
"Ik ben het niet eens met wat je zegt, maar ik zal je recht om het te zeggen
tot de dood toe verdedigen"
-- Toegeschreven aan Voltaire

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


Re: How to add CC and BCC while sending mails using python

2023-06-20 Thread Roel Schroeven via Python-list

sonam Kumari via Python-list schreef op 20/06/2023 om 9:49:
> 
> I've tried the above code and the bcc address does not receive the message, on the To & CC addresses receive it. 
> 
> Here are snippets from my code, perhaps something will stand out to you? 
> 
> to = '[email protected]' 
> cc = '[email protected]' 
> bcc = '[email protected]'
> msg = MIMEMultipart() 
> msg['To'] = to 
> msg['Cc'] = cc
> msg['Subject'] = 'My Subject text here' 
> msg['From'] = '[email protected]' 
> 
> smtp = SMTP("smtpserver") 
> smtp.ehlo() 
> smtp.sendmail(msg['From'], [to, cc, bcc], msg.as_string()) 
> 
> Thanks in advance..hope you're still out there!! 
> ~Ed



I tried this but my mail gets sent only in to but not in cc. Can anyone help?
That looks like it should work. In fact I typed in your code, with some 
email addresses of mine and another smtp server, and it does work. 
That's to say, I can see in the logs of my smtp server that three mails 
are sent out, and I see the mails arriving at the to-address and the 
cc-address. The bcc-addres doesn't seem to receive the mail reliably: 
sometimes not at all, sometimes in the spam folder. It looks like mail 
systems don't like bcc very much. As far as I can see the code is 
correct, and there is a good chance the problem is caused by a mail 
server not accepting one or more of the messages for some reason.


I added some content to the mail, and that seemed to work better.

So, some suggestions:

- Do you have access to the smtp server to check its logs and see what 
is sent, what is not sent, and any possible error messages?
- Try adding some content to the email, something which looks nothing 
like spam.


--
"Met een spitsvondig citaat bewijs je niets."
-- Voltaire

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


Re: Confusing behavior of PYTHONWARNINGS

2023-09-18 Thread Roel Schroeven via Python-list

Op 16/09/2023 om 10:17 schreef Meowxiik via Python-list:

Hello,

For the third time I am trying to work with `PYTHONWARNINGS` filter, 
and for the third time I am having a terrible time. I'd like to seek 
your assistance, I have a few questions:


**Question 1:** Does the environment variable only matter at python 
interpreter startup time? If I set the same variable before python 
start, it seems to work, but it doesn't work trough os.environ. It 
does appear to be hinted at in the docs, but imho not clear enough.
Yes, environment variables are only relevant when the interpreter starts 
up. The documentation (on the command line environment in general, not 
specific to PYTHONWARNINGS) says "These environment variables influence 
Python’s behavior, they are processed before the command-line switches 
other than -E or -I.". That implies they don't do anything if changed 
after startup.


More specific to warnings, the documentation for the -W option (which is 
referenced in the PYTHONWARNINGS environment variable) says "Warnings 
can also be controlled using the PYTHONWARNINGS environment variable and 
from within a Python program using the warnings module." implying the 
same, and giving an alternative for controlling warnings from within Python.


**Question 2:** Why do the following filters not work for filtering 
`urllib3.exceptions.InsecureRequestWarning`


- `PYTHONWARNINGS=ignore:::urllib3.exceptions`

- `PYTHONWARNINGS=ignore:::urllib3`

- `PYTHONWARNINGS=ignore:::urllib3.exceptions`

- `PYTHONWARNINGS=ignore::urllib3.exceptions.InsecureRequestWarning`

None of these filter the warning. The last one has the audacity to 
complain about "invalid module name: 'urllib3.exceptions'" which is 
very confusing to me, given that that specific module is fully 
importable during runtime, which I have tested. The only one I managed 
to get working is `ignore:Unverified`, where "Unverified" is the first 
word of the actual message, however I truly strongly dislike this 
solution.
I'd like to try this out myself, but I'm not familiar with urllib3 and I 
can't get to issue that warning; instead it throws exceptions (I tried a 
simple request with some of the URL's listed on https://badssl.com). How 
can I get urllib3 to issue that warning?


Also, which version of Python are you using, and on which operating system?

--
"Most of us, when all is said and done, like what we like and make up
reasons for it afterwards."
-- Soren F. Petersen

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


Re: Why doc call `__init__` as a method rather than function?

2023-09-18 Thread Roel Schroeven via Python-list

Op 15/09/2023 om 15:05 schreef anthony.flury via Python-list:
Like all of the other  methods you shouldn't ever need to 
call them directly : these are called dunder methods and represent 
functions and features which are called by other operators.


The only recommended way to call A.__init__ is to create an instance 
of A : obj = A() - the __init__ method gets called automatically with 
a newly created object.

There is an exception:

  super().__init__()

to call the base class's __init__ (normally from the derived class's 
__init__)


--
"Human beings, who are almost unique in having the ability to learn from the
experience of others, are also remarkable for their apparent disinclination
to do so."
-- Douglas Adams

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


Re: How to write list of integers to file with struct.pack_into?

2023-10-03 Thread Roel Schroeven via Python-list



Jen Kris via Python-list schreef op 2/10/2023 om 17:06:

My previous message just went up -- sorry for the mangled formatting.  Here it 
is properly formatted:

I want to write a list of 64-bit integers to a binary file.  Every example I 
have seen in my research converts it to .txt, but I want it in binary.  I wrote 
this code, based on some earlier work I have done:

     buf = bytes((len(qs_array)) * 8)
     for offset in range(len(qs_array)):
     item_to_write = bytes(qs_array[offset])
     struct.pack_into(buf, "

Shouldn't the two first parameters be swapped, like this?

    struct.pack_into("Also it wouldn't surprise me if you had to use offset*8 instead of just 
offset in that pack_into() call -- I would think the offset is specified 
in bytes.


--
"In the old days, writers used to sit in front of a typewriter and stare out of
the window. Nowadays, because of the marvels of convergent technology, the thing
you type on and the window you stare out of are now the same thing.”
-- Douglas Adams
--
https://mail.python.org/mailman/listinfo/python-list


Re: Where I do ask for a new feature

2023-10-20 Thread Roel Schroeven via Python-list

Op 20/10/2023 om 5:16 schreef Bongo Ferno via Python-list:

On Thursday, October 19, 2023 at 11:26:52 PM UTC-3, [email protected] wrote:

> There are many ways to make transient variables that disappear at some time 
> and do we need yet another? Yes, you can create one of those ways but what 
> is the big deal with deleting a variable when no longer used? 


Assigning a variable to something can be anything else than a temporal alias.
A with statement makes clear that the alias is an alias and is local, and it 
automatically clears the variable after the block code is used.

Python clutters the variable space with vars that are needed only on certain 
places, and an alias doesn't has a scope.
Convenient alias are short names, and short names are limited in quantity. If 
the space is cluttered with short alias, it opens risks for wrong utilization.

Its like writing a "for i" in a list comprehension and having to worry if "i" 
was already used in another place..
As long as functions are kept reasonably short, which is a good idea 
anyway, I don't really see any of that as a problem.


--
"Experience is that marvelous thing that enables you to recognize a
mistake when you make it again."
-- Franklin P. Jones

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


Re: Running a subprocess in a venv

2023-10-21 Thread Roel Schroeven via Python-list

Larry Martell via Python-list schreef op 21/10/2023 om 15:01:

I have a python script, and from that I want to run another script in
a subprocess in a venv. What is the best way to do that? I could write
a file that activates the venv then runs the script, then run that
file, but that seems messy. Is there a better way?
Activating a venv it is practical when you're working in a shell, but 
not actually needed. You can execute the python in the venv with the 
script as parameter.


Have a look in the venv directory: there will be a Script subdirectory 
(on Windows) or bin subdirectory (on Unix-like systems). Within that 
directory are several executables, one of which will be python or 
python3. That's the one you need.


So use something like

    subprocess.run(['/path/to/venv/bin/python3', 'yourscript.py', 
possible other arguments])


--
"Binnen een begrensde ruimte ligt een kritiek punt, waar voorbij de vrijheid
afneemt naarmate het aantal individuen stijgt. Dit gaat evenzeer op voor mensen
in de begrensde ruimte van een planetair ecosysteem, als voor de gasmoleculen
in een hermetisch gesloten vat. Bij mensen is het niet de vraag hoeveel er
maximaal in leven kunnen blijven in het systeem, maar wat voor soort bestaan
mogelijk is voor diegenen die in leven blijven.
  -- Pardot Kynes, eerste planetoloog van Arrakis"
  -- Frank Herbert, Duin

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


Re: Newline (NuBe Question)

2023-11-26 Thread Roel Schroeven via Python-list

Michael F. Stemper via Python-list schreef op 25/11/2023 om 15:32:

On 24/11/2023 21.45,[email protected]  wrote:
> Grizz[l]y,
> 
> I think the point is not about a sorted list or sorting in general It is

> about reasons why maintaining a data structure such as a list in a program
> can be useful beyond printing things once. There are many possible examples
> such as having a list of lists containing a record where the third item is a
> GPA for the student and writing a little list comprehension that selects a
> smaller list containing only students who are Magna Cum Laude or Summa Cum
> Laude.
> 
> studs = [

>["Peter", 82, 3.53],
>["Paul", 77, 2.83],
>["Mary", 103, 3.82]
> ]

> Of course, for serious work, some might suggest avoiding constructs like a
> list of lists and switch to using modules and data structures [...]

Those who would recommend that approach do not appear to include Mr.
Rossum, who said:

Avoid overengineering data structures. Tuples are better than

objects (try namedtuple too though). Prefer simple fields over
getter/setter functions... Built-in datatypes are your friends.
Use more numbers, strings, tuples, lists, sets, dicts. Also
check out the collections library, eps. deque.[1]

I was nodding along with the people saying "list of lists" until I

reread this quote. A list of tuples seems most appropriate to me.


I prefer namedtuples or dataclasses over tuples. They allow you to refer 
to their fields by name instead of index: student.gpa is much clearer 
than student[2], and makes it less likely to accidentally refer to the 
wrong field.


--
"Man had always assumed that he was more intelligent than dolphins because
he had achieved so much — the wheel, New York, wars and so on — whilst all
the dolphins had ever done was muck about in the water having a good time.
But conversely, the dolphins had always believed that they were far more
intelligent than man — for precisely the same reasons."
-- Douglas Adams
--
https://mail.python.org/mailman/listinfo/python-list


Re: A problem with str VS int.

2023-12-12 Thread Roel Schroeven via Python-list

Op 12/12/2023 om 9:22 schreef Steve GS via Python-list:

With all these suggestions on
how to fix it, no one seems to
answer why it fails only when
entering a two-digit number.
One and three work fine when
comparing with str values. It
is interesting that the
leading 0 on a two digit
worked.  Still, one digit and
three digit work but not two.


Three-digit numbers work because you're comparing to another three-digit 
numbers. When two integer numbers have the same number of digits, their 
lexicographical ordering matches their numeric ordering.


One-digit numbers don't work fine:

>>> "5" < "400"
False

even though we can construct cases where it seems as if they do:

>>> "1" < "400"
True

Two-digit numbers sometimes seem to work:

>>> "30" < "400"
True

But other times clearly don't work:

>>> "50" < "400"
False

String comparison first looks at the first characters of both operands. 
If they are different (as in the examples above), their ordering is used 
regardless of all the other characters that come after, and regardless 
of the length of the string. Try working through some examples (make 
sure to pick examples with a wide variety of first digits) and you'll 
see why it sometimes seems to work, but very unreliably.


--
"In the old days, writers used to sit in front of a typewriter and stare out of
the window. Nowadays, because of the marvels of convergent technology, the thing
you type on and the window you stare out of are now the same thing.”
-- Douglas Adams

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


Re: Is there a way to implement the ** operator on a custom object

2024-02-09 Thread Roel Schroeven via Python-list

Left Right via Python-list schreef op 9/02/2024 om 17:09:

In order for the "splat" operator to work, the type of the object must
populate slot `tp_as_mapping` with a struct of this type:
https://docs.python.org/3/c-api/typeobj.html#c.PyMappingMethods and
have some non-null implementations of the methods this struct is
supposed to contain.

I can do this in C, but I cannot think of a way to do this in Python
proper.


Looks like it can simply be done in Python, no tp_as_mapping needed. I 
tried it like Alan Bawden suggested (sibling post of yours):


import random # just as an example
import time   # just as an example
from collections.abc import Mapping

class VirtualKwargs(Mapping):

    def __init__(self):
    self.fncs = {
    # Simple examples of functions with varying return values to be
    # called for each lookup, instead of fixed values.
    'time': time.time,
    'random': random.random,
    }

    def __len__(self):
    return len(self.fncs)

    def __iter__(self):
    return iter(self.fncs)

    def __getitem__(self, key):
    return self.fncs[key]()


def func(**kwargs):
    for k, v in kwargs.items():
    print(f'{k}: {v}')


obj = VirtualKwargs()
func(**obj)


Output (obviously changes every run):

time: 1707497521.175763
random: 0.6765831287385126

--

"Man had always assumed that he was more intelligent than dolphins because
he had achieved so much — the wheel, New York, wars and so on — whilst all
the dolphins had ever done was muck about in the water having a good time.
But conversely, the dolphins had always believed that they were far more
intelligent than man — for precisely the same reasons."
-- Douglas Adams

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


Re: Variable scope inside and outside functions - global statement being overridden by assignation unless preceded by reference

2024-03-06 Thread Roel Schroeven via Python-list

Op 6/03/2024 om 13:55 schreef Jacob Kruger via Python-list:

If you import the contents of that file into the python interpreter, [...]


What exactly to you mean by "import the contents of that file into the 
python interpreter"? Other people have put your code in a script, 
executed it, and saw it working as expected. I pasted in IPython, and 
likewise saw it working as expected, and the same with IDLE. It seems to 
me you must be doing something different from us; maybe the way you 
execute that code might be the key to this whole confusion.


--
"Il semble que la perfection soit atteinte non quand il n'y a plus rien à
ajouter, mais quand il n'y a plus rien à retrancher."
"Perfectie is niet bereikt als er niets meer toe te voegen is, maar als er
niets meer weg te nemen is."
-- Antoine de Saint-Exupéry

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


Re: Variable scope inside and outside functions - global statement being overridden by assignation unless preceded by reference

2024-03-06 Thread Roel Schroeven via Python-list

Op 6/03/2024 om 16:39 schreef Roel Schroeven via Python-list:

Op 6/03/2024 om 13:55 schreef Jacob Kruger via Python-list:
If you import the contents of that file into the python interpreter, 
[...]


What exactly to you mean by "import the contents of that file into the 
python interpreter"? Other people have put your code in a script, 
executed it, and saw it working as expected. I pasted in IPython, and 
likewise saw it working as expected, and the same with IDLE. It seems 
to me you must be doing something different from us; maybe the way you 
execute that code might be the key to this whole confusion.
(As an aside, I made a type; "What exactly _do_ you mean" is what I 
meant to type)


If you want, you can play with the code online here:
https://tio.run/##pVPbitswEH3XVwwJITaNQ9KllATy0EKhL/2AUsqiWKNkWlkykrzZ7NJvT0e@JWT7VmPsEZozc87RqD7Ho7MPl8sUQpQ@QukUCqG9q0DJiJEqBKpqx1vDegHp@@JsHyk0UfaY0tXnIT/FQogpkKVI0lBAcJ4OZKWBJ2kaDEKo@IjPNfkz7MYGyxB9nYJsst58XBWrNb@wWm1Xq8kCJrPvxawqZgpmX7ezb5N86bE2ssQsvpDVbjewWzaxzIUwjxFD5PI/1gt4v4CHn0xKoQblHilm@VYAPwfj9kxrpLOAHjcFGX6jgrp1CqIDjxp9CnrMk/Qk9wYDaOdh7@JRtCUTMtDBgsVTp5edYbuIZZpzl/NP@dadsvzdaG1WkW2Yy@5D3mJqTzZmIzK5pTu37p3JmcOvhkUw2XB0pxsmRxlgj2h7jqh6ygcv990pOg18ZLEV5bFo0ulpoIhVaHOTP1XNvFN21rmV91W0M8adyB64hEWoUNowGHoiY8CwVg/sp8coyQ722MHTwEWRCZYy9SVGMd9KWqqbBFWcGkgh6MaWkbgOryNKlSi2igdZV8kj6RCXpUHps4FtPz/X4QwYU6F@RlNSMoESv071digk6xqtymgoJVXXMdl027DP22xyvg8cpfLt/I0KRL@RLiDwhHanPP@M3Brn@bAu2mdc6/k4B7vXMfxzs98R2L12/@tOPrb48owlz1fH575TMTbsr8sb@CfNR3kH@x9@l8tf

(sorry for the long URL; that's where tio.run puts the code)

Again it works as expected, but with or without the l_test.clear() line.

--
"Il semble que la perfection soit atteinte non quand il n'y a plus rien à
ajouter, mais quand il n'y a plus rien à retrancher."
"Perfectie is niet bereikt als er niets meer toe te voegen is, maar als er
niets meer weg te nemen is."
-- Antoine de Saint-Exupéry

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


Re: Variable scope inside and outside functions - global statement being overridden by assignation unless preceded by reference

2024-03-06 Thread Roel Schroeven via Python-list

Op 6/03/2024 om 17:40 schreef Jacob Kruger via Python-list:

>>> from scoping2 import *
Ah yes, that explains what's happening. After that statement, the name 
dt_expiry in the current namespace is bound to the same object that the 
name dt_expiry in the namespace of module scoping2 is bound to. Function 
do_it re-binds that last one to a new one, with the new value; name 
dt_expiry in the current namespace is still bound to the old object. (If 
all of that sounds like gibberish, have a look at "Facts and myths about 
Python names and values" (text: 
https://nedbatchelder.com/text/names.html; slides and video: 
https://nedbatchelder.com/text/names1.html)


I would advice not to use 'import *', if at all possible, for multiple 
reasons, one of which is to prevent problems like this.


I would also advice not to use global variables from other modules 
directly, and in fact would advice to minimize the use of globals in 
general as much as possible. If you need to keep state between methods, 
it might be better to use a class.


--
"There is a theory which states that if ever anyone discovers exactly what the
Universe is for and why it is here, it will instantly disappear and be
replaced by something even more bizarre and inexplicable.
There is another theory which states that this has already happened."
-- Douglas Adams, The Restaurant at the End of the Universe

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


Re: Variable scope inside and outside functions - global statement being overridden by assignation unless preceded by reference

2024-03-06 Thread Roel Schroeven via Python-list




Grant Edwards via Python-list schreef op 6/03/2024 om 18:59:
On 2024-03-06, Roel Schroeven via Python-list  
wrote:

> Op 6/03/2024 om 17:40 schreef Jacob Kruger via Python-list:
>> >>> from scoping2 import *
>
> [...]
>
> I would advice not to use 'import *', if at all possible, for 
multiple > reasons, one of which is to prevent problems like this.


Unfortunately, many (most?) tutorials for particular modules (and even
example code in the Python documentation itself) are all written
assuming that you do "from  import *". It saves the tutorial
write a few keystrokes, but causes untold trouble for people who learn
incorrectly that "from  import *" is the proper way to do
things.


I know ... it's really irritating.

--
"There is a theory which states that if ever anyone discovers exactly what the
Universe is for and why it is here, it will instantly disappear and be
replaced by something even more bizarre and inexplicable.
There is another theory which states that this has already happened."
-- Douglas Adams, The Restaurant at the End of the Universe

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


Re: Configuring an object via a dictionary

2024-03-16 Thread Roel Schroeven via Python-list

Barry via Python-list schreef op 16/03/2024 om 9:15:


> On 15 Mar 2024, at 19:51, Thomas Passin via Python-list 
  wrote:
> 
> I've always like writing using the "or" form and have never gotten bit


I, on the other hand, had to fix a production problem that using “or” 
introducted.
I avoid this idiom because it fails on falsy values.

Me too. It's just too fragile. When writing code you're going to need an 
alternative for cases where "config.get('source_name') or default_value" 
doesn't work correctly; much better to use that alternative for all cases.


--
"This planet has - or rather had - a problem, which was this: most of the
people living on it were unhappy for pretty much of the time. Many solutions
were suggested for this problem, but most of these were largely concerned with
the movement of small green pieces of paper, which was odd because on the whole
it wasn't the small green pieces of paper that were unhappy."
-- Douglas Adams
--
https://mail.python.org/mailman/listinfo/python-list


Re: Configuring an object via a dictionary

2024-03-20 Thread Roel Schroeven via Python-list

Op 19/03/2024 om 0:44 schreef Gilmeh Serda via Python-list:

On Mon, 18 Mar 2024 10:09:27 +1300, dn wrote:

> YMMV!
> NB your corporate Style Guide may prefer 'the happy path'...

If you only want to check for None, this works too:

>>> name = None
>>> dafault_value = "default"
>>> name or default_value
'default'
>>> name = 'Fred Flintstone'
>>> name or default_value
'Fred Flintstone'


>>> name = ''
>>> name or default_value
'default'

>>> name = False
>>> name or default_value
'default'

>>> name = []
>>> name or default_value
'default'

>>> name = 0
>>> name or default_value
'default'

You haven't only checked for None! You have rejected *every* falsish 
value, even though they may very well be acceptable values.


--
"Most of us, when all is said and done, like what we like and make up
reasons for it afterwards."
-- Soren F. Petersen

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


Re: Terminal Emulator (Posting On Python-List Prohibited)

2024-05-19 Thread Roel Schroeven via Python-list

Skip Montanaro via Python-list schreef op 20/05/2024 om 0:08:

Modern debian (ubuntu) and fedora block users installing using pip.
>

Even if you're telling it to install in ~/.local? I could see not allowing
to run it as root.


I assumed pip install --user would work, but no. I tried it (on Debian 
12 (bookworm)):



$ pip install --user docopt
error: externally-managed-environment

× This environment is externally managed
╰─> To install Python packages system-wide, try apt install
    python3-xyz, where xyz is the package you are trying to
    install.

    If you wish to install a non-Debian-packaged Python package,
    create a virtual environment using python3 -m venv path/to/venv.
    Then use path/to/venv/bin/python and path/to/venv/bin/pip. Make
    sure you have python3-full installed.

    If you wish to install a non-Debian packaged Python application,
    it may be easiest to use pipx install xyz, which will manage a
    virtual environment for you. Make sure you have pipx installed.

    See /usr/share/doc/python3.11/README.venv for more information.

note: If you believe this is a mistake, please contact your Python 
installation or OS distribution provider. You can override this, at 
the risk of breaking your Python installation or OS, by passing 
--break-system-packages.

hint: See PEP 668 for the detailed specification.


Exactly the same output for sudo pip install.

For easy reference here's a link to that PEP 668: 
https://peps.python.org/pep-0668/
Which links to the "Externally Managed Environments" on the PyPA specs 
page: 
https://packaging.python.org/en/latest/specifications/externally-managed-environments/#externally-managed-environments


--
"If you don't read the newspaper, you're uninformed. If you read the newspaper,
you're mis-informed."
-― Onbekend (dikwijls toegeschreven aan Mark Twain, waarschijnlijk 
onterecht)
--
https://mail.python.org/mailman/listinfo/python-list


Re: pip and venvs on Debian

2024-05-21 Thread Roel Schroeven via Python-list

Op 20/05/2024 om 23:48 schreef Akkana Peck via Python-list:

Every so often I need to regenerate it (like when Debian updates the system 
Python version) but that's easy to do: I don't try to duplicate what's 
installed there, I just delete the old venv, create a new one and then pip 
install packages as needed.

I know this isn't the usual pythonista model of "you should have a zillion different 
venvs, one for each program you use, and never use system Python packages", but it 
works well for me: my pip installed packages are all in a predictable place, and I get 
security updates for all the software Debian *does* package. That's my biggest beef with 
pip, the lack of an easy way to update everything at once, and it's the reason I prefer 
Debian packages when available.
If you have a requirements.txt file with all packages you want, I think 
you can do pip -install --upgrade -r requirements.txt to update them 
all. That only works if you don't specify exact versions in the 
requirements.txt file, so don't use the output of pip freeze to generate 
that requirements file. Just create it yourself: it's a simple text file 
with one package per line. Also I prefer not to include dependencies in 
it for use cases like this (it's another story for packaging, where it 
can be useful or requirements.txt to mirror your exact environment with 
dependencies and specific versions).


Having such a requirements.txt file also makes it easier to install all 
the packages again after you re-create your venv.


--
"I love science, and it pains me to think that to so many are terrified
of the subject or feel that choosing science means you cannot also
choose compassion, or the arts, or be awed by nature. Science is not
meant to cure us of mystery, but to reinvent and reinvigorate it."
-- Robert Sapolsky

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


Re: Anonymous email users

2024-06-17 Thread Roel Schroeven via Python-list

AVI GROSS via Python-list schreef op 17/06/2024 om 17:03:

I simply am thinking that people who do not allow me to easily reply to them
directly, should be ignored by me and not get my cooperation that way.
FWIW, personally I (mostly) don't see the point of replying to people 
personally. To me a public mailing list is much like any public forum, 
where my expectation is that conversations happen in public. To me it 
always feels weird when I get a personal reply when I make a public post 
in a mailing list. I mostly ignore those, unless there's really 
something in it that's best kept out of the public. Sometimes people 
write long mails with wandering thoughts only loosely related to the 
topic at hand directly to me instead of to the whole list. My take is: 
if it's not on-topic enough for the list, it's not on-topic enough for 
me either. Not that it bothers me *that* much; I just ignore those. It's 
very well possible that's just me, and that other people have different 
expectations.


But I don't go hiding my email address, that's a whole different kettle.

--
"Let everything happen to you
Beauty and terror
Just keep going
No feeling is final"
-- Rainer Maria Rilke

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


Re: FileNotFoundError thrown due to file name in file, rather than file itself

2024-11-13 Thread Roel Schroeven via Python-list

Op 12/11/2024 om 20:10 schreef Left Right via Python-list:

> I am not entirely convinced by NB2.  I am, in fact, a sort of sysadmin
> person and most of my programs write to a log file.  The programs are
> also moderately complex, so a single program might access a database,
> query an LDAP server, send email etc., so potentially quite a lot can go
> wrong.  They are also not programs whose output I would pipe to another
> command.  What would be the advantage of logging to stderr?  Quite apart
> from that, I find having a log file a useful for debugging when I am
> developing.

First, the problem with writing to files is that there is no way to
make these logs reliable.  This is what I mean by saying these are
unreliable: since logs are designed to grow indefinitely, the natural
response to this design property is log rotation.  But, it's
impossible to reliably rotate a log file.  There's always a chance
that during the rotation some log entries will be written to the file
past the point of rotation, but prior to the point where the next logs
volume starts.


What I most often do is use one logfile per day, with the date in the 
filename. Then simply delete all files older than 7 days, or 30 days, or 
whatever is useful for the task at hand. Not only does that sidestep any 
issues with rotating logs, but I also find it's very useful to have the 
date in the filename.

Of course, if you only administer your own computer, and you have low
single digits programs to run, and their behavior doesn't change
frequently, and you don't care to drop some records every now and
then... it's OK to log to files directly from a program.  But then you
aren't really in the sysadmin / infra / ops category, as you are more
of a hobby enthusiast.
I would not use my scheme for something released to a wider audience. 
For in-house software though, I like that I can easily put each 
application's logs next to its other data files, and that I don't have 
to figure out how to get the system's own log infrastructure to work is 
I want it to.

Finally, if you want your logs to go to a file, and currently, your
only option is stderr, your shell gives you a really, really simple
way of redirecting stderr to a file.
I feel this is the worst of both worlds. Now your program doesn't have 
any control over filename or log expiration, and neither does your 
system's logging infrastructure. You just get one indefinitely growing 
log file.


--
"You can fool some of the people all the time, and all of the people some
of the time, but you cannot fool all of the people all of the time."
-- Abraham Lincoln
"You can fool too many of the people too much of the time."
-- James Thurber

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


Re: Two python issues

2024-11-06 Thread Roel Schroeven via Python-list

Op 5/11/2024 om 15:48 schreef Raymond Boute via Python-list:

L.S.,

Python seem to suffer from a few poor design decisions regarding 
strings and lists that affect the elegance of the language.


(a) An error-prone "feature" is returning -1 if a substring is not 
found by "find", since -1 currently refers to the last item. An example:
This is IMO indeed not the best design decision. Fortunately there's an 
alternative: the "index" method on strings, which raises exception 
ValueError when the substring is not found, instead of returning -1. An 
example:


>>> s = 'qwertyuiop'
>>> s[s.index('p')]
'p'
>>> s[s.index('a')]
Traceback (most recent call last):
  File "", line 1, in 
    s[s.index('a')]
ValueError: substring not found

Moreover, using index -1 for the last item is a bad choice: it should 
be len(s) - 1 (no laziness!).
Negative indices should be reserved for elements preceding the element 
with index 0 (currently not implemented, but a must for orthogonal 
design supporting general sequences).
I don't agree, I think this is a case of "practicality beats purity". 
Being able to use negative indices to index from the end is often very 
useful in my experience, and leads to code that is much easier to grok. 
General sequences on the other hand is a concept that I don't see ever 
implemented in Python (or most other programming languages AFAIK). I 
think it would be wrong to avoid implementing a feature that's very 
useful in practice in order to keep the door open for a theoretical 
feature that's probably not even wanted in the language.
(b) When using assignment for slices, only lists with the same length 
as the slice should be acceptable, otherwise an error should be 
given.  Anything that re-indexes items not covered by the slice is 
against the essential idea of assignment. For changes that imply 
re-indexing (e.g., inserting a list longer than the slice), Python 
offers cleaner solutions.
Again I don't agree. I don't see anything wrong with replacing a part of 
a list with something that's longer, or shorter, or even empty. It's 
very practical, and I don't see how it's against the essential idea of 
assignment (or actually I'm not even sure what you mean by that).


Two closing remarks:

(1) I think that Python indeed has some warts, inconsistencies, gotchas. 
I think this is unavoidable in any complex system. Python got rid of a 
number of those in the transition from Python 2 to Python 3; others 
might remain forever. Overall though I feel Python is more consistent 
than most other programming languages I come in contact with.


(2) Design decisions are not necessarily wrong when they don't match 
your mental model, or don't match what you know from other languages. 
Often there are different valid options, each with their own tradeoffs.


--
"Programming today is a race between software engineers striving to build bigger
and better idiot-proof programs, and the Universe trying to produce bigger and
better idiots. So far, the Universe is winning."
-- Douglas Adams

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


Re: super().__init__() and bytes

2024-12-03 Thread Roel Schroeven via Python-list

Op 3/12/2024 om 10:41 schreef Roel Schroeven via Python-list:

[...]
When I try the same with bytes as base class though, that doesn't work 
(at least in the Python version I'm using, which is CPython 3.11.2 
64-bit on Windows 10):


class MyBytes(bytes):
    def __init__(self, data):
    super().__init__(data)
print(MyBytes(b'abcdefghijlkmn'))

This results in an exception:

Traceback (most recent call last):
  File "test_mybytes.py", line 4, in 
    print(MyBytes(b'abcdefghijlkmn'))
  ^^
  File "test_mybytes.py", line 3, in __init__
    super().__init__(data)
TypeError: object.__init__() takes exactly one argument (the instance 
to initialize)


I'm passing two arguments (data and the implicit self), and apparently 
that's one too many. Let's try without arguments (i.e. only the 
implicit self):


class MyBytes(bytes):
    def __init__(self, data):
    super().__init__()
print(MyBytes(b'abcdefghijlkmn'))

Now it works, and prints b'abcdefghijlkmn'. The same happens with int 
as base class, and presumably a number of other classes.


As a follow-up, it looks like this behavior is because bytes and int are 
immutable. When I try with bytesarray instead of bytes, which works 
largely the same but is mutable, things do work as I expect. There's a 
hint in the documentation of __new__(): "__new__() is intended mainly to 
allow subclasses of immutable types (like int, str, or tuple) to 
customize instance creation". But that doesn't tell me why using 
super().__init__() doesn't work for immutable classes.


The documentation for __init__() says " If a base class has an 
__init__() method, the derived class’s __init__() method, if any, must 
explicitly call it to ensure proper initialization of the base class 
part of the instance; for example: super().__init__([args...])". So does 
that mean that bytes and int not have an __init__() method? Is there a 
link between being immutable and not having __init__()?


--
"Man had always assumed that he was more intelligent than dolphins because
he had achieved so much — the wheel, New York, wars and so on — whilst all
the dolphins had ever done was muck about in the water having a good time.
But conversely, the dolphins had always believed that they were far more
intelligent than man — for precisely the same reasons."
-- Douglas Adams

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


Re: super().__init__() and bytes

2024-12-03 Thread Roel Schroeven via Python-list

Op 3/12/2024 om 13:55 schreef Anders Munch via Python-list:

Roel Schroeven  wrote:
> As a follow-up, it looks like this behavior is because bytes and int are 
immutable.

Yes.

OK.

> But that doesn't tell me why using super().__init__() 
doesn't work for immutable classes.

bytes.__init__ does work, but it's just an inherited object.__init__, which 
does nothing, and takes no parameters.
  __init__ cannot change the value of the bytes object; the value is set by 
bytes.__new__ and cannot change after that.


I see now why __init__, being a regular method, can't change an object's 
value (or attributes in general) if that object is immutable. I'm not 
sure why I didn't think of that before.


It's not entirely clear to me though how bytes.__new__ *can* set an 
object's value. Isn't __new__ also a regular function? Are these 
immutable classes special cases in the language that can't be recreated 
in the same way with user-defined classes? Not that that's something I 
want to do, and it's also not terribly important to me, but I'm trying 
to better understand what's going on.

Best not to define an __init__ method at all, just use __new__.

Something like:

class BytesSubclass(bytes):
 def __new__(cls, whatever, arguments, you, like):
 bytesvalue = compute(whatever, arguments, you, like)
 ob = bytes.__new__(cls, bytesvalue)
 ob.some_other_att = compute_something_else(whatever, arguments, you, 
like)
 return ob
Thanks, that works perfectly. That's also more important than 
understanding all the nitty-gritty details (I feel a basic understanding 
is important, but not necessarily always all the low-level details).


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

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


super().__init__() and bytes

2024-12-03 Thread Roel Schroeven via Python-list
We can use super().__init__() in the __init__() method of a derived 
class to initialize its base class. For example:


import string
class MyTemplate(string.Template):
    def __init__(self, template_string):
    super().__init__(template_string)
print(MyTemplate('Hello ${name}').substitute(name="Pedro"))

This works, and prints "Hello Pedro" as expected. Note that I passed 
template_string in the super().__init__() call, and that is what used to 
initialize the base class. So far nothing special.


When I try the same with bytes as base class though, that doesn't work 
(at least in the Python version I'm using, which is CPython 3.11.2 
64-bit on Windows 10):


class MyBytes(bytes):
    def __init__(self, data):
    super().__init__(data)
print(MyBytes(b'abcdefghijlkmn'))

This results in an exception:

Traceback (most recent call last):
  File "test_mybytes.py", line 4, in 
    print(MyBytes(b'abcdefghijlkmn'))
  ^^
  File "test_mybytes.py", line 3, in __init__
    super().__init__(data)
TypeError: object.__init__() takes exactly one argument (the instance to 
initialize)


I'm passing two arguments (data and the implicit self), and apparently 
that's one too many. Let's try without arguments (i.e. only the implicit 
self):


class MyBytes(bytes):
    def __init__(self, data):
    super().__init__()
print(MyBytes(b'abcdefghijlkmn'))

Now it works, and prints b'abcdefghijlkmn'. The same happens with int as 
base class, and presumably a number of other classes. That behavior is 
beyond my understanding, so I have some questions that might hopefully 
lead to a better understanding:


(1) How does that work? How does my argument end up in the code that 
initializes the instance state?


(2) How can I customize the argument is passed? For example, what if I 
want to do something like (supersimple example) super().__init__(data * 2)?


(3) Why is bytes (and int, ...) different? Is it because it's a builtin? 
Or implemented in C? Or something else?


--
"Man had always assumed that he was more intelligent than dolphins because
he had achieved so much — the wheel, New York, wars and so on — whilst all
the dolphins had ever done was muck about in the water having a good time.
But conversely, the dolphins had always believed that they were far more
intelligent than man — for precisely the same reasons."
-- Douglas Adams

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


Re: super().__init__() and bytes

2024-12-04 Thread Roel Schroeven via Python-list

Op 4/12/2024 om 0:14 schreef Greg Ewing via Python-list:

On 4/12/24 3:24 am, Roel Schroeven wrote:
It's not entirely clear to me though how bytes.__new__ *can* set an 
object's value. Isn't __new__ also a regular function?


Yes, but the __new__ methods of the builtin immutable objects (int,
str, bytes, etc.) are implemented in C, and so are able to do things
that Python methods cannot.
Aha, yes, that's what I already suspected, but I wasn't sure. Thanks for 
confirming that.


All clear now. Thanks to Anders and Greg for explaining this to me.

"In the old days, writers used to sit in front of a typewriter and stare out of
the window. Nowadays, because of the marvels of convergent technology, the thing
you type on and the window you stare out of are now the same thing.”
-- Douglas Adams

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


Re: Tools to help with text mode (i.e. non-GUI) input

2025-01-16 Thread Roel Schroeven via Python-list

Op 11/01/2025 om 15:28 schreef Chris Green via Python-list:

I'm looking for Python packages that can help with text mode input,
i.e. for use with non-GUI programs that one runs from the command
prompt in a terminal window running a bash shell or some such.

What I'm specifically after is a way to provide a default value that
can be accepted or changed easily and also a way to provide a number
of different values to choose from.

I.e. for the default sort of input one might see:-

 Colour? red

Hitting return would return 'red' to the program but you could also
backspace over the 'red' and enter something else.  Maybe even better
would be that the 'red' disappears as soon as you hit any key other
than return.


For the select a value type of input I want something like the above
but hitting (say) arrow up and arrow down would change the value
displayed by the 'Colour?' prompt and hitting return would accept the
chosen value.  In addition I want the ability to narrow down the list
by entering one or more initial characters, so if you enter 'b' at the
Colour? prompt the list of values presented would only include colours
starting with 'b' (beige, blue, black, etc.)


Are there any packages that offer this sort of thing? I'd prefer ones
from the Debian repositories but that's not absolutely necessary.
Maybe pythondialog could be useful for this. I've never used it so I 
can't really tell if it will fit your requirements, but at least it 
seems worth a look. It looks like it supports text input with a default 
value 
(https://pythondialog.sourceforge.io/doc/widgets.html#single-line-input-fields). 
The other thing you describe is, if I understand correctly, an input 
with predefined values but also the ability to enter a custom value. At 
first sight that doesn't seem to be provided.


PyPI page: https://pypi.org/project/pythondialog/
Home page: https://pythondialog.sourceforge.io/

--
"Let everything happen to you
Beauty and terror
Just keep going
No feeling is final"
-- Rainer Maria Rilke

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


Re: Pip installs to unexpected place

2025-04-17 Thread Roel Schroeven via Python-list

Op 15/04/2025 om 20:31 schreef Mats Wichmann via Python-list:
To be clear: you do not have to activate a virtualenv to use *Python* 
from it. If you just call the python by the path it's in, it figures 
everything out (and sets some variables you can query vi sysconfig if 
you have reason to actually need those details (look for installation 
schemes).


What activating gives you is some path fiddling, and some prompt 
fiddling (although the prompt fiddling keeps saying it's deprecated). 
The latter is a visual clue; the former means you can also find 
*other* commands installed in the virtualenv - including pip.


/path/to/virtualenv//bin/python -m pip install ...   will work whether 
you activated or not.


pip install ...  finds the first command in your PATH named pip, which 
may or may not be the one in the virtualenv, *unless* you've activated 
it, because that's the only way the virtualenv bin directory ends up 
early in your path.
And the pip command that is found and run will use it's own settings 
regarding where to install packages, even if you activated a virtualenv. 
For example, you can't use /usr/bin/pip to install something in a 
virtualenv. To install something in a virtualenv, you need to use the 
pip in that virtualenv (either by first activating that venv, or by 
running something like venv/bin/pip, or venv). (Of course to do that pip 
needs to be installed in that venv. That might or might not be the case 
depending on how the venv was created.)


I kinda get the feeling that something like that is going on here.

--
"There is a theory which states that if ever anyone discovers exactly what the
Universe is for and why it is here, it will instantly disappear and be
replaced by something even more bizarre and inexplicable.
There is another theory which states that this has already happened."
-- Douglas Adams, The Restaurant at the End of the Universe

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