Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unable to run IDLE without write-access to home directory #52478

Closed
cane mannequin opened this issue Mar 25, 2010 · 36 comments
Closed

Unable to run IDLE without write-access to home directory #52478

cane mannequin opened this issue Mar 25, 2010 · 36 comments
Assignees
Labels
3.7 (EOL) end of life topic-IDLE type-feature A feature request or enhancement

Comments

@cane
Copy link
Mannequin

cane mannequin commented Mar 25, 2010

BPO 8231
Nosy @terryjreedy, @ned-deily, @serwy, @asvetlov, @roseman, @mlouielu
PRs
  • bpo-8231: Call idlelib.IdleConf.GetUserCfgDir only once. #2629
  • [3.6] bpo-8231: Call idlelib.IdleConf.GetUserCfgDir only once. (GH-2629) #2631
  • Dependencies
  • bpo-25507: IDLE: user code 'import tkinter; tkinter.font' should fail
  • bpo-27534: IDLE: Reduce number and time for user process imports
  • Files
  • error.png: Error message
  • @cfgdir.diff: Use temp dir as backup user config dir.
  • @cfgdir2.diff
  • 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:

    assignee = 'https://github.com/terryjreedy'
    closed_at = None
    created_at = <Date 2010-03-25.15:39:27.987>
    labels = ['expert-IDLE', 'type-feature', '3.7']
    title = 'Unable to run IDLE without write-access to home directory'
    updated_at = <Date 2017-12-30.20:56:29.287>
    user = 'https://bugs.python.org/cane'

    bugs.python.org fields:

    activity = <Date 2017-12-30.20:56:29.287>
    actor = 'ned.deily'
    assignee = 'terry.reedy'
    closed = False
    closed_date = None
    closer = None
    components = ['IDLE']
    creation = <Date 2010-03-25.15:39:27.987>
    creator = 'cane'
    dependencies = ['25507', '27534']
    files = ['16649', '40872', '40893']
    hgrepos = []
    issue_num = 8231
    keywords = ['patch']
    message_count = 34.0
    messages = ['101708', '101716', '156771', '156773', '156774', '188115', '222687', '222694', '222709', '222716', '252042', '253404', '253413', '253414', '253561', '253575', '253588', '253604', '253637', '253668', '253681', '253714', '253719', '297255', '297914', '297915', '297923', '297926', '297976', '298023', '301835', '309247', '309250', '309257']
    nosy_count = 9.0
    nosy_names = ['terry.reedy', 'ned.deily', 'roger.serwy', 'asvetlov', 'markroseman', 'cane', 'John Gray', 'tealduck', 'louielu']
    pr_nums = ['2629', '2631']
    priority = 'normal'
    resolution = None
    stage = 'needs patch'
    status = 'open'
    superseder = None
    type = 'enhancement'
    url = 'https://bugs.python.org/issue8231'
    versions = ['Python 3.6', 'Python 3.7']

    @cane
    Copy link
    Mannequin Author

    cane mannequin commented Mar 25, 2010

    When trying to run Python 2.6.5 & 3.1 IDLE GUI on Windows 7, I receive the following error that the "IDLE's subprocess didnt make connection. Either IDLE can't start a subprocess or personal firewall software is blocking the connection."

    I've researched this error and tried following the steps to troubleshoot this error without any success. I do not have any firewall software installed or have the Microsoft firewall enabled. When following bpo-8099 and tring to set the TCL and TK library to the idle.py I get the error that I need to check the path and permissions. (see attached screenshot)

    These workstations are setup in active directory enviroment where each username that logs into the workstation is a local administrator and the referenced "M:\" drive is a home directory that is mapped for them.

    When the local administrator account logs into the workstation the user can execute the IDLE GUI without any issues.

    I found reference in one article that the os.py creates a directory called ".idlerc".

    I'm wondering if there is a way to hardcode a reference path that doesnt point to my "M:\" drive for this directory or is there something else that I can try to fix this issue?

    Thanks,
    Bryan

    @cane cane mannequin added type-crash A hard crash of the interpreter, possibly with a core dump OS-windows labels Mar 25, 2010
    @briancurtin
    Copy link
    Member

    I just reproduced this by removing write access from my user for my home directory.

    It seems odd that you wouldn't have write access to your home directory in the first place, but that's tangent to the issue. I'll see if there are other acceptable locations to attempt to place the config directory.

    @briancurtin briancurtin added the stdlib Python modules in the Lib dir label Mar 25, 2010
    @briancurtin briancurtin changed the title Subprocess Startup Error - unable to create user config directory Unable to run IDLE without write-access to config directory Mar 25, 2010
    @briancurtin briancurtin added type-bug An unexpected behavior, bug, or error and removed type-crash A hard crash of the interpreter, possibly with a core dump labels Mar 25, 2010
    @serwy serwy mannequin added topic-IDLE and removed stdlib Python modules in the Lib dir OS-windows labels Dec 17, 2011
    @asvetlov
    Copy link
    Contributor

    Let's close the issue next week as report doesn't make sense if issuer has no write access to own home dir.

    @briancurtin
    Copy link
    Member

    Please don't close it. Users in this situation can't use IDLE. We should at least try alternative locations to create this directory or perhaps prompt them for a directory they'd like to use.

    @asvetlov
    Copy link
    Contributor

    Good point. Thank you.

    @ned-deily
    Copy link
    Member

    bpo-17864 is a duplicate of this. Also, note the error reported here is a result of IDLE not having write access in the user's home directory and thus cannot create the .idlerc directory. IDLE seems to handle more gracefully the case of .idlerc existing but not writable.

    @ned-deily ned-deily changed the title Unable to run IDLE without write-access to config directory Unable to run IDLE without write-access to home directory Apr 29, 2013
    @terryjreedy
    Copy link
    Member

    I think the proper solution is to warn "Cannot write .idlerc to your home directory. Settings will not be saved." and continue.

    @terryjreedy
    Copy link
    Member

    .idlerc is a directory that contains the user versions of config-xyz.def. There are currently 4, another will probably be added. The 'offending' code is in configHandler.IdleConf.GetUserCfgDir() (line 195).
    if not os.path.exists(userDir):
    try:
    os.mkdir(userDir)
    except OSError:
    warn = ('\n Warning: unable to create user config directory\n'+
    userDir+'\n Check path and permissions.\n Exiting!\n\n')
    sys.stderr.write(warn)
    raise SystemExit

    The last line could be replaces by 'return None'. The calling code that uses the normal return would have to be changed to skip trying to read and write the config files. According to Ned, Idle already manages if .idlerc exists but is unwritable.

    The recent files list and breakpoint lists are also stored in .idlerc. Here are the 4 hits for 'GetUserCfgDir' in C:\Programs\Python34\Lib\idlelib\*.py ...

    EditorWindow.py: 145: self.recent_files_path = os.path.join(idleConf.GetUserCfgDir(),
    PyShell.py: 131: self.breakpointPath = os.path.join(idleConf.GetUserCfgDir(),
    configHandler.py: 184: userDir=self.GetUserCfgDir()
    configHandler.py: 195: def GetUserCfgDir(self):

    While Idle could continue without any of these, I like Brian's idea of asking for an alternative first. Actually, if there is no 'home' directory (if expanduser('~') below fails), Idle already tries the current directory as a backup. It could do the same if a home directory exits but is unusable.

    How far should we go with this? A command-line option to set the user cfg dir? That should be doable.

    I thought about a new idlelib/config-users.def mapping users to directories, but that has its own problems of write permission, as will as cross-platform access to user name.

    The OP (Bryan) asked "[is] there is a way to hardcode a reference path that doesnt point to my "M:\" drive for this directory[?]" Yes. GetUserCfgDir starts with
    cfgDir = '.idlerc'
    userDir = os.path.expanduser('~')
    Replace the second line, after each install, to point to a writable directory.

    @ned-deily
    Copy link
    Member

    The use case reported here sounds like a classroom or lab environment with many people (and likely novices) using open environment machines. In such cases, if users don't have write access to their home directories, it seems to me that there's no need to try to preserve IDLE configurations across sessions. Asking the user for another location in such cases would be confusing and add needless complexity. I'd say either just create a temporary directory or create the config files as temporary files as needed. For advanced users, I suppose a command line option could be added but has there been any demand for such a feature?

    @terryjreedy
    Copy link
    Member

    I don't know of any request for a new option, so I would go for something simple that lets Idle run. Temporary files are a good idea for breakpoints (temporary anyway, I think) and maybe for recent files.

    @JohnGray
    Copy link
    Mannequin

    JohnGray mannequin commented Oct 1, 2015

    See bpo-14576 which is the same underlying issue.

    @tealduck
    Copy link
    Mannequin

    tealduck mannequin commented Oct 24, 2015

    I would also like to add that the location of this directory is not correct for Windows software. This directory should be created in %APPDATA% where users by default do have write permissions.

    If there are plans to ever make this application portable then it should support a command line option to specify the location of the configuration as well.

    @terryjreedy
    Copy link
    Member

    Idle is not unique. Several other apps ported from unix also put .xyx files in the home directory on Windows. What is unusual, if not unique, about IDLE is the need to run multiple versions. If .idlerc is moved, already released versions will not be able to access it. I am not ready to make a break yet. In any case, moving it to a subdirectory of $HOME will not solve this issue, which is not being able to write to $HOME, and it therefore a different issue.

    @tealduck
    Copy link
    Mannequin

    tealduck mannequin commented Oct 24, 2015

    Hi Terry,

    I did not just make that stuff up on my last post, that is actually the standard for Windows applications. Yes, many Linux ports get it wrong but is that any reason to ever perpetuate a bad practice?

    To see the standards you can download the Windows SDK but to make things easier for you here is a link that talks about this: http://blogs.msdn.com/b/patricka/archive/2010/03/18/where-should-i-store-my-data-and-configuration-files-if-i-target-multiple-os-versions.aspx

    By using non-standard conventions the application is just asking for trouble like what is being manifested with this issue. Users will be able to write to their %APPDATA% area, no administrator would lock that down as it would cause too many applications to fail (Kiosk type installations not included).

    @roseman
    Copy link
    Mannequin

    roseman mannequin commented Oct 27, 2015

    Can I suggest that this issue continues to be about IDLE not being able to write its preferences directory/files due to permissions, and we create a new issue for the fact that IDLE is storing it in the wrong place under Windows?

    @terryjreedy
    Copy link
    Member

    Yes, that is what this issue *is* about. IDLE, like Python itself, expects to be run on machines that users can write to normally, that have not been crippled by bureaucratic policies, or by users. The editor is useless if the user cannot write files somewhere. None of this is specific to Windows.

    Ned's idea of a temporary directory seems easy. Change the warning and replace'raise SystemExit' with 'td = tempfile.TemporaryDirectory(); userDir = td.name' (see msg222694). For 2.7, however, TemporayDirectory is not available. For the underlying mkdtemp, the user "is responsible for deleting the temporary directory and its contents when done with it." (I presume failure of apps to do this is why temp file cleanup is needed.) My inclination for 2.7 would be to copy a stripped down copy of TemporaryDirectory with just the finalizer code. In fact, since we do not need or want the implicit cleanup warning (do we?), we could do that for all versions.

    We do not have to accommodate all possibilities. One report, possibly on Stackoverflow, was from a user whose home dir and, I presume, appdata dir, were on a remote server. Maybe he also had an offline home dir, I don't remember. In any case, IDLE was not happy with the setup.

    As I said before, permanently and unconditionally moving user config files on Windows will break compatibility with all previous releases, so I would not do that unless we decide to break compatibility anyway, for reasons other than MS's recommendations. However, after a general solution is applied we could consider in a separate issue using Appdata as future-looking, Windows-specific alternative to a temporary directory. However, this would require careful though lest we end up with two userdirs because the non-writability of homedir is only temporary.

    @terryjreedy terryjreedy added type-feature A feature request or enhancement and removed type-bug An unexpected behavior, bug, or error labels Oct 28, 2015
    @terryjreedy
    Copy link
    Member

    Attached is a patch that I think will work. I have not tested it because I do not know how to make my home directory, and only my home directory, read-only.

    Brian, how did you do it? I now have Win 10.

    When I rt click user/terry and select properties, there is a tri-state box "[ ] Read-only (Only applies to files in folder)". It initially has a solid square, and changes to blank and checkmark. Try to apply, there is an unselectable grayed-out choice to apply to the directory only and a mandatory choice to also apply recursively to all files and subdirectories. I am loath to do this since there are 47000 files (40000 in appdate, which seems grossly excessive, but that is the report)

    I would like this tested anyway at least once on linux and mac. Testing procedure: change name of .idlerc, lock home dir, run installed IDLE from command line. Should exit with message. Run patched repository IDLE. Should run, reporting temp dir and deleting it on exit. (Unlock home dir and rename .idlerc back).

    @roseman
    Copy link
    Mannequin

    roseman mannequin commented Oct 28, 2015

    Checked on Linux and Mac - doesn't work correctly. mkdtemp() returns a different name every time it's called, and GetUserCfgDir() is called in three places, meaning we end up with three different tmp directories (which on quick examination didn't all get cleaned up at end).

    I'd suggest changing it so that GetUserCfgDir() caches its result and returns the cached version on subsequent calls. Running out the door so don't have time to try this myself right now...

    @roseman
    Copy link
    Mannequin

    roseman mannequin commented Oct 28, 2015

    Just a note that the 'store things in APPDATA' is issue bpo-24765

    @terryjreedy
    Copy link
    Member

    OK: call GetUserCfgDir once on creation of idleConf instance and set .userdir attribute. Replace repeated calls in PyShell and Editor with attributes accesses. I tested that, with patch, IDLE starts and rewrites both breakpoints.lst and recent-files.lst as appropriate.

    @roseman
    Copy link
    Mannequin

    roseman mannequin commented Oct 29, 2015

    Better, but alas still not quite. On further investigation, the issue is that a new instance of idleConf is instantiated in the subprocess, which then calls mkdtemp() returning a different name. You can see this by doing 'restart shell' and noting that it will hit the warning you added in GetUserCfgDir.

    There are multiple places that the subprocess does access preferences, so just eliminating them is probably not the right way to go.

    I'd probably recommend that the user prefs dir be communicated to the subprocess somehow. Two suggestions are via adding a command line parameter where we launch the subprocess (build_subprocess_arglist), or have the subprocess get it via 'remotecall' when it starts up (perhaps in MyHandler.handle). Either way this would then need to be communicated to idleConf so it uses that directory.

    Would there be a preference and/or any other alternatives?

    @terryjreedy
    Copy link
    Member

    I cannot currently think of any reason why the subprocess *needs* to access idleConf, so I want to put this on hold while investigating whether the accesses can be eliminated as part of bpo-25507.

    @terryjreedy
    Copy link
    Member

    Without being able to make my homedir read-only, I don't, of course, see the messages. Since run does not use idleConf (I am now sure), you should have been able to proceed after clicking away the admittedly obnoxious repeat messages. The old extraneous user-process temporary should disappear when you restart. Can you check that?

    @terryjreedy
    Copy link
    Member

    Problems with patching 2.7 are no longer relevant.

    To test, we should refactor config so that the attempt to find and access $HOME and .idlerc are isolated in a function that can be mocked to simulate various problems.

    def get_rc():
       """Return a directory path that is readable and writable.

    If not possible, return an error indicator. <to be determined>
    """

    Testing such a function is a different issue, but I would just reuse existing code.

    @terryjreedy terryjreedy added the 3.7 (EOL) end of life label Jun 29, 2017
    @terryjreedy terryjreedy self-assigned this Jun 29, 2017
    @terryjreedy
    Copy link
    Member

    GetUserCfgDir() is called in three places, (buried in one of Mark's posts). On the fact of it, this seems like something that should be fixed.

    @terryjreedy
    Copy link
    Member

    My second patch did fix that. I think I will extract that part immediately.

    @terryjreedy
    Copy link
    Member

    New changeset 223c7e7 by terryjreedy in branch 'master':
    bpo-8231: Call idlelib.IdleConf.GetUserCfgDir only once. (bpo-2629)
    223c7e7

    @terryjreedy
    Copy link
    Member

    New changeset 552f266 by terryjreedy in branch '3.6':
    [3.6] bpo-8231: Call idlelib.IdleConf.GetUserCfgDir only once. (GH-2629) (bpo-2631)
    552f266

    @terryjreedy
    Copy link
    Member

    bpo-27534 is about reducing the imports into the user runcode process. Without rechecking the reason for each import, I think it possible that this might result in config not being indirectly imported.

    @mlouielu
    Copy link
    Mannequin

    mlouielu mannequin commented Jul 10, 2017

    How about only taking warning when not able to create dir at GetUserCfgDir(), then take the permission handler in other place?

    e.g. when user trying to save the config in bad dir, pop-out a dialog to tell it is permission problem or dir not eixsts...etc.

    @terryjreedy
    Copy link
    Member

    I closed bpo-30918 as a duplicate of this. It has full 'set' and expanduser info.

    @terryjreedy
    Copy link
    Member

    Another duplicate: bpo-32411, MacOS 10.3.1, user apparently cannot write to home dir. Starting IDLE in terminal results in

    Warning: unable to create user config directory
    /Users/Steve Margetts/.idlerc
    Check path and permissions.
    Exiting!

    @terryjreedy
    Copy link
    Member

    Ned diagnosed bpo-32447 as likely due to the space in the user name. What matters for this issue is that a) someone can do that and b) IDLE likely could continue running anyway. There might then be problems with saving files from the editor, so any warning message should include that possibility.

    @ned-deily
    Copy link
    Member

    Ned diagnosed bpo-32447 as likely due to the space in the user name.

    Actually, that's not what the primary problem was. It was a severely misconfigured home directory, both permissions and groups. I'm not sure how that situation was created (possibly through inadvertent sysadmin commands from the shell) but it's not something that IDLE needs to worry about; such a configuration breaks lots of other system programs. In other words, the OP's system was broken.

    @ezio-melotti ezio-melotti transferred this issue from another repository Apr 10, 2022
    @erlend-aasland
    Copy link
    Contributor

    IDLE now prints a user friendly warning when trying to start it with a read-only home directory; see #52478 (comment).

    Suggesting to close this, as the OP problem seems resolved. If other improvements are needed, I suggest to create targeted, narrow issues for each of these.

    @terryjreedy
    Copy link
    Member

    Given Ned's comment and that improvements were made both here and on two other issues, agreed.

    Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
    Labels
    3.7 (EOL) end of life topic-IDLE type-feature A feature request or enhancement
    Projects
    Status: Done
    Development

    No branches or pull requests

    5 participants