]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
Add port comparison in __eq__() and __ne__() method to URL
authorSanjana <sanjana0796@gmail.com>
Thu, 28 Feb 2019 15:16:13 +0000 (10:16 -0500)
committerMike Bayer <mike_mp@zzzcomputing.com>
Thu, 28 Feb 2019 19:34:52 +0000 (14:34 -0500)
Comparing two objects of :class:`.URL` using ``__eq__()`` did not take port
number into consideration, two objects differing only by port number were
considered equal. Port comparison is now added in ``__eq__()`` method of
:class:`.URL`, objects differing by port number are now not equal.
Additionally, ``__ne__()`` was not implemented for :class:`.URL` which
caused unexpected result when ``!=`` was used in Python2, since there are no
implied relationships among the comparison operators in Python2.

Fixes: #4406
Closes: #4515
Pull-request: https://github.com/sqlalchemy/sqlalchemy/pull/4515
Pull-request-sha: 0f15b805f07e7fca1f82ca6c3aad98d50ea705b8

Change-Id: Iba7d224f1282dc3f4b884d1a746f2d46669f551e

doc/build/changelog/unreleased_12/4406.rst [new file with mode: 0644]
lib/sqlalchemy/engine/url.py
test/engine/test_parseconnect.py

diff --git a/doc/build/changelog/unreleased_12/4406.rst b/doc/build/changelog/unreleased_12/4406.rst
new file mode 100644 (file)
index 0000000..aee7e5d
--- /dev/null
@@ -0,0 +1,11 @@
+.. change::
+   :tags: bug, engine
+   :tickets: 4406
+
+   Comparing two objects of :class:`.URL` using ``__eq__()`` did not take port
+   number into consideration, two objects differing only by port number were
+   considered equal. Port comparison is now added in ``__eq__()`` method of
+   :class:`.URL`, objects differing by port number are now not equal.
+   Additionally, ``__ne__()`` was not implemented for :class:`.URL` which
+   caused unexpected result when ``!=`` was used in Python2, since there are no
+   implied relationships among the comparison operators in Python2.
index 536e21c3867918b72e6e084881c4cf4a64b4d7b4..16b7c051a90630809e00fa5e0cc28bda42dee373 100644 (file)
@@ -120,8 +120,12 @@ class URL(object):
             and self.host == other.host
             and self.database == other.database
             and self.query == other.query
+            and self.port == other.port
         )
 
+    def __ne__(self, other):
+        return not self == other
+
     @property
     def password(self):
         if self.password_original is None:
index be90378c93080246f36a2fc5c5712567367e2a2c..b7e8905176c82d71949570140b4530c8248d4e01 100644 (file)
@@ -12,6 +12,8 @@ from sqlalchemy.testing import assert_raises
 from sqlalchemy.testing import eq_
 from sqlalchemy.testing import fixtures
 from sqlalchemy.testing import is_
+from sqlalchemy.testing import is_false
+from sqlalchemy.testing import is_true
 from sqlalchemy.testing import mock
 from sqlalchemy.testing.mock import call
 from sqlalchemy.testing.mock import MagicMock
@@ -21,7 +23,7 @@ from sqlalchemy.testing.mock import Mock
 dialect = None
 
 
-class ParseConnectTest(fixtures.TestBase):
+class URLTest(fixtures.TestBase):
     def test_rfc1738(self):
         for text in (
             "dbtype://username:password@hostspec:110//usr/db_file.db",
@@ -145,6 +147,29 @@ class ParseConnectTest(fixtures.TestBase):
             "dialect://user:pass@host/db?arg1=param1&arg2=param2&arg2=param3",
         )
 
+    def test_comparison(self):
+        components = ('drivername', 'username', 'password', 'host',
+                      'database', 'query', 'port')
+
+        common_url = "dbtype://username:password" \
+                     "@[2001:da8:2004:1000:202:116:160:90]:80/database?foo=bar"
+        other_url = "dbtype://uname:pwd@host/"
+
+        url1 = url.make_url(common_url)
+        url2 = url.make_url(common_url)
+        url3 = url.make_url(other_url)
+
+        is_true(url1 == url2)
+        is_false(url1 != url2)
+        is_true(url1 != url3)
+        is_false(url1 == url3)
+
+        for curr_component in components:
+            setattr(url2, curr_component, 'new_changed_value')
+            is_true(url1 != url2)
+            is_false(url1 == url2)
+            setattr(url2, curr_component, getattr(url1, curr_component))
+
 
 class DialectImportTest(fixtures.TestBase):
     def test_import_base_dialects(self):