commit:     86c0328e98c5f0e0bf8e8db163b03953c6d92467
Author:     Louis Sautier <sbraz <AT> gentoo <DOT> org>
AuthorDate: Wed Oct  7 10:42:37 2020 +0000
Commit:     Louis Sautier <sbraz <AT> gentoo <DOT> org>
CommitDate: Wed Oct  7 16:30:04 2020 +0000
URL:        https://gitweb.gentoo.org/repo/gentoo.git/commit/?id=86c0328e

dev-python/mypy: bump to 0.782, add Py3.9 support, fix tests

Also:
* Fetch the package from PyPI, removes the need to get typeshed
  separately and simplifies pre-build steps.
* Run tests directly with pytest, allowing us to remove code checkers from
  dependencies.
* Use distutils_enable_sphinx to build the doc.
* Remove live ebuild logic as no such ebuild is present.
* Use EAPI 7.

Closes: https://bugs.gentoo.org/739694
Package-Manager: Portage-3.0.8, Repoman-3.0.1
Signed-off-by: Louis Sautier <sbraz <AT> gentoo.org>

 dev-python/mypy/Manifest                          |   1 +
 dev-python/mypy/files/mypy-0.782-conftest.patch   |  24 +++
 dev-python/mypy/files/mypy-0.782-py39-fixes.patch | 138 ++++++++++++++
 dev-python/mypy/files/mypy-0.782-pytest-6.patch   | 210 ++++++++++++++++++++++
 dev-python/mypy/mypy-0.782.ebuild                 |  58 ++++++
 5 files changed, 431 insertions(+)

diff --git a/dev-python/mypy/Manifest b/dev-python/mypy/Manifest
index 523c9a998a2..767904fcde5 100644
--- a/dev-python/mypy/Manifest
+++ b/dev-python/mypy/Manifest
@@ -1,2 +1,3 @@
 DIST mypy-0.781.tar.gz 2056785 BLAKE2B 
aa95d71400d5d46223a141adae5a8d797d2f076d3b6b48a7c09db6f7f3f2193d571368759f0ca307331d8e8c241b0322e758716a10fabccca3aaa6b733a63347
 SHA512 
dd3173115720510b278d15f5083a57fdb41582dfcaaf16e587116e41e87d608f4e226b61a978f4b41ef6b5ec6d3d9279facd65c0a74888b367171dcbe25550f2
+DIST mypy-0.782.tar.gz 2529814 BLAKE2B 
c75771fb40524c2c8675236eaaddd6e39d13b4fd4f6f15f279b2e0be75eb0630987cb90f31bd7c65c4a322de4915d3a260e8f6f375b49157fea4b6362316f333
 SHA512 
f94433f79ea76b53ebb70589ca04ba3f39847050f73cf6deac00a3db13d742613a8ecb1a11fb84a878458025c6776b236b074e93e577c1b597e31d1300974767
 DIST mypy-typeshed-0.781-e199c2e.tar.gz 541588 BLAKE2B 
f663d0feccffb315efd1b6e3ebc54bbe3cf4c7873c240ed54c7be1042807e2213326db8756b5a540fd9bf5ae95a2c0850e8cb35ae2e849ec3e9a628367fabe72
 SHA512 
57f3159d909799838779c04ccc6541322c27c01efb026c26a145676fa75076f64b8cd3e99f7488501582c743e1102cad59320512d52d4a058d8731c54c0705cd

diff --git a/dev-python/mypy/files/mypy-0.782-conftest.patch 
b/dev-python/mypy/files/mypy-0.782-conftest.patch
new file mode 100644
index 00000000000..08da1b1b690
--- /dev/null
+++ b/dev-python/mypy/files/mypy-0.782-conftest.patch
@@ -0,0 +1,24 @@
+diff --git a/conftest.py b/conftest.py
+new file mode 100644
+index 00000000..83a6689f
+--- /dev/null
++++ b/conftest.py
+@@ -0,0 +1,18 @@
++import os.path
++
++pytest_plugins = [
++    'mypy.test.data',
++]
++
++
++def pytest_configure(config):
++    mypy_source_root = os.path.dirname(os.path.abspath(__file__))
++    if os.getcwd() != mypy_source_root:
++        os.chdir(mypy_source_root)
++
++
++# This function name is special to pytest.  See
++# 
http://doc.pytest.org/en/latest/writing_plugins.html#initialization-command-line-and-configuration-hooks
++def pytest_addoption(parser) -> None:
++    parser.addoption('--bench', action='store_true', default=False,
++                     help='Enable the benchmark test runs')

diff --git a/dev-python/mypy/files/mypy-0.782-py39-fixes.patch 
b/dev-python/mypy/files/mypy-0.782-py39-fixes.patch
new file mode 100644
index 00000000000..16c12daecae
--- /dev/null
+++ b/dev-python/mypy/files/mypy-0.782-py39-fixes.patch
@@ -0,0 +1,138 @@
+From 13ae58ffe8bedb7da9f4c657297f0d61e681d671 Mon Sep 17 00:00:00 2001
+From: Shantanu <12621235+hauntsani...@users.noreply.github.com>
+Date: Sun, 30 Aug 2020 18:11:57 -0700
+Subject: [PATCH] mypy: get CI green for py39 (#9376)
+
+Due to Python 3.9's new parser, this has a different (and better) error
+message on Python 3.9.
+
+This is effectively a test of typed_ast / ast, so I don't think it
+matters too much. I'm happy to alternatively just get rid of the test
+altogether, or if people feel strongly, come up with a way to run the
+test when run with older Pythons.
+
+Co-authored-by: hauntsaninja <>
+---
+ .travis.yml                        | 3 ---
+ mypy/test/testcheck.py             | 2 ++
+ test-data/unit/check-kwargs.test   | 7 -------
+ test-data/unit/check-python39.test | 9 +++++++++
+ 4 files changed, 11 insertions(+), 10 deletions(-)
+ create mode 100644 test-data/unit/check-python39.test
+
+diff --git a/mypy/test/testcheck.py b/mypy/test/testcheck.py
+index 49a85861b6..39a35c7280 100644
+--- a/mypy/test/testcheck.py
++++ b/mypy/test/testcheck.py
+@@ -94,6 +94,8 @@
+ # Tests that use Python 3.8-only AST features (like expression-scoped 
ignores):
+ if sys.version_info >= (3, 8):
+     typecheck_files.append('check-python38.test')
++if sys.version_info >= (3, 9):
++    typecheck_files.append('check-python39.test')
+ 
+ # Special tests for platforms with case-insensitive filesystems.
+ if sys.platform in ('darwin', 'win32'):
+diff --git a/test-data/unit/check-kwargs.test 
b/test-data/unit/check-kwargs.test
+index 1dd450caae..a587be3e06 100644
+--- a/test-data/unit/check-kwargs.test
++++ b/test-data/unit/check-kwargs.test
+@@ -53,13 +53,6 @@ f(b=[], a=A())
+ class A: pass
+ [builtins fixtures/list.pyi]
+ 
+-[case testGivingSameKeywordArgumentTwice]
+-import typing
+-def f(a: 'A', b: 'B') -> None: pass
+-f(a=A(), b=B(), a=A()) # E: keyword argument repeated
+-class A: pass
+-class B: pass
+-
+ [case testGivingArgumentAsPositionalAndKeywordArg]
+ import typing
+ def f(a: 'A', b: 'B' = None) -> None: pass
+diff --git a/test-data/unit/check-python39.test 
b/test-data/unit/check-python39.test
+new file mode 100644
+index 0000000000..0e9ec683ae
+--- /dev/null
++++ b/test-data/unit/check-python39.test
+@@ -0,0 +1,9 @@
++[case testGivingSameKeywordArgumentTwice]
++# This test was originally in check-kwargs.test
++# Python 3.9's new parser started producing a different error message here. 
Since this isn't the
++# most important test, to deal with this we'll only run this test with Python 
3.9 and later.
++import typing
++def f(a: 'A', b: 'B') -> None: pass
++f(a=A(), b=B(), a=A()) # E: "f" gets multiple values for keyword argument "a"
++class A: pass
++class B: pass
+From da4430119255ac9205c96d54deb2e2ebed0ce8ce Mon Sep 17 00:00:00 2001
+From: Shantanu <12621235+hauntsani...@users.noreply.github.com>
+Date: Fri, 31 Jul 2020 09:58:15 -0700
+Subject: [PATCH] mypyc: ignore deprecation (#9107)
+
+PyUnicode_AsUnicodeAndSize has been deprecated since 3.3
+
+Python 3.9 has compiler warnings for this deprecated function, and we
+compile with Werror, causing Python 3.9 builds to fail.
+
+I've just copied over the relevant deprecation ignoring code from the
+original getargs.c (including the TODO, but I can remove that)
+
+Co-authored-by: hauntsaninja <>
+---
+ mypyc/lib-rt/getargs.c | 27 +++++++++++++++++++++++++++
+ 1 file changed, 27 insertions(+)
+
+diff --git a/mypyc/lib-rt/getargs.c b/mypyc/lib-rt/getargs.c
+index 32b387c8ab..e6b1a0c937 100644
+--- a/mypyc/lib-rt/getargs.c
++++ b/mypyc/lib-rt/getargs.c
+@@ -18,6 +18,29 @@
+  *    and is responsible for decrefing them.
+  */
+ 
++// These macro definitions are copied from pyport.h in Python 3.9 and later
++// https://bugs.python.org/issue19569
++#if defined(__clang__)
++#define _Py_COMP_DIAG_PUSH _Pragma("clang diagnostic push")
++#define _Py_COMP_DIAG_IGNORE_DEPR_DECLS \
++    _Pragma("clang diagnostic ignored \"-Wdeprecated-declarations\"")
++#define _Py_COMP_DIAG_POP _Pragma("clang diagnostic pop")
++#elif defined(__GNUC__) \
++    && ((__GNUC__ >= 5) || (__GNUC__ == 4) && (__GNUC_MINOR__ >= 6))
++#define _Py_COMP_DIAG_PUSH _Pragma("GCC diagnostic push")
++#define _Py_COMP_DIAG_IGNORE_DEPR_DECLS \
++    _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"")
++#define _Py_COMP_DIAG_POP _Pragma("GCC diagnostic pop")
++#elif defined(_MSC_VER)
++#define _Py_COMP_DIAG_PUSH __pragma(warning(push))
++#define _Py_COMP_DIAG_IGNORE_DEPR_DECLS __pragma(warning(disable: 4996))
++#define _Py_COMP_DIAG_POP __pragma(warning(pop))
++#else
++#define _Py_COMP_DIAG_PUSH
++#define _Py_COMP_DIAG_IGNORE_DEPR_DECLS
++#define _Py_COMP_DIAG_POP
++#endif
++
+ #include "Python.h"
+ #include "pythonsupport.h"
+ 
+@@ -756,6 +779,9 @@ convertsimple(PyObject *arg, const char **p_format, 
va_list *p_va, int flags,
+     case 'u': /* raw unicode buffer (Py_UNICODE *) */
+     case 'Z': /* raw unicode buffer or None */
+     {
++        // TODO: Raise DeprecationWarning
++_Py_COMP_DIAG_PUSH
++_Py_COMP_DIAG_IGNORE_DEPR_DECLS
+         Py_UNICODE **p = va_arg(*p_va, Py_UNICODE **);
+ 
+         if (*format == '#') {
+@@ -795,6 +821,7 @@ convertsimple(PyObject *arg, const char **p_format, 
va_list *p_va, int flags,
+                                   arg, msgbuf, bufsize);
+         }
+         break;
++_Py_COMP_DIAG_POP
+     }
+ 
+     case 'e': {/* encoded string */

diff --git a/dev-python/mypy/files/mypy-0.782-pytest-6.patch 
b/dev-python/mypy/files/mypy-0.782-pytest-6.patch
new file mode 100644
index 00000000000..0252d113880
--- /dev/null
+++ b/dev-python/mypy/files/mypy-0.782-pytest-6.patch
@@ -0,0 +1,210 @@
+From 3e77959eacf3d445a0cb4db5a4bc6dcf606fc040 Mon Sep 17 00:00:00 2001
+From: Lawrence Chan <llc...@users.noreply.github.com>
+Date: Tue, 4 Aug 2020 18:14:55 -0500
+Subject: [PATCH] Use pytest Node.from_parent if available (#9263)
+
+* Use pytest Node.from_parent if available
+
+* Use pytest Node.from_parent unconditionally (requires pytest 5.4+)
+
+* Bump pytest test requirements
+
+* Require pytest 6.0 and remove unused type ignores
+
+* Make flake8 happy
+---
+ mypy/test/data.py            | 37 ++++++++++++++++++++++--------------
+ mypy/test/helpers.py         |  2 +-
+ mypy/test/testfinegrained.py |  2 +-
+ mypy/test/testipc.py         |  2 +-
+ mypy/test/testparse.py       |  2 +-
+ mypy/test/testpep561.py      |  2 +-
+ mypy/test/testpythoneval.py  |  2 +-
+ mypyc/test/testutil.py       |  2 +-
+ pytest.ini                   |  3 +--
+ test-requirements.txt        |  9 ++++-----
+ 10 files changed, 35 insertions(+), 28 deletions(-)
+
+diff --git a/mypy/test/data.py b/mypy/test/data.py
+index 5484fd99e9..a4f2d798b1 100644
+--- a/mypy/test/data.py
++++ b/mypy/test/data.py
+@@ -9,7 +9,7 @@
+ from abc import abstractmethod
+ import sys
+ 
+-import pytest  # type: ignore  # no pytest in typeshed
++import pytest
+ from typing import List, Tuple, Set, Optional, Iterator, Any, Dict, 
NamedTuple, Union
+ 
+ from mypy.test.config import test_data_prefix, test_temp_dir, PREFIX
+@@ -160,9 +160,12 @@ def parse_test_case(case: 'DataDrivenTestCase') -> None:
+     case.expected_fine_grained_targets = targets
+ 
+ 
+-class DataDrivenTestCase(pytest.Item):  # type: ignore  # inheriting from Any
++class DataDrivenTestCase(pytest.Item):
+     """Holds parsed data-driven test cases, and handles directory setup and 
teardown."""
+ 
++    # Override parent member type
++    parent = None  # type: DataSuiteCollector
++
+     input = None  # type: List[str]
+     output = None  # type: List[str]  # Output for the first pass
+     output2 = None  # type: Dict[int, List[str]]  # Output for runs 2+, 
indexed by run number
+@@ -266,7 +269,7 @@ def repr_failure(self, excinfo: Any, style: Optional[Any] 
= None) -> str:
+             # call exit() and they already print out a stack trace.
+             excrepr = excinfo.exconly()
+         else:
+-            self.parent._prunetraceback(excinfo)
++            self.parent._prunetraceback(excinfo)  # type: 
ignore[no-untyped-call]
+             excrepr = excinfo.getrepr(style='short')
+ 
+         return "data: {}:{}:\n{}".format(self.file, self.line, excrepr)
+@@ -510,7 +513,9 @@ def pytest_pycollect_makeitem(collector: Any, name: str,
+             # Non-None result means this obj is a test case.
+             # The collect method of the returned DataSuiteCollector instance 
will be called later,
+             # with self.obj being obj.
+-            return DataSuiteCollector(name, parent=collector)
++            return DataSuiteCollector.from_parent(  # type: 
ignore[no-untyped-call]
++                parent=collector, name=name
++            )
+     return None
+ 
+ 
+@@ -535,19 +540,23 @@ def split_test_cases(parent: 'DataSuiteCollector', 
suite: 'DataSuite',
+     for i in range(1, len(cases), 6):
+         name, writescache, only_when, platform_flag, skip, data = cases[i:i + 
6]
+         platform = platform_flag[1:] if platform_flag else None
+-        yield DataDrivenTestCase(parent, suite, file,
+-                                 name=add_test_name_suffix(name, 
suite.test_name_suffix),
+-                                 writescache=bool(writescache),
+-                                 only_when=only_when,
+-                                 platform=platform,
+-                                 skip=bool(skip),
+-                                 data=data,
+-                                 line=line_no)
++        yield DataDrivenTestCase.from_parent(
++            parent=parent,
++            suite=suite,
++            file=file,
++            name=add_test_name_suffix(name, suite.test_name_suffix),
++            writescache=bool(writescache),
++            only_when=only_when,
++            platform=platform,
++            skip=bool(skip),
++            data=data,
++            line=line_no,
++        )
+         line_no += data.count('\n') + 1
+ 
+ 
+-class DataSuiteCollector(pytest.Class):  # type: ignore  # inheriting from Any
+-    def collect(self) -> Iterator[pytest.Item]:  # type: ignore
++class DataSuiteCollector(pytest.Class):
++    def collect(self) -> Iterator[pytest.Item]:
+         """Called by pytest on each of the object returned from 
pytest_pycollect_makeitem"""
+ 
+         # obj is the object for which pytest_pycollect_makeitem returned self.
+diff --git a/mypy/test/helpers.py b/mypy/test/helpers.py
+index 46c01114c4..91c5ff6ab2 100644
+--- a/mypy/test/helpers.py
++++ b/mypy/test/helpers.py
+@@ -10,7 +10,7 @@
+ from mypy import defaults
+ import mypy.api as api
+ 
+-import pytest  # type: ignore  # no pytest in typeshed
++import pytest
+ 
+ # Exporting Suite as alias to TestCase for backwards compatibility
+ # TODO: avoid aliasing - import and subclass TestCase directly
+diff --git a/mypy/test/testfinegrained.py b/mypy/test/testfinegrained.py
+index 596391da44..d4ed18cab0 100644
+--- a/mypy/test/testfinegrained.py
++++ b/mypy/test/testfinegrained.py
+@@ -35,7 +35,7 @@
+ from mypy.config_parser import parse_config_file
+ from mypy.find_sources import create_source_list
+ 
+-import pytest  # type: ignore  # no pytest in typeshed
++import pytest
+ 
+ # Set to True to perform (somewhat expensive) checks for duplicate AST nodes 
after merge
+ CHECK_CONSISTENCY = False
+diff --git a/mypy/test/testipc.py b/mypy/test/testipc.py
+index 1d4829d561..7dd829a590 100644
+--- a/mypy/test/testipc.py
++++ b/mypy/test/testipc.py
+@@ -3,7 +3,7 @@
+ 
+ from mypy.ipc import IPCClient, IPCServer
+ 
+-import pytest  # type: ignore
++import pytest
+ import sys
+ import time
+ 
+diff --git a/mypy/test/testparse.py b/mypy/test/testparse.py
+index e990a403a5..e9ff6839bc 100644
+--- a/mypy/test/testparse.py
++++ b/mypy/test/testparse.py
+@@ -2,7 +2,7 @@
+ 
+ import sys
+ 
+-from pytest import skip  # type: ignore[import]
++from pytest import skip
+ 
+ from mypy import defaults
+ from mypy.test.helpers import assert_string_arrays_equal, parse_options
+diff --git a/mypy/test/testpep561.py b/mypy/test/testpep561.py
+index a8eabd7702..aadf01ae5f 100644
+--- a/mypy/test/testpep561.py
++++ b/mypy/test/testpep561.py
+@@ -1,6 +1,6 @@
+ from contextlib import contextmanager
+ import os
+-import pytest  # type: ignore
++import pytest
+ import re
+ import subprocess
+ from subprocess import PIPE
+diff --git a/mypy/test/testpythoneval.py b/mypy/test/testpythoneval.py
+index 7586a3854e..e7e9f16183 100644
+--- a/mypy/test/testpythoneval.py
++++ b/mypy/test/testpythoneval.py
+@@ -18,7 +18,7 @@
+ import sys
+ from tempfile import TemporaryDirectory
+ 
+-import pytest  # type: ignore  # no pytest in typeshed
++import pytest
+ 
+ from typing import List
+ 
+diff --git a/mypyc/test/testutil.py b/mypyc/test/testutil.py
+index 18ab39a103..c1ce8626ba 100644
+--- a/mypyc/test/testutil.py
++++ b/mypyc/test/testutil.py
+@@ -7,7 +7,7 @@
+ import shutil
+ from typing import List, Callable, Iterator, Optional, Tuple
+ 
+-import pytest  # type: ignore[import]
++import pytest
+ 
+ from mypy import build
+ from mypy.errors import CompileError
+diff --git a/pytest.ini b/pytest.ini
+index 81586a2370..ed76809091 100644
+--- a/pytest.ini
++++ b/pytest.ini
+@@ -1,6 +1,5 @@
+ [pytest]
+-# testpaths is new in 2.8
+-minversion = 2.8
++minversion = 6.0.0
+ 
+ testpaths = mypy/test mypyc/test
+ 

diff --git a/dev-python/mypy/mypy-0.782.ebuild 
b/dev-python/mypy/mypy-0.782.ebuild
new file mode 100644
index 00000000000..f6931385e1e
--- /dev/null
+++ b/dev-python/mypy/mypy-0.782.ebuild
@@ -0,0 +1,58 @@
+# Copyright 1999-2020 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+
+EAPI=7
+
+PYTHON_COMPAT=( python3_{6..9} )
+DISTUTILS_USE_SETUPTOOLS=rdepend
+
+inherit distutils-r1
+
+DESCRIPTION="Optional static typing for Python"
+HOMEPAGE="http://www.mypy-lang.org/";
+SRC_URI="mirror://pypi/${PN:0:1}/${PN}/${P}.tar.gz"
+
+LICENSE="MIT"
+SLOT="0"
+KEYWORDS="~amd64 ~arm64 ~x86"
+
+# stubgen collides with this package: https://bugs.gentoo.org/585594
+RDEPEND="
+       !dev-util/stubgen
+       >=dev-python/psutil-4[${PYTHON_USEDEP}]
+       >=dev-python/typed-ast-1.4.0[${PYTHON_USEDEP}]
+       <dev-python/typed-ast-1.5.0[${PYTHON_USEDEP}]
+       >=dev-python/typing-extensions-3.7.4[${PYTHON_USEDEP}]
+       >=dev-python/mypy_extensions-0.4.3[${PYTHON_USEDEP}]
+       <dev-python/mypy_extensions-0.5.0[${PYTHON_USEDEP}]
+"
+BDEPEND="
+       test? (
+                       >=dev-python/attrs-18.0[${PYTHON_USEDEP}]
+                       >=dev-python/lxml-4.4.0[${PYTHON_USEDEP}]
+                       >=dev-python/pytest-6.0.0[${PYTHON_USEDEP}]
+                       >=dev-python/pytest-xdist-1.18[${PYTHON_USEDEP}]
+                       >=dev-python/py-1.5.2[${PYTHON_USEDEP}]
+                       >=dev-python/virtualenv-16.0.0[${PYTHON_USEDEP}]
+       )
+"
+
+PATCHES=(
+       # The first two patches are backports from upstream commits
+       # They should be removed during the next bump
+       "${FILESDIR}/${P}-py39-fixes.patch"
+       "${FILESDIR}/${P}-pytest-6.patch"
+       # Needed to collect all tests
+       # https://github.com/python/mypy/pull/9543
+       "${FILESDIR}/${P}-conftest.patch"
+)
+
+distutils_enable_sphinx docs/source dev-python/sphinx_rtd_theme
+distutils_enable_tests pytest
+
+python_prepare_all() {
+       # 
https://github.com/python/mypy/commit/2f291f2e312dd3bf2c05c45da0b032b240bfd7ab
+       # Avoid a big patch by deleting the file manually
+       rm test-data/samples/crawl.py || die
+       distutils-r1_python_prepare_all
+}

Reply via email to