File: 1387.patch

package info (click to toggle)
parmed 4.3.0%2Bdfsg-3
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 290,216 kB
  • sloc: python: 62,390; xml: 49,573; cpp: 352; makefile: 157; sh: 142; javascript: 84; ansic: 26
file content (119 lines) | stat: -rw-r--r-- 4,547 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
From 62fcfcfba8b3fb597ce00b1844bc7ebb3b54e70f Mon Sep 17 00:00:00 2001
From: Matthew Burn <matthew.burn@imperagen.com>
Date: Mon, 3 Feb 2025 09:58:09 +0000
Subject: [PATCH 1/3] Removed `numpy.compat` and added `asbytes` and `asstr`

---
 parmed/utils/netcdf.py | 12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)

--- a/parmed/utils/netcdf.py
+++ b/parmed/utils/netcdf.py
@@ -39,15 +39,25 @@
 from operator import mul
 from collections import OrderedDict
 from platform import python_implementation
+from typing import Any
 
 import mmap as mm
 
 import numpy as np
-from numpy.compat import asbytes, asstr
 from numpy import frombuffer, dtype, empty, array, asarray
 from numpy import little_endian as LITTLE_ENDIAN
 from functools import reduce
 
+def asbytes(s: Any) -> bytes:
+    """Ensures input is in bytes format. Mimics numpy.compat.asbytes"""
+    return str(s).encode("latin1") if isinstance(s, str) else s
+
+
+def asstr(b: Any) -> str:
+    """Ensures input is in string format. Mimics numpy.compat.asstr"""
+    return b.decode("latin1") if isinstance(b, bytes) else str(b)
+
+
 
 IS_PYPY = python_implementation() == 'PyPy'
 
--- a/parmed/formats/pdb.py
+++ b/parmed/formats/pdb.py
@@ -7,9 +7,11 @@
 from functools import lru_cache, reduce
 from string import ascii_letters
 import io
-import ftplib
+import urllib
 import gzip
 import logging
+import urllib.error
+import urllib.request
 import numpy as np
 from ..exceptions import PDBError, PDBWarning
 from ..formats.pdbx import PdbxReader, PdbxWriter, containers
@@ -311,16 +313,18 @@
             raise ValueError('pdb_id must be the 4-letter PDB code')
 
         pdb_id = pdb_id.lower()
-        ftp = ftplib.FTP('ftp.wwpdb.org', timeout=timeout)
-        ftp.login()
+        
+        url = (
+            'https://files.wwpdb.org/pub/pdb/data/structures/divided/pdb/%s/pdb%s.ent.gz'
+        ) % (pdb_id[1:3], pdb_id)
+
         fileobj = io.BytesIO()
         try:
-            ftp_loc = f"/pub/pdb/data/structures/divided/pdb/{pdb_id[1:3]}/pdb{pdb_id}.ent.gz"
-            ftp.retrbinary(f"RETR {ftp_loc}", fileobj.write)
-        except ftplib.all_errors as err:
+            with urllib.request.urlopen(url, timeout=timeout) as response:
+                fileobj.write(response.read())
+        except (urllib.error.URLError, urllib.error.HTTPError) as err:
             raise IOError(f"Could not retrieve PDB ID {pdb_id}; {err}") from err
-        finally:
-            ftp.close()
+
         # Rewind, wrap it in a GzipFile and send it to parse
         fileobj.seek(0)
         fileobj = io.TextIOWrapper(gzip.GzipFile(fileobj=fileobj, mode='r'))
@@ -1180,17 +1184,18 @@
             raise ValueError('pdb_id must be the 4-letter PDB code')
 
         pdb_id = pdb_id.lower()
-        ftp = ftplib.FTP('ftp.wwpdb.org', timeout=timeout)
-        ftp.login()
+                
+        url = (
+            'https://files.wwpdb.org/pub/pdb/data/structures/divided/mmCIF/%s/%s.cif.gz'
+        ) % (pdb_id[1:3], pdb_id)
+        
         fileobj = io.BytesIO()
         try:
-            ftp.retrbinary('RETR /pub/pdb/data/structures/divided/mmCIF/'
-                           '%s/%s.cif.gz' % (pdb_id[1:3], pdb_id),
-                           fileobj.write)
-        except ftplib.all_errors as err:
-            raise IOError('Could not retrieve PDB ID %s; %s' % (pdb_id, err))
-        finally:
-            ftp.close()
+            with urllib.request.urlopen(url, timeout=timeout) as response:
+                fileobj.write(response.read())
+        except (urllib.error.URLError, urllib.error.HTTPError) as err:
+            raise IOError(f"Could not retrieve PDB ID {pdb_id}; {err}") from err
+        
         fileobj.seek(0)
         fileobj = io.TextIOWrapper(gzip.GzipFile(fileobj=fileobj, mode='r'))
         if saveto is not None:
--- a/test/test_parmed_genopen.py
+++ b/test/test_parmed_genopen.py
@@ -75,7 +75,8 @@
             self.assertEqual(f.read(), genopen(get_fn('4lzt.pdb.gz')).read())
 
     @unittest.skip("Not running tests requiring network access")
-    @unittest.skipUnless(is_local(), 'Cannot download files from PDB with CI systems')
+    # @unittest.skipUnless(is_local(), 'Cannot download files from PDB with CI systems')
+    @unittest.skip('RCSB deprecated FTP protocol https://www.rcsb.org/news/feature/65562f0ad78e004e766a96c1')
     def test_read_ftp_URL(self):
         """ Tests genopen reading a ftp remote file """
         url = 'ftp://ftp.wwpdb.org/pub/pdb/data/structures/divided/mmCIF/05/205l.cif.gz'