|
2 | 2 | # these are all functions _testcapi exports whose name begins with 'test_'.
|
3 | 3 |
|
4 | 4 | from collections import OrderedDict
|
5 |
| -from contextlib import contextmanager, ExitStack |
6 | 5 | import _thread
|
7 | 6 | import importlib.machinery
|
8 | 7 | import importlib.util
|
|
20 | 19 | import weakref
|
21 | 20 | from test import support
|
22 | 21 | from test.support import MISSING_C_DOCSTRINGS
|
23 |
| -from test.support import catch_unraisable_exception |
24 | 22 | from test.support import import_helper
|
25 | 23 | from test.support import threading_helper
|
26 | 24 | from test.support import warnings_helper
|
@@ -1705,333 +1703,5 @@ def func2(x=None):
|
1705 | 1703 | self.do_test(func2)
|
1706 | 1704 |
|
1707 | 1705 |
|
1708 |
| -class TestDictWatchers(unittest.TestCase): |
1709 |
| - # types of watchers testcapimodule can add: |
1710 |
| - EVENTS = 0 # appends dict events as strings to global event list |
1711 |
| - ERROR = 1 # unconditionally sets and signals a RuntimeException |
1712 |
| - SECOND = 2 # always appends "second" to global event list |
1713 |
| - |
1714 |
| - def add_watcher(self, kind=EVENTS): |
1715 |
| - return _testcapi.add_dict_watcher(kind) |
1716 |
| - |
1717 |
| - def clear_watcher(self, watcher_id): |
1718 |
| - _testcapi.clear_dict_watcher(watcher_id) |
1719 |
| - |
1720 |
| - @contextmanager |
1721 |
| - def watcher(self, kind=EVENTS): |
1722 |
| - wid = self.add_watcher(kind) |
1723 |
| - try: |
1724 |
| - yield wid |
1725 |
| - finally: |
1726 |
| - self.clear_watcher(wid) |
1727 |
| - |
1728 |
| - def assert_events(self, expected): |
1729 |
| - actual = _testcapi.get_dict_watcher_events() |
1730 |
| - self.assertEqual(actual, expected) |
1731 |
| - |
1732 |
| - def watch(self, wid, d): |
1733 |
| - _testcapi.watch_dict(wid, d) |
1734 |
| - |
1735 |
| - def unwatch(self, wid, d): |
1736 |
| - _testcapi.unwatch_dict(wid, d) |
1737 |
| - |
1738 |
| - def test_set_new_item(self): |
1739 |
| - d = {} |
1740 |
| - with self.watcher() as wid: |
1741 |
| - self.watch(wid, d) |
1742 |
| - d["foo"] = "bar" |
1743 |
| - self.assert_events(["new:foo:bar"]) |
1744 |
| - |
1745 |
| - def test_set_existing_item(self): |
1746 |
| - d = {"foo": "bar"} |
1747 |
| - with self.watcher() as wid: |
1748 |
| - self.watch(wid, d) |
1749 |
| - d["foo"] = "baz" |
1750 |
| - self.assert_events(["mod:foo:baz"]) |
1751 |
| - |
1752 |
| - def test_clone(self): |
1753 |
| - d = {} |
1754 |
| - d2 = {"foo": "bar"} |
1755 |
| - with self.watcher() as wid: |
1756 |
| - self.watch(wid, d) |
1757 |
| - d.update(d2) |
1758 |
| - self.assert_events(["clone"]) |
1759 |
| - |
1760 |
| - def test_no_event_if_not_watched(self): |
1761 |
| - d = {} |
1762 |
| - with self.watcher() as wid: |
1763 |
| - d["foo"] = "bar" |
1764 |
| - self.assert_events([]) |
1765 |
| - |
1766 |
| - def test_del(self): |
1767 |
| - d = {"foo": "bar"} |
1768 |
| - with self.watcher() as wid: |
1769 |
| - self.watch(wid, d) |
1770 |
| - del d["foo"] |
1771 |
| - self.assert_events(["del:foo"]) |
1772 |
| - |
1773 |
| - def test_pop(self): |
1774 |
| - d = {"foo": "bar"} |
1775 |
| - with self.watcher() as wid: |
1776 |
| - self.watch(wid, d) |
1777 |
| - d.pop("foo") |
1778 |
| - self.assert_events(["del:foo"]) |
1779 |
| - |
1780 |
| - def test_clear(self): |
1781 |
| - d = {"foo": "bar"} |
1782 |
| - with self.watcher() as wid: |
1783 |
| - self.watch(wid, d) |
1784 |
| - d.clear() |
1785 |
| - self.assert_events(["clear"]) |
1786 |
| - |
1787 |
| - def test_dealloc(self): |
1788 |
| - d = {"foo": "bar"} |
1789 |
| - with self.watcher() as wid: |
1790 |
| - self.watch(wid, d) |
1791 |
| - del d |
1792 |
| - self.assert_events(["dealloc"]) |
1793 |
| - |
1794 |
| - def test_unwatch(self): |
1795 |
| - d = {} |
1796 |
| - with self.watcher() as wid: |
1797 |
| - self.watch(wid, d) |
1798 |
| - d["foo"] = "bar" |
1799 |
| - self.unwatch(wid, d) |
1800 |
| - d["hmm"] = "baz" |
1801 |
| - self.assert_events(["new:foo:bar"]) |
1802 |
| - |
1803 |
| - def test_error(self): |
1804 |
| - d = {} |
1805 |
| - with self.watcher(kind=self.ERROR) as wid: |
1806 |
| - self.watch(wid, d) |
1807 |
| - with catch_unraisable_exception() as cm: |
1808 |
| - d["foo"] = "bar" |
1809 |
| - self.assertIs(cm.unraisable.object, d) |
1810 |
| - self.assertEqual(str(cm.unraisable.exc_value), "boom!") |
1811 |
| - self.assert_events([]) |
1812 |
| - |
1813 |
| - def test_two_watchers(self): |
1814 |
| - d1 = {} |
1815 |
| - d2 = {} |
1816 |
| - with self.watcher() as wid1: |
1817 |
| - with self.watcher(kind=self.SECOND) as wid2: |
1818 |
| - self.watch(wid1, d1) |
1819 |
| - self.watch(wid2, d2) |
1820 |
| - d1["foo"] = "bar" |
1821 |
| - d2["hmm"] = "baz" |
1822 |
| - self.assert_events(["new:foo:bar", "second"]) |
1823 |
| - |
1824 |
| - def test_watch_non_dict(self): |
1825 |
| - with self.watcher() as wid: |
1826 |
| - with self.assertRaisesRegex(ValueError, r"Cannot watch non-dictionary"): |
1827 |
| - self.watch(wid, 1) |
1828 |
| - |
1829 |
| - def test_watch_out_of_range_watcher_id(self): |
1830 |
| - d = {} |
1831 |
| - with self.assertRaisesRegex(ValueError, r"Invalid dict watcher ID -1"): |
1832 |
| - self.watch(-1, d) |
1833 |
| - with self.assertRaisesRegex(ValueError, r"Invalid dict watcher ID 8"): |
1834 |
| - self.watch(8, d) # DICT_MAX_WATCHERS = 8 |
1835 |
| - |
1836 |
| - def test_watch_unassigned_watcher_id(self): |
1837 |
| - d = {} |
1838 |
| - with self.assertRaisesRegex(ValueError, r"No dict watcher set for ID 1"): |
1839 |
| - self.watch(1, d) |
1840 |
| - |
1841 |
| - def test_unwatch_non_dict(self): |
1842 |
| - with self.watcher() as wid: |
1843 |
| - with self.assertRaisesRegex(ValueError, r"Cannot watch non-dictionary"): |
1844 |
| - self.unwatch(wid, 1) |
1845 |
| - |
1846 |
| - def test_unwatch_out_of_range_watcher_id(self): |
1847 |
| - d = {} |
1848 |
| - with self.assertRaisesRegex(ValueError, r"Invalid dict watcher ID -1"): |
1849 |
| - self.unwatch(-1, d) |
1850 |
| - with self.assertRaisesRegex(ValueError, r"Invalid dict watcher ID 8"): |
1851 |
| - self.unwatch(8, d) # DICT_MAX_WATCHERS = 8 |
1852 |
| - |
1853 |
| - def test_unwatch_unassigned_watcher_id(self): |
1854 |
| - d = {} |
1855 |
| - with self.assertRaisesRegex(ValueError, r"No dict watcher set for ID 1"): |
1856 |
| - self.unwatch(1, d) |
1857 |
| - |
1858 |
| - def test_clear_out_of_range_watcher_id(self): |
1859 |
| - with self.assertRaisesRegex(ValueError, r"Invalid dict watcher ID -1"): |
1860 |
| - self.clear_watcher(-1) |
1861 |
| - with self.assertRaisesRegex(ValueError, r"Invalid dict watcher ID 8"): |
1862 |
| - self.clear_watcher(8) # DICT_MAX_WATCHERS = 8 |
1863 |
| - |
1864 |
| - def test_clear_unassigned_watcher_id(self): |
1865 |
| - with self.assertRaisesRegex(ValueError, r"No dict watcher set for ID 1"): |
1866 |
| - self.clear_watcher(1) |
1867 |
| - |
1868 |
| - |
1869 |
| -class TestTypeWatchers(unittest.TestCase): |
1870 |
| - # types of watchers testcapimodule can add: |
1871 |
| - TYPES = 0 # appends modified types to global event list |
1872 |
| - ERROR = 1 # unconditionally sets and signals a RuntimeException |
1873 |
| - WRAP = 2 # appends modified type wrapped in list to global event list |
1874 |
| - |
1875 |
| - # duplicating the C constant |
1876 |
| - TYPE_MAX_WATCHERS = 8 |
1877 |
| - |
1878 |
| - def add_watcher(self, kind=TYPES): |
1879 |
| - return _testcapi.add_type_watcher(kind) |
1880 |
| - |
1881 |
| - def clear_watcher(self, watcher_id): |
1882 |
| - _testcapi.clear_type_watcher(watcher_id) |
1883 |
| - |
1884 |
| - @contextmanager |
1885 |
| - def watcher(self, kind=TYPES): |
1886 |
| - wid = self.add_watcher(kind) |
1887 |
| - try: |
1888 |
| - yield wid |
1889 |
| - finally: |
1890 |
| - self.clear_watcher(wid) |
1891 |
| - |
1892 |
| - def assert_events(self, expected): |
1893 |
| - actual = _testcapi.get_type_modified_events() |
1894 |
| - self.assertEqual(actual, expected) |
1895 |
| - |
1896 |
| - def watch(self, wid, t): |
1897 |
| - _testcapi.watch_type(wid, t) |
1898 |
| - |
1899 |
| - def unwatch(self, wid, t): |
1900 |
| - _testcapi.unwatch_type(wid, t) |
1901 |
| - |
1902 |
| - def test_watch_type(self): |
1903 |
| - class C: pass |
1904 |
| - with self.watcher() as wid: |
1905 |
| - self.watch(wid, C) |
1906 |
| - C.foo = "bar" |
1907 |
| - self.assert_events([C]) |
1908 |
| - |
1909 |
| - def test_event_aggregation(self): |
1910 |
| - class C: pass |
1911 |
| - with self.watcher() as wid: |
1912 |
| - self.watch(wid, C) |
1913 |
| - C.foo = "bar" |
1914 |
| - C.bar = "baz" |
1915 |
| - # only one event registered for both modifications |
1916 |
| - self.assert_events([C]) |
1917 |
| - |
1918 |
| - def test_lookup_resets_aggregation(self): |
1919 |
| - class C: pass |
1920 |
| - with self.watcher() as wid: |
1921 |
| - self.watch(wid, C) |
1922 |
| - C.foo = "bar" |
1923 |
| - # lookup resets type version tag |
1924 |
| - self.assertEqual(C.foo, "bar") |
1925 |
| - C.bar = "baz" |
1926 |
| - # both events registered |
1927 |
| - self.assert_events([C, C]) |
1928 |
| - |
1929 |
| - def test_unwatch_type(self): |
1930 |
| - class C: pass |
1931 |
| - with self.watcher() as wid: |
1932 |
| - self.watch(wid, C) |
1933 |
| - C.foo = "bar" |
1934 |
| - self.assertEqual(C.foo, "bar") |
1935 |
| - self.assert_events([C]) |
1936 |
| - self.unwatch(wid, C) |
1937 |
| - C.bar = "baz" |
1938 |
| - self.assert_events([C]) |
1939 |
| - |
1940 |
| - def test_clear_watcher(self): |
1941 |
| - class C: pass |
1942 |
| - # outer watcher is unused, it's just to keep events list alive |
1943 |
| - with self.watcher() as _: |
1944 |
| - with self.watcher() as wid: |
1945 |
| - self.watch(wid, C) |
1946 |
| - C.foo = "bar" |
1947 |
| - self.assertEqual(C.foo, "bar") |
1948 |
| - self.assert_events([C]) |
1949 |
| - C.bar = "baz" |
1950 |
| - # Watcher on C has been cleared, no new event |
1951 |
| - self.assert_events([C]) |
1952 |
| - |
1953 |
| - def test_watch_type_subclass(self): |
1954 |
| - class C: pass |
1955 |
| - class D(C): pass |
1956 |
| - with self.watcher() as wid: |
1957 |
| - self.watch(wid, D) |
1958 |
| - C.foo = "bar" |
1959 |
| - self.assert_events([D]) |
1960 |
| - |
1961 |
| - def test_error(self): |
1962 |
| - class C: pass |
1963 |
| - with self.watcher(kind=self.ERROR) as wid: |
1964 |
| - self.watch(wid, C) |
1965 |
| - with catch_unraisable_exception() as cm: |
1966 |
| - C.foo = "bar" |
1967 |
| - self.assertIs(cm.unraisable.object, C) |
1968 |
| - self.assertEqual(str(cm.unraisable.exc_value), "boom!") |
1969 |
| - self.assert_events([]) |
1970 |
| - |
1971 |
| - def test_two_watchers(self): |
1972 |
| - class C1: pass |
1973 |
| - class C2: pass |
1974 |
| - with self.watcher() as wid1: |
1975 |
| - with self.watcher(kind=self.WRAP) as wid2: |
1976 |
| - self.assertNotEqual(wid1, wid2) |
1977 |
| - self.watch(wid1, C1) |
1978 |
| - self.watch(wid2, C2) |
1979 |
| - C1.foo = "bar" |
1980 |
| - C2.hmm = "baz" |
1981 |
| - self.assert_events([C1, [C2]]) |
1982 |
| - |
1983 |
| - def test_watch_non_type(self): |
1984 |
| - with self.watcher() as wid: |
1985 |
| - with self.assertRaisesRegex(ValueError, r"Cannot watch non-type"): |
1986 |
| - self.watch(wid, 1) |
1987 |
| - |
1988 |
| - def test_watch_out_of_range_watcher_id(self): |
1989 |
| - class C: pass |
1990 |
| - with self.assertRaisesRegex(ValueError, r"Invalid type watcher ID -1"): |
1991 |
| - self.watch(-1, C) |
1992 |
| - with self.assertRaisesRegex(ValueError, r"Invalid type watcher ID 8"): |
1993 |
| - self.watch(self.TYPE_MAX_WATCHERS, C) |
1994 |
| - |
1995 |
| - def test_watch_unassigned_watcher_id(self): |
1996 |
| - class C: pass |
1997 |
| - with self.assertRaisesRegex(ValueError, r"No type watcher set for ID 1"): |
1998 |
| - self.watch(1, C) |
1999 |
| - |
2000 |
| - def test_unwatch_non_type(self): |
2001 |
| - with self.watcher() as wid: |
2002 |
| - with self.assertRaisesRegex(ValueError, r"Cannot watch non-type"): |
2003 |
| - self.unwatch(wid, 1) |
2004 |
| - |
2005 |
| - def test_unwatch_out_of_range_watcher_id(self): |
2006 |
| - class C: pass |
2007 |
| - with self.assertRaisesRegex(ValueError, r"Invalid type watcher ID -1"): |
2008 |
| - self.unwatch(-1, C) |
2009 |
| - with self.assertRaisesRegex(ValueError, r"Invalid type watcher ID 8"): |
2010 |
| - self.unwatch(self.TYPE_MAX_WATCHERS, C) |
2011 |
| - |
2012 |
| - def test_unwatch_unassigned_watcher_id(self): |
2013 |
| - class C: pass |
2014 |
| - with self.assertRaisesRegex(ValueError, r"No type watcher set for ID 1"): |
2015 |
| - self.unwatch(1, C) |
2016 |
| - |
2017 |
| - def test_clear_out_of_range_watcher_id(self): |
2018 |
| - with self.assertRaisesRegex(ValueError, r"Invalid type watcher ID -1"): |
2019 |
| - self.clear_watcher(-1) |
2020 |
| - with self.assertRaisesRegex(ValueError, r"Invalid type watcher ID 8"): |
2021 |
| - self.clear_watcher(self.TYPE_MAX_WATCHERS) |
2022 |
| - |
2023 |
| - def test_clear_unassigned_watcher_id(self): |
2024 |
| - with self.assertRaisesRegex(ValueError, r"No type watcher set for ID 1"): |
2025 |
| - self.clear_watcher(1) |
2026 |
| - |
2027 |
| - def test_no_more_ids_available(self): |
2028 |
| - contexts = [self.watcher() for i in range(self.TYPE_MAX_WATCHERS)] |
2029 |
| - with ExitStack() as stack: |
2030 |
| - for ctx in contexts: |
2031 |
| - stack.enter_context(ctx) |
2032 |
| - with self.assertRaisesRegex(RuntimeError, r"no more type watcher IDs"): |
2033 |
| - self.add_watcher() |
2034 |
| - |
2035 |
| - |
2036 | 1706 | if __name__ == "__main__":
|
2037 | 1707 | unittest.main()
|
0 commit comments