chore: import upstream snapshot with attribution

This commit is contained in:
wehub-resource-sync
2026-07-13 12:40:42 +08:00
commit e25996e7db
15472 changed files with 3536181 additions and 0 deletions
+16
View File
@@ -0,0 +1,16 @@
file(
GLOB TEST_OPS
RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}"
"test_*.py")
string(REPLACE ".py" "" TEST_OPS "${TEST_OPS}")
if((NOT WITH_COVERAGE) AND (LINUX))
foreach(TEST_OP ${TEST_OPS})
py_test_modules(
${TEST_OP} MODULES ${TEST_OP} ENVS
PYTHONPATH=${PADDLE_SOURCE_DIR}/tools:${PADDLE_BINARY_DIR}/python)
endforeach()
set_tests_properties(test_sampcd_processor PROPERTIES TIMEOUT 300)
set_tests_properties(test_type_checking PROPERTIES TIMEOUT 200)
endif()
+295
View File
@@ -0,0 +1,295 @@
# Copyright (c) 2026 PaddlePaddle Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import unittest
from check_abi_compatibility import (
DynamicSymbol,
MissingLibrary,
RemovedSymbol,
check_abi_issues_approval,
check_abi_removal_approval,
compare_library_symbols,
find_required_abi_approver,
is_protected_paddle_abi_symbol,
parse_readelf_dynamic_symbols,
)
def make_symbol(name, demangled_name=None, bind="GLOBAL", section="12"):
return DynamicSymbol(
name=name,
symbol_type="FUNC",
bind=bind,
section=section,
demangled_name=demangled_name or name,
)
class TestParseReadelfDynamicSymbols(unittest.TestCase):
def test_ignores_weak_undefined_and_local_symbols(self):
readelf_output = """
Symbol table '.dynsym' contains 5 entries:
Num: Value Size Type Bind Vis Ndx Name
1: 0000000000001000 42 FUNC GLOBAL DEFAULT 12 _ZN3c1017get_default_dtypeEv
2: 0000000000001010 42 FUNC WEAK DEFAULT 12 _ZN3c104weakEv
3: 0000000000000000 0 FUNC GLOBAL DEFAULT UND _ZN3c107missingEv
4: 0000000000001020 42 FUNC LOCAL DEFAULT 12 _ZN3c105localEv
5: 0000000000001030 8 OBJECT GLOBAL DEFAULT 13 _ZN3phi3barE
"""
symbols = parse_readelf_dynamic_symbols(readelf_output)
self.assertEqual(
[symbol.name for symbol in symbols],
["_ZN3c1017get_default_dtypeEv", "_ZN3phi3barE"],
)
class TestProtectedSymbols(unittest.TestCase):
def test_detects_protected_compat_cxx_namespaces(self):
self.assertTrue(
is_protected_paddle_abi_symbol(
make_symbol(
"_ZN3c1017get_default_dtypeEv",
"c10::get_default_dtype()",
)
)
)
self.assertTrue(
is_protected_paddle_abi_symbol(
make_symbol("_ZN2at6Tensor3dimEv", "at::Tensor::dim()")
)
)
self.assertTrue(
is_protected_paddle_abi_symbol(
make_symbol("_ZN5torch4cuda11synchronizeEv")
)
)
self.assertTrue(
is_protected_paddle_abi_symbol(
make_symbol(
"_ZN6caffe28TypeMeta12toScalarTypeEv",
"caffe2::TypeMeta::toScalarType()",
)
)
)
def test_ignores_non_compat_paddle_entrypoints(self):
self.assertFalse(
is_protected_paddle_abi_symbol(
make_symbol(
"_ZN3phi12is_cpu_placeERKNS_5PlaceE",
"phi::is_cpu_place(phi::Place const&)",
)
)
)
self.assertFalse(
is_protected_paddle_abi_symbol(
make_symbol("_ZN6paddle3fooEv", "paddle::foo()")
)
)
self.assertFalse(
is_protected_paddle_abi_symbol(make_symbol("PyInit_libpaddle"))
)
self.assertFalse(
is_protected_paddle_abi_symbol(make_symbol("PD_ConfigCreate"))
)
def test_ignores_third_party_symbols(self):
self.assertFalse(
is_protected_paddle_abi_symbol(make_symbol("XXH32", "XXH32"))
)
self.assertFalse(
is_protected_paddle_abi_symbol(
make_symbol("_ZN4YAML7EmitterC1Ev", "YAML::Emitter::Emitter()")
)
)
class TestCompareLibrarySymbols(unittest.TestCase):
def test_added_symbols_do_not_fail(self):
base_symbols = [
make_symbol(
"_ZN3c1017get_default_dtypeEv", "c10::get_default_dtype()"
)
]
pr_symbols = [
*base_symbols,
make_symbol(
"_ZN3c1017set_default_dtypeEv", "c10::set_default_dtype()"
),
]
issues = compare_library_symbols(
"paddle/libs/libphi_core.so", base_symbols, pr_symbols
)
self.assertEqual(issues, [])
def test_removed_protected_symbol_fails(self):
base_symbols = [
make_symbol(
"_ZN3c1017get_default_dtypeEv", "c10::get_default_dtype()"
)
]
issues = compare_library_symbols(
"paddle/libs/libphi_core.so", base_symbols, []
)
self.assertEqual(
issues,
[
RemovedSymbol(
library="paddle/libs/libphi_core.so",
name="_ZN3c1017get_default_dtypeEv",
demangled_name="c10::get_default_dtype()",
)
],
)
def test_removed_third_party_symbol_does_not_fail(self):
base_symbols = [make_symbol("XXH32", "XXH32")]
issues = compare_library_symbols(
"paddle/base/libpaddle.so", base_symbols, []
)
self.assertEqual(issues, [])
def test_removed_non_compat_phi_symbol_does_not_fail(self):
base_symbols = [
make_symbol(
"_ZN3phi12is_cpu_placeERKNS_5PlaceE",
"phi::is_cpu_place(phi::Place const&)",
)
]
issues = compare_library_symbols(
"paddle/libs/libphi_core.so", base_symbols, []
)
self.assertEqual(issues, [])
def test_missing_pr_library_fails_when_base_has_library(self):
base_symbols = [
make_symbol(
"_ZN3c1017get_default_dtypeEv", "c10::get_default_dtype()"
)
]
issues = compare_library_symbols(
"paddle/libs/libphi_core.so", base_symbols, None
)
self.assertEqual(
issues, [MissingLibrary(library="paddle/libs/libphi_core.so")]
)
def test_missing_base_library_does_not_fail(self):
pr_symbols = [
make_symbol(
"_ZN3c1017get_default_dtypeEv", "c10::get_default_dtype()"
)
]
issues = compare_library_symbols(
"paddle/libs/libphi_core.so", None, pr_symbols
)
self.assertEqual(issues, [])
class TestAbiRemovalApproval(unittest.TestCase):
def test_no_abi_issues_do_not_require_approval(self):
def fetch_reviews(_pr_id, _token, _repository):
self.fail("reviews should not be fetched without ABI issues")
approval = check_abi_issues_approval(
[], env={}, fetch_reviews=fetch_reviews
)
self.assertTrue(approval.approved)
def test_removed_symbol_without_approval_fails(self):
issues = [
RemovedSymbol(
library="paddle/libs/libphi_core.so",
name="_ZN3c1017get_default_dtypeEv",
demangled_name="c10::get_default_dtype()",
)
]
approval = check_abi_issues_approval(
issues,
env={"GIT_PR_ID": "78831", "GITHUB_API_TOKEN": "token"},
fetch_reviews=lambda _pr_id, _token, _repository: [],
)
self.assertFalse(approval.approved)
self.assertIn("no APPROVED review", approval.reason)
def test_removed_symbol_with_required_approval_passes(self):
for reviewer in ("SigureMo", "BingooYang"):
with self.subTest(reviewer=reviewer):
approval = check_abi_removal_approval(
env={"GIT_PR_ID": "78831", "GITHUB_API_TOKEN": "token"},
fetch_reviews=lambda _pr_id, _token, _repository: [
{"state": "APPROVED", "user": {"login": reviewer}}
],
)
self.assertTrue(approval.approved)
self.assertEqual(approval.reviewer, reviewer)
def test_other_reviewer_approval_does_not_pass(self):
reviews = [
{"state": "APPROVED", "user": {"login": "someone-else"}},
{"state": "COMMENTED", "user": {"login": "SigureMo"}},
]
self.assertIsNone(find_required_abi_approver(reviews))
def test_missing_review_context_fails_closed_when_abi_issue_exists(self):
issues = [
RemovedSymbol(
library="paddle/libs/libphi_core.so",
name="_ZN3c1017get_default_dtypeEv",
demangled_name="c10::get_default_dtype()",
)
]
approval = check_abi_issues_approval(
issues,
env={},
fetch_reviews=lambda _pr_id, _token, _repository: [],
)
self.assertFalse(approval.approved)
self.assertIn("GIT_PR_ID or PR_ID is not set", approval.reason)
def test_review_fetch_error_fails_closed(self):
def fetch_reviews(_pr_id, _token, _repository):
raise RuntimeError("GitHub API unavailable")
approval = check_abi_removal_approval(
env={"PR_ID": "78831", "GITHUB_TOKEN": "token"},
fetch_reviews=fetch_reviews,
)
self.assertFalse(approval.approved)
self.assertIn("GitHub API unavailable", approval.reason)
if __name__ == "__main__":
unittest.main()
File diff suppressed because it is too large Load Diff
+64
View File
@@ -0,0 +1,64 @@
# Copyright (c) 2025 PaddlePaddle Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import unittest
from gpu_kernel_compare import KernelManifestComparer
class TestKernelManifestComparer(unittest.TestCase):
def setUp(self):
# Baseline manifest simulating existing kernels
self.baseline_manifest = {
"kernel_a": [
"{data_type[float]; data_layout[Undefined(AnyLayout)]; place[Place(gpu:0)]; library_type[PLAIN]}",
"{data_type[double]; data_layout[Undefined(AnyLayout)]; place[Place(gpu:0)]; library_type[PLAIN]}",
],
"kernel_b": [
"{data_type[double]; data_layout[Undefined(AnyLayout)]; place[Place(cpu)]; library_type[PLAIN]}"
],
}
self.comparator = KernelManifestComparer(self.baseline_manifest)
def test_all_gpu_kernel_detection(self):
target_manifest = {
"kernel_a": [ # Existing kernel with additional data type
"{data_type[float]; data_layout[Undefined(AnyLayout)]; place[Place(gpu:0)]; library_type[PLAIN]}",
"{data_type[double]; data_layout[Undefined(AnyLayout)]; place[Place(gpu:0)]; library_type[PLAIN]}",
"{data_type[::phi::dtype::float16]; data_layout[Undefined(AnyLayout)]; place[Place(gpu:0)]; library_type[PLAIN]}",
],
"kernel_b": [ # Existing kernel now has GPU support
"{data_type[double]; data_layout[Undefined(AnyLayout)]; place[Place(cpu)]; library_type[PLAIN]}",
"{data_type[double]; data_layout[Undefined(AnyLayout)]; place[Place(gpu:0)]; library_type[PLAIN]}",
],
"kernel_c": [ # New kernel with GPU support
"{data_type[float]; data_layout[Undefined(AnyLayout)]; place[Place(gpu:0)]; library_type[PLAIN]}",
],
}
summary = self.comparator.compare(target_manifest)
self.assertIn("kernel_c", summary["new_kernels_with_gpu"])
self.assertEqual(len(summary["new_kernels_with_gpu"]), 1)
self.assertIn("kernel_a", summary["kernels_with_new_gpu_support"])
self.assertIn("kernel_b", summary["kernels_with_new_gpu_support"])
self.assertEqual(len(summary["kernels_with_new_gpu_support"]), 2)
self.assertIn("kernel_a", summary["gpu_kernels_with_new_data_types"])
self.assertIn(
"::phi::dtype::float16",
summary["gpu_kernels_with_new_data_types"]["kernel_a"],
)
self.assertEqual(
len(summary["gpu_kernels_with_new_data_types"]["kernel_a"]), 1
)
File diff suppressed because it is too large Load Diff
+634
View File
@@ -0,0 +1,634 @@
# Copyright (c) 2024 PaddlePaddle Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import pathlib
import unittest
# set `PYTHONPATH=<Paddle/tools>` from `CMakeLists.txt`
from type_checking import MypyChecker, get_test_results
FILE_PATH = pathlib.Path(__file__).resolve().parent
# test from `Paddle/test`
BASE_PATH_IN_TEST = FILE_PATH.parent.parent
CONFIG_FILE_IN_TEST = BASE_PATH_IN_TEST / 'pyproject.toml'
CACHE_DIR_IN_TEST = BASE_PATH_IN_TEST / '.mypy_cache'
# test from `Paddle/build/test`
BASE_PATH_IN_BUILD = FILE_PATH.parent.parent.parent
CONFIG_FILE_IN_BUILD = BASE_PATH_IN_BUILD / 'pyproject.toml'
CACHE_DIR_IN_BUILD = BASE_PATH_IN_BUILD / '.mypy_cache'
if CONFIG_FILE_IN_TEST.exists():
CONFIG_FILE = CONFIG_FILE_IN_TEST
CACHE_DIR = CACHE_DIR_IN_TEST
elif CONFIG_FILE_IN_BUILD.exists():
CONFIG_FILE = CONFIG_FILE_IN_BUILD
CACHE_DIR = CACHE_DIR_IN_BUILD
else:
raise FileNotFoundError('Can NOT found mypy config file `pyproject.toml`')
class TestMypyChecker(unittest.TestCase):
def test_mypy_pass(self):
docstrings_pass = {
'simple': """
placeholder
Examples:
.. code-block:: pycon
:name: code-example-1
this is some blabla...
>>> import abc
>>> print(1)
1
""",
'multi': """
placeholder
.. code-block:: pycon
:name: code-example-0
this is some blabla...
>>> # doctest: +SKIP('skip')
>>> print(1+1)
2
Examples:
.. code-block:: pycon
:name: code-example-1
this is some blabla...
>>> # doctest: -REQUIRES(env:GPU)
>>> print(1-1)
0
.. code-block:: pycon
:name: code-example-2
this is some blabla...
>>> # doctest: +REQUIRES(env:GPU, env:XPU, env: DISTRIBUTED)
>>> print(1-1)
0
""",
}
docstrings_from_sampcd = {
'gpu_to_gpu': """
placeholder
Examples:
.. code-block:: pycon
:name: code-example-1
this is some blabla...
>>> import paddle
>>> paddle.device.set_device('gpu')
>>> a = paddle.to_tensor(.123456789)
>>> print(a)
Tensor(shape=[1], dtype=float32, place=Place(gpu:0), stop_gradient=True,
[0.123456780])
""",
'cpu_to_cpu': """
placeholder
Examples:
.. code-block:: pycon
:name: code-example-1
this is some blabla...
>>> import paddle
>>> paddle.device.set_device('cpu')
>>> a = paddle.to_tensor(.123456789)
>>> print(a)
Tensor(shape=[1], dtype=float32, place=Place(cpu), stop_gradient=True,
[0.123456780])
""",
'gpu_to_cpu': """
placeholder
Examples:
.. code-block:: pycon
:name: code-example-1
this is some blabla...
>>> import paddle
>>> paddle.device.set_device('gpu')
>>> a = paddle.to_tensor(.123456789)
>>> print(a)
Tensor(shape=[1], dtype=float32, place=Place(cpu), stop_gradient=True,
[0.123456780])
""",
'cpu_to_gpu': """
placeholder
Examples:
.. code-block:: pycon
:name: code-example-1
this is some blabla...
>>> import paddle
>>> paddle.device.set_device('cpu')
>>> a = paddle.to_tensor(.123456789)
>>> print(a)
Tensor(shape=[1], dtype=float32, place=Place(gpu:0), stop_gradient=True,
[0.123456780])
""",
'gpu_to_cpu_array': """
placeholder
Examples:
.. code-block:: pycon
:name: code-example-1
this is some blabla...
>>> import paddle
>>> paddle.device.set_device('gpu')
>>> a = paddle.to_tensor([[1.123456789 ,2,3], [2,3,4], [3,4,5]])
>>> print(a)
Tensor(shape=[3, 3], dtype=float32, place=Place(cpu), stop_gradient=True,
[[1.123456780, 2., 3.],
[2., 3., 4.],
[3., 4., 5.]])
""",
'cpu_to_gpu_array': """
placeholder
Examples:
.. code-block:: pycon
:name: code-example-1
this is some blabla...
>>> import paddle
>>> paddle.device.set_device('cpu')
>>> a = paddle.to_tensor([[1.123456789,2,3], [2,3,4], [3,4,5]])
>>> print(a)
Tensor(shape=[3, 3], dtype=float32, place=Place(gpu:0), stop_gradient=True,
[[1.123456780, 2., 3.],
[2., 3., 4.],
[3., 4., 5.]])
""",
'mass_array': """
placeholder
Examples:
.. code-block:: pycon
:name: code-example-1
this is some blabla...
>>> import paddle
>>> paddle.device.set_device('gpu')
>>> a = paddle.to_tensor(
... [[1.123456780, 2., -3, .3],
... [2, 3, +4., 1.2+10.34e-5j],
... [3, 5.e-3, 1e2, 3e-8]]
... )
>>> # Tensor(shape=[3, 4], dtype=complex64, place=Place(gpu:0), stop_gradient=True,
>>> # [[ (1.1234568357467651+0j) ,
>>> # (2+0j) ,
>>> # (-3+0j) ,
>>> # (0.30000001192092896+0j) ],
>>> # [ (2+0j) ,
>>> # (3+0j) ,
>>> # (4+0j) ,
>>> # (1.2000000476837158+0.00010340000153519213j)],
>>> # [ (3+0j) ,
>>> # (0.004999999888241291+0j) ,
>>> # (100+0j) ,
>>> # (2.999999892949745e-08+0j) ]])
>>> print(a)
Tensor(shape=[3, 4], dtype=complex64, place=Place(AAA), stop_gradient=True,
[[ (1.123456+0j),
(2+0j),
(-3+0j),
(0.3+0j)],
[ (2+0j),
(3+0j),
(4+0j),
(1.2+0.00010340j)],
[ (3+0j),
(0.00499999+0j),
(100+0j),
(2.999999e-08+0j)]])
""",
'float_array': """
placeholder
Examples:
.. code-block:: pycon
:name: code-example-1
this is some blabla...
>>> import paddle
>>> paddle.device.set_device('cpu')
>>> x = [[2, 3, 4], [7, 8, 9]]
>>> x = paddle.to_tensor(x, dtype='float32')
>>> print(paddle.log(x))
Tensor(shape=[2, 3], dtype=float32, place=Place(cpu), stop_gradient=True,
[[0.69314718, 1.09861231, 1.38629436],
[1.94591010, 2.07944155, 2.19722462]])
""",
'float_array_diff': """
placeholder
Examples:
.. code-block:: pycon
:name: code-example-1
this is some blabla...
>>> import paddle
>>> paddle.device.set_device('cpu')
>>> x = [[2, 3, 4], [7, 8, 9]]
>>> x = paddle.to_tensor(x, dtype='float32')
>>> print(paddle.log(x))
Tensor(shape=[2, 3], dtype=float32, place=Place(cpu), stop_gradient=True,
[[0.69314712, 1.09861221, 1.386294],
[1.94591032, 2.07944156, 2.1972246]])
""",
'float_begin': """
placeholder
Examples:
.. code-block:: pycon
:name: code-example-1
this is some blabla...
>>> print(7.0)
7.
""",
'float_begin_long': """
placeholder
Examples:
.. code-block:: pycon
:name: code-example-1
this is some blabla...
>>> print(7.0000023)
7.0000024
""",
'float_begin_more': """
placeholder
Examples:
.. code-block:: pycon
:name: code-example-1
this is some blabla...
>>> print(7.0, 5., 6.123456)
7.0 5.0 6.123457
""",
'float_begin_more_diff': """
placeholder
Examples:
.. code-block:: pycon
:name: code-example-1
this is some blabla...
>>> print(7.0, 5., 6.123456)
7.0 5.0 6.123457
""",
'float_begin_more_brief': """
placeholder
Examples:
.. code-block:: pycon
:name: code-example-1
this is some blabla...
>>> print(7.0, 5., 6.123456)
7. 5. 6.123457
""",
'float_begin_fail': """
placeholder
Examples:
.. code-block:: pycon
:name: code-example-1
this is some blabla...
>>> print(7.0100023)
7.0000024
""",
}
doctester = MypyChecker(CONFIG_FILE, CACHE_DIR)
test_results = get_test_results(doctester, docstrings_pass)
self.assertIsNone(test_results)
test_results = get_test_results(doctester, docstrings_from_sampcd)
self.assertIsNone(test_results)
def test_mypy_fail(self):
docstrings_fail = {
'fail_simple': """
placeholder
Examples:
.. code-block:: pycon
:name: code-example-1
this is some blabla...
>>> import blabla
""",
'multi': """
placeholder
.. code-block:: pycon
:name: code-example-0
this is some blabla...
>>> # doctest: +SKIP('skip')
>>> print(1+1)
2
Examples:
.. code-block:: pycon
:name: code-example-1
this is some blabla...
>>> # doctest: -REQUIRES(env:GPU)
>>> blabla
>>> print(1-1)
0
.. code-block:: pycon
:name: code-example-2
this is some blabla...
>>> # doctest: +REQUIRES(env:GPU, env:XPU, env: DISTRIBUTED)
>>> blabla
>>> print(1-1)
0
""",
}
doctester = MypyChecker(CONFIG_FILE, CACHE_DIR)
test_results = get_test_results(doctester, docstrings_fail)
error_messages, _ = test_results
self.assertEqual(len(error_messages), 3)
def test_mypy_partial_fail(self):
docstrings_fail = {
'multi': """
placeholder
.. code-block:: pycon
:name: code-example-0
this is some blabla...
>>> # doctest: +SKIP('skip')
>>> print(1+1)
2
Examples:
.. code-block:: pycon
:name: code-example-1
this is some blabla...
>>> # doctest: -REQUIRES(env:GPU)
>>> blabla
>>> print(1-1)
0
.. code-block:: pycon
:name: code-example-2
this is some blabla...
>>> # doctest: +REQUIRES(env:GPU, env:XPU, env: DISTRIBUTED)
>>> print(1-1)
0
"""
}
doctester = MypyChecker(CONFIG_FILE, CACHE_DIR)
test_results = get_test_results(doctester, docstrings_fail)
error_messages, _ = test_results
self.assertEqual(len(error_messages), 1)
def test_mypy_ignore(self):
docstrings_ignore = {
'fail_simple': """
placeholder
Examples:
.. code-block:: pycon
:name: code-example-1
this is some blabla...
>>> # type: ignore
>>> import blabla
""",
'multi': """
placeholder
.. code-block:: pycon
:name: code-example-0
this is some blabla...
>>> # doctest: +SKIP('skip')
>>> print(1+1)
2
Examples:
.. code-block:: pycon
:name: code-example-1
this is some blabla...
>>> # type: ignore
>>> # doctest: -REQUIRES(env:GPU)
>>> blabla
>>> print(1-1)
0
.. code-block:: pycon
:name: code-example-2
this is some blabla...
>>> # type: ignore
>>> # doctest: +REQUIRES(env:GPU, env:XPU, env: DISTRIBUTED)
>>> blabla
>>> print(1-1)
0
""",
}
doctester = MypyChecker(CONFIG_FILE, CACHE_DIR)
test_results = get_test_results(doctester, docstrings_ignore)
self.assertIsNone(test_results)
docstrings_pass = {
'pass': """
placeholder
.. code-block:: pycon
:name: code-example-0
this is some blabla...
>>> # doctest: +SKIP('skip')
>>> print(1+1)
2
Examples:
.. code-block:: pycon
:name: code-example-1
this is some blabla...
>>> a = 1
>>> # type: ignore
>>> # doctest: -REQUIRES(env:GPU)
>>> blabla
>>> print(1-1)
0
.. code-block:: pycon
:name: code-example-2
this is some blabla...
>>> b = 2
>>> # type: ignore
>>> # doctest: +REQUIRES(env:GPU, env:XPU, env: DISTRIBUTED)
>>> blabla
>>> print(1-1)
0
""",
}
doctester = MypyChecker(CONFIG_FILE, CACHE_DIR)
test_results = get_test_results(doctester, docstrings_pass)
self.assertIsNone(test_results)
docstrings_fail = {
'fail': """
placeholder
.. code-block:: pycon
:name: code-example-0
this is some blabla...
>>> # doctest: +SKIP('skip')
>>> print(1+1)
2
Examples:
.. code-block:: pycon
:name: code-example-1
this is some blabla...
>>> import blabla
>>> a = 1
>>> # type: ignore
>>> # doctest: -REQUIRES(env:GPU)
>>> blabla
>>> print(1-1)
0
.. code-block:: pycon
:name: code-example-2
this is some blabla...
>>> import blabla
>>> # type: ignore
>>> # doctest: +REQUIRES(env:GPU, env:XPU, env: DISTRIBUTED)
>>> blabla
>>> print(1-1)
0
""",
}
doctester = MypyChecker(CONFIG_FILE, CACHE_DIR)
test_results = get_test_results(doctester, docstrings_fail)
error_messages, _ = test_results
self.assertEqual(len(error_messages), 2)
if __name__ == '__main__':
unittest.main()