Edgewall Software
Modify

Opened 4 years ago

Closed 4 years ago

#12757 closed defect (fixed)

[Errno 2] No such file or directory when running tracd on Windows with --auto-reload

Reported by: Ryan J Ollos Owned by: Jun Omae
Priority: normal Milestone: 1.0.14
Component: web frontend/tracd Version: 1.2dev
Severity: normal Keywords: windows
Cc: Branch:
Release Notes:

Fixed error starting tracd with -r/--auto-reload on Windows.

API Changes:
Internal Changes:

Description

Running tracd on windows with the -r switch:

(pve) C:\Users\Ryan Ollos\trac-dev>tracd -r -s -p 8000 tracenv
c:\users\ryanol~1\trac-dev\pve\scripts\python.exe: can't open file 'C:\Users
\RYANOL~1\trac-dev\pve\Scripts\tracd': [Errno 2] No such file or directory

Behavior seen on 1.2-stable, I need to check if behavior occurs on 1.0-stable.

It works fine without the -r switch, or when pointing to tracd-script.py rather than tracd:

  • trac-1.2-stable/trac/util/autoreload.py

     
    6363def _restart_with_reloader():
    6464    while True:
    6565        args = [sys.executable] + sys.argv
     66        args[1] += '-script.py'
    6667        if sys.platform == 'win32':
    6768            args = ['"%s"' % arg for arg in args]
    6869        new_environ = os.environ.copy()

That's not a proposed change, just a demonstration of what works.

Attachments (0)

Change History (15)

comment:1 by Jun Omae, 4 years ago

Keywords: wheel added

The same issue exists on Trac 1.0.13 but tracd-script.py isn't installed via wheel.

C:\>C:\usr\var\venv\trac-1.0.13\Scripts\python.exe -m pip install Trac==1.0.13
Collecting Trac==1.0.13
  Using cached Trac-1.0.13-py2-none-any.whl
Requirement already satisfied: setuptools>=0.6b1 in c:\usr\var\venv\trac-1.0.13\lib\site-packages (from Trac==1.0.13)
Requirement already satisfied: Genshi>=0.6 in c:\usr\var\venv\trac-1.0.13\lib\site-packages (from Trac==1.0.13)
Requirement already satisfied: six>=1.6.0 in c:\usr\var\venv\trac-1.0.13\lib\site-packages (from setuptools>=0.6b1->Trac==1.0.13)
Requirement already satisfied: packaging>=16.8 in c:\usr\var\venv\trac-1.0.13\lib\site-packages (from setuptools>=0.6b1->Trac==1.0.13)
Requirement already satisfied: appdirs>=1.4.0 in c:\usr\var\venv\trac-1.0.13\lib\site-packages (from setuptools>=0.6b1->Trac==1.0.13)
Requirement already satisfied: pyparsing in c:\usr\var\venv\trac-1.0.13\lib\site-packages (from packaging>=16.8->setuptools>=0.6b1->Trac==1.0.13)
Installing collected packages: Trac
Successfully installed Trac-1.0.13
C:\>C:\usr\var\venv\trac-1.0.13\Scripts\tracd -r -s -p 3000 C:\usr\var\trac\1.0
c:\usr\var\venv\trac-1.0.13\scripts\python.exe: can't open file 'C:\usr\var\venv\trac-1.0.13\Scripts\tracd': [Errno 2] No such file or directory

C:\>C:\usr\var\venv\trac-1.0.13\Scripts\python.exe
Python 2.7.10 (default, May 23 2015, 09:44:00) [MSC v.1500 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import os
>>> for _ in os.listdir(r'C:\usr\var\venv\trac-1.0.13\Scripts'): _
...
'activate'
'activate.bat'
'activate.ps1'
'activate_this.py'
'deactivate.bat'
'easy_install-2.7.exe'
'easy_install.exe'
'pip.exe'
'pip2.7.exe'
'pip2.exe'
'python.exe'
'pythonw.exe'
'trac-admin.exe'
'tracd.exe'
'wheel.exe'

C:\>C:\usr\var\venv\trac-1.0.13\Scripts\python.exe -m pip show -f Trac | findstr /C:"tracd"
  ..\..\Scripts\tracd.exe

C:\>C:\usr\var\venv\trac-1.0.13\Scripts\python.exe -m pip show -f Trac | findstr /C:"script"
  tracopt\mimeview\enscript.py
  tracopt\mimeview\enscript.pyc

tracd-script.py is installed if Trac is installed via egg package using easy_install.

C:\>C:\usr\var\venv\trac-1.0.13\Scripts\python.exe -m easy_install Trac==1.0.13
Searching for Trac==1.0.13
Reading https://pypi.python.org/simple/Trac/
Downloading https://pypi.python.org/packages/fa/07/2be60e9ac5f4dbd797105bc58d5dd95ce76d2f64071845a8ce035821c140/Trac-1.0.13.win-amd64.exe#md5=3ed8d0c5a9502d0dbb8b249c225d1a39
Best match: Trac 1.0.13
Processing Trac-1.0.13.win-amd64.exe
creating 'c:\users\omae\appdata\local\temp\easy_install-6flnnd\Trac-1.0.13-py2.7-win-amd64.egg' and adding 'c:\users\omae\appdata\local\temp\easy_install-6flnnd\Trac-1.0.13-py2.7-win-amd64.egg.tmp' to it
Moving Trac-1.0.13-py2.7-win-amd64.egg to c:\usr\var\venv\trac-1.0.13\lib\site-packages
Adding Trac 1.0.13 to easy-install.pth file
Installing tracd-script.py script to C:\usr\var\venv\trac-1.0.13\Scripts
Installing trac-admin-script.pyc script to C:\usr\var\venv\trac-1.0.13\Scripts
Installing trac-admin.exe script to C:\usr\var\venv\trac-1.0.13\Scripts
Installing tracd-script.pyc script to C:\usr\var\venv\trac-1.0.13\Scripts
Installing tracd.exe script to C:\usr\var\venv\trac-1.0.13\Scripts
Installing trac-admin-script.py script to C:\usr\var\venv\trac-1.0.13\Scripts
Installing trac-admin-script.py script to C:\usr\var\venv\trac-1.0.13\Scripts
Installing trac-admin.exe script to C:\usr\var\venv\trac-1.0.13\Scripts
Installing tracd-script.py script to C:\usr\var\venv\trac-1.0.13\Scripts
Installing tracd.exe script to C:\usr\var\venv\trac-1.0.13\Scripts

comment:2 by Jun Omae, 4 years ago

According to http://wheel.readthedocs.io/en/latest/#setuptools-scripts-handling, script files can be installed using wheel install-files NAME.

C:\>C:\usr\var\venv\trac-1.0.13\Scripts\python.exe -m wheel install-scripts Trac==1.0.13

C:\>C:\usr\var\venv\trac-1.0.13\Scripts\python.exe
Python 2.7.10 (default, May 23 2015, 09:44:00) [MSC v.1500 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import os
>>> for _ in os.listdir(r'C:\usr\var\venv\trac-1.0.13\Scripts'):
...   if 'script' in _:
...     _
...
'trac-admin-script.py'
'tracd-script.py'
>>>

comment:3 by Ryan J Ollos, 4 years ago

The issue I've reported is seen using develop mode with an egg, not wheel, and script files are installed. I've installed with python setup.py develop.

The issue I'm reporting is only seen when using -r/--auto-reload.

(pve) C:\Users\Ryan Ollos\trac-dev>pip list --format=columns
Package    Version    Location
---------- ---------- --------------------------------------------
appdirs    1.4.3
Genshi     0.7
packaging  16.8
pip        9.0.1
pyparsing  2.2.0
setuptools 34.3.3
six        1.10.0
Trac       1.2.2.dev0 c:\users\ryan ollos\trac-dev\trac-1.2-stable
wheel      0.29.0
(pve) C:\Users\Ryan Ollos\trac-dev>dir pve\Scripts
 Volume in drive C has no label.
 Volume Serial Number is 6C99-BF6F

 Directory of C:\Users\Ryan Ollos\trac-dev\pve\Scripts

04/04/2017  08:49 PM    <DIR>          .
04/04/2017  08:49 PM    <DIR>          ..
04/04/2017  05:31 PM             2,195 activate
04/04/2017  05:31 PM               765 activate.bat
04/04/2017  05:31 PM             8,325 activate.ps1
04/04/2017  05:31 PM             1,137 activate_this.py
04/04/2017  05:31 PM               508 deactivate.bat
04/04/2017  05:31 PM            98,180 easy_install-2.7.exe
04/04/2017  08:49 PM               433 easy_install-3.6-script.py
04/04/2017  08:49 PM            74,752 easy_install-3.6.exe
04/04/2017  08:49 PM               425 easy_install-script.py
04/04/2017  08:49 PM            74,752 easy_install.exe
04/04/2017  05:31 PM            98,152 pip.exe
04/04/2017  05:31 PM            98,152 pip2.7.exe
04/04/2017  05:31 PM            98,152 pip2.exe
04/04/2017  05:31 PM            28,160 python.exe
04/04/2017  05:31 PM            28,160 pythonw.exe
04/04/2017  08:49 PM               403 trac-admin-script.py
04/04/2017  08:49 PM            74,752 trac-admin.exe
04/04/2017  08:49 PM               393 tracd-script.py
04/04/2017  08:49 PM            74,752 tracd.exe
04/04/2017  05:31 PM            98,159 wheel.exe
              20 File(s)        860,707 bytes
               2 Dir(s)  10,092,253,184 bytes free
(pve) C:\Users\Ryan Ollos\trac-dev>tracd -r -s -p 8000 tracenv
C:\Users\RYANOL~1\trac-dev\pve\Scripts\python.exe: can't open file 'C:\Users\RYA
NOL~1\trac-dev\pve\Scripts\tracd': [Errno 2] No such file or directory
2

(pve) C:\Users\Ryan Ollos\trac-dev>tracd -s -p 8000 tracenv
Server starting in PID 4044.
Serving on 0.0.0.0:8000 view at http://127.0.0.1:8000/
Using HTTP/1.1 protocol version

Regarding the wheel behavior, see also gmessage:trac-dev:z6Vg8o0U5XA/zgJYzrREAAAJ.

comment:4 by Ryan J Ollos, 4 years ago

Keywords: wheel removed

comment:5 by Jun Omae, 4 years ago

Sorry for my noise. I consider we intentionally use only for development and debugging with -r option of trac/web/standard.py. I propose wontfix, otherwise prevent uses of -r option in installed tracd script.

See also Automatic reloading: For development: … in TracStandalone#Pros.

comment:6 by Jun Omae, 4 years ago

We could check whether sys.argv[0] is existent and executable, and whether sys.argv[0] + '.exe' is executable on Windows.

  • trac/util/autoreload.py

    diff --git a/trac/util/autoreload.py b/trac/util/autoreload.py
    index c74441058..3e83fbff5 100644
    a b def _reloader_thread(modification_callback, loop_callback):  
    6262
    6363def _restart_with_reloader():
    6464    while True:
    65         args = [sys.executable] + sys.argv
     65        if os.path.isfile(sys.argv[0]):
     66            args = sys.argv if os.access(sys.argv[0], os.X_OK) \
     67                   else [sys.executable] + sys.argv
     68        elif sys.platform == 'win32' and \
     69                os.access(sys.argv[0] + '.exe', os.X_OK):
     70            args = [sys.argv[0] + '.exe'] + sys.argv[1:]
     71        else:
     72            args = [sys.executable] + sys.argv
     73        path = args[0]
    6674        if sys.platform == 'win32':
    6775            args = ['"%s"' % arg for arg in args]
    6876        new_environ = os.environ.copy()
    def _restart_with_reloader():  
    7078
    7179        # This call reinvokes ourself and goes into the other branch of main as
    7280        # a new process.
    73         exit_code = os.spawnve(os.P_WAIT, sys.executable,
    74                                args, new_environ)
     81        exit_code = os.spawnve(os.P_WAIT, path, args, new_environ)
    7582        if exit_code != 3:
    7683            return exit_code
    7784
Last edited 4 years ago by Jun Omae (previous) (diff)

comment:7 by Ryan J Ollos, 4 years ago

Milestone: 1.2.21.0.14
Owner: set to Ryan J Ollos
Release Notes: modified (diff)
Status: newassigned

Thanks, comment:6 change works well.

comment:8 by Ryan J Ollos, 4 years ago

Resolution: fixed
Status: assignedclosed

I tested on Windows7 and OSX. Committed to 1.0-stable in r15745, merged in r15746, r15747.

comment:9 by Ryan J Ollos, 4 years ago

Owner: changed from Ryan J Ollos to Jun Omae

comment:10 by Peter Suter, 4 years ago

Hm, before r15747 tracd.exe -r works fine for me (on Windows, with Trac installed via python setup.py develop in a virtualenv):

  • <venv>\scripts\tracd.exe exists.
  • In os.spawnve(..., sys.executable, args, ...):
    • sys.executable is <venv>\scripts\python.exe (which exists).
    • args is ['"<venv>\scripts\python.exe"', '"<venv>\scripts\tracd-script.py"', '"-r"', ...]

But after r15747 when trying to run tracd.exe -r I get OSError: [Errno 8] Exec format error from os.spawnve():

  • <venv>\scripts\tracd.exe still exists.
  • In os.spawnve(..., path, args, ...):
    • path is <venv>\scripts\tracd-script.py (which exists).
    • args is ['"<venv>\scripts\tracd-script.py"', '"-r"', ...]
  • (sys.executable is still <venv>\scripts\python.exe.)
  • sys.argv[0] is<venv>\scripts\tracd-script.py.
    • os.access(sys.argv[0], os.X_OK) returns True.

Any ideas?

Last edited 4 years ago by Peter Suter (previous) (diff)

comment:11 by Peter Suter, 4 years ago

Resolution: fixed
Status: closedreopened

comment:12 by Jun Omae, 4 years ago

Thanks for the catching.

The issue is reproduced with:

Genshi (0.7)
pip (7.1.0)
setuptools (18.0.1)
Trac (1.2.2.dev0, c:\usr\src\trac\trac.git)
wheel (0.24.0)

Works fine with:

appdirs (1.4.3)
Genshi (0.7)
packaging (16.8)
pip (9.0.1)
pyparsing (2.2.0)
setuptools (34.4.1)
six (1.10.0)
Trac (1.2.2.dev0, c:\usr\src\trac\trac.git)
wheel (0.29.0)

comment:13 by Jun Omae, 4 years ago

Ah. It seems to be unable to use os.X_OK on Windows….

>>> os.access(r'setup.py', os.X_OK)
True
>>> os.access(r'setup.cfg', os.X_OK)
True

Instead, check existent and suffix of the file is .exe.

  • trac/util/autoreload.py

    diff --git a/trac/util/autoreload.py b/trac/util/autoreload.py
    index f77806b..18d45aa 100644
    a b def _reloader_thread(modification_callback, loop_callback):  
    6161        time.sleep(_SLEEP_TIME)
    6262
    6363def _restart_with_reloader():
    64     while True:
    65         if os.path.isfile(sys.argv[0]):
    66             args = sys.argv if os.access(sys.argv[0], os.X_OK) \
    67                    else [sys.executable] + sys.argv
    68         elif sys.platform == 'win32' and \
    69                 os.access(sys.argv[0] + '.exe', os.X_OK):
    70             args = [sys.argv[0] + '.exe'] + sys.argv[1:]
    71         else:
    72             args = [sys.executable] + sys.argv
    73         path = args[0]
    74         if sys.platform == 'win32':
    75             args = ['"%s"' % arg for arg in args]
    76         new_environ = os.environ.copy()
    77         new_environ['RUN_MAIN'] = 'true'
     64    is_win32 = sys.platform == 'win32'
     65    if is_win32:
     66        can_exec = lambda path: os.path.isfile(path) and \
     67                                os.path.normpath(path).endswith('.exe')
     68    else:
     69        can_exec = lambda path: os.access(path, os.X_OK)
    7870
     71    if os.path.isfile(sys.argv[0]):
     72        args = sys.argv if can_exec(sys.argv[0]) else \
     73               [sys.executable] + sys.argv
     74    elif is_win32 and can_exec(sys.argv[0] + '.exe'):
     75        args = [sys.argv[0] + '.exe'] + sys.argv[1:]
     76    elif os.path.isfile(sys.argv[0] + '-script.py'):
     77        args = [sys.executable, sys.argv[0] + '-script.py'] + sys.argv[1:]
     78    else:
     79        args = [sys.executable] + sys.argv
     80    path = args[0]
     81    if is_win32:
     82        args = ['"%s"' % arg for arg in args]
     83    new_environ = os.environ.copy()
     84    new_environ['RUN_MAIN'] = 'true'
     85
     86    while True:
    7987        # This call reinvokes ourself and goes into the other branch of main as
    8088        # a new process.
    8189        exit_code = os.spawnve(os.P_WAIT, path, args, new_environ)

in reply to:  13 comment:14 by Peter Suter, 4 years ago

Ah. It seems to be unable to use os.X_OK on Windows…. Instead, check existent and suffix of the file is .exe.

This seems to work well for me, thanks!

comment:15 by Jun Omae, 4 years ago

Resolution: fixed
Status: reopenedclosed

Thanks for the testing! Fixed in [15778-15780], again.

Modify Ticket

Change Properties
Set your email in Preferences
Action
as closed The owner will remain Jun Omae.
The resolution will be deleted. Next status will be 'reopened'.
to The owner will be changed from Jun Omae to the specified user.

Add Comment


E-mail address and name can be saved in the Preferences .
 
Note: See TracTickets for help on using tickets.