Commit 0d53a6d1 authored by Carlos Ramos Carreño's avatar Carlos Ramos Carreño Committed by Kirill Smelkov

setup: Require a minimum setuptools version for Python 3.

When the `setuptools_dso` module is used having older versions of
setuptools installed, the `wheel` module (one of its dependencies)
sets up a handler for the root logging that writes to stdout
(https://github.com/pypa/wheel/issues/622).
This breaks the expected output of the programs, and thus the
wendelin.core tests.

However, if `setuptools.logging` is available, `wheel` will use it
instead and it won't set up a handler.
Thus, I added a explicit dependency to a version of setuptools above
60.2 for Python 3, as that is the first version that provides this
module.

--------
kirr:

Move setuptools pinning close to setuptools_dso requirement to which it
relates and add corresponding comment. Setuptools pinning also fixes e.g.
the following test failure inside pygolang itself:

    golang/golang_str_test.py::test_strings_print FAILED

    ============================== FAILURES ==============================
    _________________________ test_strings_print _________________________

        def test_strings_print():
            outok = readfile(dir_testprog + "/golang_test_str.txt")
            retcode, stdout, stderr = _pyrun(["golang_test_str.py"],
                                        cwd=dir_testprog, stdout=PIPE, stderr=PIPE)
            assert retcode == 0, (stdout, stderr)
            assert stderr == b""
    >       assertDoc(outok, stdout)

    golang/golang_str_test.py:121:
    _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

    want = 'print(qq(b)): "привет αβγ b"\nprint(qq(u)): "привет αβγ u"\n'
    got = 'Extend DSO search path to \'PYGOLANG/golang/runtime\'\nprint(qq(b)): "привет αβγ b"\nprint(qq(u)): "привет αβγ u"\n'

        def assertDoc(want, got):
            want = u(want)
            got  = u(got)

            # normalize got to PYGOLANG
            udir_pygolang = abbrev_home(dir_pygolang)    # /home/x/.../pygolang -> ~/.../pygolang
            got = got.replace(dir_pygolang,  "PYGOLANG") # /home/x/.../pygolang -> PYGOLANG
            got = got.replace(udir_pygolang, "PYGOLANG") # ~/.../pygolang       -> PYGOLANG

            # got: normalize PYGOLANG\a\b\c -> PYGOLANG/a/b/c
            #                a\b\c\d.py  -> a/b/c/d.py
            def _(m):
                return m.group(0).replace(os.path.sep, '/')
            got = re.sub(r"(?<=PYGOLANG)[^\s]+(?=\s)",  _, got)
            got = re.sub(r"([\w\\\.]+)(?=\.py)",        _, got)

            # want: process conditionals
            # PY39(...) -> ...   if py ≥ 3.9 else ø  (inline)
            # `... +PY39` -> ... if py ≥ 3.9 else ø  (whole line)
            # `... -PY39` -> ... if py < 3.9 else ø  (whole line)
            have = {}  # 'PYxy' -> y/n
            for minor in (9,10,11):
                have['PY3%d' % minor] = (sys.version_info >= (3, minor))
            for x, havex in have.items():
                want = re.sub(r"%s\((.*)\)" % x, r"\1" if havex else "", want)
                r = re.compile(r'^(?P<main>.*?) +(?P<y>(\+|-))%s$' % x)
                v = []
                for l in want.splitlines():
                    m = r.match(l)
                    if m is not None:
                        l = m.group('main')
                        y = {'+':True, '-':False}[m.group('y')]
                        if (y and not havex) or (havex and not y):
                            continue
                    v.append(l)
                want = '\n'.join(v)+'\n'

            # want: ^$ -> <BLANKLINE>
            while "\n\n" in want:
                want = want.replace("\n\n", "\n<BLANKLINE>\n")

            X = doctest.OutputChecker()
            if not X.check_output(want, got, doctest.ELLIPSIS):
                # output_difference wants Example object with .want attr
                class Ex: pass
                _ = Ex()
                _.want = want
    >           fail("not equal:\n" + X.output_difference(_, got,
                            doctest.ELLIPSIS | doctest.REPORT_UDIFF))
    E           Failed: not equal:
    E           Expected:
    E               print(qq(b)): "привет αβγ b"
    E               print(qq(u)): "привет αβγ u"
    E           Got:
    E               Extend DSO search path to 'PYGOLANG/golang/runtime'
    E               print(qq(b)): "привет αβγ b"
    E               print(qq(u)): "привет αβγ u"

see e.g. https://stack.nexedi.com/test_result_module/20240509-389AC427/3
for details.

/reviewed-by @kirr
/reviewed-on !27
parent 044deb35
# -*- coding: utf-8 -*-
# pygolang | pythonic package setup # pygolang | pythonic package setup
# Copyright (C) 2018-2024 Nexedi SA and Contributors. # Copyright (C) 2018-2024 Nexedi SA and Contributors.
# Kirill Smelkov <kirr@nexedi.com> # Kirill Smelkov <kirr@nexedi.com>
...@@ -320,7 +321,10 @@ setup( ...@@ -320,7 +321,10 @@ setup(
install_requires = ['gevent', 'six', 'decorator', 'Importing;python_version<="2.7"', install_requires = ['gevent', 'six', 'decorator', 'Importing;python_version<="2.7"',
# only runtime part: for dylink_prepare_dso # only runtime part: for dylink_prepare_dso
# also need to pin setuptools ≥ 60.2 because else wheel configures logging
# to go to stdout and so dylink_prepare_dso garbles program output
'setuptools_dso >= 2.8', 'setuptools_dso >= 2.8',
'setuptools >= 60.2 ; python_version>="3"',
# pyx.build -> setuptools_dso uses multiprocessing # pyx.build -> setuptools_dso uses multiprocessing
# setuptools_dso uses multiprocessing only on Python3, and only on systems where # setuptools_dso uses multiprocessing only on Python3, and only on systems where
# mp.get_start_method()!='fork', while geventmp does not work on windows. # mp.get_start_method()!='fork', while geventmp does not work on windows.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment