Following the plan for the complete transition to the new (PEP8 compliant) API, all calls to the old API will raise a DeprecationWarning.
The new API has been introduced in PyTables 3.0 and is backward incompatible. In order to guarantee a smoother transition the old API is still usable even if it is now deprecated.
The plan for the complete transition to the new API is outlined in gh-224.
In PyTables <= 3.0 file handles (objects that are returned by the open_file() function) were stored in an internal registry and re-used when possible.
Two subsequent attempts to open the same file (with compatible open mode) returned the same file handle in PyTables <= 3.0:
In [1]: import tables
In [2]: print(tables.__version__)
3.0.0
In [3]: a = tables.open_file('test.h5', 'a')
In [4]: b = tables.open_file('test.h5', 'a')
In [5]: a is b
Out[5]: True
All this is an implementation detail, it happened under the hood and the user had no control over the process.
This kind of behaviour was considered a feature since it can speed up opening of files in case of repeated opens and it also avoids any potential problem related to multiple opens, a practice that the HDF5 developers recommend to avoid (see also H5Fopen reference page).
The trick, of course, is that files are not opened multiple times at HDF5 level, rather an open file is referenced several times.
The big drawback of this approach is that there are really few chances to use PyTables safely in a multi thread program. Several bug reports have been filed regarding this topic.
After long discussions about the possibility to actually achieve concurrent I/O and about patterns that should be used for the I/O in concurrent programs PyTables developers decided to remove the black magic under the hood and allow the users to implement the patterns they want.
Starting from PyTables 3.1 file handles are no more re-used (shared) and each call to the open_file() function returns a new file handle:
In [1]: import tables
In [2]: print tables.__version__
3.1.0
In [3]: a = tables.open_file('test.h5', 'a')
In [4]: b = tables.open_file('test.h5', 'a')
In [5]: a is b
Out[5]: False
It is important to stress that the new implementation still has an internal registry (implementation detail) and it is still not thread safe. Just now a smart enough developer should be able to use PyTables in a muti-thread program without too much headaches.
The new implementation behaves differently from the previous one, although the API has not been changed. Now users should pay more attention when they open a file multiple times (as recommended in the HDF5 reference ) and they should take care of using them in an appropriate way.
Please note that the File.open_count property was originally intended to keep track of the number of references to the same file handle. In PyTables >= 3.1, despite of the name, it maintains the same semantics, just now its value should never be higher that 1.
Note
HDF5 versions lower than 1.8.7 are not fully compatible with PyTables 3.1. A partial support to HDF5 < 1.8.7 is still provided but in that case multiple file opens are not allowed at all (even in read-only mode).