This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: weird oddity with bz2 context manager
Type: behavior Stage:
Components: Interpreter Core, Library (Lib) Versions: Python 2.7
process
Status: closed Resolution: fixed
Dependencies: Superseder:
Assigned To: Nosy List: Roman Valls, amaury.forgeotdarc, arigo, benjamin.peterson, pitrou
Priority: normal Keywords:

Created on 2010-09-23 17:44 by pitrou, last changed 2022-04-11 14:57 by admin. This issue is now closed.

Messages (7)
msg117210 - (view) Author: Antoine Pitrou (pitrou) * (Python committer) Date: 2010-09-23 17:44
I haven't investigated but this is weird (especially the fact that it doesn't *always* happen). There might be a problem with SETUP_WITH or perhaps the method cache:

>>> import bz2
>>> f = bz2.BZ2File('foo.bz2', 'wb')
>>> with f: pass
... 
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: __exit__
>>> f.__enter__().__exit__(None, None, None)
>>>
msg117211 - (view) Author: Antoine Pitrou (pitrou) * (Python committer) Date: 2010-09-23 17:56
Actually, it is because bz2 doesn't call PyType_Ready() but instead sets some field manually. Perhaps we could have a guard somewhere that raises a fatal error when a C extension type hasn't been properly readied?

In the meantime, this patch seems to solve the issue:

diff -r 843be379fb26 Modules/bz2module.c
--- a/Modules/bz2module.c       Thu Sep 23 18:45:17 2010 +0200
+++ b/Modules/bz2module.c       Thu Sep 23 19:55:19 2010 +0200
@@ -2155,9 +2155,12 @@ PyInit_bz2(void)
 {
     PyObject *m;
 
-    Py_TYPE(&BZ2File_Type) = &PyType_Type;
-    Py_TYPE(&BZ2Comp_Type) = &PyType_Type;
-    Py_TYPE(&BZ2Decomp_Type) = &PyType_Type;
+    if (PyType_Ready(&BZ2File_Type) < 0)
+        return NULL;
+    if (PyType_Ready(&BZ2Comp_Type) < 0)
+        return NULL;
+    if (PyType_Ready(&BZ2Decomp_Type) < 0)
+        return NULL;
 
     m = PyModule_Create(&bz2module);
     if (m == NULL)
msg117212 - (view) Author: Benjamin Peterson (benjamin.peterson) * (Python committer) Date: 2010-09-23 18:06
2010/9/23 Antoine Pitrou <report@bugs.python.org>:
>
> Antoine Pitrou <pitrou@free.fr> added the comment:
>
> Actually, it is because bz2 doesn't call PyType_Ready() but instead sets some field manually. Perhaps we could have a guard somewhere that raises a fatal error when a C extension type hasn't been properly readied?

The problem is that there's no one entry point for types to get into
the C-API. I suppose we could iterate through a c-module's dictionary
after it's initialized...

>
> In the meantime, this patch seems to solve the issue:

Please apply.
msg117228 - (view) Author: Antoine Pitrou (pitrou) * (Python committer) Date: 2010-09-23 20:18
Patch committed in r84980 (3.2), r84981 (3.1) and r84982 (2.7).
msg251415 - (view) Author: Roman Valls (Roman Valls) Date: 2015-09-23 08:16
It still seems to be failing with Python 2.7.10... or am I doing sth wrong? :/


$ ipython
Python 2.7.10 |Anaconda 2.2.0 (x86_64)| (default, May 28 2015, 17:04:42)
Type "copyright", "credits" or "license" for more information.

IPython 4.0.0 -- An enhanced Interactive Python.
?         -> Introduction and overview of IPython's features.
%quickref -> Quick reference.
help      -> Python's own help system.
object?   -> Details about 'object', use 'object??' for extra details.

In [1]: import bz2
In [2]: import pandas as pd
In [3]: import numpy as np
In [4]: import matplotlib as plt
In [5]: import seaborn as sns
In [6]: import cPickle as pickle

In [7]: with open("./collectl_info.pickle.bz2", "rb") as comp:
   ...:         with bz2.decompress(comp.read()) as decomp:
   ...:                 data, hardware, steps = pickle.load(decomp)
   ...:

---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-7-301445b9c3f1> in <module>()
      1 with open("./collectl_info.pickle.bz2", "rb") as comp:
----> 2         with bz2.decompress(comp.read()) as decomp:
      3                 data, hardware, steps = pickle.load(decomp)
      4

AttributeError: __exit__
msg251430 - (view) Author: Armin Rigo (arigo) * (Python committer) Date: 2015-09-23 14:43
Roman: bz2.decompress(comp.read()) returns a string, so you can't use "with" on it.  This bug was about using "with bz2.BZ2File(...) as f:".
msg251431 - (view) Author: Roman Valls (Roman Valls) Date: 2015-09-23 14:51
Gotcha, sorry about that :-S

On Wed, Sep 23, 2015 at 4:43 PM, Armin Rigo <report@bugs.python.org> wrote:
>
> Armin Rigo added the comment:
>
> Roman: bz2.decompress(comp.read()) returns a string, so you can't use "with" on it.  This bug was about using "with bz2.BZ2File(...) as f:".
>
> ----------
>
> _______________________________________
> Python tracker <report@bugs.python.org>
> <http://bugs.python.org/issue9928>
> _______________________________________
History
Date User Action Args
2022-04-11 14:57:06adminsetgithub: 54137
2015-09-23 14:51:53Roman Vallssetmessages: + msg251431
2015-09-23 14:43:13arigosetmessages: + msg251430
2015-09-23 08:16:46Roman Vallssetnosy: + Roman Valls

messages: + msg251415
versions: - Python 3.1, Python 3.2
2015-06-08 01:07:31ned.deilylinkissue24404 superseder
2010-09-23 20:18:02pitrousetstatus: open -> closed
resolution: fixed
messages: + msg117228
2010-09-23 18:06:32benjamin.petersonsetmessages: + msg117212
2010-09-23 17:56:16pitrousetmessages: + msg117211
versions: + Python 3.1, Python 2.7
2010-09-23 17:44:16pitroucreate