From 525dbbe88e5479f5e730cde011df7e33e365275c Mon Sep 17 00:00:00 2001 From: Martin Owens Date: Sun, 29 Mar 2020 21:50:07 -0400 Subject: [PATCH 1/4] Test different namespaces for namespace conflicts when importing submodules --- tests/test_inkex.py | 64 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) create mode 100644 tests/test_inkex.py diff --git a/tests/test_inkex.py b/tests/test_inkex.py new file mode 100644 index 000000000..5a83172fc --- /dev/null +++ b/tests/test_inkex.py @@ -0,0 +1,64 @@ +# +# Copyright (C) 2020 Martin Owens +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA. +# +""" +Test API collisions and other inkex portions that don't fit elsewhere. +""" + +from unittest import TestCase as BaseCase + +import inkex +import inkex.paths +import inkex.elements +from inkex.utils import PY3 + +class MyGlobals(dict): + """Python 3.3 and above globals dictionary""" + def __setitem__(self, name, value): + # This only works because setitem is called during construction It + # does not work for getitem and that's why the python docs discourage + # the use of an inherited dictionary class for exec globals. + if name in self and value != self[name]: + raise KeyError("While importing {} the API name {} was imported twice"\ + .format(self['__name__'], name)) + super(MyGlobals, self).__setitem__(name, value) + +class TestModuleCollisions(BaseCase): + """Test imports to make sure the API is clean""" + def assertNoCollisions(self, module): # pylint: disable=invalid-name + """Make sure there are no API collisions in the give module on import""" + if not PY3: + self.skipTest("API testing python 3.3 and above only.") + + with open(module.__file__, 'r') as fhl: + # name and package are esential to the exec pretending to + # be an actual module during import (and not a script) + exec(fhl.read(), MyGlobals({ # pylint: disable=exec-used + '__name__': module.__name__, + '__package__': module.__package__})) + + def test_inkex(self): + """Test inkex API have no collisions""" + self.assertNoCollisions(inkex) + + def test_inkex_elements(self): + """Test elements API have no collisions""" + self.assertNoCollisions(inkex.elements) + + def test_inkex_paths(self): + """Test elements API have no collisions""" + self.assertNoCollisions(inkex.paths) -- GitLab From 661959e2c3f836d1719feae67421bcb38a092bd8 Mon Sep 17 00:00:00 2001 From: Martin Owens Date: Tue, 31 Mar 2020 11:13:31 -0400 Subject: [PATCH 2/4] Fix doc string --- tests/test_inkex.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_inkex.py b/tests/test_inkex.py index 5a83172fc..af8ab6dbb 100644 --- a/tests/test_inkex.py +++ b/tests/test_inkex.py @@ -60,5 +60,5 @@ class TestModuleCollisions(BaseCase): self.assertNoCollisions(inkex.elements) def test_inkex_paths(self): - """Test elements API have no collisions""" + """Test paths API have no collisions""" self.assertNoCollisions(inkex.paths) -- GitLab From d2d2d5fb5c05958b6a477d1414a7453163b4455a Mon Sep 17 00:00:00 2001 From: Martin Owens Date: Tue, 31 Mar 2020 11:15:25 -0400 Subject: [PATCH 3/4] Tighten the comparison in inkex module conflict testing --- tests/test_inkex.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_inkex.py b/tests/test_inkex.py index af8ab6dbb..06573b180 100644 --- a/tests/test_inkex.py +++ b/tests/test_inkex.py @@ -32,7 +32,7 @@ class MyGlobals(dict): # This only works because setitem is called during construction It # does not work for getitem and that's why the python docs discourage # the use of an inherited dictionary class for exec globals. - if name in self and value != self[name]: + if name in self and value is not self[name]: raise KeyError("While importing {} the API name {} was imported twice"\ .format(self['__name__'], name)) super(MyGlobals, self).__setitem__(name, value) -- GitLab From e23bbe7a851c1edab65dc1417ae3d758823b0ccf Mon Sep 17 00:00:00 2001 From: Martin Owens Date: Tue, 31 Mar 2020 15:06:14 -0400 Subject: [PATCH 4/4] Refactor collision error message for clarity. --- tests/test_inkex.py | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/tests/test_inkex.py b/tests/test_inkex.py index 06573b180..1f550dd66 100644 --- a/tests/test_inkex.py +++ b/tests/test_inkex.py @@ -26,16 +26,19 @@ import inkex.paths import inkex.elements from inkex.utils import PY3 -class MyGlobals(dict): +class ProtectiveGlobals(dict): """Python 3.3 and above globals dictionary""" def __setitem__(self, name, value): # This only works because setitem is called during construction It # does not work for getitem and that's why the python docs discourage # the use of an inherited dictionary class for exec globals. if name in self and value is not self[name]: - raise KeyError("While importing {} the API name {} was imported twice"\ - .format(self['__name__'], name)) - super(MyGlobals, self).__setitem__(name, value) + assert value is self[name], ( + "While importing {} the API name `{}` was re-defined:" + "\n\t1. {}" + "\n\t2. {}" + ).format(self['__name__'], name, repr(value), repr(self[name])) + super(ProtectiveGlobals, self).__setitem__(name, value) class TestModuleCollisions(BaseCase): """Test imports to make sure the API is clean""" @@ -47,7 +50,7 @@ class TestModuleCollisions(BaseCase): with open(module.__file__, 'r') as fhl: # name and package are esential to the exec pretending to # be an actual module during import (and not a script) - exec(fhl.read(), MyGlobals({ # pylint: disable=exec-used + exec(fhl.read(), ProtectiveGlobals({ # pylint: disable=exec-used '__name__': module.__name__, '__package__': module.__package__})) @@ -58,7 +61,3 @@ class TestModuleCollisions(BaseCase): def test_inkex_elements(self): """Test elements API have no collisions""" self.assertNoCollisions(inkex.elements) - - def test_inkex_paths(self): - """Test paths API have no collisions""" - self.assertNoCollisions(inkex.paths) -- GitLab