BUG: properly close files opened by parsers
State: closed

- [x] closes #13932 
- [x] tests passed
- [x] passes `git diff upstream/master | flake8 --diff`
- [x] whatsnew entry

Addresses all ~~most~~ of the `ResourceWarning`s from #13932. There were three tests that opened files but did not close them. The rest were due to parsers (`CParserWrapper` and `PythonParser`) opening files or streams but never closing them. There was one case &mdash; the `mmap` one &mdash; that was tricky because there was a file handle going into it and immediately reaching a refcount of zero.

I am at a loss about writing new tests for this. Is it even possible?


Labels:
name: IO CSV
description: read_csv, to_csv
name: IO Stata
description: read_stata, to_stata
name: Clean

Comments:
Argh, there are still some `ResourceWarning`s left... Let me investigate.

@agraboso looks a lot cleaner! https://travis-ci.org/pydata/pandas/jobs/150768150

you can leave the mmap one (if its not easy to fix). If you can get the stata ones would be great!.

## [Current coverage](https://codecov.io/gh/pydata/pandas/pull/13940?src=pr) is 85.31% (diff: 61.44%)

> Merging [#13940](https://codecov.io/gh/pydata/pandas/pull/13940?src=pr) into [master](https://codecov.io/gh/pydata/pandas/branch/master?src=pr) will increase coverage by **0.02%**

``` diff
@@             master     #13940   diff @@
==========================================
  Files           139        139          
  Lines         50162      50370   +208   
  Methods           0          0          
  Messages          0          0          
  Branches          0          0          
==========================================
+ Hits          42785      42975   +190   
- Misses         7377       7395    +18   
  Partials          0          0          
```

> Powered by [Codecov](https://codecov.io?src=pr). Last update [5df9123...3fa7d25](https://codecov.io/gh/pydata/pandas/compare/5df9123e09168e130af0e73ba335d82f5c1a8d46...3fa7d25a00372a1312cd8fad0a82082e997f51a4?src=pr)

@jreback The `mmap` one is fixed since the first commit &mdash; I was just making the point that it took me a while to understand what was wrong.

I have fixed the `stata` cases too:
- `StataWriter` was easy: I moved the opening of the file to the [`write_file`](https://github.com/agraboso/pandas/blob/509e2e628d8447198ef90bd63c8912e434beafa4/pandas/io/stata.py#L2078-L2093) method. The file is thus always opened and closed within it, whether errors are raised or not.
- `StataReader` did not close the file when raising an error. I fixed it by wrapping most of the logic in its [`read`](https://github.com/agraboso/pandas/blob/509e2e628d8447198ef90bd63c8912e434beafa4/pandas/io/stata.py#L1406) method in a `try/except` block. This even takes care of closing the file when a `StopIteration` is raised.

I don't want to just wrap things at a high level, these should be as granular as possible.These can be actual errors (or errors in the tests, its hard to tell). Let uncaught resource warnings show thru (and then can investigate these individually). 

Notice that my proposal of wrapping most of `StataReader.read` in a `try/except` block had both a `self.close()` and a `raise`, so that we would still see all warnings and errors while making sure we do close the file.

hah! this turned into a rabbit hole!. lmk when you are ready.

> hah! this turned into a rabbit hole!

Tell me about it! It's possible that other parsers leave open files too, but I'd leave that for another PR. I think this one is ready.

> lmk when you are ready.

And it's all green!

thanks @agraboso I merged. left a couple comments that might be relevant for next PR :)

we need to try to fix remaining `ResourceWarnings` then raise if ANY are detected (its actually pretty easy). in `pandas.util.testing.TestCase.setUpClass` you can set the warning to error. This way its not set globally when `testing_mode()` is called (in case testing is just imported by a user and not actually run in the test suite).