|
618 | 618 | { |
619 | 619 | "data": { |
620 | 620 | "text/plain": [ |
621 | | - "['a', 'f', 'b', 'g', 'd', 'e', 'h', 'c']" |
| 621 | + "['b', 'a', 'd', 'e', 'f', 'h', 'g', 'c']" |
622 | 622 | ] |
623 | 623 | }, |
624 | 624 | "execution_count": null, |
|
963 | 963 | " parse_int=parse_int, parse_constant=parse_constant, object_pairs_hook=object_pairs_hook, **kw)" |
964 | 964 | ] |
965 | 965 | }, |
| 966 | + { |
| 967 | + "cell_type": "code", |
| 968 | + "execution_count": null, |
| 969 | + "metadata": {}, |
| 970 | + "outputs": [], |
| 971 | + "source": [ |
| 972 | + "#export\n", |
| 973 | + "def loads_multi(s:str):\n", |
| 974 | + " \"Generator of >=0 decoded json dicts, possibly with non-json ignored text at start and end\"\n", |
| 975 | + " _dec = json.JSONDecoder()\n", |
| 976 | + " while s.find('{')>=0:\n", |
| 977 | + " s = s[s.find('{'):]\n", |
| 978 | + " obj,pos = _dec.raw_decode(s)\n", |
| 979 | + " if not pos: raise ValueError(f'no JSON object found at {pos}')\n", |
| 980 | + " yield obj\n", |
| 981 | + " s = s[pos:]" |
| 982 | + ] |
| 983 | + }, |
| 984 | + { |
| 985 | + "cell_type": "code", |
| 986 | + "execution_count": null, |
| 987 | + "metadata": {}, |
| 988 | + "outputs": [], |
| 989 | + "source": [ |
| 990 | + "tst = \"\"\"\n", |
| 991 | + "# ignored\n", |
| 992 | + "{ \"a\":1 }\n", |
| 993 | + "hello\n", |
| 994 | + "{\n", |
| 995 | + "\"b\":2\n", |
| 996 | + "}\n", |
| 997 | + "\"\"\"\n", |
| 998 | + "\n", |
| 999 | + "test_eq(list(loads_multi(tst)), [{'a': 1}, {'b': 2}])" |
| 1000 | + ] |
| 1001 | + }, |
966 | 1002 | { |
967 | 1003 | "cell_type": "code", |
968 | 1004 | "execution_count": null, |
|
1840 | 1876 | "for o in 1,True: assert str2bool(o)" |
1841 | 1877 | ] |
1842 | 1878 | }, |
1843 | | - { |
1844 | | - "cell_type": "code", |
1845 | | - "execution_count": null, |
1846 | | - "metadata": {}, |
1847 | | - "outputs": [], |
1848 | | - "source": [ |
1849 | | - "#export\n", |
1850 | | - "def _is_instance(f, gs):\n", |
1851 | | - " tst = [g if type(g) in [type, 'function'] else g.__class__ for g in gs]\n", |
1852 | | - " for g in tst:\n", |
1853 | | - " if isinstance(f, g) or f==g: return True\n", |
1854 | | - " return False\n", |
1855 | | - "\n", |
1856 | | - "def _is_first(f, gs):\n", |
1857 | | - " for o in L(getattr(f, 'run_after', None)):\n", |
1858 | | - " if _is_instance(o, gs): return False\n", |
1859 | | - " for g in gs:\n", |
1860 | | - " if _is_instance(f, L(getattr(g, 'run_before', None))): return False\n", |
1861 | | - " return True\n", |
1862 | | - "\n", |
1863 | | - "def sort_by_run(fs):\n", |
1864 | | - " end = L(fs).attrgot('toward_end')\n", |
1865 | | - " inp,res = L(fs)[~end] + L(fs)[end], L()\n", |
1866 | | - " while len(inp):\n", |
1867 | | - " for i,o in enumerate(inp):\n", |
1868 | | - " if _is_first(o, inp):\n", |
1869 | | - " res.append(inp.pop(i))\n", |
1870 | | - " break\n", |
1871 | | - " else: raise Exception(\"Impossible to sort\")\n", |
1872 | | - " return res" |
1873 | | - ] |
1874 | | - }, |
1875 | | - { |
1876 | | - "cell_type": "markdown", |
1877 | | - "metadata": {}, |
1878 | | - "source": [ |
1879 | | - "Transforms and callbacks will have run_after/run_before attributes, this function will sort them to respect those requirements (if it's possible). Also, sometimes we want a tranform/callback to be run at the end, but still be able to use run_after/run_before behaviors. For those, the function checks for a toward_end attribute (that needs to be True)." |
1880 | | - ] |
1881 | | - }, |
1882 | | - { |
1883 | | - "cell_type": "code", |
1884 | | - "execution_count": null, |
1885 | | - "metadata": {}, |
1886 | | - "outputs": [], |
1887 | | - "source": [ |
1888 | | - "class Tst(): pass \n", |
1889 | | - "class Tst1(): run_before=[Tst]\n", |
1890 | | - "class Tst2():\n", |
1891 | | - " run_before=Tst\n", |
1892 | | - " run_after=Tst1\n", |
1893 | | - " \n", |
1894 | | - "tsts = [Tst(), Tst1(), Tst2()]\n", |
1895 | | - "test_eq(sort_by_run(tsts), [tsts[1], tsts[2], tsts[0]])\n", |
1896 | | - "\n", |
1897 | | - "Tst2.run_before,Tst2.run_after = Tst1,Tst\n", |
1898 | | - "test_fail(lambda: sort_by_run([Tst(), Tst1(), Tst2()]))\n", |
1899 | | - "\n", |
1900 | | - "def tst1(x): return x\n", |
1901 | | - "tst1.run_before = Tst\n", |
1902 | | - "test_eq(sort_by_run([tsts[0], tst1]), [tst1, tsts[0]])\n", |
1903 | | - " \n", |
1904 | | - "class Tst1():\n", |
1905 | | - " toward_end=True\n", |
1906 | | - "class Tst2():\n", |
1907 | | - " toward_end=True\n", |
1908 | | - " run_before=Tst1\n", |
1909 | | - "tsts = [Tst(), Tst1(), Tst2()]\n", |
1910 | | - "test_eq(sort_by_run(tsts), [tsts[0], tsts[2], tsts[1]])" |
1911 | | - ] |
1912 | | - }, |
1913 | 1879 | { |
1914 | 1880 | "cell_type": "markdown", |
1915 | 1881 | "metadata": {}, |
|
0 commit comments