Re: subprocess problem

2017-02-09 Thread Wolfgang Maier

On 09.02.2017 01:56, Andreas Paeffgen wrote:

The Problem with the subprocess code is: Using the sourcecode
functioning as normal.
The frozen app with cx_freeze on every platform just returns an empty
result

Here is the code in short:
def get_path_pandoc():




   settings = QSettings('Pandoc', 'PanConvert')

   path_pandoc = settings.value('path_pandoc','')




   if not os.path.isfile(path_pandoc):




   if platform.system() == 'Darwin' or os.name == 'posix':

   args = ['which', 'pandoc']

   p = subprocess.Popen(

   args,

   stdin=subprocess.PIPE,

   stdout=subprocess.PIPE)




   path_pandoc =
str.rstrip(p.communicate(path_pandoc.encode('utf-8'))[0].decode('utf-8'))


The whole problematic code can be checked on
http://github.com/apaeffgen/panconvert
in source/converters/interface_pandoc.py



Checking your repo I found that get_path_pandoc, the function from which 
you took the code snippet above, will always return None if 
os.path.isfile(path_pandoc).


This is probably not what you are intending. Do you know if path_pandoc 
is maybe set to an existing file in your frozen code already so the 
whole 'which' or 'where' branch is never executed?


Best,
Wolfgang

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


Re: subprocess problem

2017-02-09 Thread Wolfgang Maier

On 09.02.2017 01:56, Andreas Paeffgen wrote:

The Problem with the subprocess code is: Using the sourcecode
functioning as normal.
The frozen app with cx_freeze on every platform just returns an empty
result

Here is the code in short:
def get_path_pandoc():




   settings = QSettings('Pandoc', 'PanConvert')

   path_pandoc = settings.value('path_pandoc','')




   if not os.path.isfile(path_pandoc):




   if platform.system() == 'Darwin' or os.name == 'posix':

   args = ['which', 'pandoc']

   p = subprocess.Popen(

   args,

   stdin=subprocess.PIPE,

   stdout=subprocess.PIPE)




   path_pandoc =
str.rstrip(p.communicate(path_pandoc.encode('utf-8'))[0].decode('utf-8'))


The whole problematic code can be checked on
http://github.com/apaeffgen/panconvert
in source/converters/interface_pandoc.py



Checking your repo I found that get_path_pandoc, the function from which 
you took the code snippet above, will always return None if 
os.path.isfile(path_pandoc).


This is probably not what you are intending. Do you know if path_pandoc 
is maybe set to an existing file in your frozen code already so the 
whole 'which' or 'where' branch is never executed?


Best,
Wolfgang

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


Re: How to store properties

2017-02-09 Thread dieter
Cecil Westerhof  writes:
> ...
>> If you only want to read the configuration, just use an ordinary 
>> file you import. For example config.py contains the lines:
>> username=myuser
>> server=myserver
>> password=secret
>>
>> In your script:
>>
>> import config
>>
>> Now you can referenc all the variables via config., e.g.
>> config.username
>
> That I know, but it is a security risk.

It is a security risk if you allow potential attackers to modify
the Python files. Then, however, those attackers could also modify
the Python code itself (rather than the config file).
Thus, the risk may not much increase (depending on how different
the protection for the config file is compared to that for other Python
source code).

> ...
>> Another method would be a dictionary for your config. You could
>> pickle and unpickle it.
>
> Is pickle not discouraged? Better to use a JSON file I think.

"pickle", too, has a potential security risk -- if you allow
unpickling from untrusted source. Usually, however, configuration
comes from trusted sources.

However, if JSON has sufficient data type support for you, go for it.

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


Re: Decorator

2017-02-09 Thread Steven D'Aprano
On Thu, 09 Feb 2017 08:03:32 +0100, ast wrote:

> Hi
> 
> In python courses I read, it is explained that
> 
> @decor 
> def f():
> pass
> 
> is equivalent to:
> 
> def f():
> pass
> 
> f = decor(f)
> 
> But that's not always true. See this code
[...]
> any comment ?

Congratulations, you've found a microscopic corner of the language where 
the two different ways of applying decorators are different.

Are you just sharing with us, or do you think there is a problem that 
needs to be solved?


You're absolutely correct that when using `property`, trying to apply it 
by hand instead of using the @ syntax is tricky. So don't apply it by 
hand, use the @ syntax.




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


Re: How to store properties

2017-02-09 Thread Cecil Westerhof
On Wednesday  8 Feb 2017 12:26 CET, Cecil Westerhof wrote:

> In Java you (can) use a properties file store configuration. What is
> the best way to do something like that in Python?
> I saw ConfigParser, but have the feeling that it is not really used.
> Would a JSON file be a good idea?

Thanks for all the input. I think I go for configparser (as it is
called in python3). It looks very promising.

-- 
Cecil Westerhof
Senior Software Engineer
LinkedIn: http://www.linkedin.com/in/cecilwesterhof
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: How to store properties

2017-02-09 Thread Chris Angelico
On Thu, Feb 9, 2017 at 7:43 PM, dieter  wrote:
> "pickle", too, has a potential security risk -- if you allow
> unpickling from untrusted source. Usually, however, configuration
> comes from trusted sources.

Pickle's other downside is that it's an opaque binary file, unlike
ConfigParser, JSON, and Python code, which are human-readable text.
Letting the end user edit your configs is often a feature, not a bug.

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


Re: Decorator

2017-02-09 Thread ast


"Steven D'Aprano"  a écrit dans le message de 
news:589c2cdc$0$1584$c3e8da3$54964...@news.astraweb.com...

On Thu, 09 Feb 2017 08:03:32 +0100, ast wrote:



Congratulations, you've found a microscopic corner of the language where
the two different ways of applying decorators are different.

Are you just sharing with us, or do you think there is a problem that
needs to be solved?


I just wanted to have a confirmation. It's OK with Chris Angelico's
detailed answer. Ty


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


Re: Rename file without overwriting existing files

2017-02-09 Thread Steve D'Aprano
On Mon, 30 Jan 2017 09:39 pm, Peter Otten wrote:

 def rename(source, dest):
> ... os.link(source, dest)
> ... os.unlink(source)
> ...
 rename("foo", "baz")
 os.listdir()
> ['bar', 'baz']
 rename("bar", "baz")
> Traceback (most recent call last):
>   File "", line 1, in 
>   File "", line 2, in rename
> FileExistsError: [Errno 17] File exists: 'bar' -> 'baz'


Thanks Peter!

That's not quite ideal, as it isn't atomic: it is possible that the link
will succeed, but the unlink won't. But I prefer that over the alternative,
which is over-writing a file and causing data loss.

So to summarise, os.rename(source, destination):

- is atomic on POSIX systems, if source and destination are both on the 
  same file system;

- may not be atomic on Windows?

- may over-write an existing destination on POSIX systems, but not on
  Windows;

- and it doesn't work across file systems.

os.replace(source, destination) is similar, except that it may over-write an
existing destination on Windows as well as on POSIX systems.


The link/unlink trick:

- avoids over-writing existing files on POSIX systems at least;

- but maybe not Windows?

- isn't atomic, so in the worst case you end up with two links to
  the one file;

- but os.link may not be available on all platforms;

- and it won't work across file systems.


Putting that all together, here's my attempt at a version of file rename
which doesn't over-write existing files:


import os
import shutil

def rename(src, dest):
"""Rename src to dest only if dest doesn't already exist (almost)."""
if hasattr(os, 'link'):
try:
os.link(src, dest)
except OSError:
pass
else:
os.unlink(src)
return
# Fallback to an implementation which is vulnerable to a 
# Time Of Check to Time Of Use bug.
# Try to reduce the window for this race condition by minimizing
# the number of lookups needed between one call and the next.
move = shutil.move
if not os.file.exists(dest):
move(src, dest)
else:
raise shutil.Error("Destination path '%s' already exists" % dest)



Any comments? Any bugs? Any cross-platform way to slay this TOCTOU bug once
and for all?




-- 
Steve
“Cheer up,” they said, “things could be worse.” So I cheered up, and sure
enough, things got worse.

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


Re: Rename file without overwriting existing files

2017-02-09 Thread Steve D'Aprano
On Tue, 31 Jan 2017 11:17 am, Ben Finney wrote:

> Peter Otten <__pete...@web.de> writes:
> 
>>
http://stackoverflow.com/questions/3222341/how-to-rename-without-race-conditions
>>
>> and from a quick test it appears to work on Linux:
> 
> By “works on Linux”, I assume you mean “works on filesystems that use
> inodes and hard links”. That is not true for all filesystems, even on
> Linux.


Indeed it is not, and we're often very sloppy about describing file system
differences as if they were OS differences.




-- 
Steve
“Cheer up,” they said, “things could be worse.” So I cheered up, and sure
enough, things got worse.

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


Re: Rename file without overwriting existing files

2017-02-09 Thread Jussi Piitulainen
Steve D'Aprano writes:

> On Mon, 30 Jan 2017 09:39 pm, Peter Otten wrote:
>
> def rename(source, dest):
>> ... os.link(source, dest)
>> ... os.unlink(source)
>> ...
> rename("foo", "baz")
> os.listdir()
>> ['bar', 'baz']
> rename("bar", "baz")
>> Traceback (most recent call last):
>>   File "", line 1, in 
>>   File "", line 2, in rename
>> FileExistsError: [Errno 17] File exists: 'bar' -> 'baz'
>
>
> Thanks Peter!
>
> That's not quite ideal, as it isn't atomic: it is possible that the link
> will succeed, but the unlink won't. But I prefer that over the alternative,
> which is over-writing a file and causing data loss.
>
> So to summarise, os.rename(source, destination):
>
> - is atomic on POSIX systems, if source and destination are both on the 
>   same file system;
>
> - may not be atomic on Windows?
>
> - may over-write an existing destination on POSIX systems, but not on
>   Windows;
>
> - and it doesn't work across file systems.
>
> os.replace(source, destination) is similar, except that it may over-write an
> existing destination on Windows as well as on POSIX systems.
>
>
> The link/unlink trick:
>
> - avoids over-writing existing files on POSIX systems at least;
>
> - but maybe not Windows?
>
> - isn't atomic, so in the worst case you end up with two links to
>   the one file;
>
> - but os.link may not be available on all platforms;
>
> - and it won't work across file systems.
>
>
> Putting that all together, here's my attempt at a version of file rename
> which doesn't over-write existing files:
>
>
> import os
> import shutil
>
> def rename(src, dest):
> """Rename src to dest only if dest doesn't already exist (almost)."""
> if hasattr(os, 'link'):
> try:
> os.link(src, dest)
> except OSError:
> pass
> else:
> os.unlink(src)
> return
> # Fallback to an implementation which is vulnerable to a 
> # Time Of Check to Time Of Use bug.
> # Try to reduce the window for this race condition by minimizing
> # the number of lookups needed between one call and the next.
> move = shutil.move
> if not os.file.exists(dest):
> move(src, dest)
> else:
> raise shutil.Error("Destination path '%s' already exists" % dest)
>
>
>
> Any comments? Any bugs? Any cross-platform way to slay this TOCTOU bug once
> and for all?

To claim the filename before crossing a filesystem boundary, how about:

1) create a temporary file in the target directory (tempfile.mkstemp)

2) link the temporary file to the target name (in the same directory)

3) unlink the temporary name

4) now it should be safe to move the source file to the target name

5) set permissions and whatever other attributes there are?

Or maybe copy the source file to the temporary name, link the copy to
the target name, unlink the temporary name, unlink the source file;
failing the link step: unlink the temporary name but do not unlink the
source file.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Rename file without overwriting existing files

2017-02-09 Thread eryk sun
On Thu, Feb 9, 2017 at 11:46 AM, Steve D'Aprano
 wrote:
>
> So to summarise, os.rename(source, destination):
>
> - is atomic on POSIX systems, if source and destination are both on the
>   same file system;
> - may not be atomic on Windows?
> - may over-write an existing destination on POSIX systems, but not on
>   Windows;
> - and it doesn't work across file systems.

On Windows in 2.7 and prior to 3.3, os.rename will silently copy and
delete when the destination isn't on the same volume. It may even
silently leave the original file in place in some cases -- e.g. when
the file is read-only and the user isn't allowed to modify the file
attributes.

If the destination is on the same volume, renaming should be atomic
via the system calls NtOpenFile and NtSetInformationFile. Ultimately
it depends on the file system implementation of
IRP_MJ_SET_INFORMATION, FileRenameInformation [1].

> The link/unlink trick:
> - avoids over-writing existing files on POSIX systems at least;
> - but maybe not Windows?

This works for renaming files on Windows as long as the file system
supports hard links (e.g. NTFS). It's not documented on MSDN, but
WinAPI CreateHardLink is implemented by calling NtSetInformationFile
to set the FileLinkInformation, with ReplaceIfExists set to FALSE, so
it fails if the destination exists. Note that this does not allow
renaming directories. See the note for FileLinkInformation [1]; NTFS
doesn't allow directory hard links. But why bother with this 'trick'
on Windows?

[1]: https://msdn.microsoft.com/en-us/library/ff549366
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: subprocess problem

2017-02-09 Thread Andreas Paeffgen
Maybe i could use another trick to circumvent the problems in the 
frozen app? The frozen apps can be downloaded here: 
https://sourceforge.net/projects/panconvert/files/Newest/


@Cameron:

1. I use PyQT5 for a creating a gui app. To run the app on other 
systems, where no QT5 and PyQT5 is installed, a bundle is created with 
all relevant libraries, so it will start independently. This app 
bundle, is called a frozen app. Not only the source code, but all it 
dependencies are distributed including python3 itself.


2. In the test-environment pandoc is installed in /usr/local/bin/pandoc 
(Mac) or /bin/pandoc (Linux). Which returns the path correctly, at the 
terminal (shell), in Python and in the Gui-App Panconvert.


3. I am aware of the limitations of which. There is a fallback to 
manually insert the path. So the app will function anyway.  And i want 
to avoid to search the whole filesystem. This takes minutes on my test 
machines, so this is no option.


4. I suppose that something is different from executing the code in the 
frozen state. The app e.g. on Mac is not started from a python shell or 
a comand shell. But even on linux, when started from a shell it does 
not work.


5. I will try the hint with dev.null and the p.check_returncode()



@Wolfgang

1. The function should be executed only, if the path is unknown. If the 
user enters the path manually in the settings and pandoc exists, the 
function should not be executed to save computation time.


2. Only if the manually entered path is not correct or empty the 
function should be executed,  hence 'if not os.path.isfile(path_pandoc)'


3. The function fills in the path automatically if which returns a 
value. This works in the source code



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


Re: subprocess problem

2017-02-09 Thread Andreas Paeffgen
I guess which does not return an error code. If it does not find 
anything, the return is just blank. If it finds something, the path is 
returned.


So the change of code did not help, because there is just no error message.
Could there be a $path problem in the subprocess started inside the binary?


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


Re: subprocess problem

2017-02-09 Thread Wildman via Python-list
On Thu, 09 Feb 2017 11:16:18 -0600, Andreas Paeffgen wrote:

> I guess which does not return an error code. If it does not find 
> anything, the return is just blank. If it finds something, the path is 
> returned.
> 
> So the change of code did not help, because there is just no error message.
> Could there be a $path problem in the subprocess started inside the binary?

Here is a method I frequently use to replace the which
command. (air code)

import os
pathlist = os.environ["PATH"].split(":")

def which(target)
for p in pathlist:
fullpath = p + "/" + target
if os.path.isfile(fullpath):
return fullpath, True
return "", False

target, found = which("pandoc")
if found:
target will contain the full path to pandoc
else:
pandoc was not found

-- 
 GNU/Linux user #557453
The cow died so I don't need your bull!
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: subprocess problem

2017-02-09 Thread Günther Dietrich
Am 09.02.17 um 18:16 schrieb Andreas Paeffgen:
> I guess which does not return an error code.

In fact, id does return a return code. Here an example:

| honk:~ gdie$ which bash; echo $?
| /bin/bash
| 0
| honk:~ gdie$ which wzlbrmpf; echo $?
| 1

It is 0 on success, 1 for a failure. Exactly the result I would expect
from an unixoid program.


On Ubuntu 16.04, 'man which' tells of three possible exit states: 0, 1
and 2.
On Mac OS, the return codes are not documented. It seems, there are only
0 (success) and 1 (failure).

Normally, on unixoid operating systems, return code 0 indicates success,
anything else non-success, failure or error.


> If it does not find
> anything, the return is just blank. If it finds something, the path is
> returned.

That is the result on STDOUT. It is _not_ the return code!


> So the change of code did not help, because there is just no error message.

Do you expect an error message, or a return code? An error message would
-- normally -- appear on STDERR.


> Could there be a $path problem in the subprocess started inside the binary?

That's for sure. I already had this problem with py2exe. I solved it by
passing a directory containing a suitable PATH entry to the env argument
of subprocess.Popen(). Problem gone.


If you call 'python myscript.py' on the shell command line, the python
script will inherit a copy the shell's environment.
If you start a frozen python script, there is no shell's environment, it
could inherit. It is up to the tool you used to freeze the script
(cx_freeze, py2exe, etc.), which environment contents it will see.



Best regards,

Günther

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


Re: subprocess problem

2017-02-09 Thread Cameron Simpson

On 09Feb2017 11:16, Andreas Paeffgen  wrote:
I guess which does not return an error code. If it does not find 
anything, the return is just blank. If it finds something, the path is 
returned.


So the change of code did not help, because there is just no error message.
Could there be a $path problem in the subprocess started inside the binary?


You're confusing the error code (an integer returned from _every_ exiting 
process) and the process' stdout and stderr, which are data streams.


This is why I suggested the check_returncode() method, which examines the error 
code.


Cheers,
Cameron Simpson 
--
https://mail.python.org/mailman/listinfo/python-list


Re: subprocess problem

2017-02-09 Thread Cameron Simpson

On 09Feb2017 11:59, Wildman  wrote:

Here is a method I frequently use to replace the which
command. (air code)

import os
pathlist = os.environ["PATH"].split(":")

def which(target)
   for p in pathlist:
   fullpath = p + "/" + target
   if os.path.isfile(fullpath):
   return fullpath, True
   return "", False


Cleaner is to return the path if found, or None if not.


target, found = which("pandoc")
if found:
   target will contain the full path to pandoc
else:
   pandoc was not found


You want to check for execute permssion too.

Cheers,
Cameron Simpson 
--
https://mail.python.org/mailman/listinfo/python-list


Re: Decorator

2017-02-09 Thread Terry Reedy

On 2/9/2017 2:03 AM, ast wrote:

Hi

In python courses I read, it is explained that

@decor
def f():
   pass

is equivalent to:

def f():
   pass

f = decor(f)

But that's not always true. See this code


Which is why the official docs now say 'roughly equivalent'
'''
For example, the following code

@f1(arg)
@f2
def func(): pass

is roughly equivalent to

def func(): pass
func = f1(arg)(f2(func))

except that the original function is not temporarily bound to the name func.
'''

Perhaps "There are also cases in which evaluating 'fi(arg)' before 
rather than after the def statement makes a difference." should be added.



--
Terry Jan Reedy

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


Re: Decorator

2017-02-09 Thread Chris Angelico
On Fri, Feb 10, 2017 at 10:18 AM, Terry Reedy  wrote:
> Perhaps "There are also cases in which evaluating 'fi(arg)' before rather
> than after the def statement makes a difference." should be added.

Perhaps not. The word "roughly" covers the odd edge cases, and Python
has a general principle of evaluating top-to-bottom, left-to-right
[1], which covers this situation.

ChrisA

[1] if not a conditional expression, else inside-to-outside
-- 
https://mail.python.org/mailman/listinfo/python-list


The Dominion

2017-02-09 Thread Terry Reedy
A video ad for Anaconda from its maker (satirizing a well know 
data-related film).  I found it amusing, in a good way.

https://www.youtube.com/watch?v=0XDqc5wTve0

PS. I don't use Anaconda and I am not posting this to promote it, nor do 
I necessarily agree with everything said, but I do appreciate it as a 
creative Python-related product, of a sort I would like to see more of.


--
Terry Jan Reedy

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


Re: subprocess problem

2017-02-09 Thread eryk sun
On Thu, Feb 9, 2017 at 10:50 PM, Cameron Simpson  wrote:
> This is why I suggested the check_returncode() method, which examines the
> error code.

You must be thinking of the returncode attribute, which isn't a
method. check_returncode() is a method of the CompletedProcess object
that's returned by subprocess.run(), which was added in 3.5. The OP is
using both 3.4 and 3.5, so run() isn't a practical option.

The older check_output() function also checks the return code and
raises a subprocess.CalledProcessError if the command fails. For
example:

>>> subprocess.check_output(['which', 'ls'])
b'/bin/ls\n'

>>> subprocess.check_output(['which', 'pandoc'])
Traceback (most recent call last):
  File "", line 1, in 
  File "/usr/lib/python3.5/subprocess.py", line 626, in check_output
**kwargs).stdout
  File "/usr/lib/python3.5/subprocess.py", line 708, in run
output=stdout, stderr=stderr)
subprocess.CalledProcessError: Command '['which', 'pandoc']'
returned non-zero exit status 1
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: subprocess problem

2017-02-09 Thread Wildman via Python-list
On Fri, 10 Feb 2017 09:53:32 +1100, Cameron Simpson wrote:

> On 09Feb2017 11:59, Wildman  wrote:
>>Here is a method I frequently use to replace the which
>>command. (air code)
>>
>>import os
>>pathlist = os.environ["PATH"].split(":")
>>
>>def which(target)
>>for p in pathlist:
>>fullpath = p + "/" + target
>>if os.path.isfile(fullpath):
>>return fullpath, True
>>return "", False
> 
> Cleaner is to return the path if found, or None if not.

I don't see this as an important issue but you are
right.

>>target, found = which("pandoc")
>>if found:
>>target will contain the full path to pandoc
>>else:
>>pandoc was not found
> 
> You want to check for execute permssion too.

For my uses of the above code, it is unlikely that
the 'target' would not have the exec bit set.  But,
your suggestion is valid due to the fact that I
should not take anything for granted.

> Cheers,
> Cameron Simpson 

Corrected code:

def which(target)
for p in pathlist:
fullpath = p + "/" + target
if os.path.isfile(fullpath) and os.access(fullpath, os.X_OK):
return fullpath, True
return None, False

Thanks.

-- 
 GNU/Linux user #557453
Keyboard not detected! Press any key to continue...
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: subprocess problem

2017-02-09 Thread MRAB

On 2017-02-10 00:05, Wildman via Python-list wrote:

On Fri, 10 Feb 2017 09:53:32 +1100, Cameron Simpson wrote:


On 09Feb2017 11:59, Wildman  wrote:

Here is a method I frequently use to replace the which
command. (air code)

import os
pathlist = os.environ["PATH"].split(":")

def which(target)
   for p in pathlist:
   fullpath = p + "/" + target
   if os.path.isfile(fullpath):
   return fullpath, True
   return "", False


Cleaner is to return the path if found, or None if not.


I don't see this as an important issue but you are
right.


target, found = which("pandoc")
if found:
   target will contain the full path to pandoc
else:
   pandoc was not found


You want to check for execute permssion too.


For my uses of the above code, it is unlikely that
the 'target' would not have the exec bit set.  But,
your suggestion is valid due to the fact that I
should not take anything for granted.


Cheers,
Cameron Simpson 


Corrected code:

def which(target)
for p in pathlist:
fullpath = p + "/" + target
if os.path.isfile(fullpath) and os.access(fullpath, os.X_OK):
return fullpath, True
return None, False

Thanks.

The implication was that you don't need the True/False, just the 
string/None.


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


Re: subprocess problem

2017-02-09 Thread eryk sun
On Fri, Feb 10, 2017 at 12:05 AM, Wildman via Python-list
 wrote:
>
> Corrected code:
>
> def which(target)
> for p in pathlist:
> fullpath = p + "/" + target
> if os.path.isfile(fullpath) and os.access(fullpath, os.X_OK):
> return fullpath, True
> return None, False

Use shutil.which:

https://docs.python.org/3/library/shutil.html#shutil.which
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: subprocess problem

2017-02-09 Thread Cameron Simpson

On 10Feb2017 00:03, eryk sun  wrote:

On Thu, Feb 9, 2017 at 10:50 PM, Cameron Simpson  wrote:

This is why I suggested the check_returncode() method, which examines the
error code.


You must be thinking of the returncode attribute, which isn't a
method. check_returncode() is a method of the CompletedProcess object
that's returned by subprocess.run(), which was added in 3.5. The OP is
using both 3.4 and 3.5, so run() isn't a practical option.


The communicate method mentioned it; I hadn't realised it was new with 3.5, 
good point.



The older check_output() function also checks the return code and
raises a subprocess.CalledProcessError if the command fails. For
example: [...]


Cool,
Cameron Simpson 
--
https://mail.python.org/mailman/listinfo/python-list


int vs. float

2017-02-09 Thread adam14711993
Hello,

My computer programming professor challenged me to figure out a way to 
manipulate my program to display one error message if the user input is a zero 
or a negative number, and a separate error message if the user input is a 
decimal number.  My program starts out:

number_purchases_str = int(input("Enter the number of packages you're buying:"))
number_purchases = int(number_purchases_str)
format(number_purchases, "12,")

So if the user input is, for example, -9 or 0, the program will result with: 
Sorry, you must order at least one package."

What I cannot figure out is how to write it so that if my user input is, for 
example, 1.5, the program will result with: Sorry, you can only order whole 
packages.

I understand that because I am starting out by assigning my 
number_purchases_str to be an int, when the user enters a float that is a 
conflict and will crash.

My professor apparently believes there is a way to accomplish this.  Any help 
or advice would be greatly appreciated.

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


Re: int vs. float

2017-02-09 Thread Chris Angelico
On Fri, Feb 10, 2017 at 1:33 PM,   wrote:
> I understand that because I am starting out by assigning my 
> number_purchases_str to be an int, when the user enters a float that is a 
> conflict and will crash.
>
> My professor apparently believes there is a way to accomplish this.  Any help 
> or advice would be greatly appreciated.

What's actually happening is that you're converting a string to an
integer. You can play with this at the interactive prompt:

>>> int("1")
1
>>> int("9")
9
>>> int("-3")
-3
>>> int("1.5")
Traceback (most recent call last):
  File "", line 1, in 
ValueError: invalid literal for int() with base 10: '1.5'
>>> int("hello")
Traceback (most recent call last):
  File "", line 1, in 
ValueError: invalid literal for int() with base 10: 'hello'

The user always enters a string. Fundamentally, people don't type
numbers - they type strings. What you're looking for is a way to let
the user type digits that you interpret as an integer.

Fortunately, "crash" in Python really means "raise an exception".
Explore exception handling and you'll find out how you can *catch*
those exceptions you understand. I won't give you the whole solution,
but you should be able to research it from there.

To distinguish between "1.5" and "hello", you could attempt to convert
the digits to a float - if that succeeds, the user entered a
fractional number of packages. Or maybe you don't care about that
difference.

Enjoy Pythonning!

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


Re: gmail api

2017-02-09 Thread Kelvid Pang
On Tuesday, 7 February 2017 14:22:32 UTC+8, Kelvid Pang  wrote:
> hi,
> 
> I am trying to gmail api with reference to this URL: 
> https://developers.google.com/gmail/api/quickstart/python
> 
> But I couldn't find the 'gmail-python-quickstart.json' file. Any one can 
> help? thanks.


First of all, I have figured out the gmail api. thanks for those who give me 
the guide, apparently I didn't follow the guide 100%.

Side note, why reply in the email doesn't appear at the groups.google here, so 
other viewers can also know the status of the thread?
-- 
https://mail.python.org/mailman/listinfo/python-list