about summary refs log tree commit diff
path: root/.venv/lib/python3.12/site-packages/setuptools/tests/test_manifest.py
diff options
context:
space:
mode:
authorS. Solomon Darnell2025-03-28 21:52:21 -0500
committerS. Solomon Darnell2025-03-28 21:52:21 -0500
commit4a52a71956a8d46fcb7294ac71734504bb09bcc2 (patch)
treeee3dc5af3b6313e921cd920906356f5d4febc4ed /.venv/lib/python3.12/site-packages/setuptools/tests/test_manifest.py
parentcc961e04ba734dd72309fb548a2f97d67d578813 (diff)
downloadgn-ai-master.tar.gz
two version of R2R are here HEAD master
Diffstat (limited to '.venv/lib/python3.12/site-packages/setuptools/tests/test_manifest.py')
-rw-r--r--.venv/lib/python3.12/site-packages/setuptools/tests/test_manifest.py622
1 files changed, 622 insertions, 0 deletions
diff --git a/.venv/lib/python3.12/site-packages/setuptools/tests/test_manifest.py b/.venv/lib/python3.12/site-packages/setuptools/tests/test_manifest.py
new file mode 100644
index 00000000..903a528d
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/setuptools/tests/test_manifest.py
@@ -0,0 +1,622 @@
+"""sdist tests"""
+
+from __future__ import annotations
+
+import contextlib
+import io
+import itertools
+import logging
+import os
+import shutil
+import sys
+import tempfile
+
+import pytest
+
+from setuptools.command.egg_info import FileList, egg_info, translate_pattern
+from setuptools.dist import Distribution
+from setuptools.tests.textwrap import DALS
+
+from distutils import log
+from distutils.errors import DistutilsTemplateError
+
+IS_PYPY = '__pypy__' in sys.builtin_module_names
+
+
+def make_local_path(s):
+    """Converts '/' in a string to os.sep"""
+    return s.replace('/', os.sep)
+
+
+SETUP_ATTRS = {
+    'name': 'app',
+    'version': '0.0',
+    'packages': ['app'],
+}
+
+SETUP_PY = f"""\
+from setuptools import setup
+
+setup(**{SETUP_ATTRS!r})
+"""
+
+
+@contextlib.contextmanager
+def quiet():
+    old_stdout, old_stderr = sys.stdout, sys.stderr
+    sys.stdout, sys.stderr = io.StringIO(), io.StringIO()
+    try:
+        yield
+    finally:
+        sys.stdout, sys.stderr = old_stdout, old_stderr
+
+
+def touch(filename):
+    open(filename, 'wb').close()
+
+
+# The set of files always in the manifest, including all files in the
+# .egg-info directory
+default_files = frozenset(
+    map(
+        make_local_path,
+        [
+            'README.rst',
+            'MANIFEST.in',
+            'setup.py',
+            'app.egg-info/PKG-INFO',
+            'app.egg-info/SOURCES.txt',
+            'app.egg-info/dependency_links.txt',
+            'app.egg-info/top_level.txt',
+            'app/__init__.py',
+        ],
+    )
+)
+
+
+translate_specs: list[tuple[str, list[str], list[str]]] = [
+    ('foo', ['foo'], ['bar', 'foobar']),
+    ('foo/bar', ['foo/bar'], ['foo/bar/baz', './foo/bar', 'foo']),
+    # Glob matching
+    ('*.txt', ['foo.txt', 'bar.txt'], ['foo/foo.txt']),
+    ('dir/*.txt', ['dir/foo.txt', 'dir/bar.txt', 'dir/.txt'], ['notdir/foo.txt']),
+    ('*/*.py', ['bin/start.py'], []),
+    ('docs/page-?.txt', ['docs/page-9.txt'], ['docs/page-10.txt']),
+    # Globstars change what they mean depending upon where they are
+    (
+        'foo/**/bar',
+        ['foo/bing/bar', 'foo/bing/bang/bar', 'foo/bar'],
+        ['foo/abar'],
+    ),
+    (
+        'foo/**',
+        ['foo/bar/bing.py', 'foo/x'],
+        ['/foo/x'],
+    ),
+    (
+        '**',
+        ['x', 'abc/xyz', '@nything'],
+        [],
+    ),
+    # Character classes
+    (
+        'pre[one]post',
+        ['preopost', 'prenpost', 'preepost'],
+        ['prepost', 'preonepost'],
+    ),
+    (
+        'hello[!one]world',
+        ['helloxworld', 'helloyworld'],
+        ['hellooworld', 'helloworld', 'hellooneworld'],
+    ),
+    (
+        '[]one].txt',
+        ['o.txt', '].txt', 'e.txt'],
+        ['one].txt'],
+    ),
+    (
+        'foo[!]one]bar',
+        ['fooybar'],
+        ['foo]bar', 'fooobar', 'fooebar'],
+    ),
+]
+"""
+A spec of inputs for 'translate_pattern' and matches and mismatches
+for that input.
+"""
+
+match_params = itertools.chain.from_iterable(
+    zip(itertools.repeat(pattern), matches)
+    for pattern, matches, mismatches in translate_specs
+)
+
+
+@pytest.fixture(params=match_params)
+def pattern_match(request):
+    return map(make_local_path, request.param)
+
+
+mismatch_params = itertools.chain.from_iterable(
+    zip(itertools.repeat(pattern), mismatches)
+    for pattern, matches, mismatches in translate_specs
+)
+
+
+@pytest.fixture(params=mismatch_params)
+def pattern_mismatch(request):
+    return map(make_local_path, request.param)
+
+
+def test_translated_pattern_match(pattern_match):
+    pattern, target = pattern_match
+    assert translate_pattern(pattern).match(target)
+
+
+def test_translated_pattern_mismatch(pattern_mismatch):
+    pattern, target = pattern_mismatch
+    assert not translate_pattern(pattern).match(target)
+
+
+class TempDirTestCase:
+    def setup_method(self, method):
+        self.temp_dir = tempfile.mkdtemp()
+        self.old_cwd = os.getcwd()
+        os.chdir(self.temp_dir)
+
+    def teardown_method(self, method):
+        os.chdir(self.old_cwd)
+        shutil.rmtree(self.temp_dir)
+
+
+class TestManifestTest(TempDirTestCase):
+    def setup_method(self, method):
+        super().setup_method(method)
+
+        f = open(os.path.join(self.temp_dir, 'setup.py'), 'w', encoding="utf-8")
+        f.write(SETUP_PY)
+        f.close()
+        """
+        Create a file tree like:
+        - LICENSE
+        - README.rst
+        - testing.rst
+        - .hidden.rst
+        - app/
+            - __init__.py
+            - a.txt
+            - b.txt
+            - c.rst
+            - static/
+                - app.js
+                - app.js.map
+                - app.css
+                - app.css.map
+        """
+
+        for fname in ['README.rst', '.hidden.rst', 'testing.rst', 'LICENSE']:
+            touch(os.path.join(self.temp_dir, fname))
+
+        # Set up the rest of the test package
+        test_pkg = os.path.join(self.temp_dir, 'app')
+        os.mkdir(test_pkg)
+        for fname in ['__init__.py', 'a.txt', 'b.txt', 'c.rst']:
+            touch(os.path.join(test_pkg, fname))
+
+        # Some compiled front-end assets to include
+        static = os.path.join(test_pkg, 'static')
+        os.mkdir(static)
+        for fname in ['app.js', 'app.js.map', 'app.css', 'app.css.map']:
+            touch(os.path.join(static, fname))
+
+    def make_manifest(self, contents):
+        """Write a MANIFEST.in."""
+        manifest = os.path.join(self.temp_dir, 'MANIFEST.in')
+        with open(manifest, 'w', encoding="utf-8") as f:
+            f.write(DALS(contents))
+
+    def get_files(self):
+        """Run egg_info and get all the files to include, as a set"""
+        dist = Distribution(SETUP_ATTRS)
+        dist.script_name = 'setup.py'
+        cmd = egg_info(dist)
+        cmd.ensure_finalized()
+
+        cmd.run()
+
+        return set(cmd.filelist.files)
+
+    def test_no_manifest(self):
+        """Check a missing MANIFEST.in includes only the standard files."""
+        assert (default_files - set(['MANIFEST.in'])) == self.get_files()
+
+    def test_empty_files(self):
+        """Check an empty MANIFEST.in includes only the standard files."""
+        self.make_manifest("")
+        assert default_files == self.get_files()
+
+    def test_include(self):
+        """Include extra rst files in the project root."""
+        self.make_manifest("include *.rst")
+        files = default_files | set(['testing.rst', '.hidden.rst'])
+        assert files == self.get_files()
+
+    def test_exclude(self):
+        """Include everything in app/ except the text files"""
+        ml = make_local_path
+        self.make_manifest(
+            """
+            include app/*
+            exclude app/*.txt
+            """
+        )
+        files = default_files | set([ml('app/c.rst')])
+        assert files == self.get_files()
+
+    def test_include_multiple(self):
+        """Include with multiple patterns."""
+        ml = make_local_path
+        self.make_manifest("include app/*.txt app/static/*")
+        files = default_files | set([
+            ml('app/a.txt'),
+            ml('app/b.txt'),
+            ml('app/static/app.js'),
+            ml('app/static/app.js.map'),
+            ml('app/static/app.css'),
+            ml('app/static/app.css.map'),
+        ])
+        assert files == self.get_files()
+
+    def test_graft(self):
+        """Include the whole app/static/ directory."""
+        ml = make_local_path
+        self.make_manifest("graft app/static")
+        files = default_files | set([
+            ml('app/static/app.js'),
+            ml('app/static/app.js.map'),
+            ml('app/static/app.css'),
+            ml('app/static/app.css.map'),
+        ])
+        assert files == self.get_files()
+
+    def test_graft_glob_syntax(self):
+        """Include the whole app/static/ directory."""
+        ml = make_local_path
+        self.make_manifest("graft */static")
+        files = default_files | set([
+            ml('app/static/app.js'),
+            ml('app/static/app.js.map'),
+            ml('app/static/app.css'),
+            ml('app/static/app.css.map'),
+        ])
+        assert files == self.get_files()
+
+    def test_graft_global_exclude(self):
+        """Exclude all *.map files in the project."""
+        ml = make_local_path
+        self.make_manifest(
+            """
+            graft app/static
+            global-exclude *.map
+            """
+        )
+        files = default_files | set([ml('app/static/app.js'), ml('app/static/app.css')])
+        assert files == self.get_files()
+
+    def test_global_include(self):
+        """Include all *.rst, *.js, and *.css files in the whole tree."""
+        ml = make_local_path
+        self.make_manifest(
+            """
+            global-include *.rst *.js *.css
+            """
+        )
+        files = default_files | set([
+            '.hidden.rst',
+            'testing.rst',
+            ml('app/c.rst'),
+            ml('app/static/app.js'),
+            ml('app/static/app.css'),
+        ])
+        assert files == self.get_files()
+
+    def test_graft_prune(self):
+        """Include all files in app/, except for the whole app/static/ dir."""
+        ml = make_local_path
+        self.make_manifest(
+            """
+            graft app
+            prune app/static
+            """
+        )
+        files = default_files | set([ml('app/a.txt'), ml('app/b.txt'), ml('app/c.rst')])
+        assert files == self.get_files()
+
+
+class TestFileListTest(TempDirTestCase):
+    """
+    A copy of the relevant bits of distutils/tests/test_filelist.py,
+    to ensure setuptools' version of FileList keeps parity with distutils.
+    """
+
+    @pytest.fixture(autouse=os.getenv("SETUPTOOLS_USE_DISTUTILS") == "stdlib")
+    def _compat_record_logs(self, monkeypatch, caplog):
+        """Account for stdlib compatibility"""
+
+        def _log(_logger, level, msg, args):
+            exc = sys.exc_info()
+            rec = logging.LogRecord("distutils", level, "", 0, msg, args, exc)
+            caplog.records.append(rec)
+
+        monkeypatch.setattr(log.Log, "_log", _log)
+
+    def get_records(self, caplog, *levels):
+        return [r for r in caplog.records if r.levelno in levels]
+
+    def assertNoWarnings(self, caplog):
+        assert self.get_records(caplog, log.WARN) == []
+        caplog.clear()
+
+    def assertWarnings(self, caplog):
+        if IS_PYPY and not caplog.records:
+            pytest.xfail("caplog checks may not work well in PyPy")
+        else:
+            assert len(self.get_records(caplog, log.WARN)) > 0
+            caplog.clear()
+
+    def make_files(self, files):
+        for file in files:
+            file = os.path.join(self.temp_dir, file)
+            dirname, _basename = os.path.split(file)
+            os.makedirs(dirname, exist_ok=True)
+            touch(file)
+
+    def test_process_template_line(self):
+        # testing  all MANIFEST.in template patterns
+        file_list = FileList()
+        ml = make_local_path
+
+        # simulated file list
+        self.make_files([
+            'foo.tmp',
+            'ok',
+            'xo',
+            'four.txt',
+            'buildout.cfg',
+            # filelist does not filter out VCS directories,
+            # it's sdist that does
+            ml('.hg/last-message.txt'),
+            ml('global/one.txt'),
+            ml('global/two.txt'),
+            ml('global/files.x'),
+            ml('global/here.tmp'),
+            ml('f/o/f.oo'),
+            ml('dir/graft-one'),
+            ml('dir/dir2/graft2'),
+            ml('dir3/ok'),
+            ml('dir3/sub/ok.txt'),
+        ])
+
+        MANIFEST_IN = DALS(
+            """\
+        include ok
+        include xo
+        exclude xo
+        include foo.tmp
+        include buildout.cfg
+        global-include *.x
+        global-include *.txt
+        global-exclude *.tmp
+        recursive-include f *.oo
+        recursive-exclude global *.x
+        graft dir
+        prune dir3
+        """
+        )
+
+        for line in MANIFEST_IN.split('\n'):
+            if not line:
+                continue
+            file_list.process_template_line(line)
+
+        wanted = [
+            'buildout.cfg',
+            'four.txt',
+            'ok',
+            ml('.hg/last-message.txt'),
+            ml('dir/graft-one'),
+            ml('dir/dir2/graft2'),
+            ml('f/o/f.oo'),
+            ml('global/one.txt'),
+            ml('global/two.txt'),
+        ]
+
+        file_list.sort()
+        assert file_list.files == wanted
+
+    def test_exclude_pattern(self):
+        # return False if no match
+        file_list = FileList()
+        assert not file_list.exclude_pattern('*.py')
+
+        # return True if files match
+        file_list = FileList()
+        file_list.files = ['a.py', 'b.py']
+        assert file_list.exclude_pattern('*.py')
+
+        # test excludes
+        file_list = FileList()
+        file_list.files = ['a.py', 'a.txt']
+        file_list.exclude_pattern('*.py')
+        file_list.sort()
+        assert file_list.files == ['a.txt']
+
+    def test_include_pattern(self):
+        # return False if no match
+        file_list = FileList()
+        self.make_files([])
+        assert not file_list.include_pattern('*.py')
+
+        # return True if files match
+        file_list = FileList()
+        self.make_files(['a.py', 'b.txt'])
+        assert file_list.include_pattern('*.py')
+
+        # test * matches all files
+        file_list = FileList()
+        self.make_files(['a.py', 'b.txt'])
+        file_list.include_pattern('*')
+        file_list.sort()
+        assert file_list.files == ['a.py', 'b.txt']
+
+    def test_process_template_line_invalid(self):
+        # invalid lines
+        file_list = FileList()
+        for action in (
+            'include',
+            'exclude',
+            'global-include',
+            'global-exclude',
+            'recursive-include',
+            'recursive-exclude',
+            'graft',
+            'prune',
+            'blarg',
+        ):
+            with pytest.raises(DistutilsTemplateError):
+                file_list.process_template_line(action)
+
+    def test_include(self, caplog):
+        caplog.set_level(logging.DEBUG)
+        ml = make_local_path
+        # include
+        file_list = FileList()
+        self.make_files(['a.py', 'b.txt', ml('d/c.py')])
+
+        file_list.process_template_line('include *.py')
+        file_list.sort()
+        assert file_list.files == ['a.py']
+        self.assertNoWarnings(caplog)
+
+        file_list.process_template_line('include *.rb')
+        file_list.sort()
+        assert file_list.files == ['a.py']
+        self.assertWarnings(caplog)
+
+    def test_exclude(self, caplog):
+        caplog.set_level(logging.DEBUG)
+        ml = make_local_path
+        # exclude
+        file_list = FileList()
+        file_list.files = ['a.py', 'b.txt', ml('d/c.py')]
+
+        file_list.process_template_line('exclude *.py')
+        file_list.sort()
+        assert file_list.files == ['b.txt', ml('d/c.py')]
+        self.assertNoWarnings(caplog)
+
+        file_list.process_template_line('exclude *.rb')
+        file_list.sort()
+        assert file_list.files == ['b.txt', ml('d/c.py')]
+        self.assertWarnings(caplog)
+
+    def test_global_include(self, caplog):
+        caplog.set_level(logging.DEBUG)
+        ml = make_local_path
+        # global-include
+        file_list = FileList()
+        self.make_files(['a.py', 'b.txt', ml('d/c.py')])
+
+        file_list.process_template_line('global-include *.py')
+        file_list.sort()
+        assert file_list.files == ['a.py', ml('d/c.py')]
+        self.assertNoWarnings(caplog)
+
+        file_list.process_template_line('global-include *.rb')
+        file_list.sort()
+        assert file_list.files == ['a.py', ml('d/c.py')]
+        self.assertWarnings(caplog)
+
+    def test_global_exclude(self, caplog):
+        caplog.set_level(logging.DEBUG)
+        ml = make_local_path
+        # global-exclude
+        file_list = FileList()
+        file_list.files = ['a.py', 'b.txt', ml('d/c.py')]
+
+        file_list.process_template_line('global-exclude *.py')
+        file_list.sort()
+        assert file_list.files == ['b.txt']
+        self.assertNoWarnings(caplog)
+
+        file_list.process_template_line('global-exclude *.rb')
+        file_list.sort()
+        assert file_list.files == ['b.txt']
+        self.assertWarnings(caplog)
+
+    def test_recursive_include(self, caplog):
+        caplog.set_level(logging.DEBUG)
+        ml = make_local_path
+        # recursive-include
+        file_list = FileList()
+        self.make_files(['a.py', ml('d/b.py'), ml('d/c.txt'), ml('d/d/e.py')])
+
+        file_list.process_template_line('recursive-include d *.py')
+        file_list.sort()
+        assert file_list.files == [ml('d/b.py'), ml('d/d/e.py')]
+        self.assertNoWarnings(caplog)
+
+        file_list.process_template_line('recursive-include e *.py')
+        file_list.sort()
+        assert file_list.files == [ml('d/b.py'), ml('d/d/e.py')]
+        self.assertWarnings(caplog)
+
+    def test_recursive_exclude(self, caplog):
+        caplog.set_level(logging.DEBUG)
+        ml = make_local_path
+        # recursive-exclude
+        file_list = FileList()
+        file_list.files = ['a.py', ml('d/b.py'), ml('d/c.txt'), ml('d/d/e.py')]
+
+        file_list.process_template_line('recursive-exclude d *.py')
+        file_list.sort()
+        assert file_list.files == ['a.py', ml('d/c.txt')]
+        self.assertNoWarnings(caplog)
+
+        file_list.process_template_line('recursive-exclude e *.py')
+        file_list.sort()
+        assert file_list.files == ['a.py', ml('d/c.txt')]
+        self.assertWarnings(caplog)
+
+    def test_graft(self, caplog):
+        caplog.set_level(logging.DEBUG)
+        ml = make_local_path
+        # graft
+        file_list = FileList()
+        self.make_files(['a.py', ml('d/b.py'), ml('d/d/e.py'), ml('f/f.py')])
+
+        file_list.process_template_line('graft d')
+        file_list.sort()
+        assert file_list.files == [ml('d/b.py'), ml('d/d/e.py')]
+        self.assertNoWarnings(caplog)
+
+        file_list.process_template_line('graft e')
+        file_list.sort()
+        assert file_list.files == [ml('d/b.py'), ml('d/d/e.py')]
+        self.assertWarnings(caplog)
+
+    def test_prune(self, caplog):
+        caplog.set_level(logging.DEBUG)
+        ml = make_local_path
+        # prune
+        file_list = FileList()
+        file_list.files = ['a.py', ml('d/b.py'), ml('d/d/e.py'), ml('f/f.py')]
+
+        file_list.process_template_line('prune d')
+        file_list.sort()
+        assert file_list.files == ['a.py', ml('f/f.py')]
+        self.assertNoWarnings(caplog)
+
+        file_list.process_template_line('prune e')
+        file_list.sort()
+        assert file_list.files == ['a.py', ml('f/f.py')]
+        self.assertWarnings(caplog)