Skip to content

Commit 68e07f8

Browse files
authored
Merge pull request #322 from gaoflow/fix-319-httpresponse-close
Fix HTTPResponse cleanup for owl imports
2 parents 5b46638 + 361f8e7 commit 68e07f8

2 files changed

Lines changed: 72 additions & 3 deletions

File tree

pyshacl/rdfutil/load.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -251,7 +251,7 @@ def load_from_source(
251251
_maybe_id = source
252252
base_uri = source
253253
try:
254-
resp, resp_filename, web_format, raw_fp = get_rdf_from_web(source)
254+
resp, resp_filename, web_format, _raw_fp = get_rdf_from_web(source)
255255
except HTTPError:
256256
if is_imported_graph:
257257
return g
@@ -268,9 +268,8 @@ def load_from_source(
268268
else:
269269
rdf_format = web_format
270270
filename = resp_filename
271-
fp = resp.fp if raw_fp else resp
272271
source_was_open = False
273-
source = open_source = fp
272+
source = open_source = resp
274273
else:
275274
first_char = source[0]
276275
if is_windows and (first_char == '\\' or (len(source) > 3 and source[1:3] == ":\\")):

test/issues/test_319.py

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
# -*- coding: utf-8 -*-
2+
#
3+
"""
4+
https://github.com/RDFLib/pySHACL/issues/319
5+
"""
6+
7+
import gc
8+
import io
9+
import threading
10+
from contextlib import redirect_stderr
11+
from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer
12+
13+
from rdflib import OWL, RDF, URIRef
14+
15+
from pyshacl.rdfutil.load import load_from_source
16+
17+
18+
ROOT_TTL = b"""\
19+
@prefix owl: <http://www.w3.org/2002/07/owl#> .
20+
<http://example.test/root> a owl:Ontology ;
21+
owl:imports <IMPORT_URL> .
22+
"""
23+
24+
IMPORTED_TTL = b"""\
25+
@prefix owl: <http://www.w3.org/2002/07/owl#> .
26+
<http://example.test/imported> a owl:Ontology .
27+
"""
28+
29+
30+
class Issue319Handler(BaseHTTPRequestHandler):
31+
def do_GET(self):
32+
if self.path == "/root.ttl":
33+
body = self.server.root_body
34+
elif self.path == "/import.ttl":
35+
body = IMPORTED_TTL
36+
else:
37+
self.send_error(404)
38+
return
39+
self.send_response(200)
40+
self.send_header("Content-Type", "text/turtle")
41+
self.send_header("Content-Length", str(len(body)))
42+
self.end_headers()
43+
self.wfile.write(body)
44+
45+
def log_message(self, *args):
46+
pass
47+
48+
49+
def test_319_http_owl_imports_do_not_leave_closed_response_finalizers():
50+
server = ThreadingHTTPServer(("127.0.0.1", 0), Issue319Handler)
51+
host, port = server.server_address
52+
root_url = f"http://{host}:{port}/root.ttl"
53+
import_url = f"http://{host}:{port}/import.ttl"
54+
server.root_body = ROOT_TTL.replace(b"IMPORT_URL", import_url.encode("ascii"))
55+
thread = threading.Thread(target=server.serve_forever, daemon=True)
56+
thread.start()
57+
stderr = io.StringIO()
58+
try:
59+
with redirect_stderr(stderr):
60+
graph = load_from_source(root_url, do_owl_imports=True)
61+
assert (URIRef("http://example.test/imported"), RDF.type, OWL.Ontology) in graph
62+
del graph
63+
gc.collect()
64+
finally:
65+
server.shutdown()
66+
server.server_close()
67+
thread.join()
68+
stderr_text = stderr.getvalue()
69+
assert "Exception ignored while finalizing file" not in stderr_text
70+
assert "I/O operation on closed file" not in stderr_text

0 commit comments

Comments
 (0)