Repository: linkml/linkml-runtime

Issue:
question about missing dependency wheel files (shexjsg depends on antlr)
Not a python user, but I'm just trying to do enough to use linkml-runtime in a browser with javascript.  I'm using Pyodide and micropip.install and it comes up with an error about missing wheel files in pyldmod and others:

oops: PythonError: Traceback (most recent call last):
  File "/lib/python3.9/asyncio/futures.py", line 201, in result
    raise self._exception
  File "/lib/python3.9/asyncio/tasks.py", line 258, in __step
    result = coro.throw(exc)
  File "/lib/python3.9/site-packages/_pyodide/_base.py", line 494, in eval_code_async
    await CodeRunner(
  File "/lib/python3.9/site-packages/_pyodide/_base.py", line 347, in run_async
    await coroutine
  File "<exec>", line 7, in <module>
  File "/lib/python3.9/asyncio/futures.py", line 284, in __await__
    yield self  # This tells Task to wait for completion.
  File "/lib/python3.9/asyncio/tasks.py", line 328, in __wakeup
    future.result()
  File "/lib/python3.9/asyncio/futures.py", line 201, in result
    raise self._exception
  File "/lib/python3.9/asyncio/tasks.py", line 256, in __step
    result = coro.send(None)
  File "/lib/python3.9/site-packages/micropip/_micropip.py", line 191, in install
    raise ValueError(
ValueError: Couldn't find a pure Python 3 wheel for: 'pyldmod', 'antlr4-python3-runtime~=4.9', 'pyldmod', 'pyyaml<6.0.0,>=5.1.0', 'wrapt<2,>=1.10'

Discussion:

Patch:
diff --git a/linkml_runtime/utils/metamodelcore.py b/linkml_runtime/utils/metamodelcore.py
index 755a808..6e34daf 100644
--- a/linkml_runtime/utils/metamodelcore.py
+++ b/linkml_runtime/utils/metamodelcore.py
@@ -6,7 +6,6 @@ from decimal import Decimal
 from typing import Union, Optional, Tuple
 from urllib.parse import urlparse
 
-from ShExJSG.ShExJ import IRIREF, PN_PREFIX
 from rdflib import Literal, BNode, URIRef
 from rdflib.namespace import is_ncname
 from rdflib.term import Identifier as rdflib_Identifier
@@ -137,9 +136,12 @@ class URI(URIorCURIE):
             raise ValueError(f"{v}: is not a valid URI")
         super().__init__(v)
 
+    # this is more inclusive than the W3C specification
+    uri_re = re.compile("^[A-Za-z]\\S*$")
+
     @classmethod
     def is_valid(cls, v: str) -> bool:
-        return v is not None and not URIorCURIE.is_curie(v) and isinstance(v, IRIREF)
+        return v is not None and not URIorCURIE.is_curie(v) and cls.uri_re.match(v)
 
 
 class Curie(URIorCURIE):
@@ -172,7 +174,8 @@ class Curie(URIorCURIE):
     @classmethod
     def is_valid(cls, v: str) -> bool:
         pnln = cls.ns_ln(v)
-        return pnln is not None and (not pnln[0] or isinstance(pnln[0], PN_PREFIX))
+        #return pnln is not None and (not pnln[0] or isinstance(pnln[0], PN_PREFIX))
+        return pnln is not None
 
     # This code was extracted from the termorcurie package of the rdfa
     def as_uri(self, nsm: Namespaces) -> Optional[URIRef]:
diff --git a/pyproject.toml b/pyproject.toml
index 357c444..3567d4f 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -54,7 +54,6 @@ rdflib-shim = ">=1.0.3"
 rdflib-jsonld = "==0.6.1"
 rdflib-pyldmod-compat = "*"
 requests = "*"
-shexjsg = "==0.*,>=0.7.0"
 
 [tool.poetry.dev-dependencies]
 coverage = "^6.2"


Test patch:
diff --git a/tests/test_utils/test_metamodelcore.py b/tests/test_utils/test_metamodelcore.py
index 8c0525a..f3166ae 100644
--- a/tests/test_utils/test_metamodelcore.py
+++ b/tests/test_utils/test_metamodelcore.py
@@ -46,6 +46,10 @@ class MetamodelCoreTest(unittest.TestCase):
             URIorCURIE("1abc:def")
         with self.assertRaises(ValueError):
             URIorCURIE("1:def")
+        with self.assertRaises(ValueError):
+            URIorCURIE(" ")
+        with self.assertRaises(ValueError):
+            URIorCURIE("_")
         lax()
         URI(str2)
         URIorCURIE("1abc:def")
@@ -78,6 +82,14 @@ class MetamodelCoreTest(unittest.TestCase):
         self.assertEqual("http://foo.org/bargles", URI("http://foo.org/bargles"))
         with self.assertRaises(ValueError):
             URI("rdf:type")
+        with self.assertRaises(ValueError):
+            URI(":")
+        with self.assertRaises(ValueError):
+            URI("1")
+        #with self.assertRaises(ValueError):
+        #    URI("x1")
+        with self.assertRaises(ValueError):
+            URI("")
         lax()
         x = URI("rdf:type")
         self.assertFalse(URI.is_valid(x))