Abhilash Raj pushed to branch master at GNU Mailman / Mailman Core


Commits:
f0aae233 by Abhilash Raj at 2020-04-10T05:52:00+00:00
Wrap importlib.resources.path for divergent behaviors.

Create a new utility function which makes it easy to patch Mailman to work with
standard library importlib.resources by patching the divergent behavior with a
utility function.

- - - - -
31867019 by Abhilash Raj at 2020-04-10T05:52:00+00:00
Merge branch 'importlib-resources' into 'master'

Wrap importlib.resources.path for divergent behaviors.

See merge request mailman/mailman!615
- - - - -


4 changed files:

- src/mailman/utilities/filesystem.py
- src/mailman/utilities/i18n.py
- src/mailman/utilities/tests/test_modules.py
- src/mailman/utilities/tests/test_templates.py


Changes:

=====================================
src/mailman/utilities/filesystem.py
=====================================
@@ -86,6 +86,7 @@ def safe_remove(path):
         os.remove(path)
 
 
+@public
 def first_inexistent_directory(path):
     """Splits iteratively a path until it gives the first non-existent
     directory in the tree.
@@ -108,3 +109,31 @@ def first_inexistent_directory(path):
                 "The path %s exists but is not a directory.",
                 directory)
         directory, rhs = os.path.split(directory)
+
+
+@public
+def path(package, module, *args, **kw):
+    """Wrap around importlib.resources.path.
+
+    importlib_resources.path (PyPI package we use for compatibility in Python <
+    3.7) has now diverged in behavior from importlib.resources.path (in Python
+    >= 3.7), especially in terms of supporting directories. Even though we can
+    just jump to the new version of the library, many distributions packaging
+    Mailman do not package importlib_resources at all and instead patch the
+    source code to simply replace importlib_resources with importlib.resources.
+
+    This utility method is meant to keep that patching ability without any
+    complicated patches to make Mailman work with standard library
+    importlib.resources. This is only supposed to be used where the divergent
+    behavior causes problems for us.
+    """
+    # Note to packaging teams: This function will handle both standard library
+    # and 3rd party importlib_resources package. Please do not patch it.
+    try:
+        from importlib.resources import path
+        return path(package, module, *args, **kw)
+    except ImportError:                                       # pragma: nocover
+        from importlib_resources import files                 # pragma: nocover
+        if module:                                            # pragma: nocover
+            package = '{}.{}'.format(package, module)         # pragma: nocover
+        return files(package, *args, **kw)                    # pragma: nocover


=====================================
src/mailman/utilities/i18n.py
=====================================
@@ -21,11 +21,11 @@ import os
 import sys
 
 from contextlib import ExitStack
-from importlib_resources import files
 from itertools import product
 from mailman.config import config
 from mailman.core.constants import system_preferences
 from mailman.interfaces.errors import MailmanError
+from mailman.utilities.filesystem import path
 from public import public
 
 
@@ -114,7 +114,7 @@ def search(resources, template_file, mlist=None, 
language=None):
         languages.append(language)
     languages.reverse()
     # The non-language qualified $template_dir paths in search order.
-    templates_dir = str(resources.enter_context(files('mailman.templates')))
+    templates_dir = str(resources.enter_context(path('mailman', 'templates')))
     paths = [templates_dir, os.path.join(config.TEMPLATE_DIR, 'site')]
     if mlist is not None:
         # Don't forget these are in REVERSE search order!


=====================================
src/mailman/utilities/tests/test_modules.py
=====================================
@@ -22,11 +22,11 @@ import sys
 import unittest
 
 from contextlib import ExitStack, contextmanager
-from importlib_resources import files
 from mailman.interfaces.rules import IRule
 from mailman.interfaces.styles import IStyle
 from mailman.testing.helpers import configuration
 from mailman.testing.layers import ConfigLayer
+from mailman.utilities.filesystem import path
 from mailman.utilities.modules import (
     find_components, find_pluggable_components, hacked_sys_modules)
 from pathlib import Path
@@ -162,7 +162,7 @@ class AbstractStyle:
     def test_find_pluggable_components_by_plugin_name(self):
         with ExitStack() as resources:
             testing_path = resources.enter_context(
-                files('mailman.plugins.testing'))
+                path('mailman.plugins.testing',  ''))
             resources.enter_context(hack_syspath(0, str(testing_path)))
             resources.enter_context(configuration('plugin.example', **{
                 'class': 'example.hooks.ExamplePlugin',
@@ -174,7 +174,7 @@ class AbstractStyle:
     def test_find_pluggable_components_by_component_package(self):
         with ExitStack() as resources:
             testing_path = resources.enter_context(
-                files('mailman.plugins.testing'))
+                path('mailman.plugins.testing', ''))
             resources.enter_context(hack_syspath(0, str(testing_path)))
             resources.enter_context(configuration('plugin.example', **{
                 'class': 'example.hooks.ExamplePlugin',


=====================================
src/mailman/utilities/tests/test_templates.py
=====================================
@@ -23,11 +23,11 @@ import tempfile
 import unittest
 
 from contextlib import ExitStack
-from importlib_resources import files as resource_path
 from mailman.app.lifecycle import create_list
 from mailman.config import config
 from mailman.interfaces.languages import ILanguageManager
 from mailman.testing.layers import ConfigLayer
+from mailman.utilities.filesystem import path as resource_path
 from mailman.utilities.i18n import TemplateNotFoundError, find, search
 from zope.component import getUtility
 
@@ -64,7 +64,7 @@ class TestSearchOrder(unittest.TestCase):
         # /m/ as the root.
         with ExitStack() as resources:
             in_tree = str(resources.enter_context(
-                resource_path('mailman.templates')).parent)
+                resource_path('mailman', 'templates')).parent)
             raw_search_order = search(
                 resources, template_file, mailing_list, language)
         for path in raw_search_order:



View it on GitLab: 
https://gitlab.com/mailman/mailman/-/compare/a565d3e3bc6f68e7ec87082e8edff0e7490823d3...318670193143f268394dbe834ec6a87de04f8ec5

-- 
View it on GitLab: 
https://gitlab.com/mailman/mailman/-/compare/a565d3e3bc6f68e7ec87082e8edff0e7490823d3...318670193143f268394dbe834ec6a87de04f8ec5
You're receiving this email because of your account on gitlab.com.


_______________________________________________
Mailman-checkins mailing list
Mailman-checkins@python.org
Unsubscribe: 
https://mail.python.org/mailman/options/mailman-checkins/archive%40jab.org

Reply via email to