From 164c2e8dc1b97d5232dc025b78ecc560788f3354 Mon Sep 17 00:00:00 2001 From: Ivan Shcheklein Date: Sat, 20 Jul 2019 15:26:00 -0700 Subject: [PATCH 1/2] url info: fix infinite recustion on deepcopy --- dvc/path_info.py | 6 ++++++ tests/unit/test_path_info.py | 8 ++++++++ 2 files changed, 14 insertions(+) diff --git a/dvc/path_info.py b/dvc/path_info.py index c905f47fe..0366881dd 100644 --- a/dvc/path_info.py +++ b/dvc/path_info.py @@ -184,6 +184,12 @@ class URLInfo(object): __truediv__ = __div__ def __getattr__(self, name): + # When deepcopy is called, it creates and object without __init__, + # self.parsed is not initialized and it causes infinite recursion. + # More on this special ca sing here: + # https://stackoverflow.com/a/47300262/298182 + if name.startswith("__"): + raise AttributeError(name) return getattr(self.parsed, name) @cached_property diff --git a/tests/unit/test_path_info.py b/tests/unit/test_path_info.py index 46bd032b9..9ec73389b 100644 --- a/tests/unit/test_path_info.py +++ b/tests/unit/test_path_info.py @@ -1,4 +1,5 @@ import pytest +import copy from dvc.path_info import URLInfo, CloudURLInfo @@ -34,3 +35,10 @@ def test_url_info_parents(cls): cls("ssh://user@test.com/test1"), cls("ssh://user@test.com/"), ] + + +@pytest.mark.parametrize("cls", [URLInfo, CloudURLInfo]) +def test_url_info_deepcopy(cls): + u1 = cls("ssh://user@test.com:/test1/test2/test3") + u2 = copy.deepcopy(u1) + assert u1 == u2 From ef013c8472c6329cc183f33d6677a60e58feef35 Mon Sep 17 00:00:00 2001 From: Ivan Shcheklein Date: Sat, 20 Jul 2019 15:51:11 -0700 Subject: [PATCH 2/2] url info: minor fix typo in a comment --- dvc/path_info.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dvc/path_info.py b/dvc/path_info.py index 0366881dd..c7d0051d8 100644 --- a/dvc/path_info.py +++ b/dvc/path_info.py @@ -186,7 +186,7 @@ class URLInfo(object): def __getattr__(self, name): # When deepcopy is called, it creates and object without __init__, # self.parsed is not initialized and it causes infinite recursion. - # More on this special ca sing here: + # More on this special casing here: # https://stackoverflow.com/a/47300262/298182 if name.startswith("__"): raise AttributeError(name)