diff --git a/spacy/displacy/__init__.py b/spacy/displacy/__init__.py index cc4d439ee..63658518e 100644 --- a/spacy/displacy/__init__.py +++ b/spacy/displacy/__init__.py @@ -102,14 +102,15 @@ def serve( # automatically switch to the next available port if the default / given port is taken available_port = port - while is_port_in_use(available_port) and available_port <= 65535: + + while is_port_in_use(available_port) and available_port < 65535: available_port += 1 if is_in_jupyter(): warnings.warn(Warnings.W011) render(docs, style=style, page=page, minify=minify, options=options, manual=manual) - if port > 65535: + if available_port == 65535 and is_port_in_use(available_port): raise ValueError(Errors.E1048.format(host=host)) if available_port != port: diff --git a/spacy/errors.py b/spacy/errors.py index f5702056a..c6f7c55cf 100644 --- a/spacy/errors.py +++ b/spacy/errors.py @@ -958,7 +958,7 @@ class Errors(metaclass=ErrorsWithCodes): E1046 = ("{cls_name} is an abstract class and cannot be instantiated. If you are looking for spaCy's default " "knowledge base, use `InMemoryLookupKB`.") E1047 = ("`find_threshold()` only supports components with a `scorer` attribute.") - E1048 = ("No port available for displacy on host {host}. Please specify a port by `displacy.serve(doc, port)`.") + E1048 = ("No port available found for displacy on host {host}. Please specify an available port by `displacy.serve(doc, host, port)`.") # Deprecated model shortcuts, only used in errors and warnings diff --git a/spacy/util.py b/spacy/util.py index b3c9fae9d..ef9db0a72 100644 --- a/spacy/util.py +++ b/spacy/util.py @@ -1739,5 +1739,12 @@ def all_equal(iterable): def is_port_in_use(port): - with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: - return s.connect_ex(('localhost', port)) == 0 + """Check if localhost:port is in use.""" + s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + try: + s.bind(("localhost", port)) + return False + except socket.error: + return True + finally: + s.close() \ No newline at end of file