{"action":"created","issue":{"url":"https://api.github.com/repos/choderalab/openpathsampling/issues/187","labels_url":"https://api.github.com/repos/choderalab/openpathsampling/issues/187/labels{/name}","comments_url":"https://api.github.com/repos/choderalab/openpathsampling/issues/187/comments","events_url":"https://api.github.com/repos/choderalab/openpathsampling/issues/187/events","html_url":"https://github.com/choderalab/openpathsampling/issues/187","id":64777246,"number":187,"title":"Handle already-open file (for interactive use)","user":{"login":"dwhswenson","id":8178546,"avatar_url":"https://avatars.githubusercontent.com/u/8178546?v=3","gravatar_id":"","url":"https://api.github.com/users/dwhswenson","html_url":"https://github.com/dwhswenson","followers_url":"https://api.github.com/users/dwhswenson/followers","following_url":"https://api.github.com/users/dwhswenson/following{/other_user}","gists_url":"https://api.github.com/users/dwhswenson/gists{/gist_id}","starred_url":"https://api.github.com/users/dwhswenson/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dwhswenson/subscriptions","organizations_url":"https://api.github.com/users/dwhswenson/orgs","repos_url":"https://api.github.com/users/dwhswenson/repos","events_url":"https://api.github.com/users/dwhswenson/events{/privacy}","received_events_url":"https://api.github.com/users/dwhswenson/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":{"login":"jhprinz","id":5091934,"avatar_url":"https://avatars.githubusercontent.com/u/5091934?v=3","gravatar_id":"","url":"https://api.github.com/users/jhprinz","html_url":"https://github.com/jhprinz","followers_url":"https://api.github.com/users/jhprinz/followers","following_url":"https://api.github.com/users/jhprinz/following{/other_user}","gists_url":"https://api.github.com/users/jhprinz/gists{/gist_id}","starred_url":"https://api.github.com/users/jhprinz/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jhprinz/subscriptions","organizations_url":"https://api.github.com/users/jhprinz/orgs","repos_url":"https://api.github.com/users/jhprinz/repos","events_url":"https://api.github.com/users/jhprinz/events{/privacy}","received_events_url":"https://api.github.com/users/jhprinz/received_events","type":"User","site_admin":false},"milestone":null,"comments":5,"created_at":"2015-03-27T14:54:39Z","updated_at":"2015-04-06T20:33:45Z","closed_at":null,"body":"This isn’t terribly important, but is there any way to catch the case that a netCDF file has already been opened for writing?\r\n\r\nThe problem I occasionally hit is that, when working interactively in an ipynb, I try to open storage twice. One hack around this is to try to close the storage, catch and silently pass any NameError, and then open the storage. But that’s ugly and very distracting. Bad if we want the ipynb to also serve as user-facing documentation.\r\n\r\nIn my dream world, there’s a way to return the already-opened pointer. But maybe instead there’s a way to force close any other pointer to that file, and open a new one?\r\n\r\nNetCDF raises a `RuntimeError: Permission denied`, so I assume you’d need another try-except inside the catching of that exception (for cases where it is really permission, and not a lock on an already-opened file)."},"comment":{"url":"https://api.github.com/repos/choderalab/openpathsampling/issues/comments/90231498","html_url":"https://github.com/choderalab/openpathsampling/issues/187#issuecomment-90231498","issue_url":"https://api.github.com/repos/choderalab/openpathsampling/issues/187","id":90231498,"user":{"login":"dwhswenson","id":8178546,"avatar_url":"https://avatars.githubusercontent.com/u/8178546?v=3","gravatar_id":"","url":"https://api.github.com/users/dwhswenson","html_url":"https://github.com/dwhswenson","followers_url":"https://api.github.com/users/dwhswenson/followers","following_url":"https://api.github.com/users/dwhswenson/following{/other_user}","gists_url":"https://api.github.com/users/dwhswenson/gists{/gist_id}","starred_url":"https://api.github.com/users/dwhswenson/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dwhswenson/subscriptions","organizations_url":"https://api.github.com/users/dwhswenson/orgs","repos_url":"https://api.github.com/users/dwhswenson/repos","events_url":"https://api.github.com/users/dwhswenson/events{/privacy}","received_events_url":"https://api.github.com/users/dwhswenson/received_events","type":"User","site_admin":false},"created_at":"2015-04-06T20:33:44Z","updated_at":"2015-04-06T20:33:44Z","body":"@jchodera : I like the premise of your suggestion, but it would still require some extra \"all files handler\" to deal with the problem. If I understand correctly, your suggestion boils down to using the \"r\" and \"a\" modes as they already exist, and splitting \"w\" into two cases: \"w\" as it already behaves, and \"new\", where \"new\" raises an error if the file exists.\r\n\r\nBut this does still require some handler to manage all files, because without it the following will error:\r\n\r\n```python\r\nstorage1 = paths.storage.Storage(\"toy_equil.nc\", \"w\", template=template)\r\nstorage2 = paths.storage.Storage(\"toy_equil.nc\", \"w\", template=template)\r\n```\r\n\r\nEven if we assume that the user meant to do `storage1.close()` between those lines, the NetCDF error that comes out of that is \"Permission denied\". I don't know if there's an easy way to catch that error and distinguish between that case and the error you'd get from:\r\n\r\n```python\r\nstorage = paths.storage.Storage(\"/etc/passwd\", \"w\", template=template)\r\n```\r\n\r\nEven if you manage that (I guess by retesting permissions in the `except` block?) you'd still be unable to return the existing pointer.\r\n\r\nBut as I said in my comment above, I think the current work-around is good enough. As far as I'm concerned, this issue can be closed."}}