Re: save files

2019-04-22 Thread Calvin Spealman
Can you give some more information about the problem and your setup,
including:

- What OS and OS version are you running?
- What is the Python script you are trying to write?
- Do you get the same behavior if you try to save an empty file?
- Can you confirm you are talking about Idle, the editor that comes with
Python, specifically?

On Mon, Apr 22, 2019 at 2:30 AM Franko rizai  wrote:

> -- Forwarded message -
> From: Franko rizai 
> Date: Sun, 21 Apr 2019 at 19:22
> Subject: save files
> To: 
>
>
> Hello i am new to python and i have an issue.I downloaded the python
> 3.7.3(32-bit) and i start working on it.I open a new window to write(new
> file) and its ok. But when I want to save it i press save or save us or F5
> ti run it, and it crashes, it stoppes working and tells me python has
> stopped working and close the program! If you can help me on this please!
> Thank you!
>
> <
> https://www.avast.com/sig-email?utm_medium=email&utm_source=link&utm_campaign=sig-email&utm_content=webmail
> >
> Απαλλαγμένο
> από ιούς. www.avast.com
> <
> https://www.avast.com/sig-email?utm_medium=email&utm_source=link&utm_campaign=sig-email&utm_content=webmail
> >
> <#m_-8209034248381601832_DAB4FAD8-2DD7-40BB-A1B8-4E2AA1F9FDF2>
> --
> https://mail.python.org/mailman/listinfo/python-list
>


-- 

CALVIN SPEALMAN

SENIOR QUALITY ENGINEER

cspea...@redhat.com  M: +1.336.210.5107

TRIED. TESTED. TRUSTED. 
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Function to determine list max without itertools

2019-04-22 Thread Grant Edwards
On 2019-04-20, Michael Torrie  wrote:
> On 04/19/2019 04:01 AM, Sayth Renshaw wrote:
>> def max_try(listarg):
>> myMax = listarg[0]
>> try:
>> for item in listarg:
>> if item > myMax:
>> myMax = item
>> except TypeError:
>> print(f'Only numbers are supported, this entry "{item}" was not')
>> pass
>> 
>> return myMax
>
> If I were you I wouldn't catch that exception.  The reason is that a
> non-number is something your code just can't handle correctly anyway, so
> better to let that original exception bubble up to the caller who can
> deal with it.  By catching this exception, your code will fail, but
> still return as if it succeeded.
>
> Others may disagree. But I rarely catch exceptions in my code unless my
> code specifically wants or needs to deal with them.

I agree: In general, in a function, you only catch an exception if you
can _fix_ the problem.  [Though there may be some some cases where you
want to log the exception in some specific manner and re-raise it.]
If the function can't fix the problem, then leave it to the caller to
decide what to do about it.

At the very top level _sometimes_ you want to have one single, global,
try/except to catch all exceptions and handle the nofication and exit
in a non-default way.  For example: in a GUI application, it's
possible that nobody will see an excption message and stack trace
that's sent to stderr.  A good GUI framework would already handle
that, but not all do.

-- 
Grant Edwards   grant.b.edwardsYow! How many retured
  at   bricklayers from FLORIDA
  gmail.comare out purchasing PENCIL
   SHARPENERS right NOW??

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


Re: Is this a "gotcha" in Python?

2019-04-22 Thread Grant Edwards
On 2019-04-20, Chris Angelico  wrote:

> In this specific case, I actually think that "l" is a bad choice, but
> not because it's a single letter - more because there is a very strong
> convention of using "i" for a loop iterator, and the lowercase "l" is
> confusingly similar.

Also, in some fonts it's very diffcult to tell the difference between
"1" and "l".

Misreading or mistyping

foo = l
as 
foo = 1

Can result in lots of debugging fun.

The only thing worse than writing code that's hard to understand is
writing code that's easy to incorrectly understand.

Yes, there's a difference. :)

-- 
Grant Edwards   grant.b.edwardsYow! I wonder if I should
  at   put myself in ESCROW!!
  gmail.com

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


Re: Error while installing python for Windows 7 32bit

2019-04-22 Thread MRAB

On 2019-04-22 06:29, Bhargava Gurumanchi wrote:
>  Hi Good morning
> i am getting this type of error while installing python for windows 7 
32bit

> in my Laptop. please do needfull ASAP.
> Please find the attachment below
>
Your PC is missing the Visual C++ Redistributable file 
api-ms-win-crt-runtime-l1-1-0.dll.


You'll need to download and install it.

The instructions are here:

https://www.microsoft.com/en-in/download/details.aspx?id=48145

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


Re: Function to determine list max without itertools

2019-04-22 Thread Chris Angelico
On Tue, Apr 23, 2019 at 12:45 AM Grant Edwards
 wrote:
> At the very top level _sometimes_ you want to have one single, global,
> try/except to catch all exceptions and handle the nofication and exit
> in a non-default way.  For example: in a GUI application, it's
> possible that nobody will see an excption message and stack trace
> that's sent to stderr.  A good GUI framework would already handle
> that, but not all do.

I describe that as a "boundary". You can sometimes have those inside
an application, too; for instance, a web server will often want to
catch any unhandled exception during a request handler, log it
somewhere, send an HTTP 500 back to the client, and go back to serving
requests. General principle: a boundary layer will catch EVERY
exception and log them as part of handling them; everything else will
catch only what it can actually handle (and recover from), and usually
won't log them.

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


Re: Importing module from another subdirectory

2019-04-22 Thread Rich Shepard

On Thu, 18 Apr 2019, dieter wrote:


I see two options for you:

1. put your scripts directly into "bustrac" (rather than a subdirectory)


There are too many files; the directory is very cluttered.


2. extend "sys.path" in your scripts to contain the "bustrac" folder
(before you try to import infrastructure modules/packages)


I read the docs for sys and site and have insufficient experience with them
to know how best to apply them for my needs.

My research suggests that rather than appending a project directory tree to
sys.path (which would make it visible to all python invocations) I'd be
better off using site within each project's root directory so modules in
project-specific subdirectories are available to that project. I would like
advice on how to do this.

Or, can I extend sys.path within each project's root directory so the
extension applies only there?

Regards,

Rich

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


Re: save files

2019-04-22 Thread Terry Reedy

On 4/22/2019 7:51 AM, Calvin Spealman wrote:

Can you give some more information about the problem and your setup,
including:

- What OS and OS version are you running?
- What is the Python script you are trying to write?


Specifically, what name are you trying to give to the file.  If you use 
a non-BMP unicode char, that might be a reason for a crash.  Initially 
use an all-ascii name such as 'mytest.py'.


What directory are you trying to write to?
Are you sure that you have write permission for that directory?


- Do you get the same behavior if you try to save an empty file?
- Can you confirm you are talking about Idle, the editor that comes with
Python, specifically?

On Mon, Apr 22, 2019 at 2:30 AM Franko rizai  wrote:


-- Forwarded message -
From: Franko rizai 
Date: Sun, 21 Apr 2019 at 19:22
Subject: save files
To: 


Hello i am new to python and i have an issue.I downloaded the python
3.7.3(32-bit) and i start working on it.I open a new window to write(new
file) and its ok. But when I want to save it i press save or save us or F5
ti run it, and it crashes, it stoppes working and tells me python has
stopped working and close the program! If you can help me on this please!
Thank you!

<
https://www.avast.com/sig-email?utm_medium=email&utm_source=link&utm_campaign=sig-email&utm_content=webmail



Απαλλαγμένο
από ιούς. www.avast.com
<
https://www.avast.com/sig-email?utm_medium=email&utm_source=link&utm_campaign=sig-email&utm_content=webmail



<#m_-8209034248381601832_DAB4FAD8-2DD7-40BB-A1B8-4E2AA1F9FDF2>
--
https://mail.python.org/mailman/listinfo/python-list







--
Terry Jan Reedy


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


Re: Is this a "gotcha" in Python?

2019-04-22 Thread DL Neil

Isn't there an argument that in this context, using the single letter
"l" as a variable name is 'lazy'? That the "l" could be used in
different contexts (per OP). That it conveys no meaning as to the
variable's purpose?


In this specific case, I actually think that "l" is a bad choice, but
not because it's a single letter - more because there is a very strong
convention of using "i" for a loop iterator, and the lowercase "l" is
confusingly similar.


"Convention" or "Tradition"?
(cue sound-track from "Fiddler on the Roof")

Back in the days of (my) learning FORTRAN (back then I suspect it did 
not even have a (version) number), the rule was that any variable name 
starting with a letter between I and N was an integer, and all else were 
reals/floating-point. Later, the REAL and INTEGER type declarations were 
introduced - but readability suffered when a dozen pages 'down' one read 
ABC = 10 (huh?), having read INTEGER ABC way-back!


(those particular letters chosen because of IN-teger, for those who 
didn't notice!)


IIRC it was COBOL Data Division entries and FORTRAN FORMAT statements 
which introduced the place-holder convention/tradition of A for alpha, 9 
for digit, and X for alphanum. Apparently less-widely observed these days.




Surely the variable actually has 'meaning'. Otherwise it wouldn't be
used in the print statement/function! (appreciating this is a simple
situation/'toy example')

That being the case, "l" should be something like "list_of_choices"?


No; a name like that would imply that it is a *collection*. You could
iterate over such a thing, but the loop iterator gets just one of
them. (Unless you're iterating over a list of lists of choices, or
something unusual like that.)


Agreed - no idea what the OP's real-use might be.



There is an opposite case (and I'm somewhat diffident about it). Namely,
using the underscore as a temporary variable. I have not seen it very
often (YMMV). However, it seems to fit under the heading of 'a Pythonic
convention'.

for i in range(5):
 do_something(i)

PEP-8 [pep8] talks of <<<_single_leading_underscore: weak "internal use"
indicator>>> because whilst there is a convention of 'private use' it is
not enforced as a 'rule' - ie the "consenting adults" clause applies!



More or less. I would distinguish the lone underscore from the leading
underscore, but there is a broad parallel.
Generally, the lone underscore means "this doesn't matter". A Python
program might do something five times thus (as per your example...
But if you want to take notice of WHICH something you're doing, it's
much better to use a different name:


+1
Farm kids are often taught: don't name something if you're going to 
end-up eating it later.
Recommend that Python trainees be taught: name everything that has a use 
later...




Arguing that the "l" variable name conveys no meaning, or is 'just a
counter', could one then modify the previous example:
  > for _ in range( 50 ):
  >  print( _, end=" " )
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 >>>

IMO this is a dangerous use of the underscore. If you DO care about
the value, it should get another name.


+1



That said, though: the name does NOT need to be long. Single-letter
variable names are entirely valuable. Short names for short-lived
variables with small scope are absolutely fine.


Upon first coming across the "_" place-holder idea, I started to use it 
(perhaps over-use it?). However, rapidly learned/noticed the virtue of 
"use => name".


Unfortunately, sometimes dreaming-up a name seems like a lot of effort. 
So, I found myself wanting to say "counter", "pointer", "index"... 
(whilst at the same time being most thankful of Python's for-each 
construct removing the many use-cases for the for/do-loop by-index 
prevalent in other coding-languages, and the source of so many errors!).


Despite the fact that most text-editors will now 'guess' varNMs for us, 
'laziness' ensues, just as it does in email/SMS/etc. Thus "ctr", "ptr", 
"ndx"... and pretty soon, we are back to "i". Cry it from the roof-tops: 
TRADITION!


Yet, because "i" (or "n", "a", or "x"...) does not convey usage-meaning 
- other than, "I am a place-holder"! So, aren't we back to "_"?



--
Regards =dn
--
https://mail.python.org/mailman/listinfo/python-list


Re: Is this a "gotcha" in Python?

2019-04-22 Thread Chris Angelico
On Tue, Apr 23, 2019 at 6:18 AM DL Neil  wrote:
> Yet, because "i" (or "n", "a", or "x"...) does not convey usage-meaning
> - other than, "I am a place-holder"! So, aren't we back to "_"?

Not quite. The single-letter names mean "I am an iterator/index/etc",
but "_" means "I am not used anywhere". So if you're iterating over a
range of integers and doing something with them, "i" is fine, "n" is
fine, but "_" isn't.

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


Re: Is this a "gotcha" in Python?

2019-04-22 Thread Skip Montanaro
> Not quite. The single-letter names mean "I am an iterator/index/etc",
> but "_" means "I am not used anywhere".

Small addendum to this. pyflakes (at least in my experience) doesn't
interpret "_" as a variable name or prefix to a local variable as
"unused".

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


Re: Is this a "gotcha" in Python?

2019-04-22 Thread Chris Angelico
On Tue, Apr 23, 2019 at 7:28 AM Skip Montanaro  wrote:
>
> > Not quite. The single-letter names mean "I am an iterator/index/etc",
> > but "_" means "I am not used anywhere".
>
> Small addendum to this. pyflakes (at least in my experience) doesn't
> interpret "_" as a variable name or prefix to a local variable as
> "unused".

Interesting. So it would flag this code?

for _ in range(5): next(f) # skip five lines

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


Re: Is this a "gotcha" in Python?

2019-04-22 Thread Skip Montanaro
> Interesting. So it would flag this code?
>
> for _ in range(5): next(f) # skip five lines

As of at least recent versions (I have 2.1.1 in my Conda install at
home) It seems to properly accept "_" as a variable name, even when
not used. It also seems to accept any variable name as a loop index.
Here's a silly function which demonstrates current behavior:

def skipper(filename):
f = open(filename)
_ = filename.lower()
_up = filename.upper()
filename.title()
for i in range(5):
next(f)
return f

The assignment to "_" is accepted, as is the use of "i" as the loop
variable. The assignment to _up is flagged though. It also doesn't
complain about the ignored return value for filename.title(). (In all
fairness, I don't think pyflakes was ever held up as a "deep" analyzer
of Python source, so couldn't be expected to know that string's title
method operates without side effect.)

So, it's improving.

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


Re: Is this a "gotcha" in Python?

2019-04-22 Thread Chris Angelico
On Tue, Apr 23, 2019 at 8:21 AM Skip Montanaro  wrote:
>
> > Interesting. So it would flag this code?
> >
> > for _ in range(5): next(f) # skip five lines
>
> As of at least recent versions (I have 2.1.1 in my Conda install at
> home) It seems to properly accept "_" as a variable name, even when
> not used. It also seems to accept any variable name as a loop index.
> Here's a silly function which demonstrates current behavior:
>
> def skipper(filename):
> f = open(filename)
> _ = filename.lower()
> _up = filename.upper()
> filename.title()
> for i in range(5):
> next(f)
> return f
>
> The assignment to "_" is accepted, as is the use of "i" as the loop
> variable.

By "accepted" you mean that it isn't complaining? Good; although I'm
not sure why you'd use "_" in a simple assignment context. Clearly
it's quite happy to have *any* unused variable as a loop iterator, and
honestly, I think that's probably correct (since not everyone uses the
underscore convention).

> The assignment to _up is flagged though.

What kind of flagging? "Unused variable", or is it saying that "_up"
is an unconventional name for a local (and perhaps should have been
declared global)?

> It also doesn't
> complain about the ignored return value for filename.title(). (In all
> fairness, I don't think pyflakes was ever held up as a "deep" analyzer
> of Python source, so couldn't be expected to know that string's title
> method operates without side effect.)

Yeah, that one's a bit harder to flag. I wouldn't fault any linter for
not knowing that something's useless in that way. Would be cool if it
knew, but no big deal if it doesn't.

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


Re: Is this a "gotcha" in Python?

2019-04-22 Thread Skip Montanaro
>
> By "accepted" you mean that it isn't complaining?


Accepted, as in it provokes no complaints.

What kind of flagging?


Unused.

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


Re: Is this a "gotcha" in Python?

2019-04-22 Thread Chris Angelico
On Tue, Apr 23, 2019 at 8:41 AM Skip Montanaro  wrote:
>>
>> By "accepted" you mean that it isn't complaining?
>
> Accepted, as in it provokes no complaints.
>
>> What kind of flagging?
>
> Unused.
>

Cool, thanks.

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


need help understanding: converting text to binary

2019-04-22 Thread Eli the Bearded
Here's some code I wrote today:

-- cut here 8< --
HEXCHARS = (b'0', b'1', b'2', b'3', b'4', b'5', b'6', b'7', b'8', b'9',
b'A', b'B', b'C', b'D', b'E', b'F',
b'a', b'b', b'c', b'd', b'e', b'f')


# decode a single hex digit
def hord(c):
c = ord(c)
if c >= ord(b'a'):
return c - ord(b'a') + 10
elif c >= ord(b'A'):
return c - ord(b'a') + 10
else:
return c - ord(b'0')


# decode quoted printable, specifically the MIME-encoded words
# variant which is slightly different than the body text variant
def decodeqp(v):
out = b''
state = '' # used for =XY decoding
for c in list(bytes(v,'ascii')):
c = bytes((c,))

if c == b'=':
if state == '':
state = '='
else:
raise ValueError
continue

   if c == b'_':   # underscore is space only for MIME words
if state == '':
out += b' '
else:
raise ValueError
continue

if c in HEXCHARS:
if state == '':
out += c
elif state == '=':
state = hord(c)
else:
state *= 16
state += hord(c)
out += bytes((state,))
state = ''
continue

if state == '':
out += c
else:
raise ValueError
continue

if state != '':
raise ValueError

return out
-- >8 cut here --

It works, in the sense that

 print(decodeqp("=21_yes"))

will output

 b'! yes'

But the bytes() thing is really confusing me. Most of this is translated
from C code I wrote some time ago. I'm new to python and did spend some
time reading:

https://docs.python.org/3/library/stdtypes.html#bytes-objects

Why does "bytes((integertype,))" work? I'll freely admit to stealing
that trick from /usr/lib/python3.5/quopri.py on my system. (Why am I not
using quopri? Well, (a) I want to learn, (b) it decodes to a file
not a variable, (c) I want different error handling.)

Is there a more python-esque way to convert what should be plain ascii
into a binary "bytes" object? In the use case I'm working towards the
charset will not be ascii or UTF-8 all of the time, and the charset
isn't the responsibility of the python code. Think "decode this if
charset matches user-specified value, then output in that same charset;
otherwise do nothing."

Elijah
--
has yet to warm up to this language
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: need help understanding: converting text to binary

2019-04-22 Thread Chris Angelico
On Tue, Apr 23, 2019 at 10:58 AM Eli the Bearded <*@eli.users.panix.com> wrote:
>
> Here's some code I wrote today:
>
> -- cut here 8< --
> HEXCHARS = (b'0', b'1', b'2', b'3', b'4', b'5', b'6', b'7', b'8', b'9',
> b'A', b'B', b'C', b'D', b'E', b'F',
> b'a', b'b', b'c', b'd', b'e', b'f')
>
>
> # decode a single hex digit
> def hord(c):
> c = ord(c)
> if c >= ord(b'a'):
> return c - ord(b'a') + 10
> elif c >= ord(b'A'):
> return c - ord(b'a') + 10
> else:
> return c - ord(b'0')
>
>
> # decode quoted printable, specifically the MIME-encoded words
> # variant which is slightly different than the body text variant
> def decodeqp(v):

Have you checked to see if Python can already do this? You mention
quopri from the stdlib (that's
https://docs.python.org/3/library/quopri.html for those following
along at home), so I'm curious which ways your code differs from that;
it might be that the easiest way is to use that module, and then add
some extra framing around the outside of it.

> But the bytes() thing is really confusing me. Most of this is translated
> from C code I wrote some time ago. I'm new to python and did spend some
> time reading:
>
> https://docs.python.org/3/library/stdtypes.html#bytes-objects
>
> Why does "bytes((integertype,))" work? I'll freely admit to stealing
> that trick from /usr/lib/python3.5/quopri.py on my system. (Why am I not
> using quopri? Well, (a) I want to learn, (b) it decodes to a file
> not a variable, (c) I want different error handling.)

The bytes constructor will take a sequence of integers and return a
byte string with those values. For instance, bytes([1, 2, 3, 4, 5]) is
the same as bytes(range(1, 6)) and is the same as b"\1\2\3\4\5". In
this case, the iterable is a tuple of one byte value.

> Is there a more python-esque way to convert what should be plain ascii

What does "plain ASCII" actually mean, though?

> into a binary "bytes" object? In the use case I'm working towards the
> charset will not be ascii or UTF-8 all of the time, and the charset
> isn't the responsibility of the python code. Think "decode this if
> charset matches user-specified value, then output in that same charset;
> otherwise do nothing."

I'm not sure what this means, but I would strongly recommend just
encoding and decoding regardless. Use text internally and bytes at the
outside.

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


Re: need help understanding: converting text to binary

2019-04-22 Thread MRAB

On 2019-04-23 01:54, Eli the Bearded wrote:

Here's some code I wrote today:


[snip]


# decode a single hex digit
def hord(c):
 c = ord(c)
 if c >= ord(b'a'):
 return c - ord(b'a') + 10
 elif c >= ord(b'A'):


There's a bug here:


 return c - ord(b'a') + 10


It should be:

 return c - ord(b'A') + 10


 else:
 return c - ord(b'0')


However, the entire function can be replaced with int(c, 16), anyway. :-)

[snip]
--
https://mail.python.org/mailman/listinfo/python-list


Re: Questions on Instance methods

2019-04-22 Thread dieter
Arup Rakshit  writes:
> ...
> As you saw from documentation link, those are just words kind of spec.
> Which source you recommend to read which explains these concepts more with 
> example codes.

I cannot help you much with this -- I am much turned towards
spec[ification] like documentation and have little need for examples.


What helps me much in understanding Python related documentation
is using the fact that it is an interpreter, i.e. that
I can interactively play with it -- and its great introspection
features (especially its interactive "help" function, which
builds on its "inspect" module containing the introspection
infrastructure).
Thus, I can interactively construct szenarios I do not yet
understand and interactively explore them.

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


Re: Importing module from another subdirectory

2019-04-22 Thread dieter
Rich Shepard  writes:
> On Thu, 18 Apr 2019, dieter wrote:
> ...
>> 2. extend "sys.path" in your scripts to contain the "bustrac" folder
>> (before you try to import infrastructure modules/packages)
>
> I read the docs for sys and site and have insufficient experience with them
> to know how best to apply them for my needs.
>
> My research suggests that rather than appending a project directory tree to
> sys.path (which would make it visible to all python invocations) I'd be
> better off using site within each project's root directory so modules in
> project-specific subdirectories are available to that project. I would like
> advice on how to do this.

I use "virtualenv" (for "VIRTUAL ENVironmet") to separate
projects. A "virtual environment" behaves (mostly) like a separate
Python installation (while it shares part of a base Python
installation). I ("pip") install there anything needed for the project.
When working with a project, I "activate" the corresponding
"virtual environment" and this gives me a Python tailored for
this project.

Of course, a "project" can be anything - including a "meta project"
just consisting in a selection of other projects.


> ... that rather than appending a project directory tree to
> sys.path (which would make it visible to all python invocations) I'd be
> better off ...

Do not confuse the envvar "PYTHONPATH" with "sys.path".
While "PYTHONPATH" participates in the initialization of "sys.path",
they are quite different: "PYTHONPATH" affects all Python invocations;
"sys.path" is a "runtime thing" - modifications thereof become
effective immediately but only in the running process (not outside).

What I suggested for you would look like:

bustrac/
  ...
  scripts/
bustrac_setup.py
script1.py
...

Where each "script.py" would contain "import bustrac_setup" (near
its start) and "bustrac_setup" would extend "sys.path" to
make the "bustrac" infrastructure available.


If you are ready to use "virtual environment"s
and ready to learn about advanved Python packaging facilities,
then read the setuptools documentation
(--> "https://setuptools.readthedocs.io/en/latest/";).

It has a different approach to your problem and views
scripts as (just) tiny wrappers for infrastructure functions.
Problems to access the infrastructure from scripts are eliminated
(as there is (essentially) only infrastructure).
When "setuptools" "install"s a package into a Python installation
(including a virtual environment), then it creates the
script wrappers in the installation's "bin" folder - ready
for use (once the installation is "activated").
Read "https://setuptools.readthedocs.io/en/latest/setuptools.html#id12";
for details.


Note: a "virtual environment" is required only to separate
projects (and maybe to get a "local" Python installation under your
own control - without help from a system administrator).
"setuptools" works with any Python installation - whether "real"
or "virtual".


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