<p>I also figured out another way to fix this problem. After going back to the tutorial I was talking about I saw that it was made back in 2021. After seeing this I wonder if we were using the same verions of each package, turns out we were not. I'm not sure what version of nglview they were using, but they were using biopython 1.79 which was the latest verion back in 2021 and I was using biopython 1.80. While using biopython 1.80 I was getting the error seen above. But now that I'm using biopython 1.79 I get this
<a href="https://i.sstatic.net/iRzUG.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/iRzUG.png" alt="enter image description here" /></a></p>
<p>So I guess there is something going on with biopython 1.80, so I'm going to stick with 1.79</p>

CC BY-SA 4.0
2022-12-13T17:36:55.103Z
Thanks, for posting back a solution. Could you kindly upvote @pippo1980's response please? I'm not an expert, by any means, but it looks to be a good response to me. Certainly useful.
M__
CC BY-SA 4.0
2022-12-14T12:40:11.880Z
yep, same happens with my error, it goes away if I use biopython 1.79
pippo1980
CC BY-SA 4.0
2022-12-13T17:21:36.050Z
2022-12-13T17:21:36.050Z
Jeremiah Wade
<p>This is an issue with Biopython 1.80, in particular introduced by <a href="https://github.com/biopython/biopython/commit/be77131200821bb01254c87fb14ee1bf6c81dd4b" rel="nofollow noreferrer">a commit</a> that automatically closes IO objects sent to <code>PDBIO.save</code>.</p>
<p>I made <a href="https://github.com/biopython/biopython/pull/4200" rel="nofollow noreferrer">a PR</a> to change the behaviour which fixes this issue and should hopefully be in the next Biopython release. Until then, avoiding using Biopython 1.80 should work.</p>
<p>Thanks @jeremiah-wade and @pippo1980 for digging into this.</p>

CC BY-SA 4.0
2022-12-14T23:58:09.417Z
it took You 2 lines to explain what it took me a couple of days to figure out ... . My question is what is / if is there one the pitfall of having unclosed IO objects around ? I am really new to coding and python so in really plain words if you can. thanks again
pippo1980
CC BY-SA 4.0
2022-12-15T00:03:10.757Z
and on the same line, any chance to modifying the nglview adaptor.py  class BiopythonStructure(Structure) ??
pippo1980
CC BY-SA 4.0
2022-12-15T11:59:52.403Z
It's explained a bit in the linked PR but you can't read from a closed `StringIO` object. So if the `PDBIO.save` function closes the object then an error will be thrown when the string is read back. In general closing an IO object is best done with a `with` block or `.close()`, rather than being done silently when the object is given as a function argument. In general the `with` block is better since it's quite common to forget to call `.close()`. Closing IO objects once they are no longer needed frees memory and lets other software use them safely.
jgreener
CC BY-SA 4.0
2022-12-15T15:23:23.833Z
They could just add a if isinstance(filename , StringIO) and close_file = 0 in PDBIO like 1.79 and change close_file = 1 for the #filehandle I hope bit
pippo1980
CC BY-SA 4.0
2022-12-16T12:22:05.710Z
think solution could be like PDBParser handles it: `from Bio.File import as_handle` ,  https://github.com/biopython/biopython/blob/7ef56557bdca66eabd62334e61c4dc3153c997ff/Bio/File.py#L29 and in PDBIO.py  save method change  `with fhandle:`  to `with as_handle(fhandle):`
pippo1980
CC BY-SA 4.0
2022-12-18T00:36:13.727Z
or remove  `if isinstance else ...` and  change `with fhandle:    to   `with as_handle(file, mode = 'w') as fhandle:
pippo1980
CC BY-SA 4.0
2022-12-14T17:33:26.187Z
2022-12-14T17:33:26.187Z
jgreener
<p>I had a similar problem with:</p>
<pre><code>from Bio.PDB import * 
import nglview as nv


parser = PDBParser(QUIET = True)
structure = parser.get_structure(&quot;2ms2&quot;, &quot;2ms2.pdb&quot;)

save_pdb = PDBIO()
save_pdb.set_structure(structure)
save_pdb.save('pdb_out.pdb')

view = nv.show_biopython(structure)
view
</code></pre>
<p>error was like in question:</p>
<pre><code>.................site-packages/nglview/adaptor.py:201, in BiopythonStructure.get_structure_string(self)
    199 io_str = StringIO()
    200 io_pdb.save(io_str)
--&gt; 201 return io_str.getvalue()

ValueError: I/O operation on closed file
</code></pre>
<p>I modified <code>site-packages/nglview/adaptor.py:201, in  BiopythonStructure.get_structure_string(self)</code>:</p>
<pre><code>def get_structure_string(self):
        from Bio.PDB import PDBIO
        from io import StringIO
        io_pdb = PDBIO()
        io_pdb.set_structure(self._entity)
        io_str = StringIO()
        io_pdb.save(io_str)
        return io_str.getvalue()

</code></pre>
<p>with :</p>
<pre><code>def get_structure_string(self):
        from Bio.PDB import PDBIO
        
        import mmap
        
        io_pdb = PDBIO()
        
        io_pdb.set_structure(self._entity)
        
        mo = mmap_str()
        
        io_pdb.save(mo)
        
        return mo.read()

</code></pre>
<p>and added this new class <code>mmap_str()</code> , in same file:</p>
<pre><code>import mmap
import copy

class mmap_str():

    import mmap #added import at top
    
    instance = None

    def __init__(self):
    
        self.mm = mmap.mmap(-1, 2)
        
        self.a = ''
        
        b = '\n'
        
        self.mm.write(b.encode(encoding = 'utf-8'))
        
        self.mm.seek(0)
        
        #print('self.mm.read().decode() ',self.mm.read().decode(encoding = 'utf-8'))
        
        self.mm.seek(0)
        
    def __new__(cls, *args, **kwargs):
        if not isinstance(cls.instance, cls):
            cls.instance = object.__new__(cls)
        return cls.instance
        
    def write(self, string):
        
        self.a = str(copy.deepcopy(self.mm.read().decode(encoding = 'utf-8'))).lstrip('\n')
        
        self.mm.seek(0)
        
        #print('a -&gt; ', self.a)
        
        len_a = len(self.a)
        
        self.mm = mmap.mmap(-1, len(self.a)+len(string))
        
        #print('a :', self.a)
        
        #print('len self.mm ', len(self.mm))
        
        #print('lenght string : ', len(string))
        
        #print(bytes((self.a+string).encode()))
        
        self.mm.write(bytes((self.a+string).encode()))
        
        self.mm.seek(0)
        
        #print('written once ')
        
        #self.mm.seek(0)
        
    def read(self):
    
        self.mm.seek(0)
        
        a = self.mm.read().decode().lstrip('\n')
        
        self.mm.seek(0)
        
        return a
        
    def __enter__(self):
        
        return self
 
    def __exit__(self, *args):
        
        pass

</code></pre>
<p>if I uncomment the print statements I'll get the :</p>
<pre><code>IOPub data rate exceeded.
The notebook server will temporarily stop sending output
to the client in order to avoid crashing it. 
</code></pre>
<p>error , but commenting them out I get:</p>
<p><a href="https://i.sstatic.net/siSKY.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/siSKY.png" alt="" /></a></p>
<p>while using the<code>nglview.show_file(filename)</code> I get:</p>
<p><a href="https://i.sstatic.net/olG6j.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/olG6j.png" alt="enter image description here" /></a></p>
<p>tha's because, as could be seen looking at the <code>pdb_out.pdb</code> file</p>
<p>outputted by my code, <code>Biopytho.PDB.PDBParser.get_structure(name , filename)</code> doesnt retrieve the pdb header responsible for generate full CRYSTALLOGRAPHIC SYMMETRY/or biopython can't handle it (not sure about this, help if you know better),  but just the coordinates.</p>
<p>Still don't understand what is going on with the :</p>
<pre><code>--&gt; 201 return io_str.getvalue()

ValueError: I/O operation on closed file
</code></pre>
<p>it could be something related to jupiter ipykernal ? hope somebody could shed more light into this, dont know how the framework runs, but is definitely different from a normal python interpreter. As an example:</p>
<p><a href="https://i.sstatic.net/cXRlL.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/cXRlL.png" alt="enter image description here" /></a></p>
<p>Same code in one of my Python virtualenv, will run forever, so it could be ipykernel dont like <code>StringIO()</code>s or do something strange to them ?</p>
<p>OK thanks to the hint in the answer below, I went inspecting PDBIO.py in github repo for version Biopython 1.80 and compared the save method of PDBIO : <a href="https://github.com/biopython/biopython/blob/5ffdce852ba3721ca945ec383a69382507b4fa1b/Bio/PDB/PDBIO.py#L299" rel="nofollow noreferrer">def save(self, file, select=_select, write_end=True, preserve_atom_numbering=False):</a> with the one in Biopython 1.79,</p>
<p>see first bit:
<a href="https://i.sstatic.net/PCtMW.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/PCtMW.png" alt="enter image description here" /></a></p>
<p>and last bit:
<a href="https://i.sstatic.net/1hjO5.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/1hjO5.png" alt="enter image description here" /></a></p>
<p>so apparently the big difference is the <code>with fhandle:</code> block in version 1.80.</p>
<p>So I realized that changing <code>adaptor.py</code> with adding a subclass of <code>StringIO</code> that looks like:</p>
<pre><code>from io import StringIO
class StringIO(StringIO):

    def __exit__(self, *args, **kwargs):
        
        print('exiting from subclassed StringIO !!!!!')
        
        pass
</code></pre>
<p>and modifying <code>def get_structure_string(self):</code> like this:</p>
<pre><code>def get_structure_string(self):
        from Bio.PDB import PDBIO
        #from io import StringIO
        io_pdb = PDBIO()
        io_pdb.set_structure(self._entity)
        io_str = StringIO()
        io_pdb.save(io_str)
        return io_str.getvalue()


</code></pre>
<p>was enough to get my Biopython 1.80 work in jupiter with nglview.</p>
<p>That told I am not sure what are the pitfalls of not closing the StringIO object we use for the visualization, but apparently its what Biopython 1.79 was doing like my first answer using a mmap object was doing too (not closing the mmap_str)</p>

CC BY-SA 4.0
2022-12-13T15:50:00.133Z
What operating system are you on? I'm wondering if it could be a Windows issue, I can also test later on my Windows machine. There was a similar error reported a while ago for iPython and `StringIO`: https://github.com/ipython/ipython/issues/9168.
jgreener
CC BY-SA 4.0
2022-12-13T16:33:46.980Z
I am on a Debian VM (VMware on Debian Host), dont remember ipykernel version but tried downgrading it lower than 8 because of this  https://github.com/ipython/ipython/issues/9168 but getting same error nevertheless
pippo1980
CC BY-SA 4.0
2022-12-13T08:49:47.930Z
2022-12-15T07:26:19.927Z
2022-12-15T07:26:19.927Z
pippo1980
<p>tried to understand git, I ended up with this, seems more coherent with the previous habits in the biopython project, but cant push it.</p>
<p><a href="https://i.sstatic.net/zGqfC.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/zGqfC.png" alt="enter image description here" /></a></p>
<p>Anyone could pass it along ? [of course needs to be checked out, my tests are OK, but I am a novice].</p>

CC BY-SA 4.0
2022-12-19T12:44:09.193Z
2022-12-19T12:44:09.193Z
pippo1980
<p>So I have been trying to get into visualizing proteins in python, so after some research I ended up on a tutorial that was teaching you how to visualize a protein from the COVID-19 virus, so I went and setup anaconda, got jupyter notebook working in vscode, and downloaded the necessary files from the PDB database, and made sure they were in the same directory as my notebook but when I run the the <code>nglview.show_biopython(structure)</code> function I get <code>ValueError: I/O opertation on a closed file</code>. I'm stymied this is my first time using jupyter notebook so maybe there is something I'm missing, I don't know.</p>
<p>This what the code looks like</p>
<pre class="lang-py prettyprint-override"><code>from Bio.PDB import * 
import nglview as nv


parser = PDBParser()
structure = parser.get_structure(&quot;6YYT&quot;, &quot;6YYT.pdb&quot;)
view = nv.show_biopython(structure)
</code></pre>
<p>The error looks like this</p>
<pre><code>Output exceeds the size limit. Open the full output data in a text editor
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
~\AppData\Local\Temp\ipykernel_8776\2743687014.py in &lt;module&gt;
----&gt; 1 view = nv.show_biopython(structure)

c:\Users\jerem\anaconda3\lib\site-packages\nglview\show.py in show_biopython(entity, **kwargs)
    450     '''
    451     entity = BiopythonStructure(entity)
--&gt; 452     return NGLWidget(entity, **kwargs)
    453 
    454 

c:\Users\jerem\anaconda3\lib\site-packages\nglview\widget.py in __init__(self, structure, representations, parameters, **kwargs)
    243         else:
    244             if structure is not None:
--&gt; 245                 self.add_structure(structure, **kwargs)
    246 
    247         if representations:

c:\Users\jerem\anaconda3\lib\site-packages\nglview\widget.py in add_structure(self, structure, **kwargs)
   1111         if not isinstance(structure, Structure):
   1112             raise ValueError(f'{structure} is not an instance of Structure')
-&gt; 1113         self._load_data(structure, **kwargs)
   1114         self._ngl_component_ids.append(structure.id)
   1115         if self.n_components &gt; 1:
...
--&gt; 200         return io_str.getvalue()
    201 
    202 

ValueError: I/O operation on closed file
</code></pre>
<p>I only get this error when using <code>nglview.show_biopython</code>, when I run the <code>get_structure()</code> function it appears to read the file just fine. I can visualize other molucles just fine, or maybe that's because I was using the ASE library instead of a file. I don't know, that's why I'm here.</p>
<p>Update: Recently I found out that I can visualize the protein using <code>nglview.show_file()</code> instead of using <code>nglview.show_biopython()</code>. Even though I can visualize proteins now and technically my problem has been solved I would still like to know why the <code>show_biopython()</code> function isn't working properly.</p>

CC BY-SA 4.0
2022-12-12T15:45:24.230Z
I tried this in Jupyter Lab and VS code but couldn't reproduce the error. What OS are you on and what are your versions of Python, Biopython and nglview? I would like to help fix this as I added the `show_biopython` function many moons ago. In particular it seems that the `StringIO` object at https://github.com/nglviewer/nglview/blob/master/nglview/adaptor.py#L193-L200 gets closed early, preventing it being read.
jgreener
CC BY-SA 4.0
2022-12-13T00:04:35.670Z
@jgreener I'm on windows, the anaconda python kernel version is 3.9.13, my nglview version is 3.03 and my biopython version is 1.80.
Jeremiah Wade
CC BY-SA 4.0
2022-12-13T08:48:11.197Z
answered, better tried to here : https://stackoverflow.com/questions/74737766/file-i-o-error-using-nglview-show-biopythonstructure/74782007#74782007
pippo1980
<python><structural-biology><biopython>
File I/O error using nglview.show_biopython(structure)
# File I/O error using nglview.show_biopython(structure)

(Asked by: username_0 on 2022-12-09)

So I have been trying to get into visualizing proteins in python, so after some research I ended up on a tutorial that was teaching you how to visualize a protein from the COVID-19 virus, so I went and setup anaconda, got jupyter notebook working in vscode, and downloaded the necessary files from the PDB database, and made sure they were in the same directory as my notebook but when I run the the nglview.show_biopython(structure) function I get ValueError: I/O opertation on a closed file. I'm stymied this is my first time using jupyter notebook so maybe there is something I'm missing, I don't know.
This what the code looks like
from Bio.PDB import * 
import nglview as nv


parser = PDBParser()
structure = parser.get_structure("6YYT", "6YYT.pdb")
view = nv.show_biopython(structure)

The error looks like this
Output exceeds the size limit. Open the full output data in a text editor
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
~\AppData\Local\Temp\ipykernel_8776\2743687014.py in 
----> 1 view = nv.show_biopython(structure)

c:\Users\jerem\anaconda3\lib\site-packages\nglview\show.py in show_biopython(entity, **kwargs)
    450     '''
    451     entity = BiopythonStructure(entity)
--> 452     return NGLWidget(entity, **kwargs)
    453 
    454 

c:\Users\jerem\anaconda3\lib\site-packages\nglview\widget.py in __init__(self, structure, representations, parameters, **kwargs)
    243         else:
    244             if structure is not None:
--> 245                 self.add_structure(structure, **kwargs)
    246 
    247         if representations:

c:\Users\jerem\anaconda3\lib\site-packages\nglview\widget.py in add_structure(self, structure, **kwargs)
   1111         if not isinstance(structure, Structure):
   1112             raise ValueError(f'{structure} is not an instance of Structure')
-> 1113         self._load_data(structure, **kwargs)
   1114         self._ngl_component_ids.append(structure.id)
   1115         if self.n_components > 1:
...
--> 200         return io_str.getvalue()
    201 
    202 

ValueError: I/O operation on closed file

I only get this error when using nglview.show_biopython, when I run the get_structure() function it appears to read the file just fine. I can visualize other molucles just fine, or maybe that's because I was using the ASE library instead of a file. I don't know, that's why I'm here.
Update: Recently I found out that I can visualize the protein using nglview.show_file() instead of using nglview.show_biopython(). Even though I can visualize proteins now and technically my problem has been solved I would still like to know why the show_biopython() function isn't working properly.

**Tags:** python, structural-biology, biopython
> **Comments:**
> **username_1**: I tried this in Jupyter Lab and VS code but couldn't reproduce the error. What OS are you on and what are your versions of Python, Biopython and nglview? I would like to help fix this as I added the `show_biopython` function many moons ago. In particular it seems that the `StringIO` object at https://github.com/nglviewer/nglview/blob/master/nglview/adaptor.py#L193-L200 gets closed early, preventing it being read.  
> **username_0**: @jgreener I'm on windows, the anaconda python kernel version is 3.9.13, my nglview version is 3.03 and my biopython version is 1.80.  
> **username_2**: answered, better tried to here : https://stackoverflow.com/questions/74737766/file-i-o-error-using-nglview-show-biopythonstructure/74782007#74782007  

---

## 4 answers

### Answer by username_0 on 2022-12-13. Score: 4

I also figured out another way to fix this problem. After going back to the tutorial I was talking about I saw that it was made back in 2021. After seeing this I wonder if we were using the same verions of each package, turns out we were not. I'm not sure what version of nglview they were using, but they were using biopython 1.79 which was the latest verion back in 2021 and I was using biopython 1.80. While using biopython 1.80 I was getting the error seen above. But now that I'm using biopython 1.79 I get this
[![enter image description here](https://i.sstatic.net/iRzUG.png)](https://i.sstatic.net/iRzUG.png)

So I guess there is something going on with biopython 1.80, so I'm going to stick with 1.79

> **Comments:**
> **username_3**: Thanks, for posting back a solution. Could you kindly upvote @pippo1980's response please? I'm not an expert, by any means, but it looks to be a good response to me. Certainly useful.  
> **username_2**: yep, same happens with my error, it goes away if I use biopython 1.79  

---

### Answer by username_1 on 2022-12-14. Score: 3

This is an issue with Biopython 1.80, in particular introduced by [a commit](https://github.com/biopython/biopython/commit/be77131200821bb01254c87fb14ee1bf6c81dd4b) that automatically closes IO objects sent to `PDBIO.save`.

I made [a PR](https://github.com/biopython/biopython/pull/4200) to change the behaviour which fixes this issue and should hopefully be in the next Biopython release. Until then, avoiding using Biopython 1.80 should work.

Thanks @jeremiah-wade and @pippo1980 for digging into this.

> **Comments:**
> **username_2**: it took You 2 lines to explain what it took me a couple of days to figure out ... . My question is what is / if is there one the pitfall of having unclosed IO objects around ? I am really new to coding and python so in really plain words if you can. thanks again  
> **username_2**: and on the same line, any chance to modifying the nglview adaptor.py  class BiopythonStructure(Structure) ??  
> **username_1**: It's explained a bit in the linked PR but you can't read from a closed `StringIO` object. So if the `PDBIO.save` function closes the object then an error will be thrown when the string is read back. In general closing an IO object is best done with a `with` block or `.close()`, rather than being done silently when the object is given as a function argument. In general the `with` block is better since it's quite common to forget to call `.close()`. Closing IO objects once they are no longer needed frees memory and lets other software use them safely.  
> **username_2**: They could just add a if isinstance(filename , StringIO) and close_file = 0 in PDBIO like 1.79 and change close_file = 1 for the #filehandle I hope bit  
> **username_2**: think solution could be like PDBParser handles it: `from Bio.File import as_handle` ,  https://github.com/biopython/biopython/blob/7ef56557bdca66eabd62334e61c4dc3153c997ff/Bio/File.py#L29 and in PDBIO.py  save method change  `with fhandle:`  to `with as_handle(fhandle):`  
> **username_2**: or remove  `if isinstance else ...` and  change `with fhandle:    to   `with as_handle(file, mode = 'w') as fhandle:  

---

### Answer by username_2 on 2022-12-13. Score: 3

I had a similar problem with:
from Bio.PDB import * 
import nglview as nv


parser = PDBParser(QUIET = True)
structure = parser.get_structure("2ms2", "2ms2.pdb")

save_pdb = PDBIO()
save_pdb.set_structure(structure)
save_pdb.save('pdb_out.pdb')

view = nv.show_biopython(structure)
view

error was like in question:
.................site-packages/nglview/adaptor.py:201, in BiopythonStructure.get_structure_string(self)
    199 io_str = StringIO()
    200 io_pdb.save(io_str)
--> 201 return io_str.getvalue()

ValueError: I/O operation on closed file

I modified site-packages/nglview/adaptor.py:201, in  BiopythonStructure.get_structure_string(self):
def get_structure_string(self):
        from Bio.PDB import PDBIO
        from io import StringIO
        io_pdb = PDBIO()
        io_pdb.set_structure(self._entity)
        io_str = StringIO()
        io_pdb.save(io_str)
        return io_str.getvalue()


with :
def get_structure_string(self):
        from Bio.PDB import PDBIO
        
        import mmap
        
        io_pdb = PDBIO()
        
        io_pdb.set_structure(self._entity)
        
        mo = mmap_str()
        
        io_pdb.save(mo)
        
        return mo.read()


and added this new class mmap_str() , in same file:
import mmap
import copy

class mmap_str():

    import mmap #added import at top
    
    instance = None

    def __init__(self):
    
        self.mm = mmap.mmap(-1, 2)
        
        self.a = ''
        
        b = '\n'
        
        self.mm.write(b.encode(encoding = 'utf-8'))
        
        self.mm.seek(0)
        
        #print('self.mm.read().decode() ',self.mm.read().decode(encoding = 'utf-8'))
        
        self.mm.seek(0)
        
    def __new__(cls, *args, **kwargs):
        if not isinstance(cls.instance, cls):
            cls.instance = object.__new__(cls)
        return cls.instance
        
    def write(self, string):
        
        self.a = str(copy.deepcopy(self.mm.read().decode(encoding = 'utf-8'))).lstrip('\n')
        
        self.mm.seek(0)
        
        #print('a -> ', self.a)
        
        len_a = len(self.a)
        
        self.mm = mmap.mmap(-1, len(self.a)+len(string))
        
        #print('a :', self.a)
        
        #print('len self.mm ', len(self.mm))
        
        #print('lenght string : ', len(string))
        
        #print(bytes((self.a+string).encode()))
        
        self.mm.write(bytes((self.a+string).encode()))
        
        self.mm.seek(0)
        
        #print('written once ')
        
        #self.mm.seek(0)
        
    def read(self):
    
        self.mm.seek(0)
        
        a = self.mm.read().decode().lstrip('\n')
        
        self.mm.seek(0)
        
        return a
        
    def __enter__(self):
        
        return self
 
    def __exit__(self, *args):
        
        pass


if I uncomment the print statements I'll get the :
IOPub data rate exceeded.
The notebook server will temporarily stop sending output
to the client in order to avoid crashing it. 

error , but commenting them out I get:

while using thenglview.show_file(filename) I get:

tha's because, as could be seen looking at the pdb_out.pdb file
outputted by my code, Biopytho.PDB.PDBParser.get_structure(name , filename) doesnt retrieve the pdb header responsible for generate full CRYSTALLOGRAPHIC SYMMETRY/or biopython can't handle it (not sure about this, help if you know better),  but just the coordinates.
Still don't understand what is going on with the :
--> 201 return io_str.getvalue()

ValueError: I/O operation on closed file

it could be something related to jupiter ipykernal ? hope somebody could shed more light into this, dont know how the framework runs, but is definitely different from a normal python interpreter. As an example:

Same code in one of my Python virtualenv, will run forever, so it could be ipykernel dont like StringIO()s or do something strange to them ?
OK thanks to the hint in the answer below, I went inspecting PDBIO.py in github repo for version Biopython 1.80 and compared the save method of PDBIO : def save(self, file, select=_select, write_end=True, preserve_atom_numbering=False): with the one in Biopython 1.79,
see first bit:

and last bit:

so apparently the big difference is the with fhandle: block in version 1.80.
So I realized that changing adaptor.py with adding a subclass of StringIO that looks like:
from io import StringIO
class StringIO(StringIO):

    def __exit__(self, *args, **kwargs):
        
        print('exiting from subclassed StringIO !!!!!')
        
        pass

and modifying def get_structure_string(self): like this:
def get_structure_string(self):
        from Bio.PDB import PDBIO
        #from io import StringIO
        io_pdb = PDBIO()
        io_pdb.set_structure(self._entity)
        io_str = StringIO()
        io_pdb.save(io_str)
        return io_str.getvalue()



was enough to get my Biopython 1.80 work in jupiter with nglview.
That told I am not sure what are the pitfalls of not closing the StringIO object we use for the visualization, but apparently its what Biopython 1.79 was doing like my first answer using a mmap object was doing too (not closing the mmap_str)

> **Comments:**
> **username_1**: What operating system are you on? I'm wondering if it could be a Windows issue, I can also test later on my Windows machine. There was a similar error reported a while ago for iPython and `StringIO`: https://github.com/ipython/ipython/issues/9168.  
> **username_2**: I am on a Debian VM (VMware on Debian Host), dont remember ipykernel version but tried downgrading it lower than 8 because of this  https://github.com/ipython/ipython/issues/9168 but getting same error nevertheless  

---

### Answer by username_2 on 2022-12-19. Score: 1

tried to understand git, I ended up with this, seems more coherent with the previous habits in the biopython project, but cant push it.

[![enter image description here](https://i.sstatic.net/zGqfC.png)](https://i.sstatic.net/zGqfC.png)

Anyone could pass it along ? [of course needs to be checked out, my tests are OK, but I am a novice].


---

