diff --git a/elementpath/xpath2/xpath2_functions.py b/elementpath/xpath2/xpath2_functions.py index 3e8a2e32..3889a965 100644 --- a/elementpath/xpath2/xpath2_functions.py +++ b/elementpath/xpath2/xpath2_functions.py @@ -19,6 +19,7 @@ import unicodedata from copy import copy from decimal import Decimal, DecimalException +from string import ascii_letters from urllib.parse import urlsplit, quote as urllib_quote from ..datatypes import QNAME_PATTERN, DateTime10, DateTime, Date10, Date, \ @@ -35,6 +36,11 @@ method = XPath2Parser.method function = XPath2Parser.function + +def is_local_url_scheme(scheme): + return scheme in ('', 'file') or len(scheme) == 1 and scheme in ascii_letters + + ### # Sequence types (allowed only for type checking in treat-as/instance-of statements) function('empty-sequence', nargs=0, label='sequence type') @@ -1321,7 +1327,8 @@ def evaluate(self, context=None): except (KeyError, TypeError): if self.symbol == 'doc': url_parts = urlsplit(uri) - if url_parts.scheme in ('', 'file') and os.path.isdir(url_parts.path.lstrip(':')): + if is_local_url_scheme(url_parts.scheme) \ + and os.path.isdir(url_parts.path.lstrip(':')): raise self.error('FODC0005', 'document URI is a directory') raise self.error('FODC0002') return False @@ -1360,7 +1367,7 @@ def evaluate(self, context=None): collection = context.collections[uri] except (KeyError, TypeError): url_parts = urlsplit(uri) - if url_parts.scheme in ('', 'file') and \ + if is_local_url_scheme(url_parts.scheme) and \ not url_parts.path.startswith(':') and url_parts.path.endswith('/'): raise self.error('FODC0003', 'collection URI is a directory') raise self.error('FODC0002', '{!r} collection not found'.format(uri)) from None diff --git a/tests/test_xpath2_parser.py b/tests/test_xpath2_parser.py index 71f33c07..bb6f6934 100644 --- a/tests/test_xpath2_parser.py +++ b/tests/test_xpath2_parser.py @@ -21,6 +21,7 @@ # import unittest import io +import locale import os from decimal import Decimal from textwrap import dedent @@ -1083,8 +1084,12 @@ def test_default_collection_type_argument(self): "invalid sequence type for default_collection_type argument") def test_default_collation_argument(self): - self.assertEqual(self.parser.__class__().default_collation, - "http://www.w3.org/2005/xpath-functions/collation/codepoint") + default_locale = locale.getdefaultlocale() + collation = '.'.join(default_locale) if default_locale[1] else default_locale[0] + + if collation == 'en_US.UTF-8': + collation = "http://www.w3.org/2005/xpath-functions/collation/codepoint" + self.assertEqual(self.parser.__class__().default_collation, collation) parser = self.parser.__class__(default_collation='it_IT.UTF-8') self.assertEqual(parser.default_collation, 'it_IT.UTF-8')