Open a09e2537-b6b9-4978-9d1d-78b1db358cbc opened 10 years ago
On Windows IDLE's working directory is Python's install directory, e.g., C:\Python34. ISTM that this is the wrong directory for 99% of general users and for 100% of beginners since this is _not_ the directory where people should save their own .py files (unless they are experts, in which case they know better and won't anyway).
I think that IDLE should start out in the user's home directory (ideally on all platforms).
When I start IDLE ("python -m idle") from my project directory I expect that it doesn't change current directory and I can access files in this directory by short relative name.
We should be able to add enough smarts to handle both cases.
FWIW, on OS X when IDLE is launched from the Finder, for example by double-clicking on an IDLE icon, IDLE defaults to using the user's Documents folder as its working directory. When IDLE is launched from a command line shell, it uses the current working directory. Perhaps something similar can be done for Windows.
The same is on Linux. Therefore this is Windows only issue.
Mark's opening statement is incomplete. The actual situation is more complex, and probably not documented anywhere except in the code -- and the system-specific behavior not even there. Let 'working directory' mean the initial directory of an Open or Save As dialog opened from a particular window. By experiment, each window has its own working directory.
For Editor windows with a named file, the working directory is the directory of the file. Note that recently edited file can be opened from File / Recent Files, bypassing the Open dialog. (Side issue: the number of recent files kept should be expanded.) I sometimes open a file to get to its directory. Untitled Editor widows inherit the working directory from the active window where File / New File or control-N was invoked.
Output windows inherit the Shell working directory. Currently, the Shell working directory is the current working directory of the python(w) process it is running in. If python is started from a command line*, it inherits the console cwd. If python is started from a python or idle icon, its current directory is that of the python executable -- but apparently only on Windows. When Python is installed, the executable is in the install directory that also contains /lib. In a Windows repository build, the executable in /pcbuild, next to /lib. (Another side issue: this is a nuisance and currently disables File / Load Module Alt-m.)
This issue should only be about changing the Shell working directory when it would otherwise be the executable directory (from an icon start, the last case in the previous paragraph). This can be tested by looking for 'python.exe'. We could add a new config option to the Startup Preferences block of the General tab of the config dialog. Subissue: perhaps this option, unlike most, should have a command line option.
A binary option would be sufficient to switch to the user's home directory. But especially for beginners, and especially for children (Mark's presented use case on python-list), this is not the right place. Splattering .py files in \~HOME is not tremendously better than doing the same in the executable directory. So I think there should be an entry box where someone could enter, for instance, '\~/Python'. Starting in a particular directory, rather than having to switch to a Python-files directory, would not be Windows-specific.
The current Windows behavior of starting in the version-specific python tree is very handy when working on python itself. But I guess using Pathbrowser would be a substitute for that.
I retract my previous statement "Splattering .py files in \~HOME is not tremendously better than doing the same in the executable directory." and agree that when started with the default Windows icon, IDLE should start in %USERPROFILE%.
Discussion for bpo-25450 clarified some of the practical issues. Windows icons have a Shortcut tab with a Start-in field. We should like to put %USERPROFILE% there, but this does not work -- msg253393.
Steve Dower suggested to instead add a new command line option to set the starting directory for code entered in the shell window. (IDLE currently uses getopt with USAGE: idle [-deins] [-t title] [file] idle [-dns] [-t title] (-c cmd | -r file) [arg] I suggest adding option '-w path' (w for 'working directory' or 'workspace', d already being used). Any better ideas? Like d, s, t, c, and r, the new option would imply -i, open a shell window.
Shortcut tabs also have a 'target' field. For 3.5, this is an editable command line. I tested that adding "-t %USERPROFILE%" changes the Shell title accordingly. Steve has already change the installed icon.
Users could copy the icon and add a subdirectory, such as 'python', where they put python code. I presume users on other systems could do the equivalent, so the benefit of this is not limited to Windows.
For prior Python versions, the Shortcut 'target' is a read-only grayed-out 'Python x.y.z (nn bits)'. I do not know how this is resolved to running IDLE with the specified binary, but it likely would not be easy to change to the 3.5 editable field version (and not create other problems in the process). So I will not even ask MVL, the previous Windows installer maintainer, to do that.
idlelib/idle.bat was added to get around the inability to edit this field. (ADD DOC for this.) So the new startup option could be used by Windows users to start older IDLEs in their home directory.
I'm also interested in a smooth experience for beginners.
I have a factual observation with respect to Terry's comment: '''Windows icons have a Shortcut tab with a Start-in field. We should like to put %USERPROFILE% there, but this does not work -- msg253393.''' ... I note that several menu shortcuts have "Start in" set to %HOMEDRIVE%%HOMEPATH%. Examples are notepad, Internet Explorer and the command prompt. (This is on Win7x64.) What we want seems to be a normal thing to do, and achieved by some, but perhaps by a post installation script.
Alternatively, once a .py file exists where you want to work, right-click "Edit with IDLE" provides the CWD we'd like best. Idea: add a New >> Python File context menu item. Encourage users to create a new file that way, then open it, and everything from there is smooth. (New issue if liked.)
What we want seems to be a normal thing to do, and achieved by some, but perhaps by a post installation script.
It would help to have a couple of the bdist_wininst functions available for a post-install script:
create_shortcut (CreateShortcut)
get_special_folder_path (GetSpecialFolderPath)
bpo-28775 is about a user configuration setting.
I need to try out %HOMEDRIVE%%HOMEPATH%.
I am not sure what a 'post-installation script' means in practice. What language, when run, by whom?
On Windows 10, Start Menu entries are no longer shortcuts, but are titles of shortcuts. On the 'most recent' and alphabetical listings, one must right click, select 'more', and then 'open file location'. One then gets a directory of shortcuts, such as C:\Users\Terry\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Python 3.7, which can be copied and edited. If one used 'Type here to search', right clicking immediately displays 'open file location'.
I am not sure what a 'post-installation script' means in practice.
IIRC, there's no way to prevent environment-variable expansion when shortcuts are created by an MSI, so the shortcuts need to be created or modified after installing IDLE. Perhaps this can be implemented in the MSI with a custom action. Or perhaps this can be implemented after installing the package via the OnExecutePackageComplete hook method in Tools/msi/bundle/bootstrap/PythonBootstrapperApplication.cpp.
On the 'most recent' and alphabetical listings, one must right click, select 'more', and then 'open file location'. One then gets a directory of shortcuts,
They're probably hiding the action to modify shortcuts since generally they're installed for all users in %ProgramData%, and modifying them requires administrator access.
such as C:\Users\Terry\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Python 3.7, which can be copied and edited.
You shouldn't need to copy a shortcut in your own AppData. You can modify it directly.
I still think the best option is a command line flag like "--open-in-homedir" that causes Idle to do a chdir to the user's documents folder. This way we can put a static option in the start menu item in the installer and not worry about the limitations of MSI, etc. These limitations also exist in MSIX (app store packages) which is coming soon as well.
Alternatively, we could check the current directory to see if it matches sys.prefix (or whatever it matches) and chdir in that case. No option needed.
For reference, VS Code requires "code.exe ." to start in the current directory, and otherwise uses its default no matter where you start it from.
Eryk: If one wants a shortcut on the desktop, I believe the one in a directory has to be copied. I was also trying to cover the case where IDLE is installed for all users and a particular user wants a customized shortcut.
Steve: Microsoft's effort to keep most users ignorant of command lines has been all too successful. So a new C.L. option can only be part of a solution.
It seems that IDLE automatically changing directory, under some circumstances on some systems, to ???, should be part of a solution. But Documents is better that HOME. (This is the default now on Mac.)
Last week there was a discussion of this issue started by someone who teaches or supports Python for non-computer experts at a university with multiple computers around the campus networked to a central computer with installed Python. What he and others want is for IDLE to start in a particular user's Python scripts subdirectory, and not have to change the directory in the open file dialog. This will require a new config option.
For a config option to work with repository python (at least for me), I would like python.bat to the repository directory that contains /Lib rather than merely set PYTHONHOME to same.
I need to make a list a ways to start Python and the consequences for sys.path and current directory on the three major systems and add it to idlelib/README.txt. For this issue, there are also ways to open a file after IDLE is started.
ISTM, the start directory needs to be a configuration option. The problem is that most users start IDLE using an icon rather than from the command-line (the latter is already challenging on Windows because they would have to put Python on the PATH just to launch IDLE and if they've already found and changed to the executable directly, it is a unfair further burden to now have to specify a different directory where their py files will be parked).
AFAICT, the best logic is this:
if os.path.normcase(os.getcwd()) == os.path.normcase(sys.prefix):
os.chdir(get_default_location(sys.platform))
The only complexity is likely to be that "Documents" is localized on Windows, and SHGetFolderPathW 1 requires ctypes, though I wouldn't be surprised if there's a hidden English link available. There might be some trick necessary for macOS too. All the command line options will work for now, but will break in the future.
It's not real obvious, but when https://bugs.python.org/issue34977 lands - soon! - we'll get good PATH support back, including for Idle. This means you'll get "idle[3[.y]].exe" available globally that will do the same thing as the icon in Start. In this situation, the logic above is the _only_ option that will work properly, as there are no arguments we can pass. So forcing the CWD out of the install directory but otherwise leaving it alone is the best option.
This is really important for newbies. They have no business being in the system Python folder. And Idle is for newbies!
I was teaching an intro Python class, and tried to help a student who had been writing programs in Idle, but now could not get Python going. It took many minutes for me to discover that he had created a new file while the shell window had focus, and innocently saved the file as math.py, without looking for a new directory to put it in.
What a pain tracking that down!
When I start IDLE ("python -m idle") from my project directory I expect that it doesn't change current directory and I can access files in this directory by short relative name.
I rely on this behavior when teaching Python courses. IIRC, David Beazley does as well.
Steve, there is a problem in both lines of this suggestion.
if os.path.normcase(os.getcwd()) == os.path.normcase(sys.prefix):
os.chdir(get_default_location(sys.platform))
On my 3.8 repository build,
>>> import os; os.getcwd()
'F:\\dev\\38\\PCbuild\\win32'
>>> import sys; sys.prefix
'F:\\dev\\38'
# Don't match. The following does.
>>> os.path.dirname(sys.executable)
'F:\\dev\\3x\\PCbuild\\win32'
>>> get_default_location
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'get_default_location' is not defined
Raymond, I understand that you are saying that the current behavior when starting from a command prompt is correct (I agree) and depended upon. I changed the title to be clear about that. Starting IDLE from an icon includes starting python from an icon and then starting IDLE with 'import idlelib.idle', which I do routinely for repository builds.
Looking at the revised title, +1 for changing the IDLE Icon startup, but let's keep the command-line startup sticking with the current directory:
$ mkdir pyclass
$ cd pyclass
$ python3.8 -m idlelib.idle # Should start in the pyclass directory
Steve, there is a problem in both lines of this suggestion.
The only problem is that you ran from your own build. Once running from an installed layout (which you can now easily generate with python.bat PC\layout --preset-default --copy <outdir>
), the comparison will be fine.
I think it's fair to assume that the new users we are concerned about are *not* building Python from source :)
Otherwise, there's still my suggestion of a command line option to specify the start directory - e.g. --start-in-home - that we can put into the shortcut so it only affects GUI launches and not command line launches. (Though this idea may not be possible with the Store package, as the shortcut is the same for both Start and command line.)
Besides those two options, I don't know of another way to make this work. So we either need to choose one of them, choose not to fix it, or wait for someone to come up with something new.
NameError: name 'get_default_location' is not defined
Also, this was a hypothetical function that you would implement in IDLE to determine whatever the default location ought to be. I'm personally happy to stay out of that part of the argument.
An implementation note mostly to myself: In 3.8 and before, 'python relative/path/to/file.py' results in the __file attribute of the main module being the relative path, and a possibly unnormalized full path is os.curdir + __file. I believe that this is the only situation in which __file is not absolute. After os.chdir(new cwd), relative __file becomes useless unless the original curdir is saved or __file is made absolute first. The startup part of pyshell has this vulnerable line. icondir = os.path.join(os.path.dirname(file__), 'Icons') But with curdir left alone when starting from a command line, there will be no problem.
See also bpo-38775 about a configuration option. The two proposals need to be coordinated.
bpo-39927 is about changing the Mac-specific chdir hidden away in Mac/IDLE/IDLE.app/Contents/Resources/idlemain.py, line 8 A generic solution should supercede that.
Recap and proposal
When editing a named file, Open and Save start in the directory of that file. Running a file sets the initial working directory of the execution process, which affects imports in the code.
We are here discussing the working directory for the IDLE process. This affects a. the working directory for interactive code entered without having first run from the editor; b. the start directory for Open and Save in both Shell and any untitled editor windows.
When IDLE is started with command line 'python -m idlelib', its working directory is that of the console. We agree that IDLE should not change this. In this case, sys.stdout is not None. (The exception is when one starts with pythonw, which which is normally useless in the console.)
When IDLE is started Windows Explorer by right clicking a file and selecting 'Edit with IDLE' its working directory is the same as the file. I propose that IDLE should not change the directory in this case either. In this case, there is at least one filename in sys.args, which IDLE parses anyway.
I initially considered this issue to be about changing the installed Start menu shortcut. But it was suggested that IDLE code might be better. Adding a configuration option would require this. Such code would also not be limited to Windows. I am currently thinking of something like
if sys.stdout is None and no file in sys.argv:
start_dir = idleConf(...) python/issues-test-cpython#28775, default None?.
if start_dir is None:
start_dir = <system-specific default
try:
chdir(start_dir)
except OSError as e:
<display message>
try:
chdir(expanduser('~'))
except OSError as e:
<display message -- stay with system default>
This might be somehow coordinated with .idlerc location search.
if sys.stdout is None and no file in sys.argv
With the app distribution from the Microsoft Store, "idle3.x.exe" is a GUI executable that runs idlelib. There isn't a console version. Also, GUI scripts are usually run with the pyw.exe launcher or pythonw.exe, e.g. pyw -m idlelib
, to ensure it's not attached to a console session. Otherwise the shell waits for a console app such as py.exe, which blocks the console. Moreover, when a console session is closed, all processes attached to it have 5 seconds to exit before they get terminated. I generally don't want either behavior with a GUI app, except for the case of debugging an application that writes debug output to standard error or standard output. On the other hand, I generally do want to inherit the working directory of the parent process, such as a command-line shell.
I think the problem would be adequately addressed by blacklisting directories that are known to be inappropriate and a common problem, such as sys.prefix and Windows system directories. I agree with the suggestion to automatically change the working directory in such cases to the user's "Documents" directory, i.e. FOLDERID_Documents.
blacklisting directories
Ensure that filepaths in sys.argv are resolved before changing out of a blacklisted directory. Also, for file open/save dialogs, as opposed to the working directory of the Python subprocess (e.g. os.getcwd() in the REPL), it's typical to default to the user profile directory or the last-accessed directory instead of the process working directory.
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields: ```python assignee = 'https://github.com/terryjreedy' closed_at = None created_at =
labels = ['3.8', '3.9', '3.10', 'expert-IDLE', 'type-feature', 'OS-windows']
title = 'Start IDLE from icon in a better place.'
updated_at =
user = 'https://github.com/mark-summerfield'
```
bugs.python.org fields:
```python
activity =
actor = 'eryksun'
assignee = 'terry.reedy'
closed = False
closed_date = None
closer = None
components = ['IDLE', 'Windows']
creation =
creator = 'mark'
dependencies = []
files = []
hgrepos = []
issue_num = 22121
keywords = []
message_count = 28.0
messages = ['224537', '224579', '224581', '224583', '224585', '224587', '253819', '259299', '260069', '329975', '329976', '329977', '330092', '330107', '330108', '330118', '347842', '347849', '347859', '347861', '347894', '347895', '348042', '363882', '364063', '364068', '389630', '389631']
nosy_count = 9.0
nosy_names = ['rhettinger', 'terry.reedy', 'andyharrington', 'mark', 'ned.deily', 'serhiy.storchaka', 'jeff.allen', 'eryksun', 'steve.dower']
pr_nums = []
priority = 'normal'
resolution = None
stage = 'needs patch'
status = 'open'
superseder = None
type = 'enhancement'
url = 'https://bugs.python.org/issue22121'
versions = ['Python 3.8', 'Python 3.9', 'Python 3.10']
```