Repository: conan-io/conan

Issue:
conan install unexpectedly reports invalid version range
i have this requirement in my `conanfile.py`:
`foo/[>16.5.0 <17.0.0]@bar/stable`

`conan install` aborts with this error:
`ERROR: version range expression '>16.5.0<17.0.0' is not valid`

note: using the deprecated comma-based syntax works fine

* Python 3.6 on CentOS 7.5
* Conan 1.11.2
* node-semver 0.6.1


Discussion:
Reproduced, indeed an undesired bug. Thanks for reporting @mistafunk !

Resolving patch:
diff --git a/conans/model/ref.py b/conans/model/ref.py
--- a/conans/model/ref.py
+++ b/conans/model/ref.py
@@ -78,7 +78,6 @@ class ConanFileReference(namedtuple("ConanFileReference", "name version user cha
     """ Full reference of a package recipes, e.g.:
     opencv/2.4.10@lasote/testing
     """
-    whitespace_pattern = re.compile(r"\s+")
     sep_pattern = re.compile(r"([^/]+)/([^/]+)@([^/]+)/([^/#]+)#?(.+)?")
 
     def __new__(cls, name, version, user, channel, revision=None, validate=True):
@@ -107,7 +106,6 @@ def _validate(self):
     def loads(text, validate=True):
         """ Parses a text string to generate a ConanFileReference object
         """
-        text = ConanFileReference.whitespace_pattern.sub("", text)
         try:
             # Split returns empty start and end groups
             _, name, version, user, channel, revision, _ = ConanFileReference.sep_pattern.split(text)


Test patch:
diff --git a/conans/test/functional/old/paths_test.py b/conans/test/functional/old/paths_test.py
--- a/conans/test/functional/old/paths_test.py
+++ b/conans/test/functional/old/paths_test.py
@@ -32,7 +32,7 @@ def basic_test(self):
         folder = temp_folder()
         paths = SimplePaths(folder)
         self.assertEqual(paths._store_folder, folder)
-        conan_ref = ConanFileReference.loads("opencv/2.4.10 @ lasote /testing")
+        conan_ref = ConanFileReference.loads("opencv/2.4.10@lasote/testing")
         package_ref = PackageReference(conan_ref, "456fa678eae68")
         expected_base = os.path.join(folder, os.path.sep.join(["opencv", "2.4.10",
                                                                "lasote", "testing"]))
@@ -84,4 +84,3 @@ def test_with_env_variable(self, _, short_paths):
 
             self.assertEqual(self.home_short in r, short_paths)
             self.assertEqual(self.home in r, not short_paths)
-
diff --git a/conans/test/unittests/model/ref_test.py b/conans/test/unittests/model/ref_test.py
--- a/conans/test/unittests/model/ref_test.py
+++ b/conans/test/unittests/model/ref_test.py
@@ -7,7 +7,7 @@
 
 class RefTest(unittest.TestCase):
     def basic_test(self):
-        ref = ConanFileReference.loads("opencv/2.4.10 @ lasote/testing")
+        ref = ConanFileReference.loads("opencv/2.4.10@lasote/testing")
         self.assertEqual(ref.name, "opencv")
         self.assertEqual(ref.version, "2.4.10")
         self.assertEqual(ref.user, "lasote")
@@ -37,8 +37,10 @@ def basic_test(self):
     def errors_test(self):
         self.assertRaises(ConanException, ConanFileReference.loads, "")
         self.assertRaises(ConanException, ConanFileReference.loads, "opencv/2.4.10")
-        self.assertRaises(ConanException, ConanFileReference.loads, "opencv/2.4.10 @ lasote")
+        self.assertRaises(ConanException, ConanFileReference.loads, "opencv/2.4.10@lasote")
         self.assertRaises(ConanException, ConanFileReference.loads, "opencv??/2.4.10@laso/testing")
+        self.assertRaises(ConanException, ConanFileReference.loads, "opencv/2.4.10 @ laso/testing")
+        self.assertRaises(ConanException, ConanFileReference.loads, "o/2.4.10@laso/testing")
         self.assertRaises(ConanException, ConanFileReference.loads, ".opencv/2.4.10@lasote/testing")
         self.assertRaises(ConanException, ConanFileReference.loads, "o/2.4.10 @ lasote/testing")
         self.assertRaises(ConanException, ConanFileReference.loads, "lib/1.0@user&surname/channel")
diff --git a/conans/test/unittests/model/version_ranges_test.py b/conans/test/unittests/model/version_ranges_test.py
--- a/conans/test/unittests/model/version_ranges_test.py
+++ b/conans/test/unittests/model/version_ranges_test.py
@@ -287,8 +287,10 @@ class HelloConan(ConanFile):
                            # ranges
                            ('"Say/[<=1.2]@myuser/testing"', "1.2.1", False, False),
                            ('"Say/[>=0.2,<=1.0]@myuser/testing"', "0.3", False, True),
+                           ('"Say/[>=0.2 <=1.0]@myuser/testing"', "0.3", False, True),
                            ('("Say/[<=1.2]@myuser/testing", "override")', "1.2.1", True, False),
                            ('("Say/[>=0.2,<=1.0]@myuser/testing", "override")', "0.3", True, True),
+                           ('("Say/[>=0.2 <=1.0]@myuser/testing", "override")', "0.3", True, True),
                            ])
     def transitive_test(self, version_range, solution, override, valid):
         hello_text = hello_content % ">0.1, <1"