classification
Title: Unhelpful error message when a distutils package install fails due to a permissions error
Type: behavior Stage: patch review
Components: Distutils Versions: Python 3.3, Python 3.4, Python 2.7
process
Status: open Resolution:
Dependencies: Superseder:
Assigned To: eric.araujo Nosy List: alexis, eric.araujo, higery, michael.foord, pitrou, tarek
Priority: normal Keywords: easy, needs review, patch

Created on 2009-10-27 12:37 by michael.foord, last changed 2014-03-12 10:35 by eric.araujo.

Files
File name Uploaded Description Edit
fix-7219.diff eric.araujo, 2011-09-03 15:01 review
Messages (12)
msg94554 - (view) Author: Michael Foord (michael.foord) * (Python committer) Date: 2009-10-27 12:37
This problem showed up when installing a package with IronPython, where
the site-packages folder requires admin privileges to write to (which
*should* be true with CPython Windows but isn't).

If you perform a 'python setup.py install' without admin privileges the
install fails (as it should) but with a very cryptic error message:

C:\compile\test\foo-1.0>"C:\Program Files\IronPython 2.6\ipy.exe"
setup.py install
running install
running build
running build_py
creating build
creating build\lib
copying foo.py -> build\lib
running install_lib
copying build\lib\foo.py -> C:\Program Files\IronPython
2.6\Lib\site-packages
error: C:\Program Files\IronPython 2.6\Lib\site-packages\foo.py: None
msg112435 - (view) Author: Éric Araujo (eric.araujo) * (Python committer) Date: 2010-08-02 09:10
Could you run ipy.exe setup.py build, then set DISTUTILS_DEBUG in the environment and run ipy.exe
setup.py install?
msg113604 - (view) Author: Michael Foord (michael.foord) * (Python committer) Date: 2010-08-11 15:29
Output below, first without DISTUTILS_DEBUG (showing the not very useful default message) and second with. (The actual exception is "Access to the path 'C:\Program Files\IronPython 2.7\Lib\site-packages\mock.py' is denied.")

This is with IronPython 2.7A1 which includes the Python 2.7 standard library.

> ipy setup.py build
running build
running build_py
warning: build_py: byte-compiling is disabled, skipping.

C:\compile\mock
> ipy setup.py install
running install
running build
running build_py
warning: build_py: byte-compiling is disabled, skipping.

running install_lib
copying build\lib\mock.py -> C:\Program Files\IronPython 2.7\Lib\site-packages
error: C:\Program Files\IronPython 2.7\Lib\site-packages\mock.py: None
C:\compile\mock
> set DISTUTILS_DEBUG=1

C:\compile\mock
> ipy setup.py install
options (after parsing config files):
options (after parsing command line):
option dict for 'install' command:
  {}
option dict for 'sdist' command:
  {'force_manifest': ('setup.cfg', '1')}
running install
Distribution.get_command_obj(): creating 'install' command object
pre-finalize_{unix,other}:
  prefix: None
  exec_prefix: None
  home: None
  user: 0
  install_base: None
  install_platbase: None
  root: None
  install_purelib: None
  install_platlib: None
  install_lib: None
  install_headers: None
  install_scripts: None
  install_data: None
  compile: None
  compile: True
  optimize: None
  force: None
  skip_build: 0
  record: None
post-finalize_{unix,other}():
  prefix: C:\Program Files\IronPython 2.7
  exec_prefix: None
  home: None
  user: 0
  install_base: C:\Program Files\IronPython 2.7
  install_platbase: C:\Program Files\IronPython 2.7
  root: None
  install_purelib: $base/Lib/site-packages
  install_platlib: $base/Lib/site-packages
  install_lib: None
  install_headers: $base/Include/$dist_name
  install_scripts: $base/Scripts
  install_data: $base
  compile: None
  compile: True
  optimize: None
  force: None
  skip_build: 0
  record: None
post-expand_basedirs():
  prefix: C:\Program Files\IronPython 2.7
  exec_prefix: None
  home: None
  user: 0
  install_base: C:\Program Files\IronPython 2.7
  install_platbase: C:\Program Files\IronPython 2.7
  root: None
  install_purelib: $base/Lib/site-packages
  install_platlib: $base/Lib/site-packages
  install_lib: None
  install_headers: $base/Include/$dist_name
  install_scripts: $base/Scripts
  install_data: $base
  compile: None
  compile: True
  optimize: None
  force: None
  skip_build: 0
  record: None
config vars:
{'base': 'C:\\Program Files\\IronPython 2.7',
 'dist_fullname': 'mock-0.7.0',
 'dist_name': 'mock',
 'dist_version': '0.7.0',
 'exec_prefix': 'C:\\Program Files\\IronPython 2.7',
 'platbase': 'C:\\Program Files\\IronPython 2.7',
 'prefix': 'C:\\Program Files\\IronPython 2.7',
 'py_version': '2.7.0',
 'py_version_nodot': '27',
 'py_version_short': '2.7',
 'sys_exec_prefix': 'C:\\Program Files\\IronPython 2.7',
 'sys_prefix': 'C:\\Program Files\\IronPython 2.7',
 'userbase': 'C:\\Users\\michael\\AppData\\Roaming\\Python',
 'usersite': 'C:\\Users\\michael\\AppData\\Roaming\\Python\\Python27\\site-packa
ges'}
post-expand_dirs():
  prefix: C:\Program Files\IronPython 2.7
  exec_prefix: None
  home: None
  user: 0
  install_base: C:\Program Files\IronPython 2.7
  install_platbase: C:\Program Files\IronPython 2.7
  root: None
  install_purelib: C:\Program Files\IronPython Lib/site-packages
  install_platlib: C:\Program Files\IronPython Lib/site-packages
  install_lib: None
  install_headers: C:\Program Files\IronPython Include/mock
  install_scripts: C:\Program Files\IronPython 2.7/Scripts
  install_data: C:\Program Files\IronPython 2.7
  compile: None
  compile: True
  optimize: None
  force: None
  skip_build: 0
  record: None
after prepending root:
  prefix: C:\Program Files\IronPython 2.7
  exec_prefix: None
  home: None
  user: 0
  install_base: C:\Program Files\IronPython 2.7
  install_platbase: C:\Program Files\IronPython 2.7
  root: None
  install_purelib: C:\Program Files\IronPython 2.7\Lib\site-packages
  install_platlib: C:\Program Files\IronPython 2.7\Lib\site-packages
  install_lib: C:\Program Files\IronPython 2.7\Lib\site-packages\
  install_headers: C:\Program Files\IronPython 2.7\Include\mock
  install_scripts: C:\Program Files\IronPython 2.7\Scripts
  install_data: C:\Program Files\IronPython 2.7
  compile: None
  compile: True
  optimize: None
  force: None
  skip_build: 0
  record: None
Distribution.get_command_obj(): creating 'build' command object
running build
running build_py
Distribution.get_command_obj(): creating 'build_py' command object
warning: build_py: byte-compiling is disabled, skipping.

running install_lib
Distribution.get_command_obj(): creating 'install_lib' command object
copying build\lib\mock.py -> C:\Program Files\IronPython 2.7\Lib\site-packages
error: C:\Program Files\IronPython 2.7\Lib\site-packages\mock.py: None
Traceback (most recent call last):
  File "setup.py", line 69, in <module>
  File "C:\Program Files\IronPython 2.7\Lib\distutils\core.py", line 151, in set
up
  File "C:\Program Files\IronPython 2.7\Lib\distutils\dist.py", line 952, in run
_commands
  File "C:\Program Files\IronPython 2.7\Lib\distutils\dist.py", line 971, in run
_command
  File "C:\Program Files\IronPython 2.7\Lib\distutils\command\install.py", line
575, in run
  File "C:\Program Files\IronPython 2.7\Lib\distutils\cmd.py", line 326, in run_
command
  File "C:\Program Files\IronPython 2.7\Lib\distutils\dist.py", line 971, in run
_command
  File "C:\Program Files\IronPython 2.7\Lib\distutils\command\install_lib.py", l
ine 97, in run
  File "C:\Program Files\IronPython 2.7\Lib\distutils\command\install_lib.py", l
ine 115, in install
  File "C:\Program Files\IronPython 2.7\Lib\distutils\cmd.py", line 373, in copy
_tree
  File "C:\Program Files\IronPython 2.7\Lib\distutils\dir_util.py", line 159, in
 copy_tree
  File "C:\Program Files\IronPython 2.7\Lib\distutils\file_util.py", line 148, i
n copy_file
  File "C:\Program Files\IronPython 2.7\Lib\distutils\file_util.py", line 44, in
 _copy_file_contents
IOError: System.IO.IOException: Access to the path 'C:\Program Files\IronPython
2.7\Lib\site-packages\mock.py' is denied. ---> System.UnauthorizedAccessExceptio
n: Access to the path 'C:\Program Files\IronPython 2.7\Lib\site-packages\mock.py
' is denied.
   at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
   at System.IO.FileStream.Init(String path, FileMode mode, FileAccess access, I
nt32 rights, Boolean useRights, FileShare share, Int32 bufferSize, FileOptions o
ptions, SECURITY_ATTRIBUTES secAttrs, String msgPath, Boolean bFromProxy, Boolea
n useLongPath)
   at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access,
FileShare share)
   at Microsoft.Scripting.PlatformAdaptationLayer.OpenInputFileStream(String pat
h, FileMode mode, FileAccess access, FileShare share)
   at IronPython.Runtime.PythonFile.__init__(CodeContext context, String name, S
tring mode, Int32 buffering)
   --- End of inner exception stack trace ---
   at Microsoft.Scripting.Runtime.LightExceptions.CheckAndThrow(Object value)
   at Microsoft.Scripting.Interpreter.FuncCallInstruction`2.Run(InterpretedFrame
 frame)
   at Microsoft.Scripting.Interpreter.Interpreter.HandleException(InterpretedFra
me frame, Exception exception)
   at Microsoft.Scripting.Interpreter.Interpreter.Run(InterpretedFrame frame)
   at Microsoft.Scripting.Interpreter.LightLambda.Run2[T0,T1,TRet](T0 arg0, T1 a
rg1)
   at IronPython.Compiler.PythonCallTargets.OriginalCallTarget1(PythonFunction f
unction, Object arg0)
   at Microsoft.Scripting.Interpreter.FuncCallInstruction`4.Run(InterpretedFrame
 frame)
   at Microsoft.Scripting.Interpreter.Interpreter.Run(InterpretedFrame frame)
   at Microsoft.Scripting.Interpreter.LightLambda.Run4[T0,T1,T2,T3,TRet](T0 arg0
, T1 arg1, T2 arg2, T3 arg3)
   at System.Dynamic.UpdateDelegates.UpdateAndExecute3[T0,T1,T2,TRet](CallSite s
ite, T0 arg0, T1 arg1, T2 arg2)
   at Microsoft.Scripting.Interpreter.DynamicInstruction`4.Run(InterpretedFrame
frame)
   at Microsoft.Scripting.Interpreter.Interpreter.Run(InterpretedFrame frame)
   at Microsoft.Scripting.Interpreter.LightLambda.Run1[T0,TRet](T0 arg0)
   at IronPython.Compiler.RuntimeScriptCode.InvokeTarget(Scope scope)
   at IronPython.Compiler.RuntimeScriptCode.Run(Scope scope)
   at IronPython.Hosting.PythonCommandLine.RunFileWorker(String fileName)
   at IronPython.Hosting.PythonCommandLine.RunFile(String fileName)
C:\compile\mock
>
msg113872 - (view) Author: Éric Araujo (eric.araujo) * (Python committer) Date: 2010-08-14 05:36
An IOError is raised but file_util._copy_file_contents only produces the helpful message “could not create '<file>': <error>” when catching os.error.

Catching both classes is easy. We’d need a regression test first, and before that, agreement from Tarek that such a change would be okay.

I wonder what is this mysterious None that we get as a result.
msg113889 - (view) Author: Michael Foord (michael.foord) * (Python committer) Date: 2010-08-14 12:00
The "None" error message *looks* to me like the result of a failed assertion. That may not be correct of course...
msg120988 - (view) Author: Éric Araujo (eric.araujo) * (Python committer) Date: 2010-11-12 00:11
I wonder if this is IronPython-specific.  Could you temporarily make the site-packages directory of a py3k CPython read-only and try to install a distribution with that CPython?  I can try the same thing on unix.
msg143461 - (view) Author: Éric Araujo (eric.araujo) * (Python committer) Date: 2011-09-03 15:01
I have a patch that needs testing on Cpython Windows and if possible IPython.  The test makes sure that the error message contains the path to the file (which the incomplete error message you report also does, BTW), and an explanation of the error (to address the OP’s concern that the message must be helpful): it looks for the string 'denied'; if this is not cross-platform, I won’t commit this line.  (Antoine, I’ve made you nosy because I think you may have expertise on that last point.)

(BTW, I have tracked down the source of the mysterious None (I’m getting better at these things, but my mental sanity takes a toll each time): core.setup catches the exception and wants to display exc.filename and exc.strerror.)
msg143469 - (view) Author: Antoine Pitrou (pitrou) * (Python committer) Date: 2011-09-03 16:56
> The test makes sure that the error message contains the path to the
> file (which the incomplete error message you report also does, BTW),
> and an explanation of the error (to address the OP’s concern that the
> message must be helpful): it looks for the string 'denied'; if this is
> not cross-platform, I won’t commit this line. 

I really don't think C error messages are portable, so you shouldn't
test for them :)
msg143521 - (view) Author: higery (higery) Date: 2011-09-05 15:01
I have run the 'test_install_lib' on cpython3.3(windows version), the
'test_install_error' failed.

The detail is:

*FAIL: test_install_error (__main__.InstallLibTestCase)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "D:\add-develop-command\Lib\distutils\tests\test_install_lib.py",
line 112, in test_install_error
    cmd.run()
AssertionError: DistutilsFileError not raised*

The corresponding lines are:
*
with self.assertRaises(DistutilsFileError) as cm:
        cmd.run()*
msg143523 - (view) Author: Éric Araujo (eric.araujo) * (Python committer) Date: 2011-09-05 15:12
> I really don't think C error messages are portable, so you shouldn't
> test for them :)

Too bad.  I’ll have to be satisfied with a manual test from Michael then.
msg143634 - (view) Author: Éric Araujo (eric.araujo) * (Python committer) Date: 2011-09-06 17:03
Thanks for testing the patch higery.  I wonder if another exception was raised but ignored by unittest.
msg213244 - (view) Author: Éric Araujo (eric.araujo) * (Python committer) Date: 2014-03-12 10:35
The fix for #4931 may also fix this bug.  The patch should be changed to remove the code changes and adapt the tests.
History
Date User Action Args
2014-03-12 10:35:23eric.araujosetmessages: + msg213244
components: - Distutils2
versions: + Python 3.4, - 3rd party, Python 3.2
2011-09-06 17:03:22eric.araujosetmessages: + msg143634
2011-09-06 17:01:23eric.araujosetfiles: - unnamed
2011-09-05 15:12:31eric.araujosetmessages: + msg143523
2011-09-05 15:01:10higerysetfiles: + unnamed

messages: + msg143521
2011-09-03 16:56:49pitrousetmessages: + msg143469
2011-09-03 15:01:17eric.araujosetfiles: + fix-7219.diff

assignee: tarek -> eric.araujo
components: + Distutils, Distutils2
versions: + 3rd party, Python 3.3, - Python 3.1
keywords: + patch, needs review
nosy: + alexis, pitrou, higery

messages: + msg143461
stage: needs patch -> patch review
2010-11-12 00:11:05eric.araujosetmessages: + msg120988
2010-08-14 12:00:21michael.foordsetmessages: + msg113889
2010-08-14 05:36:33eric.araujosetmessages: + msg113872
2010-08-11 15:29:59michael.foordsetmessages: + msg113604
2010-08-02 09:10:30eric.araujosetnosy: + eric.araujo
messages: + msg112435
2010-07-11 10:03:30BreamoreBoysetkeywords: + easy, - 26backport
versions: + Python 3.1, - Python 2.6
2009-10-27 12:37:49michael.foordcreate