Repository: rootpy/rootpy

Issue:
rootpy.ROOT TFile wrapper problem
``` python
with ROOT.TFile("./a.root","recreate") as of:
    pass
```

``` python
Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
  File "/usr/lib/python2.7/site-packages/rootpy/io/file.py", line 225, in __exit__
    self.Close()
  File "/usr/lib/python2.7/site-packages/rootpy/io/file.py", line 254, in Close
    return self.cd_previous()
  File "/user/lib/python2.7/site-packages/rootpy/io/file.py", line 232, in cd_previous
    if isinstance(self._prev_dir, ROOT.TROOT):
  File "/usr/lib/python2.7/site-packages/rootpy/io/file.py", line 188, in __getattr__
    "{0} has no attribute '{1}'".format(self, attr))
AttributeError: File('./a.root') has no attribute '_prev_dir'
```

I simply add:

``` python
#rootpy/io/file.py: line 248
     def Close(self, *args):
        """
        Like ROOT's Close but reverts to the gDirectory before this file was
        opened.
        """
        super(_DirectoryBase, self).Close(*args)

        - return self.cd_previous()
        + try:
        +     return self.cd_previous()
        + except AttributeError:
        +     return False
```

to make it work now. Hope it can get fixed before long.



Discussion:
You must be using rootpy's ROOT wrapper like this:

``` python
from rootpy import ROOT

with ROOT.TFile("./a.root","recreate") as of:
    pass
```

I'll fix that bug, but instead it would be more ideal to do the following:

``` python
from rootpy.io import root_open

with root_open("./a.root", "recreate") as of:
    pass
```

This works, as it always has...


Resolving patch:
diff --git a/rootpy/io/file.py b/rootpy/io/file.py
--- a/rootpy/io/file.py
+++ b/rootpy/io/file.py
@@ -229,7 +229,7 @@ def cd_previous(self):
         """
         cd to the gDirectory before this file was open.
         """
-        if isinstance(self._prev_dir, ROOT.TROOT):
+        if self._prev_dir is None or isinstance(self._prev_dir, ROOT.TROOT):
             return False
         if isinstance(self._prev_dir, ROOT.TFile):
             if self._prev_dir.IsOpen() and self._prev_dir.IsWritable():
@@ -627,13 +627,17 @@ class Directory(_DirectoryBase, QROOT.TDirectoryFile):
     def __init__(self, name, title=None, classname='', parent=None):
         if title is None:
             title = name
+        # grab previous directory before creating self
+        self._prev_dir = ROOT.gDirectory.func()
+        self._parent = parent or self._prev_dir
         super(Directory, self).__init__(name, title, classname, parent or 0)
         self._post_init()
 
     def _post_init(self):
         self._path = self.GetName()
-        self._parent = ROOT.gDirectory.func()
-        self._prev_dir = None
+        # need to set _prev_dir here again if using rootpy.ROOT.TDirectory
+        self._prev_dir = getattr(self, '_prev_dir', None)
+        self._parent = getattr(self, '_parent', self._prev_dir)
         self._inited = True
 
 
@@ -642,12 +646,15 @@ class _FileBase(_DirectoryBase):
     def __init__(self, name, *args, **kwargs):
         # trigger finalSetup
         ROOT.R.kTRUE
+        # grab previous directory before creating self
         self._prev_dir = ROOT.gDirectory.func()
         super(_FileBase, self).__init__(name, *args, **kwargs)
         self._post_init()
 
     def _post_init(self):
         self._path = self.GetName()
+        # need to set _prev_dir here again if using rootpy.ROOT.TFile
+        self._prev_dir = getattr(self, '_prev_dir', None)
         self._parent = self
         self._inited = True
 


Test patch:
diff --git a/rootpy/io/tests/test_file.py b/rootpy/io/tests/test_file.py
--- a/rootpy/io/tests/test_file.py
+++ b/rootpy/io/tests/test_file.py
@@ -45,6 +45,8 @@ def test_file_open():
         pass
     with root_open(fname):
         pass
+    with ROOT.TFile(fname, 'recreate') as f:
+        assert_true(isinstance(f, File))
     os.unlink(fname)