diff --git a/.asv/results/ci-linux/06c89cf9-virtualenv-py3.13-django5.1-djc-core-html-parser.json b/.asv/results/ci-linux/06c89cf9-virtualenv-py3.13-django5.1-djc-core-html-parser.json deleted file mode 100644 index edbf55d8..00000000 --- a/.asv/results/ci-linux/06c89cf9-virtualenv-py3.13-django5.1-djc-core-html-parser.json +++ /dev/null @@ -1 +0,0 @@ -{"commit_hash": "06c89cf9e89a432197a4cabb5a1d6864dd6089ac", "env_name": "virtualenv-py3.13-django5.1-djc-core-html-parser", "date": 1749546769000, "params": {"machine": "ci-linux", "python": "3.13", "django": "5.1", "djc-core-html-parser": ""}, "python": "3.13", "requirements": {"django": "5.1", "djc-core-html-parser": ""}, "env_vars": {}, "result_columns": ["result", "params", "version", "started_at", "duration", "stats_ci_99_a", "stats_ci_99_b", "stats_q_25", "stats_q_75", "stats_number", "stats_repeat", "samples", "profile"], "results": {"Components vs Django.timeraw_render_lg_first": [[0.08026317200000221, 0.26819844099998136], [["'django'", "'django-components'"]], "be3bf6236960046a028b6ea007aad28b2337fc2b906b8ce317a09a5d4f1a6193", 1749547226154, 31.969, [0.079592, 0.26712], [0.081627, 0.27054], [0.079806, 0.26758], [0.080908, 0.27014], [1, 1], [25, 25]], "Components vs Django.timeraw_render_lg_subsequent": [[0.04349111400000538, 0.15453611999998884], [["'django'", "'django-components'"]], "b98221c11a0ee6e9de0778d416d31b9dd514a674d9017a2bb9b2fc1cd0f01920", 1749547232510, 37.93, [0.043083, 0.15395], [0.044645, 0.15628], [0.04313, 0.15396], [0.044614, 0.15596], [1, 1], [25, 25]], "Components vs Django.timeraw_render_sm_first": [[0.0036145729999930154, 0.004811176000004025], [["'django'", "'django-components'"]], "f1fc17e4a31c71f4d9265f1122da52e7cf57addb4dfa02606e303b33d6431b9b", 1749547240091, 17.086, [0.0035701, 0.0047897], [0.0036399, 0.0048885], [0.0035736, 0.004795], [0.0036371, 0.0048827], [1, 1], [25, 25]], "Components vs Django.timeraw_render_sm_subsequent": [[0.00012332000000014887, 0.0005915369999911491], [["'django'", "'django-components'"]], "6fce1cd85a9344fee383b40a22f27862120b9488a628420625592dc14e0307d3", 1749547243508, 17.13, [0.00012078, 0.0005805], [0.00013759, 0.00060184], [0.00012127, 0.00058107], [0.00012742, 0.00059879], [1, 1], [25, 25]], "Components vs Django.timeraw_startup_lg": [[0.2252378419999843, 0.2247263650000093], [["'django'", "'django-components'"]], "53151821c128ad0ecfb0707fff3146e1abd8d0bcfa301aa056b5d3fae3d793e2", 1749547246927, 19.999, [0.22441, 0.22363], [0.22729, 0.22686], [0.22452, 0.22369], [0.22639, 0.22556], [1, 1], [25, 25]], "Other.timeraw_import_time": [[0.20468290799999522], [], "a0a1c1c0db22509410b946d0d4384b52ea4a09b47b6048d7d1cfb89b0c7fe5c3", 1749547250936, 8.1567, [0.20338], [0.20624], [0.20374], [0.20582], [1], [25]], "isolated vs django modes.timeraw_render_lg_first": [[0.26819597400000816, 0.2740507329999957], [["'isolated'", "'django'"]], "f94af83427c6346f88f8785a3cd2fc42415ac5a9fbbdb7de71d27e22e6a81699", 1749547255664, 37.318, [0.26688, 0.27234], [0.26941, 0.28032], [0.26702, 0.2725], [0.26926, 0.279], [1, 1], [25, 25]], "isolated vs django modes.timeraw_render_lg_subsequent": [[0.15396625699997912, 0.16023626799997714], [["'isolated'", "'django'"]], "9f7c2fde6b33f0451a1794ed903c48d96cd7822f67da502cec36fe8e977c2414", 1749547263180, 47.125, [0.15282, 0.15877], [0.15647, 0.16443], [0.15297, 0.15902], [0.15588, 0.16441], [1, 1], [25, 25]], "isolated vs django modes.timeraw_render_sm_first": [[0.004825538000005736, 0.0047952310000027865], [["'isolated'", "'django'"]], "d15ca68909d7f1f43ff16863befb6f42681f17461417fc0069eefd6db3569296", 1749547272622, 17.085, [0.0048028, 0.0047649], [0.0048467, 0.0048197], [0.0048091, 0.0047651], [0.0048402, 0.0048192], [1, 1], [25, 25]], "isolated vs django modes.timeraw_render_sm_subsequent": [[0.0005953940000154034, 0.0005933700000468889], [["'isolated'", "'django'"]], "7444bc9516dd087e3f420349345eae991ad6941bbd22fce45265b18034b7cf77", 1749547276032, 17.147, [0.0005815, 0.00058741], [0.00060108, 0.00059832], [0.00058285, 0.0005878], [0.0006001, 0.00059759], [1, 1], [25, 25]], "isolated vs django modes.timeraw_startup_lg": [[0.22564571399999522, 0.22598634599995648], [["'isolated'", "'django'"]], "eabe311ebee4a15c5816617be12f00ec30376f7506bd668219e1c50bc897c134", 1749547279452, 19.816, [0.22324, 0.22336], [0.22965, 0.22994], [0.22384, 0.22382], [0.22963, 0.22889], [1, 1], [25, 25]], "Components vs Django.peakmem_render_lg_first": [[52932608, 55693312], [["'django'", "'django-components'"]], "301c396f017f45a5b3f71e85df58d15f54153fcfd951af7ef424641d4b31b528", 1749547223611, 0.79781], "Components vs Django.peakmem_render_lg_subsequent": [[53063680, 56180736], [["'django'", "'django-components'"]], "9a44e9999ef3ef42ea7e01323727490244febb43d66a87a4d8f88c6b8a133b8b", 1749547224409, 0.99222], "Components vs Django.peakmem_render_sm_first": [[44716032, 44834816], [["'django'", "'django-components'"]], "e93b7a5193681c883edf85bdb30b1bc0821263bf51033fdcee215b155085e036", 1749547225402, 0.37525], "Components vs Django.peakmem_render_sm_subsequent": [[44716032, 44838912], [["'django'", "'django-components'"]], "b46e0820b18950aa7cc5e61306ff3425b76b4da9dca42d64fae5b1d25c6c9026", 1749547225778, 0.37627], "isolated vs django modes.peakmem_render_lg_first": [[55263232, 54693888], [["'isolated'", "'django'"]], "c4bf0016d48d210f08b8db733b57c7dcba1cebbf548c458b93b86ace387067e9", 1749547252571, 1.0035], "isolated vs django modes.peakmem_render_lg_subsequent": [[55783424, 56160256], [["'isolated'", "'django'"]], "65bb1b8586487197a79bb6073e4c71642877b845b6eb42d1bd32398299daffbf", 1749547253575, 1.3187], "isolated vs django modes.peakmem_render_sm_first": [[44838912, 44838912], [["'isolated'", "'django'"]], "c51b91fc583295776062822225e720b5ed71aef9c9288217c401c54283c62840", 1749547254894, 0.38522], "isolated vs django modes.peakmem_render_sm_subsequent": [[44965888, 44834816], [["'isolated'", "'django'"]], "54d747fb8f40179b7ff3d2fc49eb195909ad1c880b5ef7b82f82742b27b67260", 1749547255279, 0.38471]}, "durations": {}, "version": 2} \ No newline at end of file diff --git a/.asv/results/ci-linux/5d7e2357-virtualenv-py3.13-django5.1-djc-core-html-parser.json b/.asv/results/ci-linux/5d7e2357-virtualenv-py3.13-django5.1-djc-core-html-parser.json deleted file mode 100644 index 5f591b2f..00000000 --- a/.asv/results/ci-linux/5d7e2357-virtualenv-py3.13-django5.1-djc-core-html-parser.json +++ /dev/null @@ -1 +0,0 @@ -{"commit_hash": "5d7e235725449181f6b65b7bf97e43ea0e0f8552", "env_name": "virtualenv-py3.13-django5.1-djc-core-html-parser", "date": 1753049108000, "params": {"machine": "ci-linux", "python": "3.13", "django": "5.1", "djc-core-html-parser": ""}, "python": "3.13", "requirements": {"django": "5.1", "djc-core-html-parser": ""}, "env_vars": {}, "result_columns": ["result", "params", "version", "started_at", "duration", "stats_ci_99_a", "stats_ci_99_b", "stats_q_25", "stats_q_75", "stats_number", "stats_repeat", "samples", "profile"], "results": {"Components vs Django.timeraw_render_lg_first": [[0.08105427499998541, 0.29477426600001877], [["'django'", "'django-components'"]], "be3bf6236960046a028b6ea007aad28b2337fc2b906b8ce317a09a5d4f1a6193", 1753049851954, 33.615, [0.079961, 0.29197], [0.082291, 0.29933], [0.080014, 0.29202], [0.08217, 0.29917], [1, 1], [25, 25]], "Components vs Django.timeraw_render_lg_subsequent": [[0.043648402000002307, 0.17461173199995983], [["'django'", "'django-components'"]], "b98221c11a0ee6e9de0778d416d31b9dd514a674d9017a2bb9b2fc1cd0f01920", 1753049858567, 39.742, [0.043109, 0.17344], [0.044493, 0.17591], [0.043193, 0.17344], [0.044363, 0.17568], [1, 1], [25, 25]], "Components vs Django.timeraw_render_sm_first": [[0.0037106409999978496, 0.004899473999955717], [["'django'", "'django-components'"]], "f1fc17e4a31c71f4d9265f1122da52e7cf57addb4dfa02606e303b33d6431b9b", 1753049866520, 17.599, [0.0036469, 0.0048514], [0.003775, 0.0049767], [0.0036506, 0.0048584], [0.0037527, 0.0049267], [1, 1], [25, 25]], "Components vs Django.timeraw_render_sm_subsequent": [[0.00012706900002967814, 0.0006100459999629493], [["'django'", "'django-components'"]], "6fce1cd85a9344fee383b40a22f27862120b9488a628420625592dc14e0307d3", 1753049870045, 17.527, [0.00012441, 0.0005963], [0.00012848, 0.00063084], [0.00012455, 0.00059677], [0.00012835, 0.0006285], [1, 1], [25, 25]], "Components vs Django.timeraw_startup_lg": [[0.22799248500001568, 0.22723498599998493], [["'django'", "'django-components'"]], "53151821c128ad0ecfb0707fff3146e1abd8d0bcfa301aa056b5d3fae3d793e2", 1753049873538, 20.449, [0.22611, 0.22628], [0.22958, 0.22866], [0.22612, 0.2263], [0.22904, 0.22847], [1, 1], [25, 25]], "Other.timeraw_import_time": [[0.2056691309999792], [], "a0a1c1c0db22509410b946d0d4384b52ea4a09b47b6048d7d1cfb89b0c7fe5c3", 1753049877623, 8.3423, [0.20476], [0.20838], [0.20478], [0.20831], [1], [25]], "isolated vs django modes.timeraw_render_lg_first": [[0.2920349000000044, 0.2976166970000236], [["'isolated'", "'django'"]], "f94af83427c6346f88f8785a3cd2fc42415ac5a9fbbdb7de71d27e22e6a81699", 1753049882577, 39.421, [0.29051, 0.29507], [0.29462, 0.2996], [0.29057, 0.29561], [0.29428, 0.29935], [1, 1], [25, 25]], "isolated vs django modes.timeraw_render_lg_subsequent": [[0.17414895399997476, 0.178393189000019], [["'isolated'", "'django'"]], "9f7c2fde6b33f0451a1794ed903c48d96cd7822f67da502cec36fe8e977c2414", 1753049890450, 50.139, [0.17304, 0.17805], [0.17616, 0.17928], [0.17314, 0.17806], [0.17595, 0.17923], [1, 1], [25, 25]], "isolated vs django modes.timeraw_render_sm_first": [[0.004897051999989799, 0.004863266000029398], [["'isolated'", "'django'"]], "d15ca68909d7f1f43ff16863befb6f42681f17461417fc0069eefd6db3569296", 1753049900457, 17.558, [0.0048512, 0.004838], [0.0049693, 0.0049278], [0.0048517, 0.0048435], [0.0049605, 0.0049223], [1, 1], [25, 25]], "isolated vs django modes.timeraw_render_sm_subsequent": [[0.0006159270000125616, 0.0006080119999865019], [["'isolated'", "'django'"]], "7444bc9516dd087e3f420349345eae991ad6941bbd22fce45265b18034b7cf77", 1753049903955, 17.521, [0.00060693, 0.0005956], [0.00062901, 0.00061672], [0.00060764, 0.00059691], [0.00062683, 0.00061634], [1, 1], [25, 25]], "isolated vs django modes.timeraw_startup_lg": [[0.22777395400004252, 0.2292747939999913], [["'isolated'", "'django'"]], "eabe311ebee4a15c5816617be12f00ec30376f7506bd668219e1c50bc897c134", 1753049907456, 20.282, [0.22683, 0.22736], [0.2295, 0.23339], [0.22692, 0.22764], [0.22924, 0.23178], [1, 1], [25, 25]], "Components vs Django.peakmem_render_lg_first": [[52715520, 56090624], [["'django'", "'django-components'"]], "301c396f017f45a5b3f71e85df58d15f54153fcfd951af7ef424641d4b31b528", 1753049849303, 0.82982], "Components vs Django.peakmem_render_lg_subsequent": [[52736000, 56791040], [["'django'", "'django-components'"]], "9a44e9999ef3ef42ea7e01323727490244febb43d66a87a4d8f88c6b8a133b8b", 1753049850134, 1.0513], "Components vs Django.peakmem_render_sm_first": [[44871680, 44912640], [["'django'", "'django-components'"]], "e93b7a5193681c883edf85bdb30b1bc0821263bf51033fdcee215b155085e036", 1753049851185, 0.38233], "Components vs Django.peakmem_render_sm_subsequent": [[44617728, 44986368], [["'django'", "'django-components'"]], "b46e0820b18950aa7cc5e61306ff3425b76b4da9dca42d64fae5b1d25c6c9026", 1753049851568, 0.38596], "isolated vs django modes.peakmem_render_lg_first": [[56090624, 55582720], [["'isolated'", "'django'"]], "c4bf0016d48d210f08b8db733b57c7dcba1cebbf548c458b93b86ace387067e9", 1753049879302, 1.0575], "isolated vs django modes.peakmem_render_lg_subsequent": [[56786944, 56778752], [["'isolated'", "'django'"]], "65bb1b8586487197a79bb6073e4c71642877b845b6eb42d1bd32398299daffbf", 1753049880360, 1.4396], "isolated vs django modes.peakmem_render_sm_first": [[44843008, 44851200], [["'isolated'", "'django'"]], "c51b91fc583295776062822225e720b5ed71aef9c9288217c401c54283c62840", 1753049881800, 0.38828], "isolated vs django modes.peakmem_render_sm_subsequent": [[44982272, 44986368], [["'isolated'", "'django'"]], "54d747fb8f40179b7ff3d2fc49eb195909ad1c880b5ef7b82f82742b27b67260", 1753049882189, 0.38775]}, "durations": {}, "version": 2} \ No newline at end of file diff --git a/.asv/results/ci-linux/7b24b86f-virtualenv-py3.13-django5.1-djc-core-html-parser.json b/.asv/results/ci-linux/7b24b86f-virtualenv-py3.13-django5.1-djc-core-html-parser.json deleted file mode 100644 index 3acec4f5..00000000 --- a/.asv/results/ci-linux/7b24b86f-virtualenv-py3.13-django5.1-djc-core-html-parser.json +++ /dev/null @@ -1 +0,0 @@ -{"commit_hash": "7b24b86f4a836c697acba926d9d6602afa45418d", "env_name": "virtualenv-py3.13-django5.1-djc-core-html-parser", "date": 1749076521000, "params": {"machine": "ci-linux", "python": "3.13", "django": "5.1", "djc-core-html-parser": ""}, "python": "3.13", "requirements": {"django": "5.1", "djc-core-html-parser": ""}, "env_vars": {}, "result_columns": ["result", "params", "version", "started_at", "duration", "stats_ci_99_a", "stats_ci_99_b", "stats_q_25", "stats_q_75", "stats_number", "stats_repeat", "samples", "profile"], "results": {"Components vs Django.timeraw_render_lg_first": [[0.07941284200001064, 0.26779402600004687], [["'django'", "'django-components'"]], "be3bf6236960046a028b6ea007aad28b2337fc2b906b8ce317a09a5d4f1a6193", 1749076875010, 33.29, [0.078956, 0.26662], [0.081186, 0.27149], [0.079001, 0.26705], [0.080936, 0.27135], [1, 1], [25, 25]], "Components vs Django.timeraw_render_lg_subsequent": [[0.043317416999911984, 0.15457556900003055], [["'django'", "'django-components'"]], "b98221c11a0ee6e9de0778d416d31b9dd514a674d9017a2bb9b2fc1cd0f01920", 1749076881523, 38.751, [0.042862, 0.15282], [0.044278, 0.15833], [0.042896, 0.15289], [0.044184, 0.15671], [1, 1], [25, 25]], "Components vs Django.timeraw_render_sm_first": [[0.0036632869999948525, 0.00493345400002454], [["'django'", "'django-components'"]], "f1fc17e4a31c71f4d9265f1122da52e7cf57addb4dfa02606e303b33d6431b9b", 1749076889315, 17.497, [0.0036441, 0.0048964], [0.0037017, 0.0050018], [0.0036475, 0.0049028], [0.0037007, 0.0049814], [1, 1], [25, 25]], "Components vs Django.timeraw_render_sm_subsequent": [[0.00012153600005149201, 0.0005999570000199128], [["'django'", "'django-components'"]], "6fce1cd85a9344fee383b40a22f27862120b9488a628420625592dc14e0307d3", 1749076892858, 17.52, [0.00012055, 0.00057981], [0.00012289, 0.00061584], [0.00012056, 0.00058243], [0.00012282, 0.00061301], [1, 1], [25, 25]], "Components vs Django.timeraw_startup_lg": [[0.22743783699991127, 0.226070988999993], [["'django'", "'django-components'"]], "53151821c128ad0ecfb0707fff3146e1abd8d0bcfa301aa056b5d3fae3d793e2", 1749076896345, 20.618, [0.22567, 0.22411], [0.22912, 0.22959], [0.22581, 0.22418], [0.22858, 0.22815], [1, 1], [25, 25]], "Other.timeraw_import_time": [[0.2063091950000171], [], "a0a1c1c0db22509410b946d0d4384b52ea4a09b47b6048d7d1cfb89b0c7fe5c3", 1749076900468, 8.3563, [0.20413], [0.20858], [0.20424], [0.20774], [1], [25]], "isolated vs django modes.timeraw_render_lg_first": [[0.2675778039999841, 0.2724974679999832], [["'isolated'", "'django'"]], "f94af83427c6346f88f8785a3cd2fc42415ac5a9fbbdb7de71d27e22e6a81699", 1749076905243, 38.085, [0.26574, 0.27164], [0.27197, 0.27673], [0.26585, 0.27165], [0.27065, 0.27581], [1, 1], [25, 25]], "isolated vs django modes.timeraw_render_lg_subsequent": [[0.15459265900005903, 0.15926110200007315], [["'isolated'", "'django'"]], "9f7c2fde6b33f0451a1794ed903c48d96cd7822f67da502cec36fe8e977c2414", 1749076912924, 47.983, [0.15333, 0.15793], [0.15993, 0.16206], [0.1535, 0.15845], [0.15979, 0.16152], [1, 1], [25, 25]], "isolated vs django modes.timeraw_render_sm_first": [[0.004923484000073586, 0.004925836999973399], [["'isolated'", "'django'"]], "d15ca68909d7f1f43ff16863befb6f42681f17461417fc0069eefd6db3569296", 1749076922561, 17.577, [0.0048564, 0.0048656], [0.0050014, 0.004982], [0.0048761, 0.0048661], [0.004997, 0.004977], [1, 1], [25, 25]], "isolated vs django modes.timeraw_render_sm_subsequent": [[0.0005969709999362749, 0.0005864510000037626], [["'isolated'", "'django'"]], "7444bc9516dd087e3f420349345eae991ad6941bbd22fce45265b18034b7cf77", 1749076926091, 17.606, [0.00058144, 0.00058324], [0.00060954, 0.00059625], [0.00058749, 0.00058422], [0.00060768, 0.00059614], [1, 1], [25, 25]], "isolated vs django modes.timeraw_startup_lg": [[0.22545313400001987, 0.22602228000005198], [["'isolated'", "'django'"]], "eabe311ebee4a15c5816617be12f00ec30376f7506bd668219e1c50bc897c134", 1749076929634, 20.393, [0.22445, 0.22472], [0.22834, 0.22927], [0.2245, 0.22475], [0.22781, 0.22878], [1, 1], [25, 25]], "Components vs Django.peakmem_render_lg_first": [[52957184, 55177216], [["'django'", "'django-components'"]], "301c396f017f45a5b3f71e85df58d15f54153fcfd951af7ef424641d4b31b528", 1749076872421, 0.81152], "Components vs Django.peakmem_render_lg_subsequent": [[52822016, 56242176], [["'django'", "'django-components'"]], "9a44e9999ef3ef42ea7e01323727490244febb43d66a87a4d8f88c6b8a133b8b", 1749076873233, 1.0095], "Components vs Django.peakmem_render_sm_first": [[44756992, 44744704], [["'django'", "'django-components'"]], "e93b7a5193681c883edf85bdb30b1bc0821263bf51033fdcee215b155085e036", 1749076874243, 0.37927], "Components vs Django.peakmem_render_sm_subsequent": [[44527616, 44744704], [["'django'", "'django-components'"]], "b46e0820b18950aa7cc5e61306ff3425b76b4da9dca42d64fae5b1d25c6c9026", 1749076874622, 0.38717], "isolated vs django modes.peakmem_render_lg_first": [[55222272, 54722560], [["'isolated'", "'django'"]], "c4bf0016d48d210f08b8db733b57c7dcba1cebbf548c458b93b86ace387067e9", 1749076902121, 1.0091], "isolated vs django modes.peakmem_render_lg_subsequent": [[56008704, 56143872], [["'isolated'", "'django'"]], "65bb1b8586487197a79bb6073e4c71642877b845b6eb42d1bd32398299daffbf", 1749076903130, 1.3368], "isolated vs django modes.peakmem_render_sm_first": [[44744704, 44744704], [["'isolated'", "'django'"]], "c51b91fc583295776062822225e720b5ed71aef9c9288217c401c54283c62840", 1749076904467, 0.38687], "isolated vs django modes.peakmem_render_sm_subsequent": [[44744704, 44744704], [["'isolated'", "'django'"]], "54d747fb8f40179b7ff3d2fc49eb195909ad1c880b5ef7b82f82742b27b67260", 1749076904855, 0.38848]}, "durations": {}, "version": 2} \ No newline at end of file diff --git a/.asv/results/ci-linux/c692b7a3-virtualenv-py3.13-django5.1-djc-core-html-parser.json b/.asv/results/ci-linux/c692b7a3-virtualenv-py3.13-django5.1-djc-core-html-parser.json deleted file mode 100644 index 14392b99..00000000 --- a/.asv/results/ci-linux/c692b7a3-virtualenv-py3.13-django5.1-djc-core-html-parser.json +++ /dev/null @@ -1 +0,0 @@ -{"commit_hash": "c692b7a3105c65414d2c23c357ffed9debdbf6e9", "env_name": "virtualenv-py3.13-django5.1-djc-core-html-parser", "date": 1751538441000, "params": {"machine": "ci-linux", "python": "3.13", "django": "5.1", "djc-core-html-parser": ""}, "python": "3.13", "requirements": {"django": "5.1", "djc-core-html-parser": ""}, "env_vars": {}, "result_columns": ["result", "params", "version", "started_at", "duration", "stats_ci_99_a", "stats_ci_99_b", "stats_q_25", "stats_q_75", "stats_number", "stats_repeat", "samples", "profile"], "results": {"Components vs Django.timeraw_render_lg_first": [[0.0814841690000776, 0.28364495499999975], [["'django'", "'django-components'"]], "be3bf6236960046a028b6ea007aad28b2337fc2b906b8ce317a09a5d4f1a6193", 1751538832752, 34.343, [0.079655, 0.2763], [0.083151, 0.28972], [0.079684, 0.27776], [0.082952, 0.28852], [1, 1], [25, 25]], "Components vs Django.timeraw_render_lg_subsequent": [[0.04362213900003553, 0.16551773399999092], [["'django'", "'django-components'"]], "b98221c11a0ee6e9de0778d416d31b9dd514a674d9017a2bb9b2fc1cd0f01920", 1751538839695, 39.947, [0.042835, 0.16259], [0.044314, 0.1709], [0.04289, 0.16268], [0.044297, 0.17072], [1, 1], [25, 25]], "Components vs Django.timeraw_render_sm_first": [[0.00375721499995052, 0.0049729269999261305], [["'django'", "'django-components'"]], "f1fc17e4a31c71f4d9265f1122da52e7cf57addb4dfa02606e303b33d6431b9b", 1751538847853, 18.382, [0.0036459, 0.0048221], [0.0038196, 0.0051737], [0.0036541, 0.0048489], [0.0038098, 0.0051177], [1, 1], [25, 25]], "Components vs Django.timeraw_render_sm_subsequent": [[0.00012686900004155177, 0.0006182140000419167], [["'django'", "'django-components'"]], "6fce1cd85a9344fee383b40a22f27862120b9488a628420625592dc14e0307d3", 1751538851498, 18.239, [0.00012524, 0.00060676], [0.00013161, 0.0006405], [0.00012579, 0.00060829], [0.00012952, 0.00063066], [1, 1], [25, 25]], "Components vs Django.timeraw_startup_lg": [[0.23076480500003527, 0.23163660399995933], [["'django'", "'django-components'"]], "53151821c128ad0ecfb0707fff3146e1abd8d0bcfa301aa056b5d3fae3d793e2", 1751538855102, 21.331, [0.228, 0.22934], [0.24129, 0.23958], [0.22861, 0.23032], [0.23462, 0.23903], [1, 1], [25, 25]], "Other.timeraw_import_time": [[0.21042045099989082], [], "a0a1c1c0db22509410b946d0d4384b52ea4a09b47b6048d7d1cfb89b0c7fe5c3", 1751538859357, 8.7502, [0.20296], [0.21809], [0.20498], [0.21758], [1], [25]], "isolated vs django modes.timeraw_render_lg_first": [[0.2794132599999557, 0.28440619299999526], [["'isolated'", "'django'"]], "f94af83427c6346f88f8785a3cd2fc42415ac5a9fbbdb7de71d27e22e6a81699", 1751538864363, 39.572, [0.27575, 0.28135], [0.28414, 0.29307], [0.2763, 0.28173], [0.2821, 0.29138], [1, 1], [25, 25]], "isolated vs django modes.timeraw_render_lg_subsequent": [[0.16650312799993117, 0.17177308600003016], [["'isolated'", "'django'"]], "9f7c2fde6b33f0451a1794ed903c48d96cd7822f67da502cec36fe8e977c2414", 1751538872327, 50.556, [0.1622, 0.16821], [0.16877, 0.17739], [0.16257, 0.16909], [0.16869, 0.17637], [1, 1], [25, 25]], "isolated vs django modes.timeraw_render_sm_first": [[0.005049280000093859, 0.004947880000145233], [["'isolated'", "'django'"]], "d15ca68909d7f1f43ff16863befb6f42681f17461417fc0069eefd6db3569296", 1751538882427, 18.336, [0.0048311, 0.0047979], [0.0051732, 0.0051086], [0.0048842, 0.0047995], [0.005169, 0.0050803], [1, 1], [25, 25]], "isolated vs django modes.timeraw_render_sm_subsequent": [[0.0006160310000495883, 0.0006166809999967882], [["'isolated'", "'django'"]], "7444bc9516dd087e3f420349345eae991ad6941bbd22fce45265b18034b7cf77", 1751538886046, 18.232, [0.00060088, 0.00060389], [0.00063506, 0.00063793], [0.00060598, 0.00060406], [0.00063334, 0.00063127], [1, 1], [25, 25]], "isolated vs django modes.timeraw_startup_lg": [[0.2295973340000046, 0.23030742100002044], [["'isolated'", "'django'"]], "eabe311ebee4a15c5816617be12f00ec30376f7506bd668219e1c50bc897c134", 1751538889806, 21.076, [0.22658, 0.22629], [0.24075, 0.2421], [0.22709, 0.22647], [0.23956, 0.2393], [1, 1], [25, 25]], "Components vs Django.peakmem_render_lg_first": [[53096448, 55484416], [["'django'", "'django-components'"]], "301c396f017f45a5b3f71e85df58d15f54153fcfd951af7ef424641d4b31b528", 1751538830129, 0.81232], "Components vs Django.peakmem_render_lg_subsequent": [[53018624, 56389632], [["'django'", "'django-components'"]], "9a44e9999ef3ef42ea7e01323727490244febb43d66a87a4d8f88c6b8a133b8b", 1751538830942, 1.0287], "Components vs Django.peakmem_render_sm_first": [[44716032, 44969984], [["'django'", "'django-components'"]], "e93b7a5193681c883edf85bdb30b1bc0821263bf51033fdcee215b155085e036", 1751538831971, 0.39208], "Components vs Django.peakmem_render_sm_subsequent": [[44724224, 44969984], [["'django'", "'django-components'"]], "b46e0820b18950aa7cc5e61306ff3425b76b4da9dca42d64fae5b1d25c6c9026", 1751538832363, 0.38781], "isolated vs django modes.peakmem_render_lg_first": [[55476224, 54968320], [["'isolated'", "'django'"]], "c4bf0016d48d210f08b8db733b57c7dcba1cebbf548c458b93b86ace387067e9", 1751538861133, 1.051], "isolated vs django modes.peakmem_render_lg_subsequent": [[56352768, 56516608], [["'isolated'", "'django'"]], "65bb1b8586487197a79bb6073e4c71642877b845b6eb42d1bd32398299daffbf", 1751538862185, 1.3815], "isolated vs django modes.peakmem_render_sm_first": [[44969984, 44969984], [["'isolated'", "'django'"]], "c51b91fc583295776062822225e720b5ed71aef9c9288217c401c54283c62840", 1751538863566, 0.38739], "isolated vs django modes.peakmem_render_sm_subsequent": [[44974080, 44974080], [["'isolated'", "'django'"]], "54d747fb8f40179b7ff3d2fc49eb195909ad1c880b5ef7b82f82742b27b67260", 1751538863954, 0.40929]}, "durations": {}, "version": 2} \ No newline at end of file diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json deleted file mode 100644 index 9558bffd..00000000 --- a/.devcontainer/devcontainer.json +++ /dev/null @@ -1,32 +0,0 @@ -// For format details, see https://aka.ms/devcontainer.json. For config options, see the README at: -// https://github.com/microsoft/vscode-dev-containers/tree/v0.245.0/containers/python-3 -{ - // Uncomment to run Python 3.13 or other specific version - // "image": "mcr.microsoft.com/devcontainers/python:3.13-bullseye", - - // Configure tool-specific properties. - "customizations": { - // Configure properties specific to VS Code. - "vscode": { - // Set *default* container specific settings.json values on container create. - "settings": { - "python.defaultInterpreterPath": "/usr/local/bin/python", - "python.linting.enabled": true - }, - - // Add the IDs of extensions you want installed when the container is created. - "extensions": [ - "ms-python.python", - "ms-python.vscode-pylance", - "ms-python.vscode-python-envs", - "jurooravec.python-inline-source-2" - ] - } - } - - // Use 'forwardPorts' to make a list of ports inside the container available locally. - // "forwardPorts": [], - - // Use 'postCreateCommand' to run commands after the container is created. - //"postCreateCommand": "" -} diff --git a/CHANGELOG.md b/CHANGELOG.md index 9cabbd37..6615dc98 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,71 +1,5 @@ # Release notes -## v0.141.2 - -#### Fix - -- Fix bug where JS and CSS were missing when `{% component %}` tag was inside `{% include %}` tag ([#1296](https://github.com/django-components/django-components/issues/1296)) - -## v0.141.1 - -#### Fix - -- Components' JS and CSS scripts (e.g. from `Component.js` or `Component.js_file`) are now cached at class creation time. - - This means that when you now restart the server while having a page opened in the browser, - the JS / CSS files are immediately available. - - Previously, the JS/CSS were cached only after the components were rendered. So you had to reload - the page to trigger the rendering, in order to make the JS/CSS files available. - -- Fix the default cache for JS / CSS scripts to be unbounded. - - Previously, the default cache for the JS/CSS scripts (`LocMemCache`) was accidentally limited to 300 entries (~150 components). - -- Do not send `template_rendered` signal when rendering a component with no template. ([#1277](https://github.com/django-components/django-components/issues/1277)) - -## v0.141.0 - -#### Feat - -- New extension hooks `on_template_loaded`, `on_js_loaded`, `on_css_loaded`, and `on_template_compiled` - - The first 3 hooks are called when Component's template / JS / CSS is loaded as a string. - - The `on_template_compiled` hook is called when Component's template is compiled to a Template. - - The `on_xx_loaded` hooks can modify the content by returning the new value. - - ```py - class MyExtension(ComponentExtension): - def on_template_loaded(self, ctx: OnTemplateLoadedContext) -> Optional[str]: - return ctx.content + "" - - def on_js_loaded(self, ctx: OnJsLoadedContext) -> Optional[str]: - return ctx.content + "// Hello!" - - def on_css_loaded(self, ctx: OnCssLoadedContext) -> Optional[str]: - return ctx.content + "/* Hello! */" - ``` - - See all [Extension hooks](https://django-components.github.io/django-components/0.141.0/reference/extension_hooks/). - -#### Fix - -- Subclassing - Previously, if a parent component defined `Component.template` or `Component.template_file`, it's subclass would use the same `Template` instance. - - This could lead to unexpected behavior, where a change to the template of the subclass would also change the template of the parent class. - - Now, each subclass has it's own `Template` instance, and changes to the template of the subclass do not affect the template of the parent class. - -- Fix Django failing to restart due to "TypeError: 'Dynamic' object is not iterable" ([#1232](https://github.com/django-components/django-components/issues/1232)) - -- Fix bug when error formatting failed when error value was not a string. - -#### Refactor - -- `components ext run` CLI command now allows to call only those extensions that actually have subcommands. - ## v0.140.1 #### Fix @@ -136,7 +70,7 @@ Summary: - `"append"` - `"ignore"` - See [Dependencies rendering](https://django-components.github.io/django-components/0.140.1/concepts/advanced/rendering_js_css/) for more info. + See [Dependencies rendering](https://django-components.github.io/django-components/0.140/concepts/advanced/rendering_js_css/) for more info. **Typing** @@ -160,8 +94,8 @@ Summary: text: str ``` + See [Migrating from generics to class attributes](https://django-components.github.io/django-components/0.140/concepts/fundamentals/typing_and_validation/#migrating-from-generics-to-class-attributes) for more info. - See [Migrating from generics to class attributes](https://django-components.github.io/django-components/0.140.1/concepts/fundamentals/typing_and_validation/#migrating-from-generics-to-class-attributes) for more info. - Removed `EmptyTuple` and `EmptyDict` types. Instead, there is now a single `Empty` type. ```py @@ -1049,7 +983,7 @@ Summary: - Rendered HTML is left as-is. You can still process it with a different strategy later with `render_dependencies()`. - Used for inserting rendered HTML into other components. - See [Dependencies rendering](https://django-components.github.io/django-components/0.140.1/concepts/advanced/rendering_js_css/) for more info. + See [Dependencies rendering](https://django-components.github.io/django-components/0.140/concepts/advanced/rendering_js_css/) for more info. - New `Component.args`, `Component.kwargs`, `Component.slots` attributes available on the component class itself. @@ -1129,7 +1063,7 @@ Summary: - Modify the rendered output after it has been rendered - Handle errors - See [on_render](https://django-components.github.io/django-components/0.140.1/concepts/advanced/hooks/#on_render) for more info. + See [on_render](https://django-components.github.io/django-components/0.140/concepts/advanced/hooks/#on_render) for more info. - `get_component_url()` now optionally accepts `query` and `fragment` arguments. @@ -1197,7 +1131,7 @@ Summary: - `ComponentNode` instance if the slot was created as a default slot from a `{% component %}` tag. - `None` if the slot was created from a string, function, or `Slot` instance. - See [Slot metadata](https://django-components.github.io/django-components/0.140.1/concepts/fundamentals/slots/#slot-metadata). + See [Slot metadata](https://django-components.github.io/django-components/0.140/concepts/fundamentals/slots/#slot-metadata). - `{% fill %}` tag now accepts `body` kwarg to pass a Slot instance to fill. @@ -1296,13 +1230,13 @@ Summary: ) ``` - Read more on [Component caching](https://django-components.github.io/django-components/0.140.1/concepts/advanced/component_caching/). + Read more on [Component caching](https://django-components.github.io/django-components/0.140/concepts/advanced/component_caching/). - New extension hook `on_slot_rendered()` This hook is called when a slot is rendered, and allows you to access and/or modify the rendered result. - This is used by the ["debug highlight" feature](https://django-components.github.io/django-components/0.140.1/guides/other/troubleshooting/#component-and-slot-highlighting). + This is used by the ["debug highlight" feature](https://django-components.github.io/django-components/0.140/guides/other/troubleshooting/#component-and-slot-highlighting). To modify the rendered result, return the new value: @@ -1314,7 +1248,7 @@ Summary: If you don't want to modify the rendered result, return `None`. - See all [Extension hooks](https://django-components.github.io/django-components/0.140.1/reference/extension_hooks/). + See all [Extension hooks](https://django-components.github.io/django-components/0.140/reference/extension_hooks/). - When creating extensions, the previous syntax with `ComponentExtension.ExtensionClass` was causing Mypy errors, because Mypy doesn't allow using class attributes as bases: diff --git a/README.md b/README.md index 8df3262e..241f939e 100644 --- a/README.md +++ b/README.md @@ -24,9 +24,8 @@ A component in django-components can be as simple as a Django template and Pytho ```py # components/calendar/calendar.py -from django_components import Component, register +from django_components import Component -@register("calendar") class Calendar(Component): template_file = "calendar.html" ``` @@ -57,9 +56,8 @@ document.querySelector(".calendar").onclick = () => { ```py # components/calendar/calendar.py -from django_components import Component, register +from django_components import Component -@register("calendar") class Calendar(Component): template_file = "calendar.html" js_file = "calendar.js" @@ -554,7 +552,7 @@ to see the latest features and fixes. One of our goals with `django-components` is to make it easy to share components between projects. If you have a set of components that you think would be useful to others, please open a pull request to add them to the list below. -- [django-htmx-components](https://github.com/iwanalabs/django-htmx-components): A set of components for use with [htmx](https://htmx.org/). +- [django-htmx-components](https://github.com/iwanalabs/django-htmx-components): A set of components for use with [htmx](https://htmx.org/). Try out the [live demo](https://dhc.iwanalabs.com/). - [djc-heroicons](https://pypi.org/project/djc-heroicons/): A component that renders icons from [Heroicons.com](https://heroicons.com/). diff --git a/docs/benchmarks/graphs/branch-master/django-5.1/djc-core-html-parser/machine-ci-linux/python-3.13/Components vs Django.peakmem_render_lg_first.json b/docs/benchmarks/graphs/branch-master/django-5.1/djc-core-html-parser/machine-ci-linux/python-3.13/Components vs Django.peakmem_render_lg_first.json index 97e6d62b..39721433 100644 --- a/docs/benchmarks/graphs/branch-master/django-5.1/djc-core-html-parser/machine-ci-linux/python-3.13/Components vs Django.peakmem_render_lg_first.json +++ b/docs/benchmarks/graphs/branch-master/django-5.1/djc-core-html-parser/machine-ci-linux/python-3.13/Components vs Django.peakmem_render_lg_first.json @@ -1 +1 @@ -[[1662, [52920320.0, 54566912.0]], [1672, [52350976.0, 54599680.0]], [1687, [52109312.0, 54779904.0]], [1691, [52899840.0, 54730752.0]], [1709, [52936704.0, 55009280.0]], [1726, [52379648.0, 54992896.0]], [1766, [53084160.0, 55382016.0]], [1770, [53047296.0, 55373824.0]], [1776, [52490240.0, 55361536.0]], [1801, [53153792.0, 55410688.0]], [1937, [52957184.0, 55177216.0]], [1960, [52932608.0, 55693312.0]], [1996, [53096448.0, 55484416.0]], [2029, [52715520.0, 56090624.0]]] \ No newline at end of file +[[1662, [52920320.0, 54566912.0]], [1672, [52350976.0, 54599680.0]], [1687, [52109312.0, 54779904.0]], [1691, [52899840.0, 54730752.0]], [1709, [52936704.0, 55009280.0]], [1726, [52379648.0, 54992896.0]], [1766, [53084160.0, 55382016.0]], [1770, [53047296.0, 55373824.0]], [1776, [52490240.0, 55361536.0]], [1801, [53153792.0, 55410688.0]]] \ No newline at end of file diff --git a/docs/benchmarks/graphs/branch-master/django-5.1/djc-core-html-parser/machine-ci-linux/python-3.13/Components vs Django.peakmem_render_lg_subsequent.json b/docs/benchmarks/graphs/branch-master/django-5.1/djc-core-html-parser/machine-ci-linux/python-3.13/Components vs Django.peakmem_render_lg_subsequent.json index a16e0075..6917a1b2 100644 --- a/docs/benchmarks/graphs/branch-master/django-5.1/djc-core-html-parser/machine-ci-linux/python-3.13/Components vs Django.peakmem_render_lg_subsequent.json +++ b/docs/benchmarks/graphs/branch-master/django-5.1/djc-core-html-parser/machine-ci-linux/python-3.13/Components vs Django.peakmem_render_lg_subsequent.json @@ -1 +1 @@ -[[1662, [53800960.0, 54734848.0]], [1672, [52289536.0, 55099392.0]], [1687, [52142080.0, 55255040.0]], [1691, [53796864.0, 55238656.0]], [1709, [53768192.0, 55455744.0]], [1726, [51998720.0, 55451648.0]], [1766, [53739520.0, 55812096.0]], [1770, [53948416.0, 55824384.0]], [1776, [52097024.0, 55791616.0]], [1801, [53919744.0, 55799808.0]], [1937, [52822016.0, 56242176.0]], [1960, [53063680.0, 56180736.0]], [1996, [53018624.0, 56389632.0]], [2029, [52736000.0, 56791040.0]]] \ No newline at end of file +[[1662, [53800960.0, 54734848.0]], [1672, [52289536.0, 55099392.0]], [1687, [52142080.0, 55255040.0]], [1691, [53796864.0, 55238656.0]], [1709, [53768192.0, 55455744.0]], [1726, [51998720.0, 55451648.0]], [1766, [53739520.0, 55812096.0]], [1770, [53948416.0, 55824384.0]], [1776, [52097024.0, 55791616.0]], [1801, [53919744.0, 55799808.0]]] \ No newline at end of file diff --git a/docs/benchmarks/graphs/branch-master/django-5.1/djc-core-html-parser/machine-ci-linux/python-3.13/Components vs Django.peakmem_render_sm_first.json b/docs/benchmarks/graphs/branch-master/django-5.1/djc-core-html-parser/machine-ci-linux/python-3.13/Components vs Django.peakmem_render_sm_first.json index 6f16f68b..9e1592de 100644 --- a/docs/benchmarks/graphs/branch-master/django-5.1/djc-core-html-parser/machine-ci-linux/python-3.13/Components vs Django.peakmem_render_sm_first.json +++ b/docs/benchmarks/graphs/branch-master/django-5.1/djc-core-html-parser/machine-ci-linux/python-3.13/Components vs Django.peakmem_render_sm_first.json @@ -1 +1 @@ -[[1662, [44191744.0, 44191744.0]], [1672, [44056576.0, 44048384.0]], [1687, [44191744.0, 44310528.0]], [1691, [44183552.0, 44175360.0]], [1709, [44191744.0, 44314624.0]], [1726, [44195840.0, 44314624.0]], [1766, [44322816.0, 44314624.0]], [1770, [44326912.0, 44322816.0]], [1776, [44183552.0, 44306432.0]], [1801, [44195840.0, 44453888.0]], [1937, [44756992.0, 44744704.0]], [1960, [44716032.0, 44834816.0]], [1996, [44716032.0, 44969984.0]], [2029, [44871680.0, 44912640.0]]] \ No newline at end of file +[[1662, [44191744.0, 44191744.0]], [1672, [44056576.0, 44048384.0]], [1687, [44191744.0, 44310528.0]], [1691, [44183552.0, 44175360.0]], [1709, [44191744.0, 44314624.0]], [1726, [44195840.0, 44314624.0]], [1766, [44322816.0, 44314624.0]], [1770, [44326912.0, 44322816.0]], [1776, [44183552.0, 44306432.0]], [1801, [44195840.0, 44453888.0]]] \ No newline at end of file diff --git a/docs/benchmarks/graphs/branch-master/django-5.1/djc-core-html-parser/machine-ci-linux/python-3.13/Components vs Django.peakmem_render_sm_subsequent.json b/docs/benchmarks/graphs/branch-master/django-5.1/djc-core-html-parser/machine-ci-linux/python-3.13/Components vs Django.peakmem_render_sm_subsequent.json index 76bd2928..c47dcd11 100644 --- a/docs/benchmarks/graphs/branch-master/django-5.1/djc-core-html-parser/machine-ci-linux/python-3.13/Components vs Django.peakmem_render_sm_subsequent.json +++ b/docs/benchmarks/graphs/branch-master/django-5.1/djc-core-html-parser/machine-ci-linux/python-3.13/Components vs Django.peakmem_render_sm_subsequent.json @@ -1 +1 @@ -[[1662, [44195840.0, 44187648.0]], [1672, [44060672.0, 43917312.0]], [1687, [44105728.0, 44310528.0]], [1691, [44187648.0, 44183552.0]], [1709, [44191744.0, 44437504.0]], [1726, [44322816.0, 44314624.0]], [1766, [44322816.0, 44310528.0]], [1770, [44101632.0, 44310528.0]], [1776, [44314624.0, 44437504.0]], [1801, [44191744.0, 44453888.0]], [1937, [44527616.0, 44744704.0]], [1960, [44716032.0, 44838912.0]], [1996, [44724224.0, 44969984.0]], [2029, [44617728.0, 44986368.0]]] \ No newline at end of file +[[1662, [44195840.0, 44187648.0]], [1672, [44060672.0, 43917312.0]], [1687, [44105728.0, 44310528.0]], [1691, [44187648.0, 44183552.0]], [1709, [44191744.0, 44437504.0]], [1726, [44322816.0, 44314624.0]], [1766, [44322816.0, 44310528.0]], [1770, [44101632.0, 44310528.0]], [1776, [44314624.0, 44437504.0]], [1801, [44191744.0, 44453888.0]]] \ No newline at end of file diff --git a/docs/benchmarks/graphs/branch-master/django-5.1/djc-core-html-parser/machine-ci-linux/python-3.13/Components vs Django.timeraw_render_lg_first.json b/docs/benchmarks/graphs/branch-master/django-5.1/djc-core-html-parser/machine-ci-linux/python-3.13/Components vs Django.timeraw_render_lg_first.json index e53588c7..57e279e2 100644 --- a/docs/benchmarks/graphs/branch-master/django-5.1/djc-core-html-parser/machine-ci-linux/python-3.13/Components vs Django.timeraw_render_lg_first.json +++ b/docs/benchmarks/graphs/branch-master/django-5.1/djc-core-html-parser/machine-ci-linux/python-3.13/Components vs Django.timeraw_render_lg_first.json @@ -1 +1 @@ -[[1662, [0.06960565700001098, 0.25608221199996706]], [1672, [0.07114163800000028, 0.26389872900000455]], [1687, [0.06910802600003763, 0.25746033199999374]], [1691, [0.07048037500001669, 0.2598985070000026]], [1709, [0.07402671400001282, 0.26584690599997884]], [1726, [0.07297276199997782, 0.2569234329999972]], [1766, [0.07308550800001967, 0.26274096600002395]], [1770, [0.0749189080000292, 0.26436952000000247]], [1776, [0.07303507899999317, 0.2628890319999755]], [1801, [0.07360306399999672, 0.2678246009999725]], [1937, [0.07941284200001064, 0.26779402600004687]], [1960, [0.08026317200000221, 0.26819844099998136]], [1996, [0.0814841690000776, 0.28364495499999975]], [2029, [0.08105427499998541, 0.29477426600001877]]] \ No newline at end of file +[[1662, [0.06960565700001098, 0.25608221199996706]], [1672, [0.07114163800000028, 0.26389872900000455]], [1687, [0.06910802600003763, 0.25746033199999374]], [1691, [0.07048037500001669, 0.2598985070000026]], [1709, [0.07402671400001282, 0.26584690599997884]], [1726, [0.07297276199997782, 0.2569234329999972]], [1766, [0.07308550800001967, 0.26274096600002395]], [1770, [0.0749189080000292, 0.26436952000000247]], [1776, [0.07303507899999317, 0.2628890319999755]], [1801, [0.07360306399999672, 0.2678246009999725]]] \ No newline at end of file diff --git a/docs/benchmarks/graphs/branch-master/django-5.1/djc-core-html-parser/machine-ci-linux/python-3.13/Components vs Django.timeraw_render_lg_subsequent.json b/docs/benchmarks/graphs/branch-master/django-5.1/djc-core-html-parser/machine-ci-linux/python-3.13/Components vs Django.timeraw_render_lg_subsequent.json index 72d384fe..2af46910 100644 --- a/docs/benchmarks/graphs/branch-master/django-5.1/djc-core-html-parser/machine-ci-linux/python-3.13/Components vs Django.timeraw_render_lg_subsequent.json +++ b/docs/benchmarks/graphs/branch-master/django-5.1/djc-core-html-parser/machine-ci-linux/python-3.13/Components vs Django.timeraw_render_lg_subsequent.json @@ -1 +1 @@ -[[1662, [0.03327357099999517, 0.1421111020000012]], [1672, [0.033918617999972867, 0.14395761299999776]], [1687, [0.03317536700001256, 0.14245594600001255]], [1691, [0.034316510999985894, 0.1444248799999741]], [1709, [0.03742426899998463, 0.14901454800002512]], [1726, [0.03658580800001232, 0.1459621130000528]], [1766, [0.03723830100000214, 0.15196534300002895]], [1770, [0.03752758399997447, 0.15356457899997622]], [1776, [0.03678920999999491, 0.14955294699998944]], [1801, [0.037022983000014165, 0.15138703899998518]], [1937, [0.043317416999911984, 0.15457556900003055]], [1960, [0.04349111400000538, 0.15453611999998884]], [1996, [0.04362213900003553, 0.16551773399999092]], [2029, [0.043648402000002307, 0.17461173199995983]]] \ No newline at end of file +[[1662, [0.03327357099999517, 0.1421111020000012]], [1672, [0.033918617999972867, 0.14395761299999776]], [1687, [0.03317536700001256, 0.14245594600001255]], [1691, [0.034316510999985894, 0.1444248799999741]], [1709, [0.03742426899998463, 0.14901454800002512]], [1726, [0.03658580800001232, 0.1459621130000528]], [1766, [0.03723830100000214, 0.15196534300002895]], [1770, [0.03752758399997447, 0.15356457899997622]], [1776, [0.03678920999999491, 0.14955294699998944]], [1801, [0.037022983000014165, 0.15138703899998518]]] \ No newline at end of file diff --git a/docs/benchmarks/graphs/branch-master/django-5.1/djc-core-html-parser/machine-ci-linux/python-3.13/Components vs Django.timeraw_render_sm_first.json b/docs/benchmarks/graphs/branch-master/django-5.1/djc-core-html-parser/machine-ci-linux/python-3.13/Components vs Django.timeraw_render_sm_first.json index ffd21cc0..b433e0c9 100644 --- a/docs/benchmarks/graphs/branch-master/django-5.1/djc-core-html-parser/machine-ci-linux/python-3.13/Components vs Django.timeraw_render_sm_first.json +++ b/docs/benchmarks/graphs/branch-master/django-5.1/djc-core-html-parser/machine-ci-linux/python-3.13/Components vs Django.timeraw_render_sm_first.json @@ -1 +1 @@ -[[1662, [0.0035443229999998493, 0.00467639600003622]], [1672, [0.0036137869999777195, 0.004807943000002979]], [1687, [0.0035223549999727766, 0.004706463999980315]], [1691, [0.00364059099999281, 0.004926952999994683]], [1709, [0.003602947999979733, 0.004853936999950292]], [1726, [0.0035008030000085455, 0.004695608999981005]], [1766, [0.003566315000000486, 0.004791812000007667]], [1770, [0.0036766670000361046, 0.004929383999979109]], [1776, [0.0035613420000117912, 0.004760385999986738]], [1801, [0.003639607999986083, 0.004848561000017071]], [1937, [0.0036632869999948525, 0.00493345400002454]], [1960, [0.0036145729999930154, 0.004811176000004025]], [1996, [0.00375721499995052, 0.0049729269999261305]], [2029, [0.0037106409999978496, 0.004899473999955717]]] \ No newline at end of file +[[1662, [0.0035443229999998493, 0.00467639600003622]], [1672, [0.0036137869999777195, 0.004807943000002979]], [1687, [0.0035223549999727766, 0.004706463999980315]], [1691, [0.00364059099999281, 0.004926952999994683]], [1709, [0.003602947999979733, 0.004853936999950292]], [1726, [0.0035008030000085455, 0.004695608999981005]], [1766, [0.003566315000000486, 0.004791812000007667]], [1770, [0.0036766670000361046, 0.004929383999979109]], [1776, [0.0035613420000117912, 0.004760385999986738]], [1801, [0.003639607999986083, 0.004848561000017071]]] \ No newline at end of file diff --git a/docs/benchmarks/graphs/branch-master/django-5.1/djc-core-html-parser/machine-ci-linux/python-3.13/Components vs Django.timeraw_render_sm_subsequent.json b/docs/benchmarks/graphs/branch-master/django-5.1/djc-core-html-parser/machine-ci-linux/python-3.13/Components vs Django.timeraw_render_sm_subsequent.json index 7e2dcfd6..f8d1736a 100644 --- a/docs/benchmarks/graphs/branch-master/django-5.1/djc-core-html-parser/machine-ci-linux/python-3.13/Components vs Django.timeraw_render_sm_subsequent.json +++ b/docs/benchmarks/graphs/branch-master/django-5.1/djc-core-html-parser/machine-ci-linux/python-3.13/Components vs Django.timeraw_render_sm_subsequent.json @@ -1 +1 @@ -[[1662, [0.00010400499999718704, 0.0005328339999977061]], [1672, [0.00010086800000408402, 0.0005549249999887707]], [1687, [9.818199998790078e-05, 0.0005511469999817109]], [1691, [0.0001005780000014056, 0.0005555879999974422]], [1709, [0.00012266099997759738, 0.0005711430000019391]], [1726, [0.00011641800000461444, 0.0005489540000098714]], [1766, [0.00011609900002440554, 0.0005779780000239043]], [1770, [0.0001176700000087294, 0.0005864990000077341]], [1776, [0.00011622699999236374, 0.0005842630000074678]], [1801, [0.00011665800002447213, 0.000582710000003317]], [1937, [0.00012153600005149201, 0.0005999570000199128]], [1960, [0.00012332000000014887, 0.0005915369999911491]], [1996, [0.00012686900004155177, 0.0006182140000419167]], [2029, [0.00012706900002967814, 0.0006100459999629493]]] \ No newline at end of file +[[1662, [0.00010400499999718704, 0.0005328339999977061]], [1672, [0.00010086800000408402, 0.0005549249999887707]], [1687, [9.818199998790078e-05, 0.0005511469999817109]], [1691, [0.0001005780000014056, 0.0005555879999974422]], [1709, [0.00012266099997759738, 0.0005711430000019391]], [1726, [0.00011641800000461444, 0.0005489540000098714]], [1766, [0.00011609900002440554, 0.0005779780000239043]], [1770, [0.0001176700000087294, 0.0005864990000077341]], [1776, [0.00011622699999236374, 0.0005842630000074678]], [1801, [0.00011665800002447213, 0.000582710000003317]]] \ No newline at end of file diff --git a/docs/benchmarks/graphs/branch-master/django-5.1/djc-core-html-parser/machine-ci-linux/python-3.13/Components vs Django.timeraw_startup_lg.json b/docs/benchmarks/graphs/branch-master/django-5.1/djc-core-html-parser/machine-ci-linux/python-3.13/Components vs Django.timeraw_startup_lg.json index 028b02cc..12a9f8f8 100644 --- a/docs/benchmarks/graphs/branch-master/django-5.1/djc-core-html-parser/machine-ci-linux/python-3.13/Components vs Django.timeraw_startup_lg.json +++ b/docs/benchmarks/graphs/branch-master/django-5.1/djc-core-html-parser/machine-ci-linux/python-3.13/Components vs Django.timeraw_startup_lg.json @@ -1 +1 @@ -[[1662, [0.21775109000003567, 0.21398552899995593]], [1672, [0.22476057199997967, 0.22048105400000395]], [1687, [0.21809406599999193, 0.2131839880000257]], [1691, [0.22356123500000535, 0.22167734499998915]], [1709, [0.22133603999998286, 0.21805855799999563]], [1726, [0.2166100470000174, 0.21420494400001644]], [1766, [0.22339861599999722, 0.22020213500002228]], [1770, [0.22985272800002576, 0.22544496099999378]], [1776, [0.22073260000001937, 0.2182690520000392]], [1801, [0.224061646999985, 0.2246476189999953]], [1937, [0.22743783699991127, 0.226070988999993]], [1960, [0.2252378419999843, 0.2247263650000093]], [1996, [0.23076480500003527, 0.23163660399995933]], [2029, [0.22799248500001568, 0.22723498599998493]]] \ No newline at end of file +[[1662, [0.21775109000003567, 0.21398552899995593]], [1672, [0.22476057199997967, 0.22048105400000395]], [1687, [0.21809406599999193, 0.2131839880000257]], [1691, [0.22356123500000535, 0.22167734499998915]], [1709, [0.22133603999998286, 0.21805855799999563]], [1726, [0.2166100470000174, 0.21420494400001644]], [1766, [0.22339861599999722, 0.22020213500002228]], [1770, [0.22985272800002576, 0.22544496099999378]], [1776, [0.22073260000001937, 0.2182690520000392]], [1801, [0.224061646999985, 0.2246476189999953]]] \ No newline at end of file diff --git a/docs/benchmarks/graphs/branch-master/django-5.1/djc-core-html-parser/machine-ci-linux/python-3.13/Other.timeraw_import_time.json b/docs/benchmarks/graphs/branch-master/django-5.1/djc-core-html-parser/machine-ci-linux/python-3.13/Other.timeraw_import_time.json index eb01068a..3c9dc75e 100644 --- a/docs/benchmarks/graphs/branch-master/django-5.1/djc-core-html-parser/machine-ci-linux/python-3.13/Other.timeraw_import_time.json +++ b/docs/benchmarks/graphs/branch-master/django-5.1/djc-core-html-parser/machine-ci-linux/python-3.13/Other.timeraw_import_time.json @@ -1 +1 @@ -[[1662, 0.19832900800003017], [1672, 0.20217585500000723], [1687, 0.19726691500000015], [1691, 0.20350580199999513], [1709, 0.19950735400001918], [1726, 0.19625152499997967], [1766, 0.20073733000003813], [1770, 0.20376683500001036], [1776, 0.19919827600000417], [1801, 0.2053688209999791], [1937, 0.2063091950000171], [1960, 0.20468290799999522], [1996, 0.21042045099989082], [2029, 0.2056691309999792]] \ No newline at end of file +[[1662, 0.19832900800003017], [1672, 0.20217585500000723], [1687, 0.19726691500000015], [1691, 0.20350580199999513], [1709, 0.19950735400001918], [1726, 0.19625152499997967], [1766, 0.20073733000003813], [1770, 0.20376683500001036], [1776, 0.19919827600000417], [1801, 0.2053688209999791]] \ No newline at end of file diff --git a/docs/benchmarks/graphs/branch-master/django-5.1/djc-core-html-parser/machine-ci-linux/python-3.13/isolated vs django modes.peakmem_render_lg_first.json b/docs/benchmarks/graphs/branch-master/django-5.1/djc-core-html-parser/machine-ci-linux/python-3.13/isolated vs django modes.peakmem_render_lg_first.json index e5e24d49..0fa6a923 100644 --- a/docs/benchmarks/graphs/branch-master/django-5.1/djc-core-html-parser/machine-ci-linux/python-3.13/isolated vs django modes.peakmem_render_lg_first.json +++ b/docs/benchmarks/graphs/branch-master/django-5.1/djc-core-html-parser/machine-ci-linux/python-3.13/isolated vs django modes.peakmem_render_lg_first.json @@ -1 +1 @@ -[[1662, [54439936.0, 53968896.0]], [1672, [54616064.0, 54140928.0]], [1687, [54767616.0, 54296576.0]], [1691, [54743040.0, 54087680.0]], [1709, [55001088.0, 54312960.0]], [1726, [54992896.0, 54345728.0]], [1766, [55373824.0, 54894592.0]], [1770, [55246848.0, 54898688.0]], [1776, [55357440.0, 54874112.0]], [1801, [55382016.0, 54882304.0]], [1937, [55222272.0, 54722560.0]], [1960, [55263232.0, 54693888.0]], [1996, [55476224.0, 54968320.0]], [2029, [56090624.0, 55582720.0]]] \ No newline at end of file +[[1662, [54439936.0, 53968896.0]], [1672, [54616064.0, 54140928.0]], [1687, [54767616.0, 54296576.0]], [1691, [54743040.0, 54087680.0]], [1709, [55001088.0, 54312960.0]], [1726, [54992896.0, 54345728.0]], [1766, [55373824.0, 54894592.0]], [1770, [55246848.0, 54898688.0]], [1776, [55357440.0, 54874112.0]], [1801, [55382016.0, 54882304.0]]] \ No newline at end of file diff --git a/docs/benchmarks/graphs/branch-master/django-5.1/djc-core-html-parser/machine-ci-linux/python-3.13/isolated vs django modes.peakmem_render_lg_subsequent.json b/docs/benchmarks/graphs/branch-master/django-5.1/djc-core-html-parser/machine-ci-linux/python-3.13/isolated vs django modes.peakmem_render_lg_subsequent.json index 0606c7d9..20615ac5 100644 --- a/docs/benchmarks/graphs/branch-master/django-5.1/djc-core-html-parser/machine-ci-linux/python-3.13/isolated vs django modes.peakmem_render_lg_subsequent.json +++ b/docs/benchmarks/graphs/branch-master/django-5.1/djc-core-html-parser/machine-ci-linux/python-3.13/isolated vs django modes.peakmem_render_lg_subsequent.json @@ -1 +1 @@ -[[1662, [54968320.0, 54792192.0]], [1672, [54849536.0, 54841344.0]], [1687, [55271424.0, 55304192.0]], [1691, [54984704.0, 54964224.0]], [1709, [55439360.0, 55369728.0]], [1726, [55455744.0, 55177216.0]], [1766, [55545856.0, 55631872.0]], [1770, [55812096.0, 55611392.0]], [1776, [55640064.0, 55631872.0]], [1801, [55812096.0, 55902208.0]], [1937, [56008704.0, 56143872.0]], [1960, [55783424.0, 56160256.0]], [1996, [56352768.0, 56516608.0]], [2029, [56786944.0, 56778752.0]]] \ No newline at end of file +[[1662, [54968320.0, 54792192.0]], [1672, [54849536.0, 54841344.0]], [1687, [55271424.0, 55304192.0]], [1691, [54984704.0, 54964224.0]], [1709, [55439360.0, 55369728.0]], [1726, [55455744.0, 55177216.0]], [1766, [55545856.0, 55631872.0]], [1770, [55812096.0, 55611392.0]], [1776, [55640064.0, 55631872.0]], [1801, [55812096.0, 55902208.0]]] \ No newline at end of file diff --git a/docs/benchmarks/graphs/branch-master/django-5.1/djc-core-html-parser/machine-ci-linux/python-3.13/isolated vs django modes.peakmem_render_sm_first.json b/docs/benchmarks/graphs/branch-master/django-5.1/djc-core-html-parser/machine-ci-linux/python-3.13/isolated vs django modes.peakmem_render_sm_first.json index bdcfccea..583828bf 100644 --- a/docs/benchmarks/graphs/branch-master/django-5.1/djc-core-html-parser/machine-ci-linux/python-3.13/isolated vs django modes.peakmem_render_sm_first.json +++ b/docs/benchmarks/graphs/branch-master/django-5.1/djc-core-html-parser/machine-ci-linux/python-3.13/isolated vs django modes.peakmem_render_sm_first.json @@ -1 +1 @@ -[[1662, [44187648.0, 44183552.0]], [1672, [44048384.0, 44048384.0]], [1687, [44314624.0, 44310528.0]], [1691, [44179456.0, 44175360.0]], [1709, [44314624.0, 44310528.0]], [1726, [44314624.0, 44314624.0]], [1766, [44318720.0, 44314624.0]], [1770, [44322816.0, 44314624.0]], [1776, [44306432.0, 44240896.0]], [1801, [44453888.0, 44453888.0]], [1937, [44744704.0, 44744704.0]], [1960, [44838912.0, 44838912.0]], [1996, [44969984.0, 44969984.0]], [2029, [44843008.0, 44851200.0]]] \ No newline at end of file +[[1662, [44187648.0, 44183552.0]], [1672, [44048384.0, 44048384.0]], [1687, [44314624.0, 44310528.0]], [1691, [44179456.0, 44175360.0]], [1709, [44314624.0, 44310528.0]], [1726, [44314624.0, 44314624.0]], [1766, [44318720.0, 44314624.0]], [1770, [44322816.0, 44314624.0]], [1776, [44306432.0, 44240896.0]], [1801, [44453888.0, 44453888.0]]] \ No newline at end of file diff --git a/docs/benchmarks/graphs/branch-master/django-5.1/djc-core-html-parser/machine-ci-linux/python-3.13/isolated vs django modes.peakmem_render_sm_subsequent.json b/docs/benchmarks/graphs/branch-master/django-5.1/djc-core-html-parser/machine-ci-linux/python-3.13/isolated vs django modes.peakmem_render_sm_subsequent.json index e93df054..dad71c83 100644 --- a/docs/benchmarks/graphs/branch-master/django-5.1/djc-core-html-parser/machine-ci-linux/python-3.13/isolated vs django modes.peakmem_render_sm_subsequent.json +++ b/docs/benchmarks/graphs/branch-master/django-5.1/djc-core-html-parser/machine-ci-linux/python-3.13/isolated vs django modes.peakmem_render_sm_subsequent.json @@ -1 +1 @@ -[[1662, [44187648.0, 44187648.0]], [1672, [44052480.0, 44052480.0]], [1687, [44314624.0, 44310528.0]], [1691, [44179456.0, 44179456.0]], [1709, [44310528.0, 44314624.0]], [1726, [44314624.0, 44314624.0]], [1766, [44310528.0, 44314624.0]], [1770, [44314624.0, 44318720.0]], [1776, [44437504.0, 44437504.0]], [1801, [44449792.0, 44449792.0]], [1937, [44744704.0, 44744704.0]], [1960, [44965888.0, 44834816.0]], [1996, [44974080.0, 44974080.0]], [2029, [44982272.0, 44986368.0]]] \ No newline at end of file +[[1662, [44187648.0, 44187648.0]], [1672, [44052480.0, 44052480.0]], [1687, [44314624.0, 44310528.0]], [1691, [44179456.0, 44179456.0]], [1709, [44310528.0, 44314624.0]], [1726, [44314624.0, 44314624.0]], [1766, [44310528.0, 44314624.0]], [1770, [44314624.0, 44318720.0]], [1776, [44437504.0, 44437504.0]], [1801, [44449792.0, 44449792.0]]] \ No newline at end of file diff --git a/docs/benchmarks/graphs/branch-master/django-5.1/djc-core-html-parser/machine-ci-linux/python-3.13/isolated vs django modes.timeraw_render_lg_first.json b/docs/benchmarks/graphs/branch-master/django-5.1/djc-core-html-parser/machine-ci-linux/python-3.13/isolated vs django modes.timeraw_render_lg_first.json index 47b453a9..d7dc1632 100644 --- a/docs/benchmarks/graphs/branch-master/django-5.1/djc-core-html-parser/machine-ci-linux/python-3.13/isolated vs django modes.timeraw_render_lg_first.json +++ b/docs/benchmarks/graphs/branch-master/django-5.1/djc-core-html-parser/machine-ci-linux/python-3.13/isolated vs django modes.timeraw_render_lg_first.json @@ -1 +1 @@ -[[1662, [0.2574955810000006, 0.2591010970000127]], [1672, [0.2600247560000071, 0.26185358800000813]], [1687, [0.2567828300000201, 0.2602957870000182]], [1691, [0.259077934000004, 0.2619792840000059]], [1709, [0.2646600410000133, 0.2676605120000204]], [1726, [0.2570519909999689, 0.2606809000000112]], [1766, [0.262679922000018, 0.2686107789999994]], [1770, [0.265977821000007, 0.26914772099999595]], [1776, [0.2626667089999728, 0.2663110299999971]], [1801, [0.2658582709999848, 0.2712929850000023]], [1937, [0.2675778039999841, 0.2724974679999832]], [1960, [0.26819597400000816, 0.2740507329999957]], [1996, [0.2794132599999557, 0.28440619299999526]], [2029, [0.2920349000000044, 0.2976166970000236]]] \ No newline at end of file +[[1662, [0.2574955810000006, 0.2591010970000127]], [1672, [0.2600247560000071, 0.26185358800000813]], [1687, [0.2567828300000201, 0.2602957870000182]], [1691, [0.259077934000004, 0.2619792840000059]], [1709, [0.2646600410000133, 0.2676605120000204]], [1726, [0.2570519909999689, 0.2606809000000112]], [1766, [0.262679922000018, 0.2686107789999994]], [1770, [0.265977821000007, 0.26914772099999595]], [1776, [0.2626667089999728, 0.2663110299999971]], [1801, [0.2658582709999848, 0.2712929850000023]]] \ No newline at end of file diff --git a/docs/benchmarks/graphs/branch-master/django-5.1/djc-core-html-parser/machine-ci-linux/python-3.13/isolated vs django modes.timeraw_render_lg_subsequent.json b/docs/benchmarks/graphs/branch-master/django-5.1/djc-core-html-parser/machine-ci-linux/python-3.13/isolated vs django modes.timeraw_render_lg_subsequent.json index 2c7b894a..fc2abbd2 100644 --- a/docs/benchmarks/graphs/branch-master/django-5.1/djc-core-html-parser/machine-ci-linux/python-3.13/isolated vs django modes.timeraw_render_lg_subsequent.json +++ b/docs/benchmarks/graphs/branch-master/django-5.1/djc-core-html-parser/machine-ci-linux/python-3.13/isolated vs django modes.timeraw_render_lg_subsequent.json @@ -1 +1 @@ -[[1662, [0.14273938200000202, 0.1464969190000147]], [1672, [0.14515931700000806, 0.14909453600000688]], [1687, [0.1423055980000072, 0.14642362500001127]], [1691, [0.1436571560000175, 0.14915657599999577]], [1709, [0.14860135300000366, 0.15305296299999327]], [1726, [0.14520097999997006, 0.14991973799999414]], [1766, [0.15071133700001837, 0.15540660900001058]], [1770, [0.15150350199996865, 0.1558047899999906]], [1776, [0.14876902899999322, 0.15549233400000162]], [1801, [0.15248822700002052, 0.15465820200000735]], [1937, [0.15459265900005903, 0.15926110200007315]], [1960, [0.15396625699997912, 0.16023626799997714]], [1996, [0.16650312799993117, 0.17177308600003016]], [2029, [0.17414895399997476, 0.178393189000019]]] \ No newline at end of file +[[1662, [0.14273938200000202, 0.1464969190000147]], [1672, [0.14515931700000806, 0.14909453600000688]], [1687, [0.1423055980000072, 0.14642362500001127]], [1691, [0.1436571560000175, 0.14915657599999577]], [1709, [0.14860135300000366, 0.15305296299999327]], [1726, [0.14520097999997006, 0.14991973799999414]], [1766, [0.15071133700001837, 0.15540660900001058]], [1770, [0.15150350199996865, 0.1558047899999906]], [1776, [0.14876902899999322, 0.15549233400000162]], [1801, [0.15248822700002052, 0.15465820200000735]]] \ No newline at end of file diff --git a/docs/benchmarks/graphs/branch-master/django-5.1/djc-core-html-parser/machine-ci-linux/python-3.13/isolated vs django modes.timeraw_render_sm_first.json b/docs/benchmarks/graphs/branch-master/django-5.1/djc-core-html-parser/machine-ci-linux/python-3.13/isolated vs django modes.timeraw_render_sm_first.json index 36aecfd8..8ad32812 100644 --- a/docs/benchmarks/graphs/branch-master/django-5.1/djc-core-html-parser/machine-ci-linux/python-3.13/isolated vs django modes.timeraw_render_sm_first.json +++ b/docs/benchmarks/graphs/branch-master/django-5.1/djc-core-html-parser/machine-ci-linux/python-3.13/isolated vs django modes.timeraw_render_sm_first.json @@ -1 +1 @@ -[[1662, [0.004720848000005162, 0.004705489000002672]], [1672, [0.004856270999994194, 0.00490694800001279]], [1687, [0.00473016699999107, 0.004734037999980956]], [1691, [0.004871503999993365, 0.0048899079999955575]], [1709, [0.0048215560000244295, 0.004858458999990489]], [1726, [0.004671787999996013, 0.004672599999992144]], [1766, [0.00478528000002143, 0.0047485900000197034]], [1770, [0.004901490999998259, 0.004895917999988342]], [1776, [0.00480728600001612, 0.00472804499997892]], [1801, [0.004847185000016907, 0.004857667999999649]], [1937, [0.004923484000073586, 0.004925836999973399]], [1960, [0.004825538000005736, 0.0047952310000027865]], [1996, [0.005049280000093859, 0.004947880000145233]], [2029, [0.004897051999989799, 0.004863266000029398]]] \ No newline at end of file +[[1662, [0.004720848000005162, 0.004705489000002672]], [1672, [0.004856270999994194, 0.00490694800001279]], [1687, [0.00473016699999107, 0.004734037999980956]], [1691, [0.004871503999993365, 0.0048899079999955575]], [1709, [0.0048215560000244295, 0.004858458999990489]], [1726, [0.004671787999996013, 0.004672599999992144]], [1766, [0.00478528000002143, 0.0047485900000197034]], [1770, [0.004901490999998259, 0.004895917999988342]], [1776, [0.00480728600001612, 0.00472804499997892]], [1801, [0.004847185000016907, 0.004857667999999649]]] \ No newline at end of file diff --git a/docs/benchmarks/graphs/branch-master/django-5.1/djc-core-html-parser/machine-ci-linux/python-3.13/isolated vs django modes.timeraw_render_sm_subsequent.json b/docs/benchmarks/graphs/branch-master/django-5.1/djc-core-html-parser/machine-ci-linux/python-3.13/isolated vs django modes.timeraw_render_sm_subsequent.json index a12a8dd8..0034605f 100644 --- a/docs/benchmarks/graphs/branch-master/django-5.1/djc-core-html-parser/machine-ci-linux/python-3.13/isolated vs django modes.timeraw_render_sm_subsequent.json +++ b/docs/benchmarks/graphs/branch-master/django-5.1/djc-core-html-parser/machine-ci-linux/python-3.13/isolated vs django modes.timeraw_render_sm_subsequent.json @@ -1 +1 @@ -[[1662, [0.0005377129999999397, 0.0005395769999836375]], [1672, [0.000547750000009728, 0.0005677989999810507]], [1687, [0.0005471899999918151, 0.0005447550000212686]], [1691, [0.0005559489999882317, 0.0005480739999939033]], [1709, [0.0005736080000247057, 0.0005720849999875099]], [1726, [0.000542692999999872, 0.0005430530000012368]], [1766, [0.0005853119999983392, 0.000582014999963576]], [1770, [0.0005929909999622396, 0.000583071999983531]], [1776, [0.0005810670000130358, 0.000576186999978745]], [1801, [0.0005717709999828458, 0.0005785939999896073]], [1937, [0.0005969709999362749, 0.0005864510000037626]], [1960, [0.0005953940000154034, 0.0005933700000468889]], [1996, [0.0006160310000495883, 0.0006166809999967882]], [2029, [0.0006159270000125616, 0.0006080119999865019]]] \ No newline at end of file +[[1662, [0.0005377129999999397, 0.0005395769999836375]], [1672, [0.000547750000009728, 0.0005677989999810507]], [1687, [0.0005471899999918151, 0.0005447550000212686]], [1691, [0.0005559489999882317, 0.0005480739999939033]], [1709, [0.0005736080000247057, 0.0005720849999875099]], [1726, [0.000542692999999872, 0.0005430530000012368]], [1766, [0.0005853119999983392, 0.000582014999963576]], [1770, [0.0005929909999622396, 0.000583071999983531]], [1776, [0.0005810670000130358, 0.000576186999978745]], [1801, [0.0005717709999828458, 0.0005785939999896073]]] \ No newline at end of file diff --git a/docs/benchmarks/graphs/branch-master/django-5.1/djc-core-html-parser/machine-ci-linux/python-3.13/isolated vs django modes.timeraw_startup_lg.json b/docs/benchmarks/graphs/branch-master/django-5.1/djc-core-html-parser/machine-ci-linux/python-3.13/isolated vs django modes.timeraw_startup_lg.json index 520c7cbf..2f2ec0b0 100644 --- a/docs/benchmarks/graphs/branch-master/django-5.1/djc-core-html-parser/machine-ci-linux/python-3.13/isolated vs django modes.timeraw_startup_lg.json +++ b/docs/benchmarks/graphs/branch-master/django-5.1/djc-core-html-parser/machine-ci-linux/python-3.13/isolated vs django modes.timeraw_startup_lg.json @@ -1 +1 @@ -[[1662, [0.21402431699999624, 0.21364062999998623]], [1672, [0.2221746719999942, 0.2222580240000127]], [1687, [0.2142312400000037, 0.21397752699999728]], [1691, [0.22129613300000983, 0.21942976399998315]], [1709, [0.2199001029999863, 0.22046102699999892]], [1726, [0.2147675530000015, 0.21506381099999317]], [1766, [0.22056839900000114, 0.21916191200000412]], [1770, [0.22394285699999728, 0.22330144500000415]], [1776, [0.21867883100003382, 0.21859779499999377]], [1801, [0.22378945699995256, 0.22211803700002974]], [1937, [0.22545313400001987, 0.22602228000005198]], [1960, [0.22564571399999522, 0.22598634599995648]], [1996, [0.2295973340000046, 0.23030742100002044]], [2029, [0.22777395400004252, 0.2292747939999913]]] \ No newline at end of file +[[1662, [0.21402431699999624, 0.21364062999998623]], [1672, [0.2221746719999942, 0.2222580240000127]], [1687, [0.2142312400000037, 0.21397752699999728]], [1691, [0.22129613300000983, 0.21942976399998315]], [1709, [0.2199001029999863, 0.22046102699999892]], [1726, [0.2147675530000015, 0.21506381099999317]], [1766, [0.22056839900000114, 0.21916191200000412]], [1770, [0.22394285699999728, 0.22330144500000415]], [1776, [0.21867883100003382, 0.21859779499999377]], [1801, [0.22378945699995256, 0.22211803700002974]]] \ No newline at end of file diff --git a/docs/benchmarks/graphs/branch-master/django-5.1/djc-core-html-parser/machine-ci-linux/python-3.13/summary.json b/docs/benchmarks/graphs/branch-master/django-5.1/djc-core-html-parser/machine-ci-linux/python-3.13/summary.json index 5cfe9e2e..e1eaa8c6 100644 --- a/docs/benchmarks/graphs/branch-master/django-5.1/djc-core-html-parser/machine-ci-linux/python-3.13/summary.json +++ b/docs/benchmarks/graphs/branch-master/django-5.1/djc-core-html-parser/machine-ci-linux/python-3.13/summary.json @@ -1 +1 @@ -[{"name": "Components vs Django.peakmem_render_lg_first", "idx": 0, "pretty_name": "render - large - first render (mem)('django')", "last_rev": 2029, "last_value": 52926464.0, "last_err": 238738.2857142857, "prev_value": null, "change_rev": null}, {"name": "Components vs Django.peakmem_render_lg_first", "idx": 1, "pretty_name": "render - large - first render (mem)('django-components')", "last_rev": 2029, "last_value": 55269376.0, "last_err": 352841.14285714284, "prev_value": null, "change_rev": null}, {"name": "Components vs Django.peakmem_render_lg_subsequent", "idx": 0, "pretty_name": "render - large - second render (mem)('django')", "last_rev": 2029, "last_value": 53041152.0, "last_err": 638098.2857142857, "prev_value": null, "change_rev": null}, {"name": "Components vs Django.peakmem_render_lg_subsequent", "idx": 1, "pretty_name": "render - large - second render (mem)('django-components')", "last_rev": 2029, "last_value": 55795712.0, "last_err": 429494.85714285716, "prev_value": null, "change_rev": null}, {"name": "Components vs Django.peakmem_render_sm_first", "idx": 0, "pretty_name": "render - small - first render (mem)('django')", "last_rev": 2029, "last_value": 44195840.0, "last_err": 193682.2857142857, "prev_value": null, "change_rev": null}, {"name": "Components vs Django.peakmem_render_sm_first", "idx": 1, "pretty_name": "render - small - first render (mem)('django-components')", "last_rev": 2029, "last_value": 44314624.0, "last_err": 206555.42857142858, "prev_value": null, "change_rev": null}, {"name": "Components vs Django.peakmem_render_sm_subsequent", "idx": 0, "pretty_name": "render - small - second render (mem)('django')", "last_rev": 2029, "last_value": 44255232.0, "last_err": 179346.2857142857, "prev_value": null, "change_rev": null}, {"name": "Components vs Django.peakmem_render_sm_subsequent", "idx": 1, "pretty_name": "render - small - second render (mem)('django-components')", "last_rev": 2029, "last_value": 44376064.0, "last_err": 238153.14285714287, "prev_value": null, "change_rev": null}, {"name": "Components vs Django.timeraw_render_lg_first", "idx": 0, "pretty_name": "render - large - first render('django')", "last_rev": 2029, "last_value": 0.07308550800001967, "last_err": 0.002970056988688463, "prev_value": null, "change_rev": null}, {"name": "Components vs Django.timeraw_render_lg_first", "idx": 1, "pretty_name": "render - large - first render('django-components')", "last_rev": 2029, "last_value": 0.26436952000000247, "last_err": 0.005644097774403133, "prev_value": null, "change_rev": null}, {"name": "Components vs Django.timeraw_render_lg_subsequent", "idx": 0, "pretty_name": "render - large - second render('django')", "last_rev": 2029, "last_value": 0.04362213900003553, "last_err": 0.00010141391999156615, "prev_value": 0.03723830100000214, "change_rev": [1801, 1937]}, {"name": "Components vs Django.timeraw_render_lg_subsequent", "idx": 1, "pretty_name": "render - large - second render('django-components')", "last_rev": 2029, "last_value": 0.15138703899998518, "last_err": 0.006705386360797588, "prev_value": null, "change_rev": null}, {"name": "Components vs Django.timeraw_render_sm_first", "idx": 0, "pretty_name": "render - small - first render('django')", "last_rev": 2029, "last_value": 0.003602947999979733, "last_err": 5.419141048740966e-05, "prev_value": null, "change_rev": null}, {"name": "Components vs Django.timeraw_render_sm_first", "idx": 1, "pretty_name": "render - small - first render('django-components')", "last_rev": 2029, "last_value": 0.004811176000004025, "last_err": 7.476107336392598e-05, "prev_value": null, "change_rev": null}, {"name": "Components vs Django.timeraw_render_sm_subsequent", "idx": 0, "pretty_name": "render - small - second render('django')", "last_rev": 2029, "last_value": 0.00011641800000461444, "last_err": 6.71568788300834e-06, "prev_value": null, "change_rev": null}, {"name": "Components vs Django.timeraw_render_sm_subsequent", "idx": 1, "pretty_name": "render - small - second render('django-components')", "last_rev": 2029, "last_value": 0.0005711430000019391, "last_err": 2.3656907602254418e-05, "prev_value": null, "change_rev": null}, {"name": "Components vs Django.timeraw_startup_lg", "idx": 0, "pretty_name": "startup - large('django')", "last_rev": 2029, "last_value": 0.22356123500000535, "last_err": 0.003663370721264278, "prev_value": null, "change_rev": null}, {"name": "Components vs Django.timeraw_startup_lg", "idx": 1, "pretty_name": "startup - large('django-components')", "last_rev": 2029, "last_value": 0.22048105400000395, "last_err": 0.005292030830577897, "prev_value": null, "change_rev": null}, {"name": "Other.timeraw_import_time", "idx": null, "pretty_name": "import time", "last_rev": 2029, "last_value": 0.19919827600000417, "last_err": 0.0040859881894921846, "prev_value": null, "change_rev": null}, {"name": "isolated vs django modes.peakmem_render_lg_first", "idx": 0, "pretty_name": "render - large - first render (mem)('isolated')", "last_rev": 2029, "last_value": 55234560.0, "last_err": 314806.85714285716, "prev_value": null, "change_rev": null}, {"name": "isolated vs django modes.peakmem_render_lg_first", "idx": 1, "pretty_name": "render - large - first render (mem)('django')", "last_rev": 2029, "last_value": 54708224.0, "last_err": 355474.28571428574, "prev_value": null, "change_rev": null}, {"name": "isolated vs django modes.peakmem_render_lg_subsequent", "idx": 0, "pretty_name": "render - large - second render (mem)('isolated')", "last_rev": 2029, "last_value": 55592960.0, "last_err": 405796.5714285714, "prev_value": null, "change_rev": null}, {"name": "isolated vs django modes.peakmem_render_lg_subsequent", "idx": 1, "pretty_name": "render - large - second render (mem)('django')", "last_rev": 2029, "last_value": 55621632.0, "last_err": 478939.4285714286, "prev_value": null, "change_rev": null}, {"name": "isolated vs django modes.peakmem_render_sm_first", "idx": 0, "pretty_name": "render - small - first render (mem)('isolated')", "last_rev": 2029, "last_value": 44316672.0, "last_err": 201874.2857142857, "prev_value": null, "change_rev": null}, {"name": "isolated vs django modes.peakmem_render_sm_first", "idx": 1, "pretty_name": "render - small - first render (mem)('django')", "last_rev": 2029, "last_value": 44314624.0, "last_err": 207433.14285714287, "prev_value": null, "change_rev": null}, {"name": "isolated vs django modes.peakmem_render_sm_subsequent", "idx": 0, "pretty_name": "render - small - second render (mem)('isolated')", "last_rev": 2029, "last_value": 44314624.0, "last_err": 228498.2857142857, "prev_value": null, "change_rev": null}, {"name": "isolated vs django modes.peakmem_render_sm_subsequent", "idx": 1, "pretty_name": "render - small - second render (mem)('django')", "last_rev": 2029, "last_value": 44316672.0, "last_err": 219428.57142857142, "prev_value": null, "change_rev": null}, {"name": "isolated vs django modes.timeraw_render_lg_first", "idx": 0, "pretty_name": "render - large - first render('isolated')", "last_rev": 2029, "last_value": 0.2646600410000133, "last_err": 0.007677844017113229, "prev_value": null, "change_rev": null}, {"name": "isolated vs django modes.timeraw_render_lg_first", "idx": 1, "pretty_name": "render - large - first render('django')", "last_rev": 2029, "last_value": 0.2676605120000204, "last_err": 0.00784939843762128, "prev_value": null, "change_rev": null}, {"name": "isolated vs django modes.timeraw_render_lg_subsequent", "idx": 0, "pretty_name": "render - large - second render('isolated')", "last_rev": 2029, "last_value": 0.15071133700001837, "last_err": 0.006184059019873227, "prev_value": null, "change_rev": null}, {"name": "isolated vs django modes.timeraw_render_lg_subsequent", "idx": 1, "pretty_name": "render - large - second render('django')", "last_rev": 2029, "last_value": 0.15540660900001058, "last_err": 0.009898742429098032, "prev_value": null, "change_rev": null}, {"name": "isolated vs django modes.timeraw_render_sm_first", "idx": 0, "pretty_name": "render - small - first render('isolated')", "last_rev": 2029, "last_value": 0.004825538000005736, "last_err": 5.909934210844408e-05, "prev_value": null, "change_rev": null}, {"name": "isolated vs django modes.timeraw_render_sm_first", "idx": 1, "pretty_name": "render - small - first render('django')", "last_rev": 2029, "last_value": 0.0047952310000027865, "last_err": 7.102011245001072e-05, "prev_value": null, "change_rev": null}, {"name": "isolated vs django modes.timeraw_render_sm_subsequent", "idx": 0, "pretty_name": "render - small - second render('isolated')", "last_rev": 2029, "last_value": 0.0005736080000247057, "last_err": 2.103986485491359e-05, "prev_value": null, "change_rev": null}, {"name": "isolated vs django modes.timeraw_render_sm_subsequent", "idx": 1, "pretty_name": "render - small - second render('django')", "last_rev": 2029, "last_value": 0.000582014999963576, "last_err": 1.7671096085730627e-05, "prev_value": null, "change_rev": null}, {"name": "isolated vs django modes.timeraw_startup_lg", "idx": 0, "pretty_name": "startup - large('isolated')", "last_rev": 2029, "last_value": 0.22129613300000983, "last_err": 0.003939909589791106, "prev_value": null, "change_rev": null}, {"name": "isolated vs django modes.timeraw_startup_lg", "idx": 1, "pretty_name": "startup - large('django')", "last_rev": 2029, "last_value": 0.21916191200000412, "last_err": 0.00459183551388232, "prev_value": null, "change_rev": null}] \ No newline at end of file +[{"name": "Components vs Django.peakmem_render_lg_first", "idx": 0, "pretty_name": "render - large - first render (mem)('django')", "last_rev": 1801, "last_value": 52910080.0, "last_err": 291225.6, "prev_value": null, "change_rev": null}, {"name": "Components vs Django.peakmem_render_lg_first", "idx": 1, "pretty_name": "render - large - first render (mem)('django-components')", "last_rev": 1801, "last_value": 55001088.0, "last_err": 286720.0, "prev_value": null, "change_rev": null}, {"name": "Components vs Django.peakmem_render_lg_subsequent", "idx": 0, "pretty_name": "render - large - second render (mem)('django')", "last_rev": 1801, "last_value": 53753856.0, "last_err": 696729.6, "prev_value": null, "change_rev": null}, {"name": "Components vs Django.peakmem_render_lg_subsequent", "idx": 1, "pretty_name": "render - large - second render (mem)('django-components')", "last_rev": 1801, "last_value": 55453696.0, "last_err": 290406.4, "prev_value": null, "change_rev": null}, {"name": "Components vs Django.peakmem_render_sm_first", "idx": 0, "pretty_name": "render - small - first render (mem)('django')", "last_rev": 1801, "last_value": 44191744.0, "last_err": 42598.4, "prev_value": null, "change_rev": null}, {"name": "Components vs Django.peakmem_render_sm_first", "idx": 1, "pretty_name": "render - small - first render (mem)('django-components')", "last_rev": 1801, "last_value": 44453888.0, "last_err": 0.0, "prev_value": 44306432.0, "change_rev": [1776, 1801]}, {"name": "Components vs Django.peakmem_render_sm_subsequent", "idx": 0, "pretty_name": "render - small - second render (mem)('django')", "last_rev": 1801, "last_value": 44191744.0, "last_err": 70041.6, "prev_value": null, "change_rev": null}, {"name": "Components vs Django.peakmem_render_sm_subsequent", "idx": 1, "pretty_name": "render - small - second render (mem)('django-components')", "last_rev": 1801, "last_value": 44310528.0, "last_err": 104448.0, "prev_value": null, "change_rev": null}, {"name": "Components vs Django.timeraw_render_lg_first", "idx": 0, "pretty_name": "render - large - first render('django')", "last_rev": 1801, "last_value": 0.07303507899999317, "last_err": 0.0015079635926781693, "prev_value": null, "change_rev": null}, {"name": "Components vs Django.timeraw_render_lg_first", "idx": 1, "pretty_name": "render - large - first render('django-components')", "last_rev": 1801, "last_value": 0.26274096600002395, "last_err": 0.0030797882742699726, "prev_value": null, "change_rev": null}, {"name": "Components vs Django.timeraw_render_lg_subsequent", "idx": 0, "pretty_name": "render - large - second render('django')", "last_rev": 1801, "last_value": 0.03723830100000214, "last_err": 0.00030398760529811336, "prev_value": 0.03327357099999517, "change_rev": [1691, 1709]}, {"name": "Components vs Django.timeraw_render_lg_subsequent", "idx": 1, "pretty_name": "render - large - second render('django-components')", "last_rev": 1801, "last_value": 0.14901454800002512, "last_err": 0.0034185043586025974, "prev_value": null, "change_rev": null}, {"name": "Components vs Django.timeraw_render_sm_first", "idx": 0, "pretty_name": "render - small - first render('django')", "last_rev": 1801, "last_value": 0.0035613420000117912, "last_err": 4.282955140889142e-05, "prev_value": null, "change_rev": null}, {"name": "Components vs Django.timeraw_render_sm_first", "idx": 1, "pretty_name": "render - small - first render('django-components')", "last_rev": 1801, "last_value": 0.004791812000007667, "last_err": 7.393313127925657e-05, "prev_value": null, "change_rev": null}, {"name": "Components vs Django.timeraw_render_sm_subsequent", "idx": 0, "pretty_name": "render - small - second render('django')", "last_rev": 1801, "last_value": 0.00011641800000461444, "last_err": 1.0240076479630366e-06, "prev_value": 0.0001005780000014056, "change_rev": [1691, 1709]}, {"name": "Components vs Django.timeraw_render_sm_subsequent", "idx": 1, "pretty_name": "render - small - second render('django-components')", "last_rev": 1801, "last_value": 0.0005549249999887707, "last_err": 1.689840424952132e-05, "prev_value": null, "change_rev": null}, {"name": "Components vs Django.timeraw_startup_lg", "idx": 0, "pretty_name": "startup - large('django')", "last_rev": 1801, "last_value": 0.22073260000001937, "last_err": 0.0033423623770026715, "prev_value": null, "change_rev": null}, {"name": "Components vs Django.timeraw_startup_lg", "idx": 1, "pretty_name": "startup - large('django-components')", "last_rev": 1801, "last_value": 0.2182690520000392, "last_err": 0.0038591938736867977, "prev_value": null, "change_rev": null}, {"name": "Other.timeraw_import_time", "idx": null, "pretty_name": "import time", "last_rev": 1801, "last_value": 0.19919827600000417, "last_err": 0.0030941523965093633, "prev_value": null, "change_rev": null}, {"name": "isolated vs django modes.peakmem_render_lg_first", "idx": 0, "pretty_name": "render - large - first render (mem)('isolated')", "last_rev": 1801, "last_value": 54996992.0, "last_err": 280166.4, "prev_value": null, "change_rev": null}, {"name": "isolated vs django modes.peakmem_render_lg_first", "idx": 1, "pretty_name": "render - large - first render (mem)('django')", "last_rev": 1801, "last_value": 54329344.0, "last_err": 308838.4, "prev_value": null, "change_rev": null}, {"name": "isolated vs django modes.peakmem_render_lg_subsequent", "idx": 0, "pretty_name": "render - large - second render (mem)('isolated')", "last_rev": 1801, "last_value": 55447552.0, "last_err": 275251.2, "prev_value": null, "change_rev": null}, {"name": "isolated vs django modes.peakmem_render_lg_subsequent", "idx": 1, "pretty_name": "render - large - second render (mem)('django')", "last_rev": 1801, "last_value": 55336960.0, "last_err": 306790.4, "prev_value": null, "change_rev": null}, {"name": "isolated vs django modes.peakmem_render_sm_first", "idx": 0, "pretty_name": "render - small - first render (mem)('isolated')", "last_rev": 1801, "last_value": 44314624.0, "last_err": 68812.8, "prev_value": null, "change_rev": null}, {"name": "isolated vs django modes.peakmem_render_sm_first", "idx": 1, "pretty_name": "render - small - first render (mem)('django')", "last_rev": 1801, "last_value": 44310528.0, "last_err": 74956.8, "prev_value": null, "change_rev": null}, {"name": "isolated vs django modes.peakmem_render_sm_subsequent", "idx": 0, "pretty_name": "render - small - second render (mem)('isolated')", "last_rev": 1801, "last_value": 44312576.0, "last_err": 79052.8, "prev_value": null, "change_rev": null}, {"name": "isolated vs django modes.peakmem_render_sm_subsequent", "idx": 1, "pretty_name": "render - small - second render (mem)('django')", "last_rev": 1801, "last_value": 44314624.0, "last_err": 79052.8, "prev_value": null, "change_rev": null}, {"name": "isolated vs django modes.timeraw_render_lg_first", "idx": 0, "pretty_name": "render - large - first render('isolated')", "last_rev": 1801, "last_value": 0.2600247560000071, "last_err": 0.0032147405172077217, "prev_value": null, "change_rev": null}, {"name": "isolated vs django modes.timeraw_render_lg_first", "idx": 1, "pretty_name": "render - large - first render('django')", "last_rev": 1801, "last_value": 0.2619792840000059, "last_err": 0.003903341080694231, "prev_value": null, "change_rev": null}, {"name": "isolated vs django modes.timeraw_render_lg_subsequent", "idx": 0, "pretty_name": "render - large - second render('isolated')", "last_rev": 1801, "last_value": 0.14520097999997006, "last_err": 0.0033867810433681326, "prev_value": null, "change_rev": null}, {"name": "isolated vs django modes.timeraw_render_lg_subsequent", "idx": 1, "pretty_name": "render - large - second render('django')", "last_rev": 1801, "last_value": 0.14991973799999414, "last_err": 0.0035610771318715317, "prev_value": null, "change_rev": null}, {"name": "isolated vs django modes.timeraw_render_sm_first", "idx": 0, "pretty_name": "render - small - first render('isolated')", "last_rev": 1801, "last_value": 0.00480728600001612, "last_err": 5.8194676056223595e-05, "prev_value": null, "change_rev": null}, {"name": "isolated vs django modes.timeraw_render_sm_first", "idx": 1, "pretty_name": "render - small - first render('django')", "last_rev": 1801, "last_value": 0.0047485900000197034, "last_err": 6.830220604588864e-05, "prev_value": null, "change_rev": null}, {"name": "isolated vs django modes.timeraw_render_sm_subsequent", "idx": 0, "pretty_name": "render - small - second render('isolated')", "last_rev": 1801, "last_value": 0.0005559489999882317, "last_err": 1.5941242766015683e-05, "prev_value": null, "change_rev": null}, {"name": "isolated vs django modes.timeraw_render_sm_subsequent", "idx": 1, "pretty_name": "render - small - second render('django')", "last_rev": 1801, "last_value": 0.0005720849999875099, "last_err": 1.5267871206365328e-05, "prev_value": null, "change_rev": null}, {"name": "isolated vs django modes.timeraw_startup_lg", "idx": 0, "pretty_name": "startup - large('isolated')", "last_rev": 1801, "last_value": 0.2199001029999863, "last_err": 0.003117201156386737, "prev_value": null, "change_rev": null}, {"name": "isolated vs django modes.timeraw_startup_lg", "idx": 1, "pretty_name": "startup - large('django')", "last_rev": 1801, "last_value": 0.21859779499999377, "last_err": 0.0030780461178069223, "prev_value": null, "change_rev": null}] \ No newline at end of file diff --git a/docs/benchmarks/graphs/summary/Components vs Django.peakmem_render_lg_first.json b/docs/benchmarks/graphs/summary/Components vs Django.peakmem_render_lg_first.json index 9b9d166a..f93d9312 100644 --- a/docs/benchmarks/graphs/summary/Components vs Django.peakmem_render_lg_first.json +++ b/docs/benchmarks/graphs/summary/Components vs Django.peakmem_render_lg_first.json @@ -1 +1 @@ -[[1662, 53737309.613078326], [1672, 53463506.59363525], [1687, 53427924.42970294], [1691, 53807508.99158667], [1709, 53963042.655257314], [1726, 53670369.245800875], [1766, 54220916.6140389], [1770, 54198077.75539557], [1776, 53906774.26269022], [1801, 54270509.344660625], [1937, 54055804.31664803], [1960, 54295416.494559616], [1996, 54277301.04707094], [2029, 54376892.25474807]] \ No newline at end of file +[[1662, 53737309.613078326], [1672, 53463506.59363525], [1687, 53427924.42970294], [1691, 53807508.99158667], [1709, 53963042.655257314], [1726, 53670369.245800875], [1766, 54220916.6140389], [1770, 54198077.75539557], [1776, 53906774.26269022], [1801, 54270509.344660625]] \ No newline at end of file diff --git a/docs/benchmarks/graphs/summary/Components vs Django.peakmem_render_lg_subsequent.json b/docs/benchmarks/graphs/summary/Components vs Django.peakmem_render_lg_subsequent.json index 16c667e1..e66c7875 100644 --- a/docs/benchmarks/graphs/summary/Components vs Django.peakmem_render_lg_subsequent.json +++ b/docs/benchmarks/graphs/summary/Components vs Django.peakmem_render_lg_subsequent.json @@ -1 +1 @@ -[[1662, 54265895.0709751], [1672, 53676080.7209516], [1687, 53675997.57883592], [1691, 54512993.537089705], [1709, 54605449.27839023], [1726, 53697436.790693834], [1766, 54766004.5031032], [1770, 54878384.55144014], [1776, 53912680.86221259], [1801, 54851721.60114168], [1937, 54505276.07990639], [1960, 54599968.83944605], [1996, 54678155.56971878], [2029, 54725974.50425164]] \ No newline at end of file +[[1662, 54265895.0709751], [1672, 53676080.7209516], [1687, 53675997.57883592], [1691, 54512993.537089705], [1709, 54605449.27839023], [1726, 53697436.790693834], [1766, 54766004.5031032], [1770, 54878384.55144014], [1776, 53912680.86221259], [1801, 54851721.60114168]] \ No newline at end of file diff --git a/docs/benchmarks/graphs/summary/Components vs Django.peakmem_render_sm_first.json b/docs/benchmarks/graphs/summary/Components vs Django.peakmem_render_sm_first.json index b5b77f9d..ae819aef 100644 --- a/docs/benchmarks/graphs/summary/Components vs Django.peakmem_render_sm_first.json +++ b/docs/benchmarks/graphs/summary/Components vs Django.peakmem_render_sm_first.json @@ -1 +1 @@ -[[1662, 44191743.99999999], [1672, 44052479.80957694], [1687, 44251096.14326895], [1691, 44179455.81012423], [1709, 44253141.3491094], [1726, 44255192.14695785], [1766, 44318719.81072088], [1770, 44324863.95268679], [1776, 44244949.34121254], [1801, 44324676.21343578], [1937, 44750847.578234404], [1960, 44775384.609963], [1996, 44842828.229087956], [2029, 44892155.328466915]] \ No newline at end of file +[[1662, 44191743.99999999], [1672, 44052479.80957694], [1687, 44251096.14326895], [1691, 44179455.81012423], [1709, 44253141.3491094], [1726, 44255192.14695785], [1766, 44318719.81072088], [1770, 44324863.95268679], [1776, 44244949.34121254], [1801, 44324676.21343578]] \ No newline at end of file diff --git a/docs/benchmarks/graphs/summary/Components vs Django.peakmem_render_sm_subsequent.json b/docs/benchmarks/graphs/summary/Components vs Django.peakmem_render_sm_subsequent.json index 764451a5..d2dff9cf 100644 --- a/docs/benchmarks/graphs/summary/Components vs Django.peakmem_render_sm_subsequent.json +++ b/docs/benchmarks/graphs/summary/Components vs Django.peakmem_render_sm_subsequent.json @@ -1 +1 @@ -[[1662, 44191743.81017703], [1672, 43988933.59873213], [1687, 44208009.40445502], [1691, 44185599.95253766], [1709, 44314453.63272547], [1726, 44318719.81072088], [1766, 44316671.57410231], [1770, 44205956.60747199], [1776, 44376021.4672124], [1801, 44322622.19567646], [1937, 44636028.0238471], [1960, 44777429.84849827], [1996, 44846935.655543014], [2029, 44801668.84315699]] \ No newline at end of file +[[1662, 44191743.81017703], [1672, 43988933.59873213], [1687, 44208009.40445502], [1691, 44185599.95253766], [1709, 44314453.63272547], [1726, 44318719.81072088], [1766, 44316671.57410231], [1770, 44205956.60747199], [1776, 44376021.4672124], [1801, 44322622.19567646]] \ No newline at end of file diff --git a/docs/benchmarks/graphs/summary/Components vs Django.timeraw_render_lg_first.json b/docs/benchmarks/graphs/summary/Components vs Django.timeraw_render_lg_first.json index d7a7b9c6..e27dd178 100644 --- a/docs/benchmarks/graphs/summary/Components vs Django.timeraw_render_lg_first.json +++ b/docs/benchmarks/graphs/summary/Components vs Django.timeraw_render_lg_first.json @@ -1 +1 @@ -[[1662, 0.13350944016163727], [1672, 0.1370189324406613], [1687, 0.13338881256624893], [1691, 0.13534306127506], [1709, 0.14028461383291016], [1726, 0.1369248426273554], [1766, 0.13857329097819557], [1770, 0.14073477092350728], [1776, 0.1385645020210802], [1801, 0.14040196312080028], [1937, 0.14582964264952603], [1960, 0.14671897491501892], [1996, 0.15202819951982394], [2029, 0.15457268328939747]] \ No newline at end of file +[[1662, 0.13350944016163727], [1672, 0.1370189324406613], [1687, 0.13338881256624893], [1691, 0.13534306127506], [1709, 0.14028461383291016], [1726, 0.1369248426273554], [1766, 0.13857329097819557], [1770, 0.14073477092350728], [1776, 0.1385645020210802], [1801, 0.14040196312080028]] \ No newline at end of file diff --git a/docs/benchmarks/graphs/summary/Components vs Django.timeraw_render_lg_subsequent.json b/docs/benchmarks/graphs/summary/Components vs Django.timeraw_render_lg_subsequent.json index 807386ec..783555c7 100644 --- a/docs/benchmarks/graphs/summary/Components vs Django.timeraw_render_lg_subsequent.json +++ b/docs/benchmarks/graphs/summary/Components vs Django.timeraw_render_lg_subsequent.json @@ -1 +1 @@ -[[1662, 0.0687644082522681], [1672, 0.06987734456556612], [1687, 0.06874611472573841], [1691, 0.07039998567606925], [1709, 0.07467771106069107], [1726, 0.07307627413528986], [1766, 0.0752258677863117], [1770, 0.07591381717343901], [1776, 0.0741750279629251], [1801, 0.07486521068773488], [1937, 0.08182795598310513], [1960, 0.08198138820511656], [1996, 0.08497198126158123], [2029, 0.08730133488241124]] \ No newline at end of file +[[1662, 0.0687644082522681], [1672, 0.06987734456556612], [1687, 0.06874611472573841], [1691, 0.07039998567606925], [1709, 0.07467771106069107], [1726, 0.07307627413528986], [1766, 0.0752258677863117], [1770, 0.07591381717343901], [1776, 0.0741750279629251], [1801, 0.07486521068773488]] \ No newline at end of file diff --git a/docs/benchmarks/graphs/summary/Components vs Django.timeraw_render_sm_first.json b/docs/benchmarks/graphs/summary/Components vs Django.timeraw_render_sm_first.json index bd943ad3..f5e8aacd 100644 --- a/docs/benchmarks/graphs/summary/Components vs Django.timeraw_render_sm_first.json +++ b/docs/benchmarks/graphs/summary/Components vs Django.timeraw_render_sm_first.json @@ -1 +1 @@ -[[1662, 0.004071198582731586], [1672, 0.004168318834979474], [1687, 0.004071589002161507], [1691, 0.004235212007582172], [1709, 0.004181923314217816], [1726, 0.004054429932062044], [1766, 0.004133897799028137], [1770, 0.004257194320585938], [1776, 0.004117446125697445], [1801, 0.004200816754404154], [1937, 0.004251194879485355], [1960, 0.0041701734817425696], [1996, 0.004322540447211732], [2029, 0.004263823296369016]] \ No newline at end of file +[[1662, 0.004071198582731586], [1672, 0.004168318834979474], [1687, 0.004071589002161507], [1691, 0.004235212007582172], [1709, 0.004181923314217816], [1726, 0.004054429932062044], [1766, 0.004133897799028137], [1770, 0.004257194320585938], [1776, 0.004117446125697445], [1801, 0.004200816754404154]] \ No newline at end of file diff --git a/docs/benchmarks/graphs/summary/Components vs Django.timeraw_render_sm_subsequent.json b/docs/benchmarks/graphs/summary/Components vs Django.timeraw_render_sm_subsequent.json index 8d882c01..fafee4ea 100644 --- a/docs/benchmarks/graphs/summary/Components vs Django.timeraw_render_sm_subsequent.json +++ b/docs/benchmarks/graphs/summary/Components vs Django.timeraw_render_sm_subsequent.json @@ -1 +1 @@ -[[1662, 0.00023540900613243872], [1672, 0.0002365886195511814], [1687, 0.0002326213978668684], [1691, 0.0002363893607261623], [1709, 0.0002646827752432008], [1726, 0.00025280056719810247], [1766, 0.00025904182642747317], [1770, 0.0002627038966898471], [1776, 0.00026058997620285855], [1801, 0.000260725493948419], [1937, 0.0002700303204925571], [1960, 0.00027008950893915996], [1996, 0.0002800574798090668], [2029, 0.000278420428825539]] \ No newline at end of file +[[1662, 0.00023540900613243872], [1672, 0.0002365886195511814], [1687, 0.0002326213978668684], [1691, 0.0002363893607261623], [1709, 0.0002646827752432008], [1726, 0.00025280056719810247], [1766, 0.00025904182642747317], [1770, 0.0002627038966898471], [1776, 0.00026058997620285855], [1801, 0.000260725493948419]] \ No newline at end of file diff --git a/docs/benchmarks/graphs/summary/Components vs Django.timeraw_startup_lg.json b/docs/benchmarks/graphs/summary/Components vs Django.timeraw_startup_lg.json index a58dd726..4ae2493b 100644 --- a/docs/benchmarks/graphs/summary/Components vs Django.timeraw_startup_lg.json +++ b/docs/benchmarks/graphs/summary/Components vs Django.timeraw_startup_lg.json @@ -1 +1 @@ -[[1662, 0.21586009863792485], [1672, 0.22261052942796597], [1687, 0.21562505130206716], [1691, 0.2226172972159168], [1709, 0.21969118716012626], [1726, 0.21540413874268913], [1766, 0.2217946171557135], [1770, 0.22763817627917332], [1776, 0.21949736979633283], [1801, 0.22435444169386096], [1937, 0.22675338309844276], [1960, 0.22498195815021013], [1996, 0.23120029358312028], [2029, 0.22761342037999505]] \ No newline at end of file +[[1662, 0.21586009863792485], [1672, 0.22261052942796597], [1687, 0.21562505130206716], [1691, 0.2226172972159168], [1709, 0.21969118716012626], [1726, 0.21540413874268913], [1766, 0.2217946171557135], [1770, 0.22763817627917332], [1776, 0.21949736979633283], [1801, 0.22435444169386096]] \ No newline at end of file diff --git a/docs/benchmarks/graphs/summary/Other.timeraw_import_time.json b/docs/benchmarks/graphs/summary/Other.timeraw_import_time.json index eb01068a..3c9dc75e 100644 --- a/docs/benchmarks/graphs/summary/Other.timeraw_import_time.json +++ b/docs/benchmarks/graphs/summary/Other.timeraw_import_time.json @@ -1 +1 @@ -[[1662, 0.19832900800003017], [1672, 0.20217585500000723], [1687, 0.19726691500000015], [1691, 0.20350580199999513], [1709, 0.19950735400001918], [1726, 0.19625152499997967], [1766, 0.20073733000003813], [1770, 0.20376683500001036], [1776, 0.19919827600000417], [1801, 0.2053688209999791], [1937, 0.2063091950000171], [1960, 0.20468290799999522], [1996, 0.21042045099989082], [2029, 0.2056691309999792]] \ No newline at end of file +[[1662, 0.19832900800003017], [1672, 0.20217585500000723], [1687, 0.19726691500000015], [1691, 0.20350580199999513], [1709, 0.19950735400001918], [1726, 0.19625152499997967], [1766, 0.20073733000003813], [1770, 0.20376683500001036], [1776, 0.19919827600000417], [1801, 0.2053688209999791]] \ No newline at end of file diff --git a/docs/benchmarks/graphs/summary/isolated vs django modes.peakmem_render_lg_first.json b/docs/benchmarks/graphs/summary/isolated vs django modes.peakmem_render_lg_first.json index 4429f303..6bb13555 100644 --- a/docs/benchmarks/graphs/summary/isolated vs django modes.peakmem_render_lg_first.json +++ b/docs/benchmarks/graphs/summary/isolated vs django modes.peakmem_render_lg_first.json @@ -1 +1 @@ -[[1662, 54203904.32644733], [1672, 54377977.05567385], [1687, 54531587.401090905], [1691, 54414373.37457081], [1709, 54655941.05401974], [1726, 54668354.35558938], [1766, 55133687.30603648], [1770, 55072492.873806104], [1776, 55115246.19008138], [1801, 55131593.83007953], [1937, 54971848.18483294], [1960, 54977822.99733244], [1996, 55221688.06930552], [2029, 55836094.494666085]] \ No newline at end of file +[[1662, 54203904.32644733], [1672, 54377977.05567385], [1687, 54531587.401090905], [1691, 54414373.37457081], [1709, 54655941.05401974], [1726, 54668354.35558938], [1766, 55133687.30603648], [1770, 55072492.873806104], [1776, 55115246.19008138], [1801, 55131593.83007953]] \ No newline at end of file diff --git a/docs/benchmarks/graphs/summary/isolated vs django modes.peakmem_render_lg_subsequent.json b/docs/benchmarks/graphs/summary/isolated vs django modes.peakmem_render_lg_subsequent.json index bed4ea23..4d7a2293 100644 --- a/docs/benchmarks/graphs/summary/isolated vs django modes.peakmem_render_lg_subsequent.json +++ b/docs/benchmarks/graphs/summary/isolated vs django modes.peakmem_render_lg_subsequent.json @@ -1 +1 @@ -[[1662, 54880185.34368702], [1672, 54845439.84705003], [1687, 55287805.57238104], [1691, 54974463.04630629], [1709, 55404533.06087942], [1726, 55316304.695168346], [1766, 55588847.36277981], [1770, 55711653.6193069], [1776, 55635967.849223286], [1801, 55857133.82825839], [1937, 56076247.273349956], [1960, 55971522.87008585], [1996, 56434628.542863145], [2029, 56782847.85226863]] \ No newline at end of file +[[1662, 54880185.34368702], [1672, 54845439.84705003], [1687, 55287805.57238104], [1691, 54974463.04630629], [1709, 55404533.06087942], [1726, 55316304.695168346], [1766, 55588847.36277981], [1770, 55711653.6193069], [1776, 55635967.849223286], [1801, 55857133.82825839]] \ No newline at end of file diff --git a/docs/benchmarks/graphs/summary/isolated vs django modes.peakmem_render_sm_first.json b/docs/benchmarks/graphs/summary/isolated vs django modes.peakmem_render_sm_first.json index d6903d84..8d0b2b2e 100644 --- a/docs/benchmarks/graphs/summary/isolated vs django modes.peakmem_render_sm_first.json +++ b/docs/benchmarks/graphs/summary/isolated vs django modes.peakmem_render_sm_first.json @@ -1 +1 @@ -[[1662, 44185599.95253766], [1672, 44048383.99999999], [1687, 44312575.95267366], [1691, 44177407.95252886], [1709, 44312575.95267366], [1726, 44314624.0], [1766, 44316671.95267803], [1770, 44318719.81072088], [1776, 44273651.87380721], [1801, 44453888.0], [1937, 44744704.0], [1960, 44838912.00000001], [1996, 44969983.99999999], [2029, 44847103.812950954]] \ No newline at end of file +[[1662, 44185599.95253766], [1672, 44048383.99999999], [1687, 44312575.95267366], [1691, 44177407.95252886], [1709, 44312575.95267366], [1726, 44314624.0], [1766, 44316671.95267803], [1770, 44318719.81072088], [1776, 44273651.87380721], [1801, 44453888.0]] \ No newline at end of file diff --git a/docs/benchmarks/graphs/summary/isolated vs django modes.peakmem_render_sm_subsequent.json b/docs/benchmarks/graphs/summary/isolated vs django modes.peakmem_render_sm_subsequent.json index 1f44ef9f..0a514fe4 100644 --- a/docs/benchmarks/graphs/summary/isolated vs django modes.peakmem_render_sm_subsequent.json +++ b/docs/benchmarks/graphs/summary/isolated vs django modes.peakmem_render_sm_subsequent.json @@ -1 +1 @@ -[[1662, 44187648.0], [1672, 44052479.99999999], [1687, 44312575.95267366], [1691, 44179455.99999999], [1709, 44312575.95267366], [1726, 44314624.0], [1766, 44312575.95267366], [1770, 44316671.95267803], [1776, 44437504.0], [1801, 44449792.0], [1937, 44744704.0], [1960, 44900304.17220587], [1996, 44974080.0], [2029, 44984319.953380376]] \ No newline at end of file +[[1662, 44187648.0], [1672, 44052479.99999999], [1687, 44312575.95267366], [1691, 44179455.99999999], [1709, 44312575.95267366], [1726, 44314624.0], [1766, 44312575.95267366], [1770, 44316671.95267803], [1776, 44437504.0], [1801, 44449792.0]] \ No newline at end of file diff --git a/docs/benchmarks/graphs/summary/isolated vs django modes.timeraw_render_lg_first.json b/docs/benchmarks/graphs/summary/isolated vs django modes.timeraw_render_lg_first.json index 58c7bd0b..ba1cfb26 100644 --- a/docs/benchmarks/graphs/summary/isolated vs django modes.timeraw_render_lg_first.json +++ b/docs/benchmarks/graphs/summary/isolated vs django modes.timeraw_render_lg_first.json @@ -1 +1 @@ -[[1662, 0.2582970915627115], [1672, 0.2609375697890752], [1687, 0.2585333418012986], [1691, 0.2605245701455466], [1709, 0.26615604836262874], [1726, 0.25886008645727265], [1766, 0.2656287982807661], [1770, 0.2675580766089799], [1776, 0.2644825926606367], [1801, 0.26856188100049755], [1937, 0.2700264321932048], [1960, 0.2711075492537049], [1996, 0.28189867248766043], [2029, 0.29481258851469266]] \ No newline at end of file +[[1662, 0.2582970915627115], [1672, 0.2609375697890752], [1687, 0.2585333418012986], [1691, 0.2605245701455466], [1709, 0.26615604836262874], [1726, 0.25886008645727265], [1766, 0.2656287982807661], [1770, 0.2675580766089799], [1776, 0.2644825926606367], [1801, 0.26856188100049755]] \ No newline at end of file diff --git a/docs/benchmarks/graphs/summary/isolated vs django modes.timeraw_render_lg_subsequent.json b/docs/benchmarks/graphs/summary/isolated vs django modes.timeraw_render_lg_subsequent.json index 56f4bd5d..b4039ef7 100644 --- a/docs/benchmarks/graphs/summary/isolated vs django modes.timeraw_render_lg_subsequent.json +++ b/docs/benchmarks/graphs/summary/isolated vs django modes.timeraw_render_lg_subsequent.json @@ -1 +1 @@ -[[1662, 0.144605946222714], [1672, 0.14711376894836906], [1687, 0.14434992731884352], [1691, 0.14638104217028877], [1709, 0.1508107336447194], [1726, 0.14754149544768042], [1766, 0.15304096778650703], [1770, 0.1536390943522132], [1776, 0.15209353551720362], [1801, 0.15356938175949056], [1937, 0.15690951925702573], [1960, 0.15706997937098616], [1996, 0.16911758076913888], [2029, 0.17625829701058932]] \ No newline at end of file +[[1662, 0.144605946222714], [1672, 0.14711376894836906], [1687, 0.14434992731884352], [1691, 0.14638104217028877], [1709, 0.1508107336447194], [1726, 0.14754149544768042], [1766, 0.15304096778650703], [1770, 0.1536390943522132], [1776, 0.15209353551720362], [1801, 0.15356938175949056]] \ No newline at end of file diff --git a/docs/benchmarks/graphs/summary/isolated vs django modes.timeraw_render_sm_first.json b/docs/benchmarks/graphs/summary/isolated vs django modes.timeraw_render_sm_first.json index 5ba7c936..31d99ef0 100644 --- a/docs/benchmarks/graphs/summary/isolated vs django modes.timeraw_render_sm_first.json +++ b/docs/benchmarks/graphs/summary/isolated vs django modes.timeraw_render_sm_first.json @@ -1 +1 @@ -[[1662, 0.004713162243622524], [1672, 0.004881543738505435], [1687, 0.004732102104161917], [1691, 0.00488069732533968], [1709, 0.004839972328668506], [1726, 0.004672193982353972], [1766, 0.004766899700580667], [1770, 0.004898703707479391], [1776, 0.004767500868992566], [1801, 0.004852423669122516], [1937, 0.004924660359490744], [1960, 0.004810360631940079], [1996, 0.004998322871483767], [2029, 0.004880129761791827]] \ No newline at end of file +[[1662, 0.004713162243622524], [1672, 0.004881543738505435], [1687, 0.004732102104161917], [1691, 0.00488069732533968], [1709, 0.004839972328668506], [1726, 0.004672193982353972], [1766, 0.004766899700580667], [1770, 0.004898703707479391], [1776, 0.004767500868992566], [1801, 0.004852423669122516]] \ No newline at end of file diff --git a/docs/benchmarks/graphs/summary/isolated vs django modes.timeraw_render_sm_subsequent.json b/docs/benchmarks/graphs/summary/isolated vs django modes.timeraw_render_sm_subsequent.json index dec783d0..f50d1376 100644 --- a/docs/benchmarks/graphs/summary/isolated vs django modes.timeraw_render_sm_subsequent.json +++ b/docs/benchmarks/graphs/summary/isolated vs django modes.timeraw_render_sm_subsequent.json @@ -1 +1 @@ -[[1662, 0.0005386441936864901], [1672, 0.0005576844109755481], [1687, 0.0005459711425132094], [1691, 0.0005519974567116778], [1709, 0.0005728459938648165], [1726, 0.0005428729701593198], [1766, 0.0005836611719634209], [1770, 0.0005880105852110292], [1776, 0.0005786218553806627], [1801, 0.0005751723828193878], [1937, 0.0005916876201898046], [1960, 0.000594381138510516], [1996, 0.0006163559143381376], [2029, 0.0006119567036345985]] \ No newline at end of file +[[1662, 0.0005386441936864901], [1672, 0.0005576844109755481], [1687, 0.0005459711425132094], [1691, 0.0005519974567116778], [1709, 0.0005728459938648165], [1726, 0.0005428729701593198], [1766, 0.0005836611719634209], [1770, 0.0005880105852110292], [1776, 0.0005786218553806627], [1801, 0.0005751723828193878]] \ No newline at end of file diff --git a/docs/benchmarks/graphs/summary/isolated vs django modes.timeraw_startup_lg.json b/docs/benchmarks/graphs/summary/isolated vs django modes.timeraw_startup_lg.json index 2b8c756c..e4dee048 100644 --- a/docs/benchmarks/graphs/summary/isolated vs django modes.timeraw_startup_lg.json +++ b/docs/benchmarks/graphs/summary/isolated vs django modes.timeraw_startup_lg.json @@ -1 +1 @@ -[[1662, 0.21383238744211777], [1672, 0.22221634409189991], [1687, 0.21410434591886193], [1691, 0.2203609725843055], [1709, 0.22018038637622225], [1726, 0.2149156309515977], [1766, 0.2198640308272821], [1770, 0.22362192103085216], [1776, 0.21863830924562072], [1801, 0.22295218072522197], [1937, 0.22573752762853083], [1960, 0.22581596577171012], [1996, 0.22995210340856065], [2029, 0.2285231418957897]] \ No newline at end of file +[[1662, 0.21383238744211777], [1672, 0.22221634409189991], [1687, 0.21410434591886193], [1691, 0.2203609725843055], [1709, 0.22018038637622225], [1726, 0.2149156309515977], [1766, 0.2198640308272821], [1770, 0.22362192103085216], [1776, 0.21863830924562072], [1801, 0.22295218072522197]] \ No newline at end of file diff --git a/docs/benchmarks/index.json b/docs/benchmarks/index.json index d98e1855..86c1d84f 100644 --- a/docs/benchmarks/index.json +++ b/docs/benchmarks/index.json @@ -1 +1 @@ -{"project": "django-components", "project_url": "/django-components/", "show_commit_url": "#", "hash_length": 8, "revision_to_hash": {"250": "45a18626d74b280aa05498aa380eba687010cc0f", "268": "c9f0068741871b24756045805aaab8fbf368601a", "343": "ed2cd57bdcc12bf390f42058061a6ed077e558b0", "359": "501a055fe21abb4c7ad9af1a3a1b42eea24afacf", "369": "1937d594100d0651b151c8edbe1189b5a88b358f", "380": "1d091f50999cca0fa8c7852da2ea71684eadda6d", "388": "f5c3f64c866d06dfa2435d1d18b936dddb9eb67c", "427": "24d9db39c3c55f5eb91c9ce2112ad22507ccdd60", "457": "9103eda2f4ed80f46ff03d215491009c5476b410", "487": "384ff79e0875ac3a64a2755010ef86ec09a090b5", "500": "c102019811586f40cb11952f283797ddee96de3c", "503": "a350ad1a869bb46c6bac093f54ac40ea85d8cd8f", "508": "16022429da16e459b8a1e6e9cd8ab41d95dcb59d", "536": "ea7beb518c435389d9daff7ea557eec9ddc2464e", "550": "2cfc7285e12677a54247e9998967081c0e031efc", "552": "fcbfae3c5f0611519636290ef99b25bc0a319825", "564": "316310e842f276fd43436b432781430bd255410b", "575": "e0a5c2a4bcf5e8f577e19333e3b719440c37b10b", "577": "c174aa9802cc73b5d8fef4b0c704de3fb68b1cbb", "598": "979781012532f18c147a570ff4441c65c7503b6f", "612": "9d7d0b40b9d3bbd8e5b754e3b1b20df982cdd184", "622": "24032ac2ea80627f0fdde88058a2c3fbcae0d3fe", "646": "4f1a8184465fc472995bc226bebd66c250d501f6", "651": "8ce649498ff63a64761c83cf713983b7e2f24b81", "663": "93facba53e050619a477fa214da89fccf118ec13", "675": "ea33e0db6c54486b67e2fa496ec1c3ec3de06ec7", "681": "6874b1531df0e8836000bbc76fcca5a3de42724a", "691": "9f4243232018708fdf330f0e922a09317c60234c", "704": "188a9dc7eef4c45ee4f87efa8a0d6728e94f210d", "724": "76a0cde3af7b3061127d149c138fbc78462a07fe", "729": "c932f28cb4840dc45d2d26b4d927c1480459272f", "742": "7058f05e0415965ddd162d0ba663c5106e7ffb66", "748": "95d6eacb5c03a611f92cd9a6e254cea7e0ce57eb", "752": "d512cfb0fec8a42ab58d2f106047fc4c0ec65427", "757": "04160f4e0b2ec4d901d6724c34ed8df883363064", "773": "20847b978b3ddb5979489fbb4bd8e971b9b16fbf", "775": "ae5cda9f727454a077ab16c51a237fec076bd442", "779": "cd791caa572c9acd6d56445c04d6c9b55a50c602", "787": "274be104789e31955f88e26f14c89ed648f25448", "806": "c3a80b729049b5ea1b4799e742e4100a7640efab", "845": "0abb5aa63ff0396328ef4dfdc2e78e872671f135", "855": "e4e787b29dc9cd2cf35ad02f22bad6fa15a7211c", "867": "e346c07298b268d9212fcf93d132968e69824730", "884": "2316f79dff66260b7a9fe91effb55c74524deca0", "887": "085c60a8c96442d9fd4f72d66a7eb295e7cfb2d9", "889": "ba86cee578490df944ad167674db32182b8bbf7b", "891": "dd292b03508b7c03b2ad4f9fb9c17dec747845ba", "898": "badffdda3538a8082137453c757509ed4f035a3e", "902": "c07f0e634121ced0119bb665ed544ca4447c416b", "904": "8bbe81d7171ec3512f250927653d8454c7ff005e", "908": "881c36219a45581086da35a17d3715ee0698ca88", "910": "9bfb50b8f27f7ff521226109ab30426633f6b514", "912": "3a7d5355cfa5d37641a4c80ee9fd2423cea10c1b", "930": "09a720009767f45bebcfa48f3587219c03082601", "935": "a4b4905bee778a51f9a99a042ce14ed2424cc9fb", "940": "31257a475dcfdacaaeb408f59ea92b736a668815", "942": "d47927054c820ecf3f9f97a62f03dfbb5496a11b", "956": "fbbbf6c694b8213832fc127ee8a3e31872308aff", "958": "d819f3ff491866abaeb9a7dbba6a6ca3c21da9f8", "960": "c202c5a901106392ccdde49100211182c986eca5", "965": "7bbfcf7565159d92de41bb0d738b7878d78f4533", "978": "b89c09aa5f13903b1d056c70afbfd327f0ed6362", "980": "03af25aad6841b6edb56c925d2599817e08ceb44", "982": "5cb649fae62a42e525c1ea9fb74d7838886cc1a8", "986": "f97717cdb35eaadb78b1f468728b1bd386e742d8", "1056": "b26a2011380c959bfc98043821f6b4aa337a281d", "1058": "8c5b088c31b7166932e18739f882c2eef632f3a4", "1060": "682bfc42397c0bdbeb1a2b6ccabb8aca89686d4f", "1089": "8f13a641ac096e93a0464f048a4fa53e591bb8db", "1098": "30d04fe1b053e6c5de0b6f34a7758a627517be8c", "1125": "f7846b9c0ae7a8fd0b7f6edf664316e485455e76", "1132": "a3d66586b19b7e2aacbf793edfba20bcd9858f4a", "1179": "0064de9c78db5eccc7c498e2a6d4c3c5ffa745ec", "1252": "d093bfb05212555e14c5cd46c94b0ba057cbeceb", "1270": "c0a4fd5f685d694218b583b2d0a3e8417925d53a", "1277": "2a4b0f52894d5d0bb8d325d6096a3950286db541", "1282": "5a23101038d7085959087b2352e71590eafe9529", "1287": "ce3305a5fff095e990707de851f85bc27120596c", "1312": "cdc830fca3bdd98669e0510841536be14d1bd728", "1328": "468a593a472c35379fe7567918e8a534b2d53748", "1337": "2f14e8e0908657459909c6338106e561edc5d0f4", "1352": "a5659691d0f947643ce6542b7f09075e3f931646", "1361": "aaeba99f54b206baed072ffd0572035ddf5118a7", "1366": "6813c9d7aa4acfb04df9665651a2864d04bbe8ba", "1381": "6681fc0085fdb4b76cb74c1bbf20d44fa22f40fe", "1387": "6bb73bd8afd350db84889efc09b74255cea08979", "1392": "c76f8198dd497b34735fc17a0f7a678bdd811a3f", "1447": "3bbd4326e6c1bfb4a02039e16021a3f720910308", "1488": "914576e68133bc6ec356f3918016c45691ed3534", "1505": "3d187d7abad80f8464bd70dfba847d27a8e173db", "1514": "e105500350a320dfccf36fc19cad7421d38c3736", "1546": "61515b34540d27311fc3286b50212c1e314ce39e", "1571": "691443a0a821eb1a02f9b42ad0e32bcd71d94943", "1591": "dcd4203eeadafc5d500b4b72c5cf04f1fe7317e7", "1662": "d0a42a2698f2ba21e7ab2dec750c5dbadeda0db5", "1672": "2037ed20b7252cc52008e69bdd3d8e095ad6ea08", "1687": "2472c2ad338a23fba015d4d9816cb62d1325455f", "1691": "42818ad6ffb47bd650d8a379b84c3d48394f9f77", "1709": "a6455d70f6c28ddbd4be8e58902f6cbc101e5ff3", "1726": "fdd29baa65e9ef78eb24a0ad2ca0b5d7c624dad3", "1766": "1319a95627493fc0745b5af0600af2dc8c5117f9", "1770": "07f747d70500bbe3e135725b0e1b102815ab9416", "1776": "ad402fc619922b6d2edf1e99b7082d2a58632076", "1801": "4c909486069f3c3c8ee7915239174f820f081da4", "1933": "593c66db7fce8f7d0e45768f516d1920e53d0967", "1937": "7b24b86f4a836c697acba926d9d6602afa45418d", "1960": "06c89cf9e89a432197a4cabb5a1d6864dd6089ac", "1996": "c692b7a3105c65414d2c23c357ffed9debdbf6e9", "2029": "5d7e235725449181f6b65b7bf97e43ea0e0f8552"}, "revision_to_date": {"250": 1630912817000, "268": 1631273531000, "343": 1654029104000, "359": 1657786741000, "369": 1657798498000, "380": 1658057264000, "388": 1658128984000, "427": 1670931380000, "457": 1673095465000, "487": 1675977478000, "500": 1678833725000, "503": 1678834812000, "508": 1679329468000, "536": 1680808865000, "550": 1681214445000, "552": 1681388770000, "564": 1682351069000, "575": 1684433482000, "577": 1684760359000, "598": 1693734426000, "612": 1695996512000, "622": 1696883504000, "646": 1702127213000, "651": 1702852887000, "663": 1705268832000, "675": 1705701480000, "681": 1706343740000, "691": 1706393538000, "704": 1707467055000, "724": 1708588716000, "729": 1708984309000, "742": 1709796107000, "748": 1710542375000, "752": 1711216985000, "757": 1711278671000, "773": 1711752109000, "775": 1711786713000, "779": 1712212506000, "787": 1712872453000, "806": 1713128940000, "845": 1713390260000, "855": 1713901297000, "867": 1714590581000, "884": 1714912319000, "887": 1715087715000, "889": 1715111097000, "891": 1715505986000, "898": 1716105516000, "902": 1716441018000, "904": 1716488913000, "908": 1717051130000, "910": 1717227227000, "912": 1717232115000, "930": 1718176374000, "935": 1718991590000, "940": 1720427258000, "942": 1720429478000, "956": 1722279535000, "958": 1722325182000, "960": 1722666822000, "965": 1722890429000, "978": 1723843975000, "980": 1723993321000, "982": 1724243667000, "986": 1724363119000, "1056": 1724732902000, "1058": 1724824521000, "1060": 1724924003000, "1089": 1725480929000, "1098": 1725655525000, "1125": 1726084755000, "1132": 1726347108000, "1179": 1728564427000, "1252": 1732525062000, "1270": 1732629701000, "1277": 1732644681000, "1282": 1732658332000, "1287": 1732726640000, "1312": 1733164405000, "1328": 1733471329000, "1337": 1733644953000, "1352": 1733834654000, "1361": 1734080521000, "1366": 1734245122000, "1381": 1734464187000, "1387": 1734600366000, "1392": 1734955786000, "1447": 1736287315000, "1488": 1737558545000, "1505": 1738157680000, "1514": 1738404847000, "1546": 1738662755000, "1571": 1739736734000, "1591": 1740050674000, "1662": 1742502414000, "1672": 1742645505000, "1687": 1742720064000, "1691": 1742765538000, "1709": 1743430242000, "1726": 1743837055000, "1766": 1744204166000, "1770": 1744216267000, "1776": 1744443333000, "1801": 1745143092000, "1933": 1749073294000, "1937": 1749076521000, "1960": 1749546769000, "1996": 1751538441000, "2029": 1753049108000}, "params": {"machine": ["ci-linux"], "python": ["3.13"], "django": ["5.1"], "djc-core-html-parser": [""], "branch": ["master"]}, "graph_param_list": [{"machine": "ci-linux", "python": "3.13", "django": "5.1", "djc-core-html-parser": "", "branch": "master"}], "benchmarks": {"Components vs Django.peakmem_render_lg_first": {"code": "class DjangoComponentsVsDjangoTests:\n @benchmark(\n pretty_name=\"render - large - first render (mem)\",\n group_name=DJC_VS_DJ_GROUP,\n number=1,\n rounds=5,\n params={\n \"renderer\": [\"django\", \"django-components\"],\n },\n setup=lambda renderer: setup_templating_memory_benchmark(renderer, \"lg\", \"first\", \"isolated\"),\n )\n def peakmem_render_lg_first(self, renderer: TemplatingRenderer):\n do_render()\n\nsetup=lambda renderer: setup_templating_memory_benchmark(renderer, \"lg\", \"first\", \"isolated\"),", "name": "Components vs Django.peakmem_render_lg_first", "param_names": ["renderer"], "params": [["'django'", "'django-components'"]], "pretty_name": "render - large - first render (mem)", "type": "peakmemory", "unit": "bytes", "version": "301c396f017f45a5b3f71e85df58d15f54153fcfd951af7ef424641d4b31b528"}, "Components vs Django.peakmem_render_lg_subsequent": {"code": "class DjangoComponentsVsDjangoTests:\n @benchmark(\n pretty_name=\"render - large - second render (mem)\",\n group_name=DJC_VS_DJ_GROUP,\n number=1,\n rounds=5,\n params={\n \"renderer\": [\"django\", \"django-components\"],\n },\n setup=lambda renderer: setup_templating_memory_benchmark(renderer, \"lg\", \"subsequent\", \"isolated\"),\n )\n def peakmem_render_lg_subsequent(self, renderer: TemplatingRenderer):\n do_render()\n\nsetup=lambda renderer: setup_templating_memory_benchmark(renderer, \"lg\", \"subsequent\", \"isolated\"),", "name": "Components vs Django.peakmem_render_lg_subsequent", "param_names": ["renderer"], "params": [["'django'", "'django-components'"]], "pretty_name": "render - large - second render (mem)", "type": "peakmemory", "unit": "bytes", "version": "9a44e9999ef3ef42ea7e01323727490244febb43d66a87a4d8f88c6b8a133b8b"}, "Components vs Django.peakmem_render_sm_first": {"code": "class DjangoComponentsVsDjangoTests:\n @benchmark(\n pretty_name=\"render - small - first render (mem)\",\n group_name=DJC_VS_DJ_GROUP,\n number=1,\n rounds=5,\n params={\n \"renderer\": [\"django\", \"django-components\"],\n },\n setup=lambda renderer: setup_templating_memory_benchmark(renderer, \"sm\", \"first\", \"isolated\"),\n )\n def peakmem_render_sm_first(self, renderer: TemplatingRenderer):\n do_render()\n\nsetup=lambda renderer: setup_templating_memory_benchmark(renderer, \"sm\", \"first\", \"isolated\"),", "name": "Components vs Django.peakmem_render_sm_first", "param_names": ["renderer"], "params": [["'django'", "'django-components'"]], "pretty_name": "render - small - first render (mem)", "type": "peakmemory", "unit": "bytes", "version": "e93b7a5193681c883edf85bdb30b1bc0821263bf51033fdcee215b155085e036"}, "Components vs Django.peakmem_render_sm_subsequent": {"code": "class DjangoComponentsVsDjangoTests:\n @benchmark(\n pretty_name=\"render - small - second render (mem)\",\n group_name=DJC_VS_DJ_GROUP,\n number=1,\n rounds=5,\n params={\n \"renderer\": [\"django\", \"django-components\"],\n },\n setup=lambda renderer: setup_templating_memory_benchmark(renderer, \"sm\", \"subsequent\", \"isolated\"),\n )\n def peakmem_render_sm_subsequent(self, renderer: TemplatingRenderer):\n do_render()\n\nsetup=lambda renderer: setup_templating_memory_benchmark(renderer, \"sm\", \"subsequent\", \"isolated\"),", "name": "Components vs Django.peakmem_render_sm_subsequent", "param_names": ["renderer"], "params": [["'django'", "'django-components'"]], "pretty_name": "render - small - second render (mem)", "type": "peakmemory", "unit": "bytes", "version": "b46e0820b18950aa7cc5e61306ff3425b76b4da9dca42d64fae5b1d25c6c9026"}, "Components vs Django.timeraw_render_lg_first": {"code": "class DjangoComponentsVsDjangoTests:\n @benchmark(\n pretty_name=\"render - large - first render\",\n group_name=DJC_VS_DJ_GROUP,\n number=1,\n rounds=5,\n params={\n \"renderer\": [\"django\", \"django-components\"],\n },\n include_in_quick_benchmark=True,\n )\n def timeraw_render_lg_first(self, renderer: TemplatingRenderer):\n return prepare_templating_benchmark(renderer, \"lg\", \"first\", \"isolated\")", "min_run_count": 2, "name": "Components vs Django.timeraw_render_lg_first", "number": 1, "param_names": ["renderer"], "params": [["'django'", "'django-components'"]], "pretty_name": "render - large - first render", "repeat": 0, "rounds": 5, "sample_time": 0.01, "type": "time", "unit": "seconds", "version": "be3bf6236960046a028b6ea007aad28b2337fc2b906b8ce317a09a5d4f1a6193", "warmup_time": -1}, "Components vs Django.timeraw_render_lg_subsequent": {"code": "class DjangoComponentsVsDjangoTests:\n @benchmark(\n pretty_name=\"render - large - second render\",\n group_name=DJC_VS_DJ_GROUP,\n number=1,\n rounds=5,\n params={\n \"renderer\": [\"django\", \"django-components\"],\n },\n )\n def timeraw_render_lg_subsequent(self, renderer: TemplatingRenderer):\n return prepare_templating_benchmark(renderer, \"lg\", \"subsequent\", \"isolated\")", "min_run_count": 2, "name": "Components vs Django.timeraw_render_lg_subsequent", "number": 1, "param_names": ["renderer"], "params": [["'django'", "'django-components'"]], "pretty_name": "render - large - second render", "repeat": 0, "rounds": 5, "sample_time": 0.01, "type": "time", "unit": "seconds", "version": "b98221c11a0ee6e9de0778d416d31b9dd514a674d9017a2bb9b2fc1cd0f01920", "warmup_time": -1}, "Components vs Django.timeraw_render_sm_first": {"code": "class DjangoComponentsVsDjangoTests:\n @benchmark(\n pretty_name=\"render - small - first render\",\n group_name=DJC_VS_DJ_GROUP,\n number=1,\n rounds=5,\n params={\n \"renderer\": [\"django\", \"django-components\"],\n },\n )\n def timeraw_render_sm_first(self, renderer: TemplatingRenderer):\n return prepare_templating_benchmark(renderer, \"sm\", \"first\", \"isolated\")", "min_run_count": 2, "name": "Components vs Django.timeraw_render_sm_first", "number": 1, "param_names": ["renderer"], "params": [["'django'", "'django-components'"]], "pretty_name": "render - small - first render", "repeat": 0, "rounds": 5, "sample_time": 0.01, "type": "time", "unit": "seconds", "version": "f1fc17e4a31c71f4d9265f1122da52e7cf57addb4dfa02606e303b33d6431b9b", "warmup_time": -1}, "Components vs Django.timeraw_render_sm_subsequent": {"code": "class DjangoComponentsVsDjangoTests:\n @benchmark(\n pretty_name=\"render - small - second render\",\n group_name=DJC_VS_DJ_GROUP,\n number=1,\n rounds=5,\n params={\n \"renderer\": [\"django\", \"django-components\"],\n },\n )\n def timeraw_render_sm_subsequent(self, renderer: TemplatingRenderer):\n return prepare_templating_benchmark(renderer, \"sm\", \"subsequent\", \"isolated\")", "min_run_count": 2, "name": "Components vs Django.timeraw_render_sm_subsequent", "number": 1, "param_names": ["renderer"], "params": [["'django'", "'django-components'"]], "pretty_name": "render - small - second render", "repeat": 0, "rounds": 5, "sample_time": 0.01, "type": "time", "unit": "seconds", "version": "6fce1cd85a9344fee383b40a22f27862120b9488a628420625592dc14e0307d3", "warmup_time": -1}, "Components vs Django.timeraw_startup_lg": {"code": "class DjangoComponentsVsDjangoTests:\n @benchmark(\n pretty_name=\"startup - large\",\n group_name=DJC_VS_DJ_GROUP,\n number=1,\n rounds=5,\n params={\n \"renderer\": [\"django\", \"django-components\"],\n },\n )\n def timeraw_startup_lg(self, renderer: TemplatingRenderer):\n return prepare_templating_benchmark(renderer, \"lg\", \"startup\", \"isolated\")", "min_run_count": 2, "name": "Components vs Django.timeraw_startup_lg", "number": 1, "param_names": ["renderer"], "params": [["'django'", "'django-components'"]], "pretty_name": "startup - large", "repeat": 0, "rounds": 5, "sample_time": 0.01, "type": "time", "unit": "seconds", "version": "53151821c128ad0ecfb0707fff3146e1abd8d0bcfa301aa056b5d3fae3d793e2", "warmup_time": -1}, "Other.timeraw_import_time": {"code": "class OtherTests:\n @benchmark(\n pretty_name=\"import time\",\n group_name=OTHER_GROUP,\n number=1,\n rounds=5,\n )\n def timeraw_import_time(self):\n return prepare_templating_benchmark(\"django-components\", \"lg\", \"startup\", \"isolated\", imports_only=True)", "min_run_count": 2, "name": "Other.timeraw_import_time", "number": 1, "param_names": [], "params": [], "pretty_name": "import time", "repeat": 0, "rounds": 5, "sample_time": 0.01, "type": "time", "unit": "seconds", "version": "a0a1c1c0db22509410b946d0d4384b52ea4a09b47b6048d7d1cfb89b0c7fe5c3", "warmup_time": -1}, "isolated vs django modes.peakmem_render_lg_first": {"code": "class IsolatedVsDjangoContextModesTests:\n @benchmark(\n pretty_name=\"render - large - first render (mem)\",\n group_name=DJC_ISOLATED_VS_NON_GROUP,\n number=1,\n rounds=5,\n params={\n \"context_mode\": [\"isolated\", \"django\"],\n },\n setup=lambda context_mode: setup_templating_memory_benchmark(\n \"django-components\",\n \"lg\",\n \"first\",\n context_mode,\n ),\n )\n def peakmem_render_lg_first(self, context_mode: DjcContextMode):\n do_render()\n\nsetup=lambda context_mode: setup_templating_memory_benchmark(\n \"django-components\",\n \"lg\",\n \"first\",\n context_mode,\n),", "name": "isolated vs django modes.peakmem_render_lg_first", "param_names": ["context_mode"], "params": [["'isolated'", "'django'"]], "pretty_name": "render - large - first render (mem)", "type": "peakmemory", "unit": "bytes", "version": "c4bf0016d48d210f08b8db733b57c7dcba1cebbf548c458b93b86ace387067e9"}, "isolated vs django modes.peakmem_render_lg_subsequent": {"code": "class IsolatedVsDjangoContextModesTests:\n @benchmark(\n pretty_name=\"render - large - second render (mem)\",\n group_name=DJC_ISOLATED_VS_NON_GROUP,\n number=1,\n rounds=5,\n params={\n \"context_mode\": [\"isolated\", \"django\"],\n },\n setup=lambda context_mode: setup_templating_memory_benchmark(\n \"django-components\",\n \"lg\",\n \"subsequent\",\n context_mode,\n ),\n )\n def peakmem_render_lg_subsequent(self, context_mode: DjcContextMode):\n do_render()\n\nsetup=lambda context_mode: setup_templating_memory_benchmark(\n \"django-components\",\n \"lg\",\n \"subsequent\",\n context_mode,\n),", "name": "isolated vs django modes.peakmem_render_lg_subsequent", "param_names": ["context_mode"], "params": [["'isolated'", "'django'"]], "pretty_name": "render - large - second render (mem)", "type": "peakmemory", "unit": "bytes", "version": "65bb1b8586487197a79bb6073e4c71642877b845b6eb42d1bd32398299daffbf"}, "isolated vs django modes.peakmem_render_sm_first": {"code": "class IsolatedVsDjangoContextModesTests:\n @benchmark(\n pretty_name=\"render - small - first render (mem)\",\n group_name=DJC_ISOLATED_VS_NON_GROUP,\n number=1,\n rounds=5,\n params={\n \"context_mode\": [\"isolated\", \"django\"],\n },\n setup=lambda context_mode: setup_templating_memory_benchmark(\"django-components\", \"sm\", \"first\", context_mode),\n )\n def peakmem_render_sm_first(self, context_mode: DjcContextMode):\n do_render()\n\nsetup=lambda context_mode: setup_templating_memory_benchmark(\"django-components\", \"sm\", \"first\", context_mode),", "name": "isolated vs django modes.peakmem_render_sm_first", "param_names": ["context_mode"], "params": [["'isolated'", "'django'"]], "pretty_name": "render - small - first render (mem)", "type": "peakmemory", "unit": "bytes", "version": "c51b91fc583295776062822225e720b5ed71aef9c9288217c401c54283c62840"}, "isolated vs django modes.peakmem_render_sm_subsequent": {"code": "class IsolatedVsDjangoContextModesTests:\n @benchmark(\n pretty_name=\"render - small - second render (mem)\",\n group_name=DJC_ISOLATED_VS_NON_GROUP,\n number=1,\n rounds=5,\n params={\n \"context_mode\": [\"isolated\", \"django\"],\n },\n setup=lambda context_mode: setup_templating_memory_benchmark(\n \"django-components\",\n \"sm\",\n \"subsequent\",\n context_mode,\n ),\n )\n def peakmem_render_sm_subsequent(self, context_mode: DjcContextMode):\n do_render()\n\nsetup=lambda context_mode: setup_templating_memory_benchmark(\n \"django-components\",\n \"sm\",\n \"subsequent\",\n context_mode,\n),", "name": "isolated vs django modes.peakmem_render_sm_subsequent", "param_names": ["context_mode"], "params": [["'isolated'", "'django'"]], "pretty_name": "render - small - second render (mem)", "type": "peakmemory", "unit": "bytes", "version": "54d747fb8f40179b7ff3d2fc49eb195909ad1c880b5ef7b82f82742b27b67260"}, "isolated vs django modes.timeraw_render_lg_first": {"code": "class IsolatedVsDjangoContextModesTests:\n @benchmark(\n pretty_name=\"render - large - first render\",\n group_name=DJC_ISOLATED_VS_NON_GROUP,\n number=1,\n rounds=5,\n params={\n \"context_mode\": [\"isolated\", \"django\"],\n },\n )\n def timeraw_render_lg_first(self, context_mode: DjcContextMode):\n return prepare_templating_benchmark(\"django-components\", \"lg\", \"first\", context_mode)", "min_run_count": 2, "name": "isolated vs django modes.timeraw_render_lg_first", "number": 1, "param_names": ["context_mode"], "params": [["'isolated'", "'django'"]], "pretty_name": "render - large - first render", "repeat": 0, "rounds": 5, "sample_time": 0.01, "type": "time", "unit": "seconds", "version": "f94af83427c6346f88f8785a3cd2fc42415ac5a9fbbdb7de71d27e22e6a81699", "warmup_time": -1}, "isolated vs django modes.timeraw_render_lg_subsequent": {"code": "class IsolatedVsDjangoContextModesTests:\n @benchmark(\n pretty_name=\"render - large - second render\",\n group_name=DJC_ISOLATED_VS_NON_GROUP,\n number=1,\n rounds=5,\n params={\n \"context_mode\": [\"isolated\", \"django\"],\n },\n )\n def timeraw_render_lg_subsequent(self, context_mode: DjcContextMode):\n return prepare_templating_benchmark(\"django-components\", \"lg\", \"subsequent\", context_mode)", "min_run_count": 2, "name": "isolated vs django modes.timeraw_render_lg_subsequent", "number": 1, "param_names": ["context_mode"], "params": [["'isolated'", "'django'"]], "pretty_name": "render - large - second render", "repeat": 0, "rounds": 5, "sample_time": 0.01, "type": "time", "unit": "seconds", "version": "9f7c2fde6b33f0451a1794ed903c48d96cd7822f67da502cec36fe8e977c2414", "warmup_time": -1}, "isolated vs django modes.timeraw_render_sm_first": {"code": "class IsolatedVsDjangoContextModesTests:\n @benchmark(\n pretty_name=\"render - small - first render\",\n group_name=DJC_ISOLATED_VS_NON_GROUP,\n number=1,\n rounds=5,\n params={\n \"context_mode\": [\"isolated\", \"django\"],\n },\n )\n def timeraw_render_sm_first(self, context_mode: DjcContextMode):\n return prepare_templating_benchmark(\"django-components\", \"sm\", \"first\", context_mode)", "min_run_count": 2, "name": "isolated vs django modes.timeraw_render_sm_first", "number": 1, "param_names": ["context_mode"], "params": [["'isolated'", "'django'"]], "pretty_name": "render - small - first render", "repeat": 0, "rounds": 5, "sample_time": 0.01, "type": "time", "unit": "seconds", "version": "d15ca68909d7f1f43ff16863befb6f42681f17461417fc0069eefd6db3569296", "warmup_time": -1}, "isolated vs django modes.timeraw_render_sm_subsequent": {"code": "class IsolatedVsDjangoContextModesTests:\n @benchmark(\n pretty_name=\"render - small - second render\",\n group_name=DJC_ISOLATED_VS_NON_GROUP,\n number=1,\n rounds=5,\n params={\n \"context_mode\": [\"isolated\", \"django\"],\n },\n )\n def timeraw_render_sm_subsequent(self, context_mode: DjcContextMode):\n return prepare_templating_benchmark(\"django-components\", \"sm\", \"subsequent\", context_mode)", "min_run_count": 2, "name": "isolated vs django modes.timeraw_render_sm_subsequent", "number": 1, "param_names": ["context_mode"], "params": [["'isolated'", "'django'"]], "pretty_name": "render - small - second render", "repeat": 0, "rounds": 5, "sample_time": 0.01, "type": "time", "unit": "seconds", "version": "7444bc9516dd087e3f420349345eae991ad6941bbd22fce45265b18034b7cf77", "warmup_time": -1}, "isolated vs django modes.timeraw_startup_lg": {"code": "class IsolatedVsDjangoContextModesTests:\n @benchmark(\n pretty_name=\"startup - large\",\n group_name=DJC_ISOLATED_VS_NON_GROUP,\n number=1,\n rounds=5,\n params={\n \"context_mode\": [\"isolated\", \"django\"],\n },\n )\n def timeraw_startup_lg(self, context_mode: DjcContextMode):\n return prepare_templating_benchmark(\"django-components\", \"lg\", \"startup\", context_mode)", "min_run_count": 2, "name": "isolated vs django modes.timeraw_startup_lg", "number": 1, "param_names": ["context_mode"], "params": [["'isolated'", "'django'"]], "pretty_name": "startup - large", "repeat": 0, "rounds": 5, "sample_time": 0.01, "type": "time", "unit": "seconds", "version": "eabe311ebee4a15c5816617be12f00ec30376f7506bd668219e1c50bc897c134", "warmup_time": -1}}, "machines": {"ci-linux": {"machine": "ci-linux", "version": 1}}, "tags": {"0.100": 1125, "0.101": 1132, "0.102": 1179, "0.110": 1252, "0.111": 1270, "0.112": 1277, "0.113": 1282, "0.114": 1287, "0.115": 1312, "0.116": 1328, "0.117": 1337, "0.118": 1352, "0.119": 1361, "0.120": 1366, "0.121": 1381, "0.122": 1387, "0.123": 1392, "0.124": 1447, "0.125": 1488, "0.126": 1505, "0.127": 1514, "0.128": 1546, "0.129": 1571, "0.130": 1591, "0.131": 1662, "0.132": 1672, "0.133": 1687, "0.134": 1691, "0.135": 1709, "0.136": 1726, "0.137": 1766, "0.138": 1770, "0.139": 1776, "0.139.1": 1801, "0.140.0": 1933, "0.140.1": 1937, "0.141.0": 1960, "0.141.1": 1996, "0.141.2": 2029, "0.16": 250, "0.17": 268, "0.26.2": 508, "0.27": 550, "0.27.1": 552, "0.27.2": 564, "0.28.0": 575, "0.28.1": 577, "0.67": 845, "0.68": 855, "0.70": 867, "0.71": 884, "0.72": 887, "0.73": 889, "0.74": 891, "0.75": 898, "0.76": 902, "0.77": 904, "0.78": 908, "0.79": 910, "0.80": 912, "0.81": 930, "0.82": 935, "0.83": 940, "0.84": 942, "0.85": 956, "0.86": 958, "0.87": 960, "0.88": 965, "0.89": 978, "0.90": 980, "0.91": 982, "0.92": 986, "0.93": 1056, "0.94": 1058, "0.95": 1060, "0.96": 1089, "0.97": 1098, "0.18": 343, "0.22": 388, "0.21": 380, "0.20": 369, "0.19": 359, "0.24": 457, "0.23": 427, "0.25": 487, "0.26": 500, "0.26.1": 503, "0.26.3": 536, "0.28.2": 598, "0.28.3": 612, "0.29": 622, "0.30": 646, "0.31": 651, "0.32": 663, "0.33": 675, "0.34": 681, "0.34.1": 691, "0.35": 704, "0.37": 724, "0.50": 729, "0.51": 742, "0.52": 748, "0.60": 752, "0.61": 757, "0.62": 773, "0.63": 775, "0.64": 779, "0.65": 787, "0.66": 806}, "pages": [["", "Grid view", "Display as a agrid"], ["summarylist", "List view", "Display as a list"], ["regressions", "Show regressions", "Display information about recent regressions"]]} \ No newline at end of file +{"project": "django-components", "project_url": "/django-components/", "show_commit_url": "#", "hash_length": 8, "revision_to_hash": {"250": "45a18626d74b280aa05498aa380eba687010cc0f", "268": "c9f0068741871b24756045805aaab8fbf368601a", "343": "ed2cd57bdcc12bf390f42058061a6ed077e558b0", "359": "501a055fe21abb4c7ad9af1a3a1b42eea24afacf", "369": "1937d594100d0651b151c8edbe1189b5a88b358f", "380": "1d091f50999cca0fa8c7852da2ea71684eadda6d", "388": "f5c3f64c866d06dfa2435d1d18b936dddb9eb67c", "427": "24d9db39c3c55f5eb91c9ce2112ad22507ccdd60", "457": "9103eda2f4ed80f46ff03d215491009c5476b410", "487": "384ff79e0875ac3a64a2755010ef86ec09a090b5", "500": "c102019811586f40cb11952f283797ddee96de3c", "503": "a350ad1a869bb46c6bac093f54ac40ea85d8cd8f", "508": "16022429da16e459b8a1e6e9cd8ab41d95dcb59d", "536": "ea7beb518c435389d9daff7ea557eec9ddc2464e", "550": "2cfc7285e12677a54247e9998967081c0e031efc", "552": "fcbfae3c5f0611519636290ef99b25bc0a319825", "564": "316310e842f276fd43436b432781430bd255410b", "575": "e0a5c2a4bcf5e8f577e19333e3b719440c37b10b", "577": "c174aa9802cc73b5d8fef4b0c704de3fb68b1cbb", "598": "979781012532f18c147a570ff4441c65c7503b6f", "612": "9d7d0b40b9d3bbd8e5b754e3b1b20df982cdd184", "622": "24032ac2ea80627f0fdde88058a2c3fbcae0d3fe", "646": "4f1a8184465fc472995bc226bebd66c250d501f6", "651": "8ce649498ff63a64761c83cf713983b7e2f24b81", "663": "93facba53e050619a477fa214da89fccf118ec13", "675": "ea33e0db6c54486b67e2fa496ec1c3ec3de06ec7", "681": "6874b1531df0e8836000bbc76fcca5a3de42724a", "691": "9f4243232018708fdf330f0e922a09317c60234c", "704": "188a9dc7eef4c45ee4f87efa8a0d6728e94f210d", "724": "76a0cde3af7b3061127d149c138fbc78462a07fe", "729": "c932f28cb4840dc45d2d26b4d927c1480459272f", "742": "7058f05e0415965ddd162d0ba663c5106e7ffb66", "748": "95d6eacb5c03a611f92cd9a6e254cea7e0ce57eb", "752": "d512cfb0fec8a42ab58d2f106047fc4c0ec65427", "757": "04160f4e0b2ec4d901d6724c34ed8df883363064", "773": "20847b978b3ddb5979489fbb4bd8e971b9b16fbf", "775": "ae5cda9f727454a077ab16c51a237fec076bd442", "779": "cd791caa572c9acd6d56445c04d6c9b55a50c602", "787": "274be104789e31955f88e26f14c89ed648f25448", "806": "c3a80b729049b5ea1b4799e742e4100a7640efab", "845": "0abb5aa63ff0396328ef4dfdc2e78e872671f135", "855": "e4e787b29dc9cd2cf35ad02f22bad6fa15a7211c", "867": "e346c07298b268d9212fcf93d132968e69824730", "884": "2316f79dff66260b7a9fe91effb55c74524deca0", "887": "085c60a8c96442d9fd4f72d66a7eb295e7cfb2d9", "889": "ba86cee578490df944ad167674db32182b8bbf7b", "891": "dd292b03508b7c03b2ad4f9fb9c17dec747845ba", "898": "badffdda3538a8082137453c757509ed4f035a3e", "902": "c07f0e634121ced0119bb665ed544ca4447c416b", "904": "8bbe81d7171ec3512f250927653d8454c7ff005e", "908": "881c36219a45581086da35a17d3715ee0698ca88", "910": "9bfb50b8f27f7ff521226109ab30426633f6b514", "912": "3a7d5355cfa5d37641a4c80ee9fd2423cea10c1b", "930": "09a720009767f45bebcfa48f3587219c03082601", "935": "a4b4905bee778a51f9a99a042ce14ed2424cc9fb", "940": "31257a475dcfdacaaeb408f59ea92b736a668815", "942": "d47927054c820ecf3f9f97a62f03dfbb5496a11b", "956": "fbbbf6c694b8213832fc127ee8a3e31872308aff", "958": "d819f3ff491866abaeb9a7dbba6a6ca3c21da9f8", "960": "c202c5a901106392ccdde49100211182c986eca5", "965": "7bbfcf7565159d92de41bb0d738b7878d78f4533", "978": "b89c09aa5f13903b1d056c70afbfd327f0ed6362", "980": "03af25aad6841b6edb56c925d2599817e08ceb44", "982": "5cb649fae62a42e525c1ea9fb74d7838886cc1a8", "986": "f97717cdb35eaadb78b1f468728b1bd386e742d8", "1056": "b26a2011380c959bfc98043821f6b4aa337a281d", "1058": "8c5b088c31b7166932e18739f882c2eef632f3a4", "1060": "682bfc42397c0bdbeb1a2b6ccabb8aca89686d4f", "1089": "8f13a641ac096e93a0464f048a4fa53e591bb8db", "1098": "30d04fe1b053e6c5de0b6f34a7758a627517be8c", "1125": "f7846b9c0ae7a8fd0b7f6edf664316e485455e76", "1132": "a3d66586b19b7e2aacbf793edfba20bcd9858f4a", "1179": "0064de9c78db5eccc7c498e2a6d4c3c5ffa745ec", "1252": "d093bfb05212555e14c5cd46c94b0ba057cbeceb", "1270": "c0a4fd5f685d694218b583b2d0a3e8417925d53a", "1277": "2a4b0f52894d5d0bb8d325d6096a3950286db541", "1282": "5a23101038d7085959087b2352e71590eafe9529", "1287": "ce3305a5fff095e990707de851f85bc27120596c", "1312": "cdc830fca3bdd98669e0510841536be14d1bd728", "1328": "468a593a472c35379fe7567918e8a534b2d53748", "1337": "2f14e8e0908657459909c6338106e561edc5d0f4", "1352": "a5659691d0f947643ce6542b7f09075e3f931646", "1361": "aaeba99f54b206baed072ffd0572035ddf5118a7", "1366": "6813c9d7aa4acfb04df9665651a2864d04bbe8ba", "1381": "6681fc0085fdb4b76cb74c1bbf20d44fa22f40fe", "1387": "6bb73bd8afd350db84889efc09b74255cea08979", "1392": "c76f8198dd497b34735fc17a0f7a678bdd811a3f", "1447": "3bbd4326e6c1bfb4a02039e16021a3f720910308", "1488": "914576e68133bc6ec356f3918016c45691ed3534", "1505": "3d187d7abad80f8464bd70dfba847d27a8e173db", "1514": "e105500350a320dfccf36fc19cad7421d38c3736", "1546": "61515b34540d27311fc3286b50212c1e314ce39e", "1571": "691443a0a821eb1a02f9b42ad0e32bcd71d94943", "1591": "dcd4203eeadafc5d500b4b72c5cf04f1fe7317e7", "1662": "d0a42a2698f2ba21e7ab2dec750c5dbadeda0db5", "1672": "2037ed20b7252cc52008e69bdd3d8e095ad6ea08", "1687": "2472c2ad338a23fba015d4d9816cb62d1325455f", "1691": "42818ad6ffb47bd650d8a379b84c3d48394f9f77", "1709": "a6455d70f6c28ddbd4be8e58902f6cbc101e5ff3", "1726": "fdd29baa65e9ef78eb24a0ad2ca0b5d7c624dad3", "1766": "1319a95627493fc0745b5af0600af2dc8c5117f9", "1770": "07f747d70500bbe3e135725b0e1b102815ab9416", "1776": "ad402fc619922b6d2edf1e99b7082d2a58632076", "1801": "4c909486069f3c3c8ee7915239174f820f081da4"}, "revision_to_date": {"250": 1630912817000, "268": 1631273531000, "343": 1654029104000, "359": 1657786741000, "369": 1657798498000, "380": 1658057264000, "388": 1658128984000, "427": 1670931380000, "457": 1673095465000, "487": 1675977478000, "500": 1678833725000, "503": 1678834812000, "508": 1679329468000, "536": 1680808865000, "550": 1681214445000, "552": 1681388770000, "564": 1682351069000, "575": 1684433482000, "577": 1684760359000, "598": 1693734426000, "612": 1695996512000, "622": 1696883504000, "646": 1702127213000, "651": 1702852887000, "663": 1705268832000, "675": 1705701480000, "681": 1706343740000, "691": 1706393538000, "704": 1707467055000, "724": 1708588716000, "729": 1708984309000, "742": 1709796107000, "748": 1710542375000, "752": 1711216985000, "757": 1711278671000, "773": 1711752109000, "775": 1711786713000, "779": 1712212506000, "787": 1712872453000, "806": 1713128940000, "845": 1713390260000, "855": 1713901297000, "867": 1714590581000, "884": 1714912319000, "887": 1715087715000, "889": 1715111097000, "891": 1715505986000, "898": 1716105516000, "902": 1716441018000, "904": 1716488913000, "908": 1717051130000, "910": 1717227227000, "912": 1717232115000, "930": 1718176374000, "935": 1718991590000, "940": 1720427258000, "942": 1720429478000, "956": 1722279535000, "958": 1722325182000, "960": 1722666822000, "965": 1722890429000, "978": 1723843975000, "980": 1723993321000, "982": 1724243667000, "986": 1724363119000, "1056": 1724732902000, "1058": 1724824521000, "1060": 1724924003000, "1089": 1725480929000, "1098": 1725655525000, "1125": 1726084755000, "1132": 1726347108000, "1179": 1728564427000, "1252": 1732525062000, "1270": 1732629701000, "1277": 1732644681000, "1282": 1732658332000, "1287": 1732726640000, "1312": 1733164405000, "1328": 1733471329000, "1337": 1733644953000, "1352": 1733834654000, "1361": 1734080521000, "1366": 1734245122000, "1381": 1734464187000, "1387": 1734600366000, "1392": 1734955786000, "1447": 1736287315000, "1488": 1737558545000, "1505": 1738157680000, "1514": 1738404847000, "1546": 1738662755000, "1571": 1739736734000, "1591": 1740050674000, "1662": 1742502414000, "1672": 1742645505000, "1687": 1742720064000, "1691": 1742765538000, "1709": 1743430242000, "1726": 1743837055000, "1766": 1744204166000, "1770": 1744216267000, "1776": 1744443333000, "1801": 1745143092000}, "params": {"machine": ["ci-linux"], "python": ["3.13"], "django": ["5.1"], "djc-core-html-parser": [""], "branch": ["master"]}, "graph_param_list": [{"machine": "ci-linux", "python": "3.13", "django": "5.1", "djc-core-html-parser": "", "branch": "master"}], "benchmarks": {"Components vs Django.peakmem_render_lg_first": {"code": "class DjangoComponentsVsDjangoTests:\n @benchmark(\n pretty_name=\"render - large - first render (mem)\",\n group_name=DJC_VS_DJ_GROUP,\n number=1,\n rounds=5,\n params={\n \"renderer\": [\"django\", \"django-components\"],\n },\n setup=lambda renderer: setup_templating_memory_benchmark(renderer, \"lg\", \"first\", \"isolated\"),\n )\n def peakmem_render_lg_first(self, renderer: TemplatingRenderer):\n do_render()\n\nsetup=lambda renderer: setup_templating_memory_benchmark(renderer, \"lg\", \"first\", \"isolated\"),", "name": "Components vs Django.peakmem_render_lg_first", "param_names": ["renderer"], "params": [["'django'", "'django-components'"]], "pretty_name": "render - large - first render (mem)", "type": "peakmemory", "unit": "bytes", "version": "301c396f017f45a5b3f71e85df58d15f54153fcfd951af7ef424641d4b31b528"}, "Components vs Django.peakmem_render_lg_subsequent": {"code": "class DjangoComponentsVsDjangoTests:\n @benchmark(\n pretty_name=\"render - large - second render (mem)\",\n group_name=DJC_VS_DJ_GROUP,\n number=1,\n rounds=5,\n params={\n \"renderer\": [\"django\", \"django-components\"],\n },\n setup=lambda renderer: setup_templating_memory_benchmark(renderer, \"lg\", \"subsequent\", \"isolated\"),\n )\n def peakmem_render_lg_subsequent(self, renderer: TemplatingRenderer):\n do_render()\n\nsetup=lambda renderer: setup_templating_memory_benchmark(renderer, \"lg\", \"subsequent\", \"isolated\"),", "name": "Components vs Django.peakmem_render_lg_subsequent", "param_names": ["renderer"], "params": [["'django'", "'django-components'"]], "pretty_name": "render - large - second render (mem)", "type": "peakmemory", "unit": "bytes", "version": "9a44e9999ef3ef42ea7e01323727490244febb43d66a87a4d8f88c6b8a133b8b"}, "Components vs Django.peakmem_render_sm_first": {"code": "class DjangoComponentsVsDjangoTests:\n @benchmark(\n pretty_name=\"render - small - first render (mem)\",\n group_name=DJC_VS_DJ_GROUP,\n number=1,\n rounds=5,\n params={\n \"renderer\": [\"django\", \"django-components\"],\n },\n setup=lambda renderer: setup_templating_memory_benchmark(renderer, \"sm\", \"first\", \"isolated\"),\n )\n def peakmem_render_sm_first(self, renderer: TemplatingRenderer):\n do_render()\n\nsetup=lambda renderer: setup_templating_memory_benchmark(renderer, \"sm\", \"first\", \"isolated\"),", "name": "Components vs Django.peakmem_render_sm_first", "param_names": ["renderer"], "params": [["'django'", "'django-components'"]], "pretty_name": "render - small - first render (mem)", "type": "peakmemory", "unit": "bytes", "version": "e93b7a5193681c883edf85bdb30b1bc0821263bf51033fdcee215b155085e036"}, "Components vs Django.peakmem_render_sm_subsequent": {"code": "class DjangoComponentsVsDjangoTests:\n @benchmark(\n pretty_name=\"render - small - second render (mem)\",\n group_name=DJC_VS_DJ_GROUP,\n number=1,\n rounds=5,\n params={\n \"renderer\": [\"django\", \"django-components\"],\n },\n setup=lambda renderer: setup_templating_memory_benchmark(renderer, \"sm\", \"subsequent\", \"isolated\"),\n )\n def peakmem_render_sm_subsequent(self, renderer: TemplatingRenderer):\n do_render()\n\nsetup=lambda renderer: setup_templating_memory_benchmark(renderer, \"sm\", \"subsequent\", \"isolated\"),", "name": "Components vs Django.peakmem_render_sm_subsequent", "param_names": ["renderer"], "params": [["'django'", "'django-components'"]], "pretty_name": "render - small - second render (mem)", "type": "peakmemory", "unit": "bytes", "version": "b46e0820b18950aa7cc5e61306ff3425b76b4da9dca42d64fae5b1d25c6c9026"}, "Components vs Django.timeraw_render_lg_first": {"code": "class DjangoComponentsVsDjangoTests:\n @benchmark(\n pretty_name=\"render - large - first render\",\n group_name=DJC_VS_DJ_GROUP,\n number=1,\n rounds=5,\n params={\n \"renderer\": [\"django\", \"django-components\"],\n },\n include_in_quick_benchmark=True,\n )\n def timeraw_render_lg_first(self, renderer: TemplatingRenderer):\n return prepare_templating_benchmark(renderer, \"lg\", \"first\", \"isolated\")", "min_run_count": 2, "name": "Components vs Django.timeraw_render_lg_first", "number": 1, "param_names": ["renderer"], "params": [["'django'", "'django-components'"]], "pretty_name": "render - large - first render", "repeat": 0, "rounds": 5, "sample_time": 0.01, "type": "time", "unit": "seconds", "version": "be3bf6236960046a028b6ea007aad28b2337fc2b906b8ce317a09a5d4f1a6193", "warmup_time": -1}, "Components vs Django.timeraw_render_lg_subsequent": {"code": "class DjangoComponentsVsDjangoTests:\n @benchmark(\n pretty_name=\"render - large - second render\",\n group_name=DJC_VS_DJ_GROUP,\n number=1,\n rounds=5,\n params={\n \"renderer\": [\"django\", \"django-components\"],\n },\n )\n def timeraw_render_lg_subsequent(self, renderer: TemplatingRenderer):\n return prepare_templating_benchmark(renderer, \"lg\", \"subsequent\", \"isolated\")", "min_run_count": 2, "name": "Components vs Django.timeraw_render_lg_subsequent", "number": 1, "param_names": ["renderer"], "params": [["'django'", "'django-components'"]], "pretty_name": "render - large - second render", "repeat": 0, "rounds": 5, "sample_time": 0.01, "type": "time", "unit": "seconds", "version": "b98221c11a0ee6e9de0778d416d31b9dd514a674d9017a2bb9b2fc1cd0f01920", "warmup_time": -1}, "Components vs Django.timeraw_render_sm_first": {"code": "class DjangoComponentsVsDjangoTests:\n @benchmark(\n pretty_name=\"render - small - first render\",\n group_name=DJC_VS_DJ_GROUP,\n number=1,\n rounds=5,\n params={\n \"renderer\": [\"django\", \"django-components\"],\n },\n )\n def timeraw_render_sm_first(self, renderer: TemplatingRenderer):\n return prepare_templating_benchmark(renderer, \"sm\", \"first\", \"isolated\")", "min_run_count": 2, "name": "Components vs Django.timeraw_render_sm_first", "number": 1, "param_names": ["renderer"], "params": [["'django'", "'django-components'"]], "pretty_name": "render - small - first render", "repeat": 0, "rounds": 5, "sample_time": 0.01, "type": "time", "unit": "seconds", "version": "f1fc17e4a31c71f4d9265f1122da52e7cf57addb4dfa02606e303b33d6431b9b", "warmup_time": -1}, "Components vs Django.timeraw_render_sm_subsequent": {"code": "class DjangoComponentsVsDjangoTests:\n @benchmark(\n pretty_name=\"render - small - second render\",\n group_name=DJC_VS_DJ_GROUP,\n number=1,\n rounds=5,\n params={\n \"renderer\": [\"django\", \"django-components\"],\n },\n )\n def timeraw_render_sm_subsequent(self, renderer: TemplatingRenderer):\n return prepare_templating_benchmark(renderer, \"sm\", \"subsequent\", \"isolated\")", "min_run_count": 2, "name": "Components vs Django.timeraw_render_sm_subsequent", "number": 1, "param_names": ["renderer"], "params": [["'django'", "'django-components'"]], "pretty_name": "render - small - second render", "repeat": 0, "rounds": 5, "sample_time": 0.01, "type": "time", "unit": "seconds", "version": "6fce1cd85a9344fee383b40a22f27862120b9488a628420625592dc14e0307d3", "warmup_time": -1}, "Components vs Django.timeraw_startup_lg": {"code": "class DjangoComponentsVsDjangoTests:\n @benchmark(\n pretty_name=\"startup - large\",\n group_name=DJC_VS_DJ_GROUP,\n number=1,\n rounds=5,\n params={\n \"renderer\": [\"django\", \"django-components\"],\n },\n )\n def timeraw_startup_lg(self, renderer: TemplatingRenderer):\n return prepare_templating_benchmark(renderer, \"lg\", \"startup\", \"isolated\")", "min_run_count": 2, "name": "Components vs Django.timeraw_startup_lg", "number": 1, "param_names": ["renderer"], "params": [["'django'", "'django-components'"]], "pretty_name": "startup - large", "repeat": 0, "rounds": 5, "sample_time": 0.01, "type": "time", "unit": "seconds", "version": "53151821c128ad0ecfb0707fff3146e1abd8d0bcfa301aa056b5d3fae3d793e2", "warmup_time": -1}, "Other.timeraw_import_time": {"code": "class OtherTests:\n @benchmark(\n pretty_name=\"import time\",\n group_name=OTHER_GROUP,\n number=1,\n rounds=5,\n )\n def timeraw_import_time(self):\n return prepare_templating_benchmark(\"django-components\", \"lg\", \"startup\", \"isolated\", imports_only=True)", "min_run_count": 2, "name": "Other.timeraw_import_time", "number": 1, "param_names": [], "params": [], "pretty_name": "import time", "repeat": 0, "rounds": 5, "sample_time": 0.01, "type": "time", "unit": "seconds", "version": "a0a1c1c0db22509410b946d0d4384b52ea4a09b47b6048d7d1cfb89b0c7fe5c3", "warmup_time": -1}, "isolated vs django modes.peakmem_render_lg_first": {"code": "class IsolatedVsDjangoContextModesTests:\n @benchmark(\n pretty_name=\"render - large - first render (mem)\",\n group_name=DJC_ISOLATED_VS_NON_GROUP,\n number=1,\n rounds=5,\n params={\n \"context_mode\": [\"isolated\", \"django\"],\n },\n setup=lambda context_mode: setup_templating_memory_benchmark(\n \"django-components\",\n \"lg\",\n \"first\",\n context_mode,\n ),\n )\n def peakmem_render_lg_first(self, context_mode: DjcContextMode):\n do_render()\n\nsetup=lambda context_mode: setup_templating_memory_benchmark(\n \"django-components\",\n \"lg\",\n \"first\",\n context_mode,\n),", "name": "isolated vs django modes.peakmem_render_lg_first", "param_names": ["context_mode"], "params": [["'isolated'", "'django'"]], "pretty_name": "render - large - first render (mem)", "type": "peakmemory", "unit": "bytes", "version": "c4bf0016d48d210f08b8db733b57c7dcba1cebbf548c458b93b86ace387067e9"}, "isolated vs django modes.peakmem_render_lg_subsequent": {"code": "class IsolatedVsDjangoContextModesTests:\n @benchmark(\n pretty_name=\"render - large - second render (mem)\",\n group_name=DJC_ISOLATED_VS_NON_GROUP,\n number=1,\n rounds=5,\n params={\n \"context_mode\": [\"isolated\", \"django\"],\n },\n setup=lambda context_mode: setup_templating_memory_benchmark(\n \"django-components\",\n \"lg\",\n \"subsequent\",\n context_mode,\n ),\n )\n def peakmem_render_lg_subsequent(self, context_mode: DjcContextMode):\n do_render()\n\nsetup=lambda context_mode: setup_templating_memory_benchmark(\n \"django-components\",\n \"lg\",\n \"subsequent\",\n context_mode,\n),", "name": "isolated vs django modes.peakmem_render_lg_subsequent", "param_names": ["context_mode"], "params": [["'isolated'", "'django'"]], "pretty_name": "render - large - second render (mem)", "type": "peakmemory", "unit": "bytes", "version": "65bb1b8586487197a79bb6073e4c71642877b845b6eb42d1bd32398299daffbf"}, "isolated vs django modes.peakmem_render_sm_first": {"code": "class IsolatedVsDjangoContextModesTests:\n @benchmark(\n pretty_name=\"render - small - first render (mem)\",\n group_name=DJC_ISOLATED_VS_NON_GROUP,\n number=1,\n rounds=5,\n params={\n \"context_mode\": [\"isolated\", \"django\"],\n },\n setup=lambda context_mode: setup_templating_memory_benchmark(\"django-components\", \"sm\", \"first\", context_mode),\n )\n def peakmem_render_sm_first(self, context_mode: DjcContextMode):\n do_render()\n\nsetup=lambda context_mode: setup_templating_memory_benchmark(\"django-components\", \"sm\", \"first\", context_mode),", "name": "isolated vs django modes.peakmem_render_sm_first", "param_names": ["context_mode"], "params": [["'isolated'", "'django'"]], "pretty_name": "render - small - first render (mem)", "type": "peakmemory", "unit": "bytes", "version": "c51b91fc583295776062822225e720b5ed71aef9c9288217c401c54283c62840"}, "isolated vs django modes.peakmem_render_sm_subsequent": {"code": "class IsolatedVsDjangoContextModesTests:\n @benchmark(\n pretty_name=\"render - small - second render (mem)\",\n group_name=DJC_ISOLATED_VS_NON_GROUP,\n number=1,\n rounds=5,\n params={\n \"context_mode\": [\"isolated\", \"django\"],\n },\n setup=lambda context_mode: setup_templating_memory_benchmark(\n \"django-components\",\n \"sm\",\n \"subsequent\",\n context_mode,\n ),\n )\n def peakmem_render_sm_subsequent(self, context_mode: DjcContextMode):\n do_render()\n\nsetup=lambda context_mode: setup_templating_memory_benchmark(\n \"django-components\",\n \"sm\",\n \"subsequent\",\n context_mode,\n),", "name": "isolated vs django modes.peakmem_render_sm_subsequent", "param_names": ["context_mode"], "params": [["'isolated'", "'django'"]], "pretty_name": "render - small - second render (mem)", "type": "peakmemory", "unit": "bytes", "version": "54d747fb8f40179b7ff3d2fc49eb195909ad1c880b5ef7b82f82742b27b67260"}, "isolated vs django modes.timeraw_render_lg_first": {"code": "class IsolatedVsDjangoContextModesTests:\n @benchmark(\n pretty_name=\"render - large - first render\",\n group_name=DJC_ISOLATED_VS_NON_GROUP,\n number=1,\n rounds=5,\n params={\n \"context_mode\": [\"isolated\", \"django\"],\n },\n )\n def timeraw_render_lg_first(self, context_mode: DjcContextMode):\n return prepare_templating_benchmark(\"django-components\", \"lg\", \"first\", context_mode)", "min_run_count": 2, "name": "isolated vs django modes.timeraw_render_lg_first", "number": 1, "param_names": ["context_mode"], "params": [["'isolated'", "'django'"]], "pretty_name": "render - large - first render", "repeat": 0, "rounds": 5, "sample_time": 0.01, "type": "time", "unit": "seconds", "version": "f94af83427c6346f88f8785a3cd2fc42415ac5a9fbbdb7de71d27e22e6a81699", "warmup_time": -1}, "isolated vs django modes.timeraw_render_lg_subsequent": {"code": "class IsolatedVsDjangoContextModesTests:\n @benchmark(\n pretty_name=\"render - large - second render\",\n group_name=DJC_ISOLATED_VS_NON_GROUP,\n number=1,\n rounds=5,\n params={\n \"context_mode\": [\"isolated\", \"django\"],\n },\n )\n def timeraw_render_lg_subsequent(self, context_mode: DjcContextMode):\n return prepare_templating_benchmark(\"django-components\", \"lg\", \"subsequent\", context_mode)", "min_run_count": 2, "name": "isolated vs django modes.timeraw_render_lg_subsequent", "number": 1, "param_names": ["context_mode"], "params": [["'isolated'", "'django'"]], "pretty_name": "render - large - second render", "repeat": 0, "rounds": 5, "sample_time": 0.01, "type": "time", "unit": "seconds", "version": "9f7c2fde6b33f0451a1794ed903c48d96cd7822f67da502cec36fe8e977c2414", "warmup_time": -1}, "isolated vs django modes.timeraw_render_sm_first": {"code": "class IsolatedVsDjangoContextModesTests:\n @benchmark(\n pretty_name=\"render - small - first render\",\n group_name=DJC_ISOLATED_VS_NON_GROUP,\n number=1,\n rounds=5,\n params={\n \"context_mode\": [\"isolated\", \"django\"],\n },\n )\n def timeraw_render_sm_first(self, context_mode: DjcContextMode):\n return prepare_templating_benchmark(\"django-components\", \"sm\", \"first\", context_mode)", "min_run_count": 2, "name": "isolated vs django modes.timeraw_render_sm_first", "number": 1, "param_names": ["context_mode"], "params": [["'isolated'", "'django'"]], "pretty_name": "render - small - first render", "repeat": 0, "rounds": 5, "sample_time": 0.01, "type": "time", "unit": "seconds", "version": "d15ca68909d7f1f43ff16863befb6f42681f17461417fc0069eefd6db3569296", "warmup_time": -1}, "isolated vs django modes.timeraw_render_sm_subsequent": {"code": "class IsolatedVsDjangoContextModesTests:\n @benchmark(\n pretty_name=\"render - small - second render\",\n group_name=DJC_ISOLATED_VS_NON_GROUP,\n number=1,\n rounds=5,\n params={\n \"context_mode\": [\"isolated\", \"django\"],\n },\n )\n def timeraw_render_sm_subsequent(self, context_mode: DjcContextMode):\n return prepare_templating_benchmark(\"django-components\", \"sm\", \"subsequent\", context_mode)", "min_run_count": 2, "name": "isolated vs django modes.timeraw_render_sm_subsequent", "number": 1, "param_names": ["context_mode"], "params": [["'isolated'", "'django'"]], "pretty_name": "render - small - second render", "repeat": 0, "rounds": 5, "sample_time": 0.01, "type": "time", "unit": "seconds", "version": "7444bc9516dd087e3f420349345eae991ad6941bbd22fce45265b18034b7cf77", "warmup_time": -1}, "isolated vs django modes.timeraw_startup_lg": {"code": "class IsolatedVsDjangoContextModesTests:\n @benchmark(\n pretty_name=\"startup - large\",\n group_name=DJC_ISOLATED_VS_NON_GROUP,\n number=1,\n rounds=5,\n params={\n \"context_mode\": [\"isolated\", \"django\"],\n },\n )\n def timeraw_startup_lg(self, context_mode: DjcContextMode):\n return prepare_templating_benchmark(\"django-components\", \"lg\", \"startup\", context_mode)", "min_run_count": 2, "name": "isolated vs django modes.timeraw_startup_lg", "number": 1, "param_names": ["context_mode"], "params": [["'isolated'", "'django'"]], "pretty_name": "startup - large", "repeat": 0, "rounds": 5, "sample_time": 0.01, "type": "time", "unit": "seconds", "version": "eabe311ebee4a15c5816617be12f00ec30376f7506bd668219e1c50bc897c134", "warmup_time": -1}}, "machines": {"ci-linux": {"machine": "ci-linux", "version": 1}}, "tags": {"0.100": 1125, "0.101": 1132, "0.102": 1179, "0.110": 1252, "0.111": 1270, "0.112": 1277, "0.113": 1282, "0.114": 1287, "0.115": 1312, "0.116": 1328, "0.117": 1337, "0.118": 1352, "0.119": 1361, "0.120": 1366, "0.121": 1381, "0.122": 1387, "0.123": 1392, "0.124": 1447, "0.125": 1488, "0.126": 1505, "0.127": 1514, "0.128": 1546, "0.129": 1571, "0.130": 1591, "0.131": 1662, "0.132": 1672, "0.133": 1687, "0.134": 1691, "0.135": 1709, "0.136": 1726, "0.137": 1766, "0.138": 1770, "0.139": 1776, "0.139.1": 1801, "0.16": 250, "0.17": 268, "0.26.2": 508, "0.27": 550, "0.27.1": 552, "0.27.2": 564, "0.28.0": 575, "0.28.1": 577, "0.67": 845, "0.68": 855, "0.70": 867, "0.71": 884, "0.72": 887, "0.73": 889, "0.74": 891, "0.75": 898, "0.76": 902, "0.77": 904, "0.78": 908, "0.79": 910, "0.80": 912, "0.81": 930, "0.82": 935, "0.83": 940, "0.84": 942, "0.85": 956, "0.86": 958, "0.87": 960, "0.88": 965, "0.89": 978, "0.90": 980, "0.91": 982, "0.92": 986, "0.93": 1056, "0.94": 1058, "0.95": 1060, "0.96": 1089, "0.97": 1098, "0.18": 343, "0.22": 388, "0.21": 380, "0.20": 369, "0.19": 359, "0.24": 457, "0.23": 427, "0.25": 487, "0.26": 500, "0.26.1": 503, "0.26.3": 536, "0.28.2": 598, "0.28.3": 612, "0.29": 622, "0.30": 646, "0.31": 651, "0.32": 663, "0.33": 675, "0.34": 681, "0.34.1": 691, "0.35": 704, "0.37": 724, "0.50": 729, "0.51": 742, "0.52": 748, "0.60": 752, "0.61": 757, "0.62": 773, "0.63": 775, "0.64": 779, "0.65": 787, "0.66": 806}, "pages": [["", "Grid view", "Display as a agrid"], ["summarylist", "List view", "Display as a list"], ["regressions", "Show regressions", "Display information about recent regressions"]]} \ No newline at end of file diff --git a/docs/benchmarks/info.json b/docs/benchmarks/info.json index 032015bd..cc536bb4 100644 --- a/docs/benchmarks/info.json +++ b/docs/benchmarks/info.json @@ -1,4 +1,4 @@ { "asv-version": "0.6.4", - "timestamp": 1753049912703 + "timestamp": 1745143636166 } \ No newline at end of file diff --git a/docs/benchmarks/regressions.json b/docs/benchmarks/regressions.json index 0203f18b..ddd12532 100644 --- a/docs/benchmarks/regressions.json +++ b/docs/benchmarks/regressions.json @@ -1 +1 @@ -{"regressions": [["Components vs Django.timeraw_render_lg_subsequent('django')", "graphs/branch-master/django-5.1/djc-core-html-parser/machine-ci-linux/python-3.13/Components vs Django.timeraw_render_lg_subsequent.json", {}, 0, 0.04362213900003553, 0.03327357099999517, [[1691, 1709, 0.03327357099999517, 0.03723830100000214], [1801, 1937, 0.03723830100000214, 0.04362213900003553]]]]} \ No newline at end of file +{"regressions": [["Components vs Django.timeraw_render_lg_subsequent('django')", "graphs/branch-master/django-5.1/djc-core-html-parser/machine-ci-linux/python-3.13/Components vs Django.timeraw_render_lg_subsequent.json", {}, 0, 0.03723830100000214, 0.03327357099999517, [[1691, 1709, 0.03327357099999517, 0.03723830100000214]]], ["Components vs Django.timeraw_render_sm_subsequent('django')", "graphs/branch-master/django-5.1/djc-core-html-parser/machine-ci-linux/python-3.13/Components vs Django.timeraw_render_sm_subsequent.json", {}, 0, 0.00011641800000461444, 0.0001005780000014056, [[1691, 1709, 0.0001005780000014056, 0.00011641800000461444]]]]} \ No newline at end of file diff --git a/docs/benchmarks/regressions.xml b/docs/benchmarks/regressions.xml index 3e718e7e..3469b682 100644 --- a/docs/benchmarks/regressions.xml +++ b/docs/benchmarks/regressions.xml @@ -1,8 +1,8 @@ -tag:django-components.asv,1970-01-01:/cddbdcca8b398afd301fbfc73cc4d51103d4e3059c0e6b938d4c467ad3d1aa25Airspeed Velocitydjango-components performance regressions2025-06-04T22:41:21Ztag:django-components.asv,2025-06-04:/38b868a38890eb5bccfd51983abf3a15cedf2846ef6cf2452e941122dbde2bde17.14% Components vs Django.timeraw_render_lg_subsequent('django')2025-06-04T22:41:21Z<a href="index.html#Components vs Django.timeraw_render_lg_subsequent?p-renderer=%27django%27&commits=4c909486069f3c3c8ee7915239174f820f081da4-7b24b86f4a836c697acba926d9d6602afa45418d">17.14% regression</a> on 2025-06-04 22:35:21 in commits <a href="#4c909486069f3c3c8ee7915239174f820f081da4">4c909486...7b24b86f</a>.<br> - New value: 43.6ms, old value: 37.2ms.<br> - Latest value: 43.6ms (31.10% worse - than best value 33.3ms).tag:django-components.asv,2025-03-31:/7a13128cbc4d175ca09ebda40e8a303789275bd84b00a5d496cfa08a26ad2f8b11.92% Components vs Django.timeraw_render_lg_subsequent('django')2025-03-31T14:16:53Z<a href="index.html#Components vs Django.timeraw_render_lg_subsequent?p-renderer=%27django%27&commits=42818ad6ffb47bd650d8a379b84c3d48394f9f77-a6455d70f6c28ddbd4be8e58902f6cbc101e5ff3">11.92% regression</a> on 2025-03-31 14:10:42 in commits <a href="#42818ad6ffb47bd650d8a379b84c3d48394f9f77">42818ad6...a6455d70</a>.<br> +tag:django-components.asv,1970-01-01:/cddbdcca8b398afd301fbfc73cc4d51103d4e3059c0e6b938d4c467ad3d1aa25Airspeed Velocitydjango-components performance regressions2025-03-31T14:17:04Ztag:django-components.asv,2025-03-31:/3489e338e3aeb103ea646e0f8aee41043fa61c99d14c7b57d874c9ebc1c79b2215.75% Components vs Django.timeraw_render_sm_subsequent('django')2025-03-31T14:17:04Z<a href="index.html#Components vs Django.timeraw_render_sm_subsequent?p-renderer=%27django%27&commits=42818ad6ffb47bd650d8a379b84c3d48394f9f77-a6455d70f6c28ddbd4be8e58902f6cbc101e5ff3">15.75% regression</a> on 2025-03-31 14:10:42 in commits <a href="#42818ad6ffb47bd650d8a379b84c3d48394f9f77">42818ad6...a6455d70</a>.<br> + New value: 116μs, old value: 101μs.<br> + Latest value: 116μs (15.75% worse + than best value 101μs).tag:django-components.asv,2025-03-31:/7a13128cbc4d175ca09ebda40e8a303789275bd84b00a5d496cfa08a26ad2f8b11.92% Components vs Django.timeraw_render_lg_subsequent('django')2025-03-31T14:16:53Z<a href="index.html#Components vs Django.timeraw_render_lg_subsequent?p-renderer=%27django%27&commits=42818ad6ffb47bd650d8a379b84c3d48394f9f77-a6455d70f6c28ddbd4be8e58902f6cbc101e5ff3">11.92% regression</a> on 2025-03-31 14:10:42 in commits <a href="#42818ad6ffb47bd650d8a379b84c3d48394f9f77">42818ad6...a6455d70</a>.<br> New value: 37.2ms, old value: 33.3ms.<br> - Latest value: 43.6ms (31.10% worse + Latest value: 37.2ms (11.92% worse than best value 33.3ms). \ No newline at end of file diff --git a/docs/getting_started/adding_slots.md b/docs/getting_started/adding_slots.md index 9081e5c1..19687a79 100644 --- a/docs/getting_started/adding_slots.md +++ b/docs/getting_started/adding_slots.md @@ -134,7 +134,7 @@ Which will render as: {% endcomponent %} ``` -### 4. Wait, there's a bug +### 5. Wait, there's a bug There is a mistake in our code! `2024-12-13` is Friday, so that's fine. But if we updated the to `2024-12-14`, which is Saturday, our template from previous step would render this: @@ -289,8 +289,3 @@ each time: Moreover, slots are treated as part of the template - for example the CSS scoping (work in progress) is applied to the slot content too. - ---- - -So far we've rendered components using template tag. [Next, let’s explore other ways to render components ➡️] -(./rendering_components.md) diff --git a/docs/getting_started/components_in_templates.md b/docs/getting_started/components_in_templates.md index ae798a8d..cca78909 100644 --- a/docs/getting_started/components_in_templates.md +++ b/docs/getting_started/components_in_templates.md @@ -55,7 +55,7 @@ by calling `{% load component_tags %}` inside the template. like `{% component "calendar" / %}`. `ComponentRegistries` also make it possible to group and share components as standalone packages. - [Learn more here](../../concepts/advanced/component_libraries). + [Learn more here](../../concepts/advanced/authoring_component_libraries). !!! note diff --git a/docs/getting_started/parametrising_components.md b/docs/getting_started/parametrising_components.md index 7ebc3c0d..f0cab85d 100644 --- a/docs/getting_started/parametrising_components.md +++ b/docs/getting_started/parametrising_components.md @@ -220,6 +220,10 @@ the parametrized version of the component: ``` +--- + +Next, you will learn [how to use slots give your components even more flexibility ➡️](./adding_slots.md) + ### 5. Add defaults In our example, we've set the `extra_class` to default to `"text-blue"` by setting it in the @@ -254,7 +258,3 @@ class Calendar(Component): "extra_class": kwargs["extra_class"], # <--- changed } ``` - ---- - -Next, you will learn [how to use slots give your components even more flexibility ➡️](./adding_slots.md) diff --git a/docs/getting_started/rendering_components.md b/docs/getting_started/rendering_components.md index 72205149..1232ff30 100644 --- a/docs/getting_started/rendering_components.md +++ b/docs/getting_started/rendering_components.md @@ -160,7 +160,7 @@ def my_view(request): response_class = MyCustomResponse ``` -### 4. Rendering slots +### Rendering slots Slots content are automatically escaped by default to prevent XSS attacks. @@ -203,7 +203,7 @@ Calendar.render( [`format_html`](https://docs.djangoproject.com/en/5.2/ref/utils/#django.utils.html.format_html) and [`mark_safe`](https://docs.djangoproject.com/en/5.2/ref/utils/#django.utils.safestring.mark_safe). -### 5. Component views and URLs +### Component views and URLs For web applications, it's common to define endpoints that serve HTML content (AKA views). diff --git a/docs/getting_started/your_first_component.md b/docs/getting_started/your_first_component.md index 328c8737..21b403af 100644 --- a/docs/getting_started/your_first_component.md +++ b/docs/getting_started/your_first_component.md @@ -35,9 +35,8 @@ document.querySelector(".calendar").onclick = function () { ``` ```py title="calendar.py" -from django_components import Component, register +from django_components import Component -@register("calendar") class Calendar(Component): template_file = "calendar.html" js_file = "calendar.js" diff --git a/docs/overview/community.md b/docs/overview/community.md index 38a28394..75fe49a9 100644 --- a/docs/overview/community.md +++ b/docs/overview/community.md @@ -7,9 +7,9 @@ Please, before opening a new discussion, [check if similar discussion wasn't ope ## Community examples One of our goals with `django-components` is to make it easy to share components between projects -([see how to package components](../concepts/advanced/component_libraries.md)). +([see how to package components](../concepts/advanced/authoring_component_libraries.md)). If you have a set of components that you think would be useful to others, please open a pull request to add them to the list below. -- [django-htmx-components](https://github.com/iwanalabs/django-htmx-components): A set of components for use with [htmx](https://htmx.org/). +- [django-htmx-components](https://github.com/iwanalabs/django-htmx-components): A set of components for use with [htmx](https://htmx.org/). Try out the [live demo](https://dhc.iwanalabs.com/). - [djc-heroicons](https://pypi.org/project/djc-heroicons/): A component that renders icons from [Heroicons.com](https://heroicons.com/). diff --git a/docs/overview/welcome.md b/docs/overview/welcome.md index d703b048..6c16cbc6 100644 --- a/docs/overview/welcome.md +++ b/docs/overview/welcome.md @@ -18,9 +18,8 @@ A component in django-components can be as simple as a Django template and Pytho ``` ```py title="components/calendar/calendar.py" -from django_components import Component, register +from django_components import Component -@register("calendar") class Calendar(Component): template_file = "calendar.html" ``` @@ -47,9 +46,8 @@ document.querySelector(".calendar").onclick = () => { ``` ```py title="components/calendar/calendar.py" -from django_components import Component, register +from django_components import Component -@register("calendar") class Calendar(Component): template_file = "calendar.html" js_file = "calendar.js" diff --git a/docs/reference/.nav.yml b/docs/reference/.nav.yml index 42aab39b..dbea3cb1 100644 --- a/docs/reference/.nav.yml +++ b/docs/reference/.nav.yml @@ -1,16 +1,16 @@ # `.nav.yml` is provided by https://lukasgeiter.github.io/mkdocs-awesome-nav nav: - API: api.md - - CLI commands: commands.md + - Commands: commands.md - Components: components.md - Exceptions: exceptions.md + - Extension commands: extension_commands.md - Extension hooks: extension_hooks.md - - Extension commands API: extension_commands.md - - Extension URLs API: extension_urls.md + - Extension URLs: extension_urls.md - Settings: settings.md - Signals: signals.md - Tag formatters: tag_formatters.md - Template tags: template_tags.md - - Template variables: template_variables.md + - Template vars: template_vars.md - URLs: urls.md - Testing API: testing_api.md diff --git a/docs/reference/extension_commands.md b/docs/reference/extension_commands.md index 40a18b83..ba29d401 100644 --- a/docs/reference/extension_commands.md +++ b/docs/reference/extension_commands.md @@ -1,6 +1,6 @@ -# Extension commands API +# Extension commands Overview of all classes, functions, and other objects related to defining extension commands. diff --git a/docs/reference/extension_hooks.md b/docs/reference/extension_hooks.md index e9f95c07..43090eb0 100644 --- a/docs/reference/extension_hooks.md +++ b/docs/reference/extension_hooks.md @@ -148,42 +148,6 @@ name | type | description `name` | `str` | The name the component was registered under `registry` | [`ComponentRegistry`](../api#django_components.ComponentRegistry) | The registry the component was unregistered from -::: django_components.extension.ComponentExtension.on_css_loaded - options: - heading_level: 3 - show_root_heading: true - show_signature: true - separate_signature: true - show_symbol_type_heading: false - show_symbol_type_toc: false - show_if_no_docstring: true - show_labels: false - -**Available data:** - -name | type | description ---|--|-- -`component_cls` | [`Type[Component]`](../api#django_components.Component) | The Component class whose CSS was loaded -`content` | `str` | The CSS content (string) - -::: django_components.extension.ComponentExtension.on_js_loaded - options: - heading_level: 3 - show_root_heading: true - show_signature: true - separate_signature: true - show_symbol_type_heading: false - show_symbol_type_toc: false - show_if_no_docstring: true - show_labels: false - -**Available data:** - -name | type | description ---|--|-- -`component_cls` | [`Type[Component]`](../api#django_components.Component) | The Component class whose JS was loaded -`content` | `str` | The JS content (string) - ::: django_components.extension.ComponentExtension.on_registry_created options: heading_level: 3 @@ -243,44 +207,6 @@ name | type | description `slot_name` | `str` | The name of the `{% slot %}` tag `slot_node` | `SlotNode` | The node instance of the `{% slot %}` tag -::: django_components.extension.ComponentExtension.on_template_compiled - options: - heading_level: 3 - show_root_heading: true - show_signature: true - separate_signature: true - show_symbol_type_heading: false - show_symbol_type_toc: false - show_if_no_docstring: true - show_labels: false - -**Available data:** - -name | type | description ---|--|-- -`component_cls` | [`Type[Component]`](../api#django_components.Component) | The Component class whose template was loaded -`template` | `django.template.base.Template` | The compiled template object - -::: django_components.extension.ComponentExtension.on_template_loaded - options: - heading_level: 3 - show_root_heading: true - show_signature: true - separate_signature: true - show_symbol_type_heading: false - show_symbol_type_toc: false - show_if_no_docstring: true - show_labels: false - -**Available data:** - -name | type | description ---|--|-- -`component_cls` | [`Type[Component]`](../api#django_components.Component) | The Component class whose template was loaded -`content` | `str` | The template string -`name` | `Optional[str]` | The name of the template -`origin` | `Optional[django.template.base.Origin]` | The origin of the template - ## Objects ::: django_components.extension.OnComponentClassCreatedContext diff --git a/docs/reference/extension_urls.md b/docs/reference/extension_urls.md index 10570d2e..f651ceb7 100644 --- a/docs/reference/extension_urls.md +++ b/docs/reference/extension_urls.md @@ -1,6 +1,6 @@ -# Extension URLs API +# Extension URLs Overview of all classes, functions, and other objects related to defining extension URLs. diff --git a/docs/reference/template_tags.md b/docs/reference/template_tags.md index d5c9145f..b0fd167b 100644 --- a/docs/reference/template_tags.md +++ b/docs/reference/template_tags.md @@ -67,7 +67,7 @@ If you insert this tag multiple times, ALL JS scripts will be duplicately insert -See source code +See source code diff --git a/docs/reference/template_variables.md b/docs/reference/template_vars.md similarity index 100% rename from docs/reference/template_variables.md rename to docs/reference/template_vars.md diff --git a/docs/scripts/reference.py b/docs/scripts/reference.py index 28963a22..6f1ee7da 100644 --- a/docs/scripts/reference.py +++ b/docs/scripts/reference.py @@ -44,7 +44,6 @@ from pathlib import Path from textwrap import dedent from typing import Any, Dict, List, NamedTuple, Optional, Sequence, Tuple, Type, Union -from django.conf import settings from django.core.management.base import BaseCommand from django.urls import URLPattern, URLResolver @@ -466,13 +465,7 @@ def gen_reference_commands(): # Add link to source code module_abs_path = import_module(cmd_def_cls.__module__).__file__ module_rel_path = Path(module_abs_path).relative_to(Path.cwd()).as_posix() # type: ignore[arg-type] - - # NOTE: Raises `OSError` if the file is not found. - try: - obj_lineno = inspect.findsource(cmd_def_cls)[1] - except Exception: - obj_lineno = None - + obj_lineno = inspect.findsource(cmd_def_cls)[1] source_code_link = _format_source_code_html(module_rel_path, obj_lineno) # NOTE: For the commands we have to generate the markdown entries ourselves, @@ -531,7 +524,7 @@ def gen_reference_commands(): ) -def gen_reference_template_tags(): +def gen_reference_templatetags(): """ Generate documentation for all Django template tags defined by django-components, like `{% slot %}`, `{% component %}`, etc. @@ -544,7 +537,7 @@ def gen_reference_template_tags(): ] preface = "\n\n" - preface += (root / "docs/templates/reference_template_tags.md").read_text() + preface += (root / "docs/templates/reference_templatetags.md").read_text() out_file = root / "docs/reference/template_tags.md" out_file.parent.mkdir(parents=True, exist_ok=True) @@ -592,14 +585,14 @@ def gen_reference_template_tags(): ) -def gen_reference_template_variables(): +def gen_reference_templatevars(): """ Generate documentation for all variables that are available inside the component templates under the `{{ component_vars }}` variable, as defined by `ComponentVars`. """ preface = "\n\n" - preface += (root / "docs/templates/reference_template_variables.md").read_text() - out_file = root / "docs/reference/template_variables.md" + preface += (root / "docs/templates/reference_templatevars.md").read_text() + out_file = root / "docs/reference/template_vars.md" out_file.parent.mkdir(parents=True, exist_ok=True) with out_file.open("w", encoding="utf-8") as f: @@ -1106,13 +1099,6 @@ def _is_extension_url_api(obj: Any) -> bool: def gen_reference(): """The entrypoint to generate all the reference documentation.""" - - # Set up Django settings so we can import `extensions` - if not settings.configured: - settings.configure( - BASE_DIR=Path(__file__).parent.parent.parent, - ) - gen_reference_api() gen_reference_exceptions() gen_reference_components() @@ -1120,8 +1106,8 @@ def gen_reference(): gen_reference_tagformatters() gen_reference_urls() gen_reference_commands() - gen_reference_template_tags() - gen_reference_template_variables() + gen_reference_templatetags() + gen_reference_templatevars() gen_reference_signals() gen_reference_testing_api() gen_reference_extension_hooks() diff --git a/docs/templates/reference_extension_commands.md b/docs/templates/reference_extension_commands.md index 9d9c51ea..0df90645 100644 --- a/docs/templates/reference_extension_commands.md +++ b/docs/templates/reference_extension_commands.md @@ -1,4 +1,4 @@ -# Extension commands API +# Extension commands Overview of all classes, functions, and other objects related to defining extension commands. diff --git a/docs/templates/reference_extension_urls.md b/docs/templates/reference_extension_urls.md index eaa55135..10692b23 100644 --- a/docs/templates/reference_extension_urls.md +++ b/docs/templates/reference_extension_urls.md @@ -1,4 +1,4 @@ -# Extension URLs API +# Extension URLs Overview of all classes, functions, and other objects related to defining extension URLs. diff --git a/docs/templates/reference_template_tags.md b/docs/templates/reference_templatetags.md similarity index 100% rename from docs/templates/reference_template_tags.md rename to docs/templates/reference_templatetags.md diff --git a/docs/templates/reference_template_variables.md b/docs/templates/reference_templatevars.md similarity index 100% rename from docs/templates/reference_template_variables.md rename to docs/templates/reference_templatevars.md diff --git a/pyproject.toml b/pyproject.toml index 452cf567..45e6918d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "django_components" -version = "0.141.2" +version = "0.140.1" requires-python = ">=3.8, <4.0" description = "A way to create simple reusable template components in Django." keywords = ["django", "components", "css", "js", "html"] diff --git a/requirements-ci.in b/requirements-ci.in index 058ff96f..7b5e9b79 100644 --- a/requirements-ci.in +++ b/requirements-ci.in @@ -7,7 +7,7 @@ whitenoise asv # NOTE: pin virtualenv to <20.31 until asv fixes integration # See https://github.com/airspeed-velocity/asv/issues/1484 -virtualenv==20.33.0 +virtualenv==20.31.2 pytest-asyncio pytest-django typing-extensions>=4.12.2 diff --git a/requirements-ci.txt b/requirements-ci.txt index bcaeef9b..26fa6317 100644 --- a/requirements-ci.txt +++ b/requirements-ci.txt @@ -104,7 +104,7 @@ urllib3==2.2.3 # via # requests # types-requests -virtualenv==20.33.0 +virtualenv==20.31.2 # via # -r requirements-ci.in # asv diff --git a/requirements-dev.in b/requirements-dev.in index 2124b58d..4bff8d14 100644 --- a/requirements-dev.in +++ b/requirements-dev.in @@ -20,6 +20,6 @@ pygments-djc asv # NOTE: pin virtualenv to <20.31 until asv fixes integration # See https://github.com/airspeed-velocity/asv/issues/1484 -virtualenv==20.33.0 +virtualenv==20.31.2 typing-extensions>=4.12.2 pathspec \ No newline at end of file diff --git a/requirements-dev.txt b/requirements-dev.txt index ae78c53a..a728065e 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -30,7 +30,7 @@ colorama==0.4.6 # via tox distlib==0.3.9 # via virtualenv -django==4.2.23 +django==4.2.21 # via -r requirements-dev.in djc-core-html-parser==1.0.2 # via -r requirements-dev.in @@ -40,7 +40,7 @@ filelock==3.16.1 # via # tox # virtualenv -flake8==7.3.0 +flake8==7.2.0 # via # -r requirements-dev.in # flake8-pyproject @@ -64,7 +64,7 @@ json5==0.10.0 # via asv mccabe==0.7.0 # via flake8 -mypy==1.17.1 +mypy==1.16.0 # via -r requirements-dev.in mypy-extensions==1.0.0 # via @@ -97,11 +97,11 @@ pluggy==1.5.0 # tox pre-commit==4.2.0 # via -r requirements-dev.in -pycodestyle==2.14.0 +pycodestyle==2.13.0 # via flake8 pyee==12.0.0 # via playwright -pyflakes==3.4.0 +pyflakes==3.3.2 # via flake8 pygments==2.19.1 # via @@ -163,7 +163,7 @@ urllib3==2.2.3 # via # requests # types-requests -virtualenv==20.33.0 +virtualenv==20.31.2 # via # -r requirements-dev.in # asv diff --git a/requirements-docs.txt b/requirements-docs.txt index 635d0e02..e3dca646 100644 --- a/requirements-docs.txt +++ b/requirements-docs.txt @@ -24,7 +24,7 @@ # - djc-core-html-parser>=1.0 # -asgiref==3.9.1 +asgiref==3.8.1 # via django babel==2.17.0 # via @@ -32,13 +32,13 @@ babel==2.17.0 # mkdocs-material black==25.1.0 # via hatch.envs.docs -bracex==2.6 +bracex==2.5.post1 # via wcmatch cairocffi==1.7.1 # via cairosvg cairosvg==2.8.2 # via mkdocs-material -certifi==2025.8.3 +certifi==2025.4.26 # via requests cffi==1.17.1 # via cairocffi @@ -58,7 +58,7 @@ cssselect2==0.8.0 # via cairosvg defusedxml==0.7.1 # via cairosvg -django==4.2.23 +django==4.2.21 # via hatch.envs.docs djc-core-html-parser==1.0.2 # via hatch.envs.docs @@ -66,9 +66,9 @@ ghp-import==2.1.0 # via mkdocs gitdb==4.0.12 # via gitpython -gitpython==3.1.45 +gitpython==3.1.44 # via mkdocs-git-revision-date-localized-plugin -griffe==1.9.0 +griffe==1.7.3 # via mkdocstrings-python htmlmin2==0.1.13 # via mkdocs-minify-plugin @@ -86,14 +86,14 @@ jinja2==3.1.6 # mkdocstrings jsmin==3.0.1 # via mkdocs-minify-plugin -markdown==3.8.2 +markdown==3.8 # via # mkdocs # mkdocs-autorefs # mkdocs-material # mkdocstrings # pymdown-extensions -markdown-exec==1.11.0 +markdown-exec==1.10.3 # via hatch.envs.docs markupsafe==3.0.2 # via @@ -134,13 +134,13 @@ mkdocs-get-deps==0.2.0 # via # mkdocs # mkdocstrings -mkdocs-git-authors-plugin==0.10.0 +mkdocs-git-authors-plugin==0.9.5 # via hatch.envs.docs mkdocs-git-revision-date-localized-plugin==1.4.7 # via hatch.envs.docs -mkdocs-include-markdown-plugin==7.1.6 +mkdocs-include-markdown-plugin==7.1.5 # via hatch.envs.docs -mkdocs-material==9.6.15 +mkdocs-material==9.6.14 # via hatch.envs.docs mkdocs-material-extensions==1.3.1 # via mkdocs-material @@ -148,11 +148,11 @@ mkdocs-minify-plugin==0.8.0 # via hatch.envs.docs mkdocs-redirects==1.2.2 # via hatch.envs.docs -mkdocstrings==0.30.0 +mkdocstrings==0.29.1 # via # hatch.envs.docs # mkdocstrings-python -mkdocstrings-python==1.16.12 +mkdocstrings-python==1.16.11 # via hatch.envs.docs mypy-extensions==1.1.0 # via black @@ -166,7 +166,7 @@ pathspec==0.12.1 # via # black # mkdocs -pillow==11.3.0 +pillow==11.2.1 # via # cairosvg # mkdocs-material @@ -176,14 +176,14 @@ platformdirs==4.3.8 # mkdocs-get-deps pycparser==2.22 # via cffi -pygments==2.19.2 +pygments==2.19.1 # via # hatch.envs.docs # mkdocs-material # pygments-djc pygments-djc==1.0.1 # via hatch.envs.docs -pymdown-extensions==10.16.1 +pymdown-extensions==10.15 # via # hatch.envs.docs # markdown-exec @@ -206,9 +206,9 @@ pyyaml-env-tag==1.1 # via # mike # mkdocs -regex==2025.7.34 +regex==2024.11.6 # via mkdocs-material -requests==2.32.4 +requests==2.32.3 # via mkdocs-material six==1.17.0 # via python-dateutil @@ -220,17 +220,17 @@ tinycss2==1.4.0 # via # cairosvg # cssselect2 -urllib3==2.5.0 +urllib3==2.4.0 # via requests verspec==0.1.0 # via mike watchdog==6.0.0 # via mkdocs -wcmatch==10.1 +wcmatch==10.0 # via mkdocs-include-markdown-plugin webencodings==0.5.1 # via # cssselect2 # tinycss2 -zipp==3.23.0 +zipp==3.22.0 # via importlib-metadata diff --git a/src/django_components/app_settings.py b/src/django_components/app_settings.py index aa1a2d9f..53bfacc8 100644 --- a/src/django_components/app_settings.py +++ b/src/django_components/app_settings.py @@ -746,8 +746,8 @@ defaults = ComponentsSettings( # # Settings are loaded from Django settings only once, at `apps.py` in `ready()`. class InternalSettings: - def __init__(self) -> None: - self._settings: Optional[ComponentsSettings] = None + def __init__(self, settings: Optional[Dict[str, Any]] = None): + self._settings = ComponentsSettings(**settings) if settings else defaults def _load_settings(self) -> None: data = getattr(settings, "COMPONENTS", {}) @@ -786,11 +786,6 @@ class InternalSettings: tag_formatter=default(components_settings.tag_formatter, defaults.tag_formatter), # type: ignore[arg-type] ) - def _get_settings(self) -> ComponentsSettings: - if self._settings is None: - self._load_settings() - return cast(ComponentsSettings, self._settings) - def _prepare_extensions(self, new_settings: ComponentsSettings) -> List["ComponentExtension"]: extensions: Sequence[Union[Type["ComponentExtension"], str]] = default( new_settings.extensions, cast(List[str], defaults.extensions) @@ -800,7 +795,6 @@ class InternalSettings: from django_components.extensions.cache import CacheExtension from django_components.extensions.debug_highlight import DebugHighlightExtension from django_components.extensions.defaults import DefaultsExtension - from django_components.extensions.dependencies import DependenciesExtension from django_components.extensions.view import ViewExtension extensions = cast( @@ -808,7 +802,6 @@ class InternalSettings: [ CacheExtension, DefaultsExtension, - DependenciesExtension, ViewExtension, DebugHighlightExtension, ], @@ -860,73 +853,70 @@ class InternalSettings: return raw_value + # TODO REMOVE THE PROPERTIES BELOW? THEY NO LONGER SERVE ANY PURPOSE @property def AUTODISCOVER(self) -> bool: - return self._get_settings().autodiscover # type: ignore[return-value] + return self._settings.autodiscover # type: ignore[return-value] @property def CACHE(self) -> Optional[str]: - return self._get_settings().cache + return self._settings.cache @property def DIRS(self) -> Sequence[Union[str, PathLike, Tuple[str, str], Tuple[str, PathLike]]]: - return self._get_settings().dirs # type: ignore[return-value] + return self._settings.dirs # type: ignore[return-value] @property def APP_DIRS(self) -> Sequence[str]: - return self._get_settings().app_dirs # type: ignore[return-value] + return self._settings.app_dirs # type: ignore[return-value] @property def DEBUG_HIGHLIGHT_COMPONENTS(self) -> bool: - return self._get_settings().debug_highlight_components # type: ignore[return-value] + return self._settings.debug_highlight_components # type: ignore[return-value] @property def DEBUG_HIGHLIGHT_SLOTS(self) -> bool: - return self._get_settings().debug_highlight_slots # type: ignore[return-value] + return self._settings.debug_highlight_slots # type: ignore[return-value] @property def DYNAMIC_COMPONENT_NAME(self) -> str: - return self._get_settings().dynamic_component_name # type: ignore[return-value] + return self._settings.dynamic_component_name # type: ignore[return-value] @property def LIBRARIES(self) -> List[str]: - return self._get_settings().libraries # type: ignore[return-value] + return self._settings.libraries # type: ignore[return-value] @property def EXTENSIONS(self) -> List["ComponentExtension"]: - return self._get_settings().extensions # type: ignore[return-value] - - @property - def EXTENSIONS_DEFAULTS(self) -> Dict[str, Any]: - return self._get_settings().extensions_defaults # type: ignore[return-value] + return self._settings.extensions # type: ignore[return-value] @property def MULTILINE_TAGS(self) -> bool: - return self._get_settings().multiline_tags # type: ignore[return-value] + return self._settings.multiline_tags # type: ignore[return-value] @property def RELOAD_ON_FILE_CHANGE(self) -> bool: - return self._get_settings().reload_on_file_change # type: ignore[return-value] + return self._settings.reload_on_file_change # type: ignore[return-value] @property def TEMPLATE_CACHE_SIZE(self) -> int: - return self._get_settings().template_cache_size # type: ignore[return-value] + return self._settings.template_cache_size # type: ignore[return-value] @property def STATIC_FILES_ALLOWED(self) -> Sequence[Union[str, re.Pattern]]: - return self._get_settings().static_files_allowed # type: ignore[return-value] + return self._settings.static_files_allowed # type: ignore[return-value] @property def STATIC_FILES_FORBIDDEN(self) -> Sequence[Union[str, re.Pattern]]: - return self._get_settings().static_files_forbidden # type: ignore[return-value] + return self._settings.static_files_forbidden # type: ignore[return-value] @property def CONTEXT_BEHAVIOR(self) -> ContextBehavior: - return ContextBehavior(self._get_settings().context_behavior) + return ContextBehavior(self._settings.context_behavior) @property def TAG_FORMATTER(self) -> Union["TagFormatterABC", str]: - return self._get_settings().tag_formatter # type: ignore[return-value] + return self._settings.tag_formatter # type: ignore[return-value] app_settings = InternalSettings() diff --git a/src/django_components/apps.py b/src/django_components/apps.py index 15217168..3a5e4a91 100644 --- a/src/django_components/apps.py +++ b/src/django_components/apps.py @@ -4,7 +4,6 @@ from typing import Any from django.apps import AppConfig from django.template import Template -from django.template.loader_tags import IncludeNode from django.utils.autoreload import file_changed, trigger_reload @@ -19,13 +18,14 @@ class ComponentsConfig(AppConfig): from django_components.component_registry import registry from django_components.components.dynamic import DynamicComponent from django_components.extension import extensions - from django_components.util.django_monkeypatch import monkeypatch_include_node, monkeypatch_template_cls + from django_components.util.django_monkeypatch import monkeypatch_template_cls + + app_settings._load_settings() # NOTE: This monkeypatch is applied here, before Django processes any requests. # To make django-components work with django-debug-toolbar-template-profiler # See https://github.com/django-components/django-components/discussions/819 monkeypatch_template_cls(Template) - monkeypatch_include_node(IncludeNode) # Import modules set in `COMPONENTS.libraries` setting import_libraries() diff --git a/src/django_components/cache.py b/src/django_components/cache.py index 0b4c443d..a14954ed 100644 --- a/src/django_components/cache.py +++ b/src/django_components/cache.py @@ -1,4 +1,3 @@ -import sys from typing import Optional from django.core.cache import BaseCache, caches @@ -37,14 +36,9 @@ def get_component_media_cache() -> BaseCache: component_media_cache = LocMemCache( "django-components-media", { - # No max size nor timeout - # NOTE: Implementation of `BaseCache` coerces the `MAX_ENTRIES` value - # to `int()` so we use exact max size instead of `inf` or `None`. - # See https://github.com/django/django/blob/94ebcf8366d62f6360851b40e9c4dfe3f71d202f/django/core/cache/backends/base.py#L73 # noqa: E501 - "TIMEOUT": None, - "OPTIONS": { - "MAX_ENTRIES": sys.maxsize, - }, + "TIMEOUT": None, # No timeout + "MAX_ENTRIES": None, # No max size + "CULL_FREQUENCY": 3, }, ) diff --git a/src/django_components/commands/ext_run.py b/src/django_components/commands/ext_run.py index d1dd0a8a..af2825cf 100644 --- a/src/django_components/commands/ext_run.py +++ b/src/django_components/commands/ext_run.py @@ -19,11 +19,8 @@ from django_components.util.command import ComponentCommand def _gen_subcommands() -> List[Type[ComponentCommand]]: commands: List[Type[ComponentCommand]] = [] for extension in extensions.extensions: - if not extension.commands: - continue - ExtCommand = type( - "ExtRunSubcommand_" + extension.name, + "ExtCommand", (ComponentCommand,), { "name": extension.name, diff --git a/src/django_components/component.py b/src/django_components/component.py index b7245a1d..7caee9da 100644 --- a/src/django_components/component.py +++ b/src/django_components/component.py @@ -32,7 +32,7 @@ from django_components.component_media import ComponentMediaInput, ComponentMedi from django_components.component_registry import ComponentRegistry from django_components.component_registry import registry as registry_ from django_components.constants import COMP_ID_PREFIX -from django_components.context import _COMPONENT_CONTEXT_KEY, COMPONENT_IS_NESTED_KEY, make_isolated_context_copy +from django_components.context import _COMPONENT_CONTEXT_KEY, make_isolated_context_copy from django_components.dependencies import ( DependenciesStrategy, cache_component_css, @@ -2277,7 +2277,7 @@ class Component(metaclass=ComponentMeta): deps_strategy = cast(DependenciesStrategy, default(deps_strategy, "document")) - self.id = default(id, _gen_component_id, factory=True) # type: ignore[arg-type] + self.id = default(id, _gen_component_id, factory=True) self.name = _get_component_name(self.__class__, registered_name) self.registered_name: Optional[str] = registered_name self.args = default(args, []) @@ -2314,6 +2314,9 @@ class Component(metaclass=ComponentMeta): cls.class_id = hash_comp_cls(cls) comp_cls_id_mapping[cls.class_id] = cls + # Make sure that subclassed component will store it's own template, not the parent's. + cls._template = None + ALL_COMPONENTS.append(cached_ref(cls)) # type: ignore[arg-type] extensions._init_component_class(cls) extensions.on_component_class_created(OnComponentClassCreatedContext(cls)) @@ -3486,12 +3489,11 @@ class Component(metaclass=ComponentMeta): ) ) - # Cache component's JS and CSS scripts, in case they have been evicted from the cache. - cache_component_js(comp_cls, force=False) - cache_component_css(comp_cls, force=False) - - # Create JS/CSS scripts that will load the JS/CSS variables into the page. + # Process Component's JS and CSS + cache_component_js(comp_cls) js_input_hash = cache_component_js_vars(comp_cls, js_data) if js_data else None + + cache_component_css(comp_cls) css_input_hash = cache_component_css_vars(comp_cls, css_data) if css_data else None ############################################################################# @@ -3515,14 +3517,14 @@ class Component(metaclass=ComponentMeta): # Then we can simply apply `template_data` to the context in the same layer # where we apply `context_processor_data` and `component_vars`. with prepare_component_template(component, template_data) as template: - # Set `_DJC_COMPONENT_IS_NESTED` based on whether we're currently INSIDE + # Set `Template._djc_is_component_nested` based on whether we're currently INSIDE # the `{% extends %}` tag. # Part of fix for https://github.com/django-components/django-components/issues/508 # See django_monkeypatch.py if template is not None: - comp_is_nested = bool(context.render_context.get(BLOCK_CONTEXT_KEY)) # type: ignore[union-attr] - else: - comp_is_nested = False + template._djc_is_component_nested = bool( + context.render_context.get(BLOCK_CONTEXT_KEY) # type: ignore[union-attr] + ) # Capture the template name so we can print better error messages (currently used in slots) component_ctx.template_name = template.name if template else None @@ -3533,7 +3535,6 @@ class Component(metaclass=ComponentMeta): **component.context_processors_data, # Private context fields _COMPONENT_CONTEXT_KEY: render_id, - COMPONENT_IS_NESTED_KEY: comp_is_nested, # NOTE: Public API for variables accessible from within a component's template # See https://github.com/django-components/django-components/issues/280#issuecomment-2081180940 "component_vars": ComponentVars( @@ -3671,7 +3672,7 @@ class Component(metaclass=ComponentMeta): # ``` def _gen_component_renderer( self, - template: Optional[Template], + template: Template, context: Context, component_path: List[str], css_input_hash: Optional[str], @@ -3696,8 +3697,7 @@ class Component(metaclass=ComponentMeta): component.on_render_before(context, template) # Emit signal that the template is about to be rendered - if template is not None: - template_rendered.send(sender=template, template=template, context=context) + template_rendered.send(sender=template, template=template, context=context) # Get the component's HTML # To access the *final* output (with all its children rendered) from within `Component.on_render()`, diff --git a/src/django_components/component_media.py b/src/django_components/component_media.py index d3957c78..42442d83 100644 --- a/src/django_components/component_media.py +++ b/src/django_components/component_media.py @@ -27,12 +27,10 @@ from weakref import WeakKeyDictionary from django.contrib.staticfiles import finders from django.core.exceptions import ImproperlyConfigured from django.forms.widgets import Media as MediaCls -from django.template import Template from django.utils.safestring import SafeData from typing_extensions import TypeGuard -from django_components.extension import OnCssLoadedContext, OnJsLoadedContext, extensions -from django_components.template import ensure_unique_template, load_component_template +from django_components.template import load_component_template from django_components.util.loader import get_component_dirs, resolve_file from django_components.util.logger import logger from django_components.util.misc import flatten, get_import_path, get_module_info, is_glob @@ -45,7 +43,7 @@ T = TypeVar("T") # These are all the attributes that are handled by ComponentMedia and lazily-resolved -COMP_MEDIA_LAZY_ATTRS = ("media", "template", "template_file", "js", "js_file", "css", "css_file", "_template") +COMP_MEDIA_LAZY_ATTRS = ("media", "template", "template_file", "js", "js_file", "css", "css_file") # Sentinel value to indicate that a media attribute is not set. @@ -269,8 +267,6 @@ class ComponentMedia: js_file: Union[str, Unset, None] = UNSET css: Union[str, Unset, None] = UNSET css_file: Union[str, Unset, None] = UNSET - # Template instance that was loaded for this component - _template: Union[Template, Unset, None] = UNSET def __post_init__(self) -> None: for inlined_attr in ("template", "js", "css"): @@ -303,7 +299,6 @@ class ComponentMedia: def reset(self) -> None: self.__dict__.update(self._original.__dict__) self.resolved = False - self.resolved_relative_files = False # This metaclass is all about one thing - lazily resolving the media files. @@ -492,10 +487,6 @@ def _get_comp_cls_media(comp_cls: Type["Component"]) -> Any: if curr_cls in media_cache: continue - comp_media: Optional[ComponentMedia] = getattr(curr_cls, "_component_media", None) - if comp_media is not None and not comp_media.resolved: - _resolve_media(curr_cls, comp_media) - # Prepare base classes # NOTE: If the `Component.Media` class is explicitly set to `None`, then we should not inherit # from any parent classes. @@ -620,39 +611,20 @@ def _resolve_media(comp_cls: Type["Component"], comp_media: ComponentMedia) -> N # Effectively, even if the Component class defined `js_file` (or others), at "runtime" the `js` attribute # will be set to the content of the file. # So users can access `Component.js` even if they defined `Component.js_file`. - template_str, template_obj = _get_asset( + comp_media.template = _get_asset( comp_cls, comp_media, inlined_attr="template", file_attr="template_file", comp_dirs=comp_dirs, + type="template", + ) + comp_media.js = _get_asset( + comp_cls, comp_media, inlined_attr="js", file_attr="js_file", comp_dirs=comp_dirs, type="static" + ) + comp_media.css = _get_asset( + comp_cls, comp_media, inlined_attr="css", file_attr="css_file", comp_dirs=comp_dirs, type="static" ) - comp_media.template = template_str - - js_str, _ = _get_asset(comp_cls, comp_media, inlined_attr="js", file_attr="js_file", comp_dirs=comp_dirs) - comp_media.js = js_str - - css_str, _ = _get_asset(comp_cls, comp_media, inlined_attr="css", file_attr="css_file", comp_dirs=comp_dirs) - comp_media.css = css_str - - # If `Component.template` or `Component.template_file` were explicitly set on this class, - # then Template instance was already created. - # - # Otherwise, search for Template instance in parent classes, and make a copy of it. - if not isinstance(template_obj, Unset): - comp_media._template = template_obj - else: - parent_template = _get_comp_cls_attr(comp_cls, "_template") - - # One of base classes has set `template` or `template_file` to `None`, - # or none of the base classes had set `template` or `template_file` - if parent_template is None: - comp_media._template = parent_template - - # One of base classes has set `template` or `template_file` to string. - # Make a copy of the Template instance. - else: - comp_media._template = ensure_unique_template(comp_cls, parent_template) def _normalize_media(media: Type[ComponentMediaInput]) -> None: @@ -1001,10 +973,11 @@ def _find_component_dir_containing_file( def _get_asset( comp_cls: Type["Component"], comp_media: ComponentMedia, - inlined_attr: Literal["template", "js", "css"], - file_attr: Literal["template_file", "js_file", "css_file"], + inlined_attr: str, + file_attr: str, comp_dirs: List[Path], -) -> Tuple[Union[str, Unset, None], Union[Template, Unset, None]]: # Tuple of (content, Template) + type: Literal["template", "static"], +) -> Union[str, Unset, None]: """ In case of Component's JS or CSS, one can either define that as "inlined" or as a file. @@ -1037,7 +1010,7 @@ def _get_asset( # pass # ``` if asset_content is UNSET and asset_file is UNSET: - return UNSET, UNSET + return UNSET # Either file or content attr was set to `None` # ```py @@ -1058,7 +1031,7 @@ def _get_asset( if (asset_content in (UNSET, None) and asset_file is None) or ( asset_content is None and asset_file in (UNSET, None) ): - return None, None + return None # Received both inlined content and file name # ```py @@ -1088,68 +1061,42 @@ def _get_asset( # At this point we can tell that only EITHER `asset_content` OR `asset_file` is set. # If the content was inlined into the component (e.g. `Component.template = "..."`) - # then there's nothing to resolve. Use it as is. - if not isinstance(asset_content, Unset): - if asset_content is None: - return None, None + # then there's nothing to resolve. Return as is. + if asset_content is not UNSET: + return asset_content - content: str = asset_content + if asset_file is None: + return None - # If we got inlined `Component.template`, then create a Template instance from it - # to trigger the extension hooks that may modify the template string. - if inlined_attr == "template": - # NOTE: `load_component_template()` applies `on_template_loaded()` and `on_template_compiled()` hooks. - template = load_component_template(comp_cls, filepath=None, content=content) - return template.source, template + # The rest of the code assumes that we were given only a file name + asset_file = cast(str, asset_file) - # This else branch assumes that we were given a file name (possibly None) - # Load the contents of the file. - else: - if asset_file is None: - return None, None + if type == "template": + # NOTE: While we return on the "source" (plain string) of the template, + # by calling `load_component_template()`, we also cache the Template instance. + # So later in Component's `render_impl()`, we don't have to re-compile the Template. + template = load_component_template(comp_cls, asset_file) + return template.source - asset_file = cast(str, asset_file) + # For static files, we have a few options: + # 1. Check if the file is in one of the components' directories + full_path = resolve_file(asset_file, comp_dirs) - if inlined_attr == "template": - # NOTE: `load_component_template()` applies `on_template_loaded()` and `on_template_compiled()` hooks. - template = load_component_template(comp_cls, filepath=asset_file, content=None) - return template.source, template + # 2. If not, check if it's in the static files + if full_path is None: + full_path = finders.find(asset_file) - # Following code concerns with loading JS / CSS files. - # Here we have a few options: - # - # 1. Check if the file is in one of the components' directories - full_path = resolve_file(asset_file, comp_dirs) + if full_path is None: + # NOTE: The short name, e.g. `js` or `css` is used in the error message for convenience + raise ValueError(f"Could not find {inlined_attr} file {asset_file}") - # 2. If not, check if it's in the static files - if full_path is None: - full_path = finders.find(asset_file) + # NOTE: Use explicit encoding for compat with Windows, see #1074 + asset_content = Path(full_path).read_text(encoding="utf8") - if full_path is None: - # NOTE: The short name, e.g. `js` or `css` is used in the error message for convenience - raise ValueError(f"Could not find {inlined_attr} file {asset_file}") + # TODO: Apply `extensions.on_js_preprocess()` and `extensions.on_css_preprocess()` + # NOTE: `on_template_preprocess()` is already applied inside `load_component_template()` - # NOTE: Use explicit encoding for compat with Windows, see #1074 - content = Path(full_path).read_text(encoding="utf8") - - # NOTE: `on_template_loaded()` is already applied inside `load_component_template()` - # but we still need to call extension hooks for JS / CSS content (whether inlined or not). - if inlined_attr == "js": - content = extensions.on_js_loaded( - OnJsLoadedContext( - component_cls=comp_cls, - content=content, - ) - ) - elif inlined_attr == "css": - content = extensions.on_css_loaded( - OnCssLoadedContext( - component_cls=comp_cls, - content=content, - ) - ) - - return content, None + return asset_content def is_set(value: Union[T, Unset, None]) -> TypeGuard[T]: diff --git a/src/django_components/context.py b/src/django_components/context.py index 71cb0c61..6dfe7cf6 100644 --- a/src/django_components/context.py +++ b/src/django_components/context.py @@ -11,7 +11,6 @@ from django.template import Context from django_components.util.misc import get_last_index _COMPONENT_CONTEXT_KEY = "_DJC_COMPONENT_CTX" -COMPONENT_IS_NESTED_KEY = "_DJC_COMPONENT_IS_NESTED" _STRATEGY_CONTEXT_KEY = "DJC_DEPS_STRATEGY" _INJECT_CONTEXT_KEY_PREFIX = "_DJC_INJECT__" diff --git a/src/django_components/dependencies.py b/src/django_components/dependencies.py index 4f4a8830..ffa06e7a 100644 --- a/src/django_components/dependencies.py +++ b/src/django_components/dependencies.py @@ -107,16 +107,13 @@ def _cache_script( cache.set(cache_key, script.strip()) -def cache_component_js(comp_cls: Type["Component"], force: bool) -> None: +def cache_component_js(comp_cls: Type["Component"]) -> None: """ Cache the content from `Component.js`. This is the common JS that's shared among all instances of the same component. So even if the component is rendered multiple times, this JS is loaded only once. """ - if not comp_cls.js or not is_nonempty_str(comp_cls.js): - return None - - if not force and _is_script_in_cache(comp_cls, "js", None): + if not comp_cls.js or not is_nonempty_str(comp_cls.js) or _is_script_in_cache(comp_cls, "js", None): return None _cache_script( @@ -170,16 +167,13 @@ def wrap_component_js(comp_cls: Type["Component"], content: str) -> str: return f"" -def cache_component_css(comp_cls: Type["Component"], force: bool) -> None: +def cache_component_css(comp_cls: Type["Component"]) -> None: """ Cache the content from `Component.css`. This is the common CSS that's shared among all instances of the same component. So even if the component is rendered multiple times, this CSS is loaded only once. """ - if not comp_cls.css or not is_nonempty_str(comp_cls.css): - return None - - if not force and _is_script_in_cache(comp_cls, "css", None): + if not comp_cls.css or not is_nonempty_str(comp_cls.css) or _is_script_in_cache(comp_cls, "css", None): return None _cache_script( diff --git a/src/django_components/extension.py b/src/django_components/extension.py index a95d9755..17750218 100644 --- a/src/django_components/extension.py +++ b/src/django_components/extension.py @@ -16,7 +16,7 @@ from typing import ( ) import django.urls -from django.template import Context, Origin, Template +from django.template import Context from django.urls import URLPattern, URLResolver, get_resolver, get_urlconf from django_components.app_settings import app_settings @@ -168,42 +168,6 @@ class OnSlotRenderedContext(NamedTuple): """The rendered result of the slot""" -@mark_extension_hook_api -class OnTemplateLoadedContext(NamedTuple): - component_cls: Type["Component"] - """The Component class whose template was loaded""" - content: str - """The template string""" - origin: Optional[Origin] - """The origin of the template""" - name: Optional[str] - """The name of the template""" - - -@mark_extension_hook_api -class OnTemplateCompiledContext(NamedTuple): - component_cls: Type["Component"] - """The Component class whose template was loaded""" - template: Template - """The compiled template object""" - - -@mark_extension_hook_api -class OnCssLoadedContext(NamedTuple): - component_cls: Type["Component"] - """The Component class whose CSS was loaded""" - content: str - """The CSS content (string)""" - - -@mark_extension_hook_api -class OnJsLoadedContext(NamedTuple): - component_cls: Type["Component"] - """The Component class whose JS was loaded""" - content: str - """The JS content (string)""" - - ################################################ # EXTENSIONS CORE ################################################ @@ -799,108 +763,6 @@ class ComponentExtension(metaclass=ExtensionMeta): """ pass - ########################## - # Template / JS / CSS hooks - ########################## - - def on_template_loaded(self, ctx: OnTemplateLoadedContext) -> Optional[str]: - """ - Called when a Component's template is loaded as a string. - - This hook runs only once per [`Component`](../api#django_components.Component) class and works for both - [`Component.template`](../api#django_components.Component.template) and - [`Component.template_file`](../api#django_components.Component.template_file). - - Use this hook to read or modify the template before it's compiled. - - To modify the template, return a new string from this hook. - - **Example:** - - ```python - from django_components import ComponentExtension, OnTemplateLoadedContext - - class MyExtension(ComponentExtension): - def on_template_loaded(self, ctx: OnTemplateLoadedContext) -> Optional[str]: - # Modify the template - return ctx.content.replace("Hello", "Hi") - ``` - """ - pass - - def on_template_compiled(self, ctx: OnTemplateCompiledContext) -> None: - """ - Called when a Component's template is compiled - into a [`Template`](https://docs.djangoproject.com/en/5.2/ref/templates/api/#django.template.Template) object. - - This hook runs only once per [`Component`](../api#django_components.Component) class and works for both - [`Component.template`](../api#django_components.Component.template) and - [`Component.template_file`](../api#django_components.Component.template_file). - - Use this hook to read or modify the template (in-place) after it's compiled. - - **Example:** - - ```python - from django_components import ComponentExtension, OnTemplateCompiledContext - - class MyExtension(ComponentExtension): - def on_template_compiled(self, ctx: OnTemplateCompiledContext) -> None: - print(f"Template origin: {ctx.template.origin.name}") - ``` - """ - pass - - def on_css_loaded(self, ctx: OnCssLoadedContext) -> Optional[str]: - """ - Called when a Component's CSS is loaded as a string. - - This hook runs only once per [`Component`](../api#django_components.Component) class and works for both - [`Component.css`](../api#django_components.Component.css) and - [`Component.css_file`](../api#django_components.Component.css_file). - - Use this hook to read or modify the CSS. - - To modify the CSS, return a new string from this hook. - - **Example:** - - ```python - from django_components import ComponentExtension, OnCssLoadedContext - - class MyExtension(ComponentExtension): - def on_css_loaded(self, ctx: OnCssLoadedContext) -> Optional[str]: - # Modify the CSS - return ctx.content.replace("Hello", "Hi") - ``` - """ - pass - - def on_js_loaded(self, ctx: OnJsLoadedContext) -> Optional[str]: - """ - Called when a Component's JS is loaded as a string. - - This hook runs only once per [`Component`](../api#django_components.Component) class and works for both - [`Component.js`](../api#django_components.Component.js) and - [`Component.js_file`](../api#django_components.Component.js_file). - - Use this hook to read or modify the JS. - - To modify the JS, return a new string from this hook. - - **Example:** - - ```python - from django_components import ComponentExtension, OnCssLoadedContext - - class MyExtension(ComponentExtension): - def on_js_loaded(self, ctx: OnJsLoadedContext) -> Optional[str]: - # Modify the JS - return ctx.content.replace("Hello", "Hi") - ``` - """ - pass - ########################## # Tags lifecycle hooks ########################## @@ -1047,7 +909,7 @@ class ExtensionManager: # - `MyExtensionBase` is the base class that the extension class inherits from. bases_list = [ext_base_class] - all_extensions_defaults = app_settings.EXTENSIONS_DEFAULTS or {} + all_extensions_defaults = app_settings._settings.extensions_defaults or {} extension_defaults = all_extensions_defaults.get(extension.name, None) if extension_defaults: # Create dummy class that holds the extension defaults @@ -1307,34 +1169,9 @@ class ExtensionManager: return ctx.result, ctx.error ########################## - # Template / JS / CSS hooks + # Tags lifecycle hooks ########################## - def on_template_loaded(self, ctx: OnTemplateLoadedContext) -> str: - for extension in self.extensions: - content = extension.on_template_loaded(ctx) - if content is not None: - ctx = ctx._replace(content=content) - return ctx.content - - def on_template_compiled(self, ctx: OnTemplateCompiledContext) -> None: - for extension in self.extensions: - extension.on_template_compiled(ctx) - - def on_css_loaded(self, ctx: OnCssLoadedContext) -> str: - for extension in self.extensions: - content = extension.on_css_loaded(ctx) - if content is not None: - ctx = ctx._replace(content=content) - return ctx.content - - def on_js_loaded(self, ctx: OnJsLoadedContext) -> str: - for extension in self.extensions: - content = extension.on_js_loaded(ctx) - if content is not None: - ctx = ctx._replace(content=content) - return ctx.content - def on_slot_rendered(self, ctx: OnSlotRenderedContext) -> Optional[str]: for extension in self.extensions: result = extension.on_slot_rendered(ctx) diff --git a/src/django_components/extensions/dependencies.py b/src/django_components/extensions/dependencies.py deleted file mode 100644 index 20c4d444..00000000 --- a/src/django_components/extensions/dependencies.py +++ /dev/null @@ -1,21 +0,0 @@ -from django_components.dependencies import cache_component_css, cache_component_js -from django_components.extension import ( - ComponentExtension, - OnComponentClassCreatedContext, -) - - -class DependenciesExtension(ComponentExtension): - """ - This extension adds a nested `Dependencies` class to each `Component`. - - This extension is automatically added to all components. - """ - - name = "dependencies" - - # Cache the component's JS and CSS scripts when the class is created, so that - # components' JS/CSS files are accessible even before having to render the component first. - def on_component_class_created(self, ctx: OnComponentClassCreatedContext) -> None: - cache_component_js(ctx.component_cls, force=True) - cache_component_css(ctx.component_cls, force=True) diff --git a/src/django_components/slots.py b/src/django_components/slots.py index 69c60b10..dfc653f0 100644 --- a/src/django_components/slots.py +++ b/src/django_components/slots.py @@ -28,7 +28,7 @@ from django.utils.html import conditional_escape from django.utils.safestring import SafeString, mark_safe from django_components.app_settings import ContextBehavior -from django_components.context import _COMPONENT_CONTEXT_KEY, _INJECT_CONTEXT_KEY_PREFIX, COMPONENT_IS_NESTED_KEY +from django_components.context import _COMPONENT_CONTEXT_KEY, _INJECT_CONTEXT_KEY_PREFIX from django_components.extension import OnSlotRenderedContext, extensions from django_components.node import BaseNode from django_components.perfutil.component import component_context_cache @@ -1585,6 +1585,8 @@ def _nodelist_to_slot( # and binds the context. template = Template("") template.nodelist = nodelist + # This allows the template to access current RenderContext layer. + template._djc_is_component_nested = True def render_func(ctx: SlotContext) -> SlotResult: context = ctx.context or Context() @@ -1637,12 +1639,10 @@ def _nodelist_to_slot( trace_component_msg("RENDER_NODELIST", component_name, component_id=None, slot_name=slot_name) - # NOTE 1: We wrap the slot nodelist in Template. However, we also override Django's `Template.render()` - # to call `render_dependencies()` on the results. So we need to set the strategy to `ignore` - # so that the dependencies are processed only once the whole component tree is rendered. - # NOTE 2: We also set `_DJC_COMPONENT_IS_NESTED` to `True` so that the template can access - # current RenderContext layer. - with context.push({"DJC_DEPS_STRATEGY": "ignore", COMPONENT_IS_NESTED_KEY: True}): + # We wrap the slot nodelist in Template. However, we also override Django's `Template.render()` + # to call `render_dependencies()` on the results. So we need to set the strategy to `ignore` + # so that the dependencies are processed only once the whole component tree is rendered. + with context.push({"DJC_DEPS_STRATEGY": "ignore"}): rendered = template.render(context) # After the rendering is done, remove the `extra_context` from the context stack diff --git a/src/django_components/template.py b/src/django_components/template.py index 6b6ebb24..24abce6d 100644 --- a/src/django_components/template.py +++ b/src/django_components/template.py @@ -1,6 +1,6 @@ import sys from contextlib import contextmanager -from typing import TYPE_CHECKING, Any, Dict, Generator, List, Optional, Type, Union +from typing import TYPE_CHECKING, Any, Dict, Generator, List, Optional, Type, Union, cast from weakref import ReferenceType, ref from django.core.exceptions import ImproperlyConfigured @@ -8,7 +8,7 @@ from django.template import Context, Origin, Template from django.template.loader import get_template as django_get_template from django_components.cache import get_template_cache -from django_components.util.django_monkeypatch import is_cls_patched +from django_components.util.django_monkeypatch import is_template_cls_patched from django_components.util.loader import get_component_dirs from django_components.util.logger import trace_component_msg from django_components.util.misc import get_import_path, get_module_info @@ -98,7 +98,7 @@ def prepare_component_template( yield template return - if not is_cls_patched(template): + if not is_template_cls_patched(template): raise RuntimeError( "Django-components received a Template instance which was not patched." "If you are using Django's Template class, check if you added django-components" @@ -170,45 +170,30 @@ def _maybe_bind_template(context: Context, template: Template) -> Generator[None loading_components: List["ComponentRef"] = [] -def load_component_template( - component_cls: Type["Component"], - filepath: Optional[str] = None, - content: Optional[str] = None, -) -> Template: - if filepath is None and content is None: - raise ValueError("Either `filepath` or `content` must be provided.") +def load_component_template(component_cls: Type["Component"], filepath: str) -> Template: + if component_cls._template is not None: + return component_cls._template loading_components.append(ref(component_cls)) - if filepath is not None: - # Use Django's `get_template()` to load the template file - template = _load_django_template(filepath) - template = ensure_unique_template(component_cls, template) + # Use Django's `get_template()` to load the template + template = _load_django_template(filepath) - elif content is not None: - template = _create_template_from_string(component_cls, content, is_component_template=True) - else: - raise ValueError("Received both `filepath` and `content`. These are mutually exclusive.") - - loading_components.pop() - - return template - - -# When loading a Template instance, it may be cached by Django / template loaders. -# In that case we want to make a copy of the template which would -# be owned by the current Component class. -# Thus each Component has it's own Template instance with their own Origins -# pointing to the correct Component class. -def ensure_unique_template(component_cls: Type["Component"], template: Template) -> Template: - # Use `template.origin.component_cls` to check if the template was cached by Django / template loaders. - if get_component_from_origin(template.origin) is None: - set_component_to_origin(template.origin, component_cls) - else: + # If template.origin.component_cls is already set, then this + # Template instance was cached by Django / template loaders. + # In that case we want to make a copy of the template which would + # be owned by the current Component class. + # Thus each Component has it's own Template instance with their own Origins + # pointing to the correct Component class. + if get_component_from_origin(template.origin) is not None: origin_copy = Origin(template.origin.name, template.origin.template_name, template.origin.loader) set_component_to_origin(origin_copy, component_cls) template = Template(template.source, origin=origin_copy, name=template.name, engine=template.engine) + component_cls._template = template + + loading_components.pop() + return template @@ -265,13 +250,24 @@ def _get_component_template(component: "Component") -> Optional[Template]: template = None template_string = template_sources["get_template"] elif component.template or component.template_file: - # If the template was loaded from `Component.template` or `Component.template_file`, - # then the Template instance was already created and cached in `Component._template`. + # If the template was loaded from `Component.template_file`, then the Template + # instance was already created and cached in `Component._template`. # # NOTE: This is important to keep in mind, because the implication is that we should # treat Templates AND their nodelists as IMMUTABLE. - template = component.__class__._component_media._template # type: ignore[attr-defined] - template_string = None + if component.__class__._template is not None: + template = component.__class__._template + template_string = None + # Otherwise user have set `Component.template` as string and we still need to + # create the instance. + else: + template = _create_template_from_string( + component, + # NOTE: We can't reach this branch if `Component.template` is None + cast(str, component.template), + is_component_template=True, + ) + template_string = None # No template else: template = None @@ -282,7 +278,7 @@ def _get_component_template(component: "Component") -> Optional[Template]: return template # Create the template from the string elif template_string is not None: - return _create_template_from_string(component.__class__, template_string) + return _create_template_from_string(component, template_string) # Otherwise, Component has no template - this is valid, as it may be instead rendered # via `Component.on_render()` @@ -290,7 +286,7 @@ def _get_component_template(component: "Component") -> Optional[Template]: def _create_template_from_string( - component: Type["Component"], + component: "Component", template_string: str, is_component_template: bool = False, ) -> Template: @@ -311,17 +307,18 @@ def _create_template_from_string( # ``` # # See https://docs.djangoproject.com/en/5.2/howto/custom-template-backend/#template-origin-api - _, _, module_filepath = get_module_info(component) + _, _, module_filepath = get_module_info(component.__class__) origin = Origin( - name=f"{module_filepath}::{component.__name__}", + name=f"{module_filepath}::{component.__class__.__name__}", template_name=None, loader=None, ) - set_component_to_origin(origin, component) + set_component_to_origin(origin, component.__class__) if is_component_template: template = Template(template_string, name=origin.template_name, origin=origin) + component.__class__._template = template else: # TODO_V1 - `cached_template()` won't be needed as there will be only 1 template per component # so we will be able to instead use `template_cache` to store the template diff --git a/src/django_components/util/django_monkeypatch.py b/src/django_components/util/django_monkeypatch.py index 722eba02..6ee295b0 100644 --- a/src/django_components/util/django_monkeypatch.py +++ b/src/django_components/util/django_monkeypatch.py @@ -1,28 +1,23 @@ from typing import Any, Optional, Type from django.template import Context, NodeList, Template -from django.template.base import Node, Origin, Parser -from django.template.loader_tags import IncludeNode +from django.template.base import Origin, Parser -from django_components.context import _COMPONENT_CONTEXT_KEY, _STRATEGY_CONTEXT_KEY, COMPONENT_IS_NESTED_KEY +from django_components.context import _COMPONENT_CONTEXT_KEY, _STRATEGY_CONTEXT_KEY from django_components.dependencies import COMPONENT_COMMENT_REGEX, render_dependencies -from django_components.extension import OnTemplateCompiledContext, OnTemplateLoadedContext, extensions from django_components.util.template_parser import parse_template # In some cases we can't work around Django's design, and need to patch the template class. def monkeypatch_template_cls(template_cls: Type[Template]) -> None: - if is_cls_patched(template_cls): - return - monkeypatch_template_init(template_cls) monkeypatch_template_compile_nodelist(template_cls) monkeypatch_template_render(template_cls) template_cls._djc_patched = True -# Patch `Template.__init__` to apply `on_template_loaded()` and `on_template_compiled()` -# extension hooks if the template belongs to a Component. +# Patch `Template.__init__` to apply `extensions.on_template_preprocess()` if the template +# belongs to a Component. def monkeypatch_template_init(template_cls: Type[Template]) -> None: original_init = template_cls.__init__ @@ -32,7 +27,6 @@ def monkeypatch_template_init(template_cls: Type[Template]) -> None: self: Template, template_string: Any, origin: Optional[Origin] = None, - name: Optional[str] = None, *args: Any, **kwargs: Any, ) -> None: @@ -62,27 +56,11 @@ def monkeypatch_template_init(template_cls: Type[Template]) -> None: component_cls = None if component_cls is not None: - template_string = str(template_string) - template_string = extensions.on_template_loaded( - OnTemplateLoadedContext( - component_cls=component_cls, - content=template_string, - origin=origin, - name=name, - ) - ) + # TODO - Apply extensions.on_template_preprocess() here. + # Then also test both cases when template as `template` or `template_file`. + pass - # Calling original `Template.__init__` should also compile the template into a Nodelist - # via `Template.compile_nodelist()`. - original_init(self, template_string, origin, name, *args, **kwargs) # type: ignore[misc] - - if component_cls is not None: - extensions.on_template_compiled( - OnTemplateCompiledContext( - component_cls=component_cls, - template=self, - ) - ) + original_init(self, template_string, origin, *args, **kwargs) # type: ignore[misc] template_cls.__init__ = __init__ @@ -132,7 +110,7 @@ def monkeypatch_template_compile_nodelist(template_cls: Type[Template]) -> None: def monkeypatch_template_render(template_cls: Type[Template]) -> None: # Modify `Template.render` to set `isolated_context` kwarg of `push_state` - # based on our custom `_DJC_COMPONENT_IS_NESTED`. + # based on our custom `Template._djc_is_component_nested`. # # Part of fix for https://github.com/django-components/django-components/issues/508 # @@ -147,11 +125,11 @@ def monkeypatch_template_render(template_cls: Type[Template]) -> None: # doesn't require the source to be parsed multiple times. User can pass extra args/kwargs, # and can modify the rendering behavior by overriding the `_render` method. # - # NOTE 2: Instead of setting `_DJC_COMPONENT_IS_NESTED` context key, alternatively we could + # NOTE 2: Instead of setting `Template._djc_is_component_nested`, alternatively we could # have passed the value to `monkeypatch_template_render` directly. However, we intentionally # did NOT do that, so the monkey-patched method is more robust, and can be e.g. copied # to other. - if is_cls_patched(template_cls): + if is_template_cls_patched(template_cls): # Do not patch if done so already. This helps us avoid RecursionError return @@ -159,12 +137,12 @@ def monkeypatch_template_render(template_cls: Type[Template]) -> None: def _template_render(self: Template, context: Context, *args: Any, **kwargs: Any) -> str: "Display stage -- can be called many times" # We parametrized `isolated_context`, which was `True` in the original method. - if COMPONENT_IS_NESTED_KEY not in context: + if not hasattr(self, "_djc_is_component_nested"): isolated_context = True else: # MUST be `True` for templates that are NOT import with `{% extends %}` tag, # and `False` otherwise. - isolated_context = not context[COMPONENT_IS_NESTED_KEY] + isolated_context = not self._djc_is_component_nested # This is original implementation, except we override `isolated_context`, # and we post-process the result with `render_dependencies()`. @@ -211,37 +189,5 @@ def monkeypatch_template_render(template_cls: Type[Template]) -> None: template_cls.render = _template_render -def monkeypatch_include_node(include_node_cls: Type[Node]) -> None: - if is_cls_patched(include_node_cls): - return - - monkeypatch_include_render(include_node_cls) - include_node_cls._djc_patched = True - - -def monkeypatch_include_render(include_node_cls: Type[Node]) -> None: - # Modify `IncludeNode.render()` (what renders `{% include %}` tag) so that the included - # template does NOT render the JS/CSS by itself. - # - # Instead, we want the parent template - # (which contains the `{% component %}` tag) to decide whether to render the JS/CSS. - # - # We achieve this by setting `DJC_DEPS_STRATEGY` to `ignore` in the context. - # - # Fix for https://github.com/django-components/django-components/issues/1296 - if is_cls_patched(include_node_cls): - # Do not patch if done so already. This helps us avoid RecursionError - return - - orig_include_render = include_node_cls.render - - # NOTE: This implementation is based on Django v5.1.3) - def _include_render(self: IncludeNode, context: Context, *args: Any, **kwargs: Any) -> str: - with context.update({_STRATEGY_CONTEXT_KEY: "ignore"}): - return orig_include_render(self, context, *args, **kwargs) - - include_node_cls.render = _include_render - - -def is_cls_patched(cls: Type[Any]) -> bool: - return getattr(cls, "_djc_patched", False) +def is_template_cls_patched(template_cls: Type[Template]) -> bool: + return getattr(template_cls, "_djc_patched", False) diff --git a/src/django_components/util/exception.py b/src/django_components/util/exception.py index dc57b7c3..b7dbb97b 100644 --- a/src/django_components/util/exception.py +++ b/src/django_components/util/exception.py @@ -25,7 +25,7 @@ def component_error_message(component_path: List[str]) -> Generator[None, None, if not components: orig_msg = str(err.args[0]) else: - orig_msg = str(err.args[0]).split("\n", 1)[-1] + orig_msg = err.args[0].split("\n", 1)[-1] else: orig_msg = str(err) diff --git a/tests/templates/component_inside_include_base.html b/tests/templates/test_cached_component_inside_include_base.html similarity index 58% rename from tests/templates/component_inside_include_base.html rename to tests/templates/test_cached_component_inside_include_base.html index 2711df5f..260d3df5 100644 --- a/tests/templates/component_inside_include_base.html +++ b/tests/templates/test_cached_component_inside_include_base.html @@ -1,4 +1,4 @@ -{% include "component_inside_include_sub.html" %} +{% include "test_cached_component_inside_include_sub.html" %} {% block content %} THIS_IS_IN_BASE_TEMPLATE_SO_SHOULD_BE_OVERRIDDEN {% endblock %} \ No newline at end of file diff --git a/tests/templates/component_inside_include_sub.html b/tests/templates/test_cached_component_inside_include_sub.html similarity index 100% rename from tests/templates/component_inside_include_sub.html rename to tests/templates/test_cached_component_inside_include_sub.html diff --git a/tests/test_autodiscover.py b/tests/test_autodiscover.py index 03aee405..142a0552 100644 --- a/tests/test_autodiscover.py +++ b/tests/test_autodiscover.py @@ -50,6 +50,8 @@ class TestImportLibraries: } ) def test_import_libraries(self): + # Ensure we start with a clean state + registry.clear() all_components = registry.all().copy() assert "single_file_component" not in all_components assert "multi_file_component" not in all_components @@ -78,6 +80,8 @@ class TestImportLibraries: } ) def test_import_libraries_map_modules(self): + # Ensure we start with a clean state + registry.clear() all_components = registry.all().copy() assert "single_file_component" not in all_components assert "multi_file_component" not in all_components diff --git a/tests/test_cache.py b/tests/test_cache.py index 58630a93..8a7b7bdd 100644 --- a/tests/test_cache.py +++ b/tests/test_cache.py @@ -1,3 +1,5 @@ +from django.core.cache.backends.locmem import LocMemCache + from django_components import Component, register from django_components.testing import djc_test from django_components.util.cache import LRUCache @@ -66,26 +68,16 @@ class TestCache: @djc_test class TestComponentMediaCache: - @djc_test( - components_settings={"cache": "test-cache"}, - django_settings={ - "CACHES": { - # See https://docs.djangoproject.com/en/5.2/topics/cache/#local-memory-caching - "test-cache": { - "BACKEND": "django.core.cache.backends.locmem.LocMemCache", - "LOCATION": "test-cache", - "TIMEOUT": None, # No timeout - "OPTIONS": { - "MAX_ENTRIES": 10_000, - }, - }, - }, - }, - ) + @djc_test(components_settings={"cache": "test-cache"}) def test_component_media_caching(self): - from django.core.cache import caches - - test_cache = caches["test-cache"] + test_cache = LocMemCache( + "test-cache", + { + "TIMEOUT": None, # No timeout + "MAX_ENTRIES": None, # No max size + "CULL_FREQUENCY": 3, + }, + ) @register("test_simple") class TestSimpleComponent(Component): @@ -116,6 +108,14 @@ class TestComponentMediaCache: def get_css_data(self, args, kwargs, slots, context): return {"color": "blue"} + # Register our test cache + from django.core.cache import caches + + caches["test-cache"] = test_cache + + # Render the components to trigger caching + TestMediaAndVarsComponent.render() + # Check that JS/CSS is cached for components that have them assert test_cache.has_key(f"__components:{TestMediaAndVarsComponent.class_id}:js") assert test_cache.has_key(f"__components:{TestMediaAndVarsComponent.class_id}:css") @@ -128,9 +128,6 @@ class TestComponentMediaCache: assert test_cache.get(f"__components:{TestMediaNoVarsComponent.class_id}:js").strip() == "console.log('Hello from JS');" # noqa: E501 assert test_cache.get(f"__components:{TestMediaNoVarsComponent.class_id}:css").strip() == ".novars-component { color: blue; }" # noqa: E501 - # Render the components to trigger caching of JS/CSS variables from `get_js_data` / `get_css_data` - TestMediaAndVarsComponent.render() - # Check that we cache JS / CSS scripts generated from `get_js_data` / `get_css_data` # NOTE: The hashes is generated from the data. js_vars_hash = "216ecc" diff --git a/tests/test_command_ext.py b/tests/test_command_ext.py index c43dc54a..9c461bed 100644 --- a/tests/test_command_ext.py +++ b/tests/test_command_ext.py @@ -103,7 +103,6 @@ class TestExtensionsListCommand: "===============\n" "cache \n" "defaults \n" - "dependencies \n" "view \n" "debug_highlight" ) @@ -122,7 +121,6 @@ class TestExtensionsListCommand: "===============\n" "cache \n" "defaults \n" - "dependencies \n" "view \n" "debug_highlight\n" "empty \n" @@ -143,7 +141,6 @@ class TestExtensionsListCommand: "===============\n" "cache \n" "defaults \n" - "dependencies \n" "view \n" "debug_highlight\n" "empty \n" @@ -164,7 +161,6 @@ class TestExtensionsListCommand: "===============\n" "cache \n" "defaults \n" - "dependencies \n" "view \n" "debug_highlight\n" "empty \n" @@ -183,7 +179,6 @@ class TestExtensionsListCommand: assert output.strip() == ( "cache \n" "defaults \n" - "dependencies \n" "view \n" "debug_highlight\n" "empty \n" @@ -211,16 +206,21 @@ class TestExtensionsRunCommand: output == dedent( f""" - usage: components ext run [-h] {{dummy}} ... + usage: components ext run [-h] {{cache,defaults,view,debug_highlight,empty,dummy}} ... Run a command added by an extension. {OPTIONS_TITLE}: - -h, --help show this help message and exit + -h, --help show this help message and exit subcommands: - {{dummy}} - dummy Run commands added by the 'dummy' extension. + {{cache,defaults,view,debug_highlight,empty,dummy}} + cache Run commands added by the 'cache' extension. + defaults Run commands added by the 'defaults' extension. + view Run commands added by the 'view' extension. + debug_highlight Run commands added by the 'debug_highlight' extension. + empty Run commands added by the 'empty' extension. + dummy Run commands added by the 'dummy' extension. """ ).lstrip() ) @@ -231,23 +231,19 @@ class TestExtensionsRunCommand: def test_run_command_ext_empty(self): out = StringIO() with patch("sys.stdout", new=out): - call_command("components", "ext", "run", "dummy") + call_command("components", "ext", "run", "empty") output = out.getvalue() assert ( output == dedent( f""" - usage: components ext run dummy [-h] {{dummy_cmd}} ... + usage: components ext run empty [-h] - Run commands added by the 'dummy' extension. + Run commands added by the 'empty' extension. {OPTIONS_TITLE}: - -h, --help show this help message and exit - - subcommands: - {{dummy_cmd}} - dummy_cmd Dummy command description. + -h, --help show this help message and exit """ ).lstrip() ) diff --git a/tests/test_component_cache.py b/tests/test_component_cache.py index b2ec2dc3..9e2c3fb3 100644 --- a/tests/test_component_cache.py +++ b/tests/test_component_cache.py @@ -219,7 +219,7 @@ class TestComponentCache: template = Template( """ - {% extends "component_inside_include_base.html" %} + {% extends "test_cached_component_inside_include_base.html" %} {% block content %} THIS_IS_IN_ACTUAL_TEMPLATE_SO_SHOULD_NOT_BE_OVERRIDDEN {% endblock %} diff --git a/tests/test_component_media.py b/tests/test_component_media.py index 3bce7716..7b3dd3a2 100644 --- a/tests/test_component_media.py +++ b/tests/test_component_media.py @@ -15,6 +15,7 @@ from django.utils.safestring import mark_safe from pytest_django.asserts import assertHTMLEqual, assertInHTML from django_components import Component, autodiscover, registry, render_dependencies, types +from django_components.component_media import UNSET from django_components.testing import djc_test from .testutils import setup_test_config @@ -45,7 +46,7 @@ class TestMainMedia: rendered = TestComponent.render() assertInHTML( - '
Content
', + '
Content
', rendered, ) assertInHTML( @@ -69,9 +70,6 @@ class TestMainMedia: assert TestComponent.css == ".html-css-only { color: blue; }" assert TestComponent.js == "console.log('HTML and JS only');" - assert isinstance(TestComponent._template, Template) - assert TestComponent._template.origin.component_cls is TestComponent - @djc_test( django_settings={ "STATICFILES_DIRS": [ @@ -129,9 +127,6 @@ class TestMainMedia: assert TestComponent.css == ".html-css-only {\n color: blue;\n}\n" assert TestComponent.js == 'console.log("JS file");\n' - assert isinstance(TestComponent._template, Template) - assert TestComponent._template.origin.component_cls is TestComponent - @djc_test( django_settings={ "STATICFILES_DIRS": [ @@ -156,9 +151,6 @@ class TestMainMedia: assert ".html-css-only {\n color: blue;\n}" in TestComponent.css # type: ignore[operator] assert 'console.log("HTML and JS only");' in TestComponent.js # type: ignore[operator] - assert isinstance(TestComponent._template, Template) - assert TestComponent._template.origin.component_cls is TestComponent - rendered = Template( """ {% load component_tags %} @@ -203,18 +195,13 @@ class TestMainMedia: class TestComponent(AppLvlCompComponent): pass - # NOTE: Currently the components' JS/CSS are loaded eagerly, to make the JS/CSS - # files available via endpoints. If that is no longer true, uncomment the - # following lines to test the lazy loading of the CSS. - # - # # Since this is a subclass, actual CSS is defined on the parent class, and thus - # # the corresponding ComponentMedia instance is also on the parent class. - # assert AppLvlCompComponent._component_media.css is UNSET # type: ignore[attr-defined] - # assert AppLvlCompComponent._component_media.css_file == "app_lvl_comp.css" # type: ignore[attr-defined] - # assert AppLvlCompComponent._component_media._template is UNSET # type: ignore[attr-defined] - # - # # Access the property to load the CSS - # _ = TestComponent.css + # NOTE: Since this is a subclass, actual CSS is defined on the parent class, and thus + # the corresponding ComponentMedia instance is also on the parent class. + assert AppLvlCompComponent._component_media.css is UNSET # type: ignore[attr-defined] + assert AppLvlCompComponent._component_media.css_file == "app_lvl_comp.css" # type: ignore[attr-defined] + + # Access the property to load the CSS + _ = TestComponent.css assert AppLvlCompComponent._component_media.css == (".html-css-only {\n" " color: blue;\n" "}\n") # type: ignore[attr-defined] assert AppLvlCompComponent._component_media.css_file == "app_lvl_comp/app_lvl_comp.css" # type: ignore[attr-defined] @@ -231,9 +218,6 @@ class TestMainMedia: assert AppLvlCompComponent._component_media.js == 'console.log("JS file");\n' # type: ignore[attr-defined] assert AppLvlCompComponent._component_media.js_file == "app_lvl_comp/app_lvl_comp.js" # type: ignore[attr-defined] - assert isinstance(AppLvlCompComponent._component_media._template, Template) # type: ignore[attr-defined] - assert AppLvlCompComponent._component_media._template.origin.component_cls is AppLvlCompComponent # type: ignore[attr-defined] - def test_html_variable_filtered(self): class FilteredComponent(Component): template: types.django_html = """ @@ -1053,121 +1037,73 @@ class TestSubclassingAttributes: class TestComp(Component): js = None js_file = None - template = None - template_file = None assert TestComp.js is None assert TestComp.js_file is None - assert TestComp.template is None - assert TestComp.template_file is None def test_mixing_none_and_non_none_raises(self): with pytest.raises( ImproperlyConfigured, - match=re.escape("Received non-empty value from both 'template' and 'template_file' in Component TestComp"), + match=re.escape("Received non-empty value from both 'js' and 'js_file' in Component TestComp"), ): class TestComp(Component): js = "console.log('hi')" js_file = None - template = "

hi

" - template_file = None def test_both_non_none_raises(self): with pytest.raises( ImproperlyConfigured, - match=re.escape("Received non-empty value from both 'template' and 'template_file' in Component TestComp"), + match=re.escape("Received non-empty value from both 'js' and 'js_file' in Component TestComp"), ): class TestComp(Component): js = "console.log('hi')" js_file = "file.js" - template = "

hi

" - template_file = "file.html" def test_parent_non_null_child_non_null(self): class ParentComp(Component): js = "console.log('parent')" - template = "

parent

" class TestComp(ParentComp): js = "console.log('child')" - template = "

child

" assert TestComp.js == "console.log('child')" assert TestComp.js_file is None - assert TestComp.template == "

child

" - assert TestComp.template_file is None - - assert isinstance(ParentComp._template, Template) - assert ParentComp._template.source == "

parent

" - assert ParentComp._template.origin.component_cls == ParentComp - - assert isinstance(TestComp._template, Template) - assert TestComp._template.source == "

child

" - assert TestComp._template.origin.component_cls == TestComp def test_parent_null_child_non_null(self): class ParentComp(Component): js = None - template = None class TestComp(ParentComp): js = "console.log('child')" - template = "

child

" assert TestComp.js == "console.log('child')" assert TestComp.js_file is None - assert TestComp.template == "

child

" - assert TestComp.template_file is None - - assert ParentComp._template is None - - assert isinstance(TestComp._template, Template) - assert TestComp._template.source == "

child

" - assert TestComp._template.origin.component_cls == TestComp def test_parent_non_null_child_null(self): class ParentComp(Component): js: Optional[str] = "console.log('parent')" - template: Optional[str] = "

parent

" class TestComp(ParentComp): js = None - template = None assert TestComp.js is None assert TestComp.js_file is None - assert TestComp.template is None - assert TestComp.template_file is None - - assert TestComp._template is None - - assert isinstance(ParentComp._template, Template) - assert ParentComp._template.source == "

parent

" - assert ParentComp._template.origin.component_cls == ParentComp def test_parent_null_child_null(self): class ParentComp(Component): js = None - template = None class TestComp(ParentComp): js = None - template = None assert TestComp.js is None assert TestComp.js_file is None - assert TestComp.template is None - assert TestComp.template_file is None - - assert TestComp._template is None - assert ParentComp._template is None def test_grandparent_non_null_parent_pass_child_pass(self): class GrandParentComp(Component): js = "console.log('grandparent')" - template = "

grandparent

" class ParentComp(GrandParentComp): pass @@ -1177,97 +1113,45 @@ class TestSubclassingAttributes: assert TestComp.js == "console.log('grandparent')" assert TestComp.js_file is None - assert TestComp.template == "

grandparent

" - assert TestComp.template_file is None - - assert isinstance(GrandParentComp._template, Template) - assert GrandParentComp._template.source == "

grandparent

" - assert GrandParentComp._template.origin.component_cls == GrandParentComp - - assert isinstance(ParentComp._template, Template) - assert ParentComp._template.source == "

grandparent

" - assert ParentComp._template.origin.component_cls == ParentComp - - assert isinstance(TestComp._template, Template) - assert TestComp._template.source == "

grandparent

" - assert TestComp._template.origin.component_cls == TestComp def test_grandparent_non_null_parent_null_child_pass(self): class GrandParentComp(Component): js: Optional[str] = "console.log('grandparent')" - template: Optional[str] = "

grandparent

" class ParentComp(GrandParentComp): js = None - template = None class TestComp(ParentComp): pass assert TestComp.js is None assert TestComp.js_file is None - assert TestComp.template is None - assert TestComp.template_file is None - - assert isinstance(GrandParentComp._template, Template) - assert GrandParentComp._template.source == "

grandparent

" - assert GrandParentComp._template.origin.component_cls == GrandParentComp - - assert ParentComp._template is None - assert TestComp._template is None def test_grandparent_non_null_parent_pass_child_non_null(self): class GrandParentComp(Component): js = "console.log('grandparent')" - template = "

grandparent

" class ParentComp(GrandParentComp): pass class TestComp(ParentComp): js = "console.log('child')" - template = "

child

" assert TestComp.js == "console.log('child')" assert TestComp.js_file is None - assert TestComp.template == "

child

" - assert TestComp.template_file is None - - assert isinstance(GrandParentComp._template, Template) - assert GrandParentComp._template.source == "

grandparent

" - assert GrandParentComp._template.origin.component_cls == GrandParentComp - - assert isinstance(ParentComp._template, Template) - assert ParentComp._template.source == "

grandparent

" - assert ParentComp._template.origin.component_cls == ParentComp - - assert isinstance(TestComp._template, Template) - assert TestComp._template.source == "

child

" - assert TestComp._template.origin.component_cls == TestComp def test_grandparent_null_parent_pass_child_non_null(self): class GrandParentComp(Component): js = None - template = None class ParentComp(GrandParentComp): pass class TestComp(ParentComp): js = "console.log('child')" - template = "

child

" assert TestComp.js == "console.log('child')" assert TestComp.js_file is None - assert TestComp.template == "

child

" - assert TestComp.template_file is None - - assert GrandParentComp._template is None - assert ParentComp._template is None - - assert isinstance(TestComp._template, Template) - assert TestComp._template.source == "

child

" - assert TestComp._template.origin.component_cls == TestComp @djc_test diff --git a/tests/test_extension.py b/tests/test_extension.py index cfd1c1cc..0f7da373 100644 --- a/tests/test_extension.py +++ b/tests/test_extension.py @@ -3,7 +3,7 @@ from typing import Any, Callable, Dict, List, cast import pytest from django.http import HttpRequest, HttpResponse -from django.template import Context, Origin, Template +from django.template import Context from django.test import Client from django_components import Component, Slot, SlotNode, register, registry @@ -23,15 +23,10 @@ from django_components.extension import ( OnComponentDataContext, OnComponentRenderedContext, OnSlotRenderedContext, - OnTemplateLoadedContext, - OnTemplateCompiledContext, - OnJsLoadedContext, - OnCssLoadedContext, ) from django_components.extensions.cache import CacheExtension from django_components.extensions.debug_highlight import DebugHighlightExtension from django_components.extensions.defaults import DefaultsExtension -from django_components.extensions.dependencies import DependenciesExtension from django_components.extensions.view import ViewExtension from django_components.testing import djc_test @@ -90,10 +85,6 @@ class DummyExtension(ComponentExtension): "on_component_data": [], "on_component_rendered": [], "on_slot_rendered": [], - "on_template_loaded": [], - "on_template_compiled": [], - "on_js_loaded": [], - "on_css_loaded": [], } urls = [ @@ -135,18 +126,6 @@ class DummyExtension(ComponentExtension): def on_slot_rendered(self, ctx: OnSlotRenderedContext) -> None: self.calls["on_slot_rendered"].append(ctx) - def on_template_loaded(self, ctx): - self.calls["on_template_loaded"].append(ctx) - - def on_template_compiled(self, ctx): - self.calls["on_template_compiled"].append(ctx) - - def on_js_loaded(self, ctx): - self.calls["on_js_loaded"].append(ctx) - - def on_css_loaded(self, ctx): - self.calls["on_css_loaded"].append(ctx) - class DummyNestedExtension(ComponentExtension): name = "test_nested_extension" @@ -203,30 +182,16 @@ def with_registry(on_created: Callable): on_created(registry) -class OverrideAssetExtension(ComponentExtension): - name = "override_asset_extension" - - def on_template_loaded(self, ctx): - return "OVERRIDDEN TEMPLATE" - - def on_js_loaded(self, ctx): - return "OVERRIDDEN JS" - - def on_css_loaded(self, ctx): - return "OVERRIDDEN CSS" - - @djc_test class TestExtension: @djc_test(components_settings={"extensions": [DummyExtension]}) def test_extensions_setting(self): - assert len(app_settings.EXTENSIONS) == 6 + assert len(app_settings.EXTENSIONS) == 5 assert isinstance(app_settings.EXTENSIONS[0], CacheExtension) assert isinstance(app_settings.EXTENSIONS[1], DefaultsExtension) - assert isinstance(app_settings.EXTENSIONS[2], DependenciesExtension) - assert isinstance(app_settings.EXTENSIONS[3], ViewExtension) - assert isinstance(app_settings.EXTENSIONS[4], DebugHighlightExtension) - assert isinstance(app_settings.EXTENSIONS[5], DummyExtension) + assert isinstance(app_settings.EXTENSIONS[2], ViewExtension) + assert isinstance(app_settings.EXTENSIONS[3], DebugHighlightExtension) + assert isinstance(app_settings.EXTENSIONS[4], DummyExtension) @djc_test(components_settings={"extensions": [DummyExtension]}) def test_access_component_from_extension(self): @@ -265,7 +230,7 @@ class TestExtension: class TestExtensionHooks: @djc_test(components_settings={"extensions": [DummyExtension]}) def test_component_class_lifecycle_hooks(self): - extension = cast(DummyExtension, app_settings.EXTENSIONS[5]) + extension = cast(DummyExtension, app_settings.EXTENSIONS[4]) assert len(extension.calls["on_component_class_created"]) == 0 assert len(extension.calls["on_component_class_deleted"]) == 0 @@ -297,7 +262,7 @@ class TestExtensionHooks: @djc_test(components_settings={"extensions": [DummyExtension]}) def test_registry_lifecycle_hooks(self): - extension = cast(DummyExtension, app_settings.EXTENSIONS[5]) + extension = cast(DummyExtension, app_settings.EXTENSIONS[4]) assert len(extension.calls["on_registry_created"]) == 0 assert len(extension.calls["on_registry_deleted"]) == 0 @@ -334,7 +299,7 @@ class TestExtensionHooks: return {"name": kwargs.get("name", "World")} registry.register("test_comp", TestComponent) - extension = cast(DummyExtension, app_settings.EXTENSIONS[5]) + extension = cast(DummyExtension, app_settings.EXTENSIONS[4]) # Verify on_component_registered was called assert len(extension.calls["on_component_registered"]) == 1 @@ -372,7 +337,7 @@ class TestExtensionHooks: test_slots = {"content": "Some content"} TestComponent.render(context=test_context, args=("arg1", "arg2"), kwargs={"name": "Test"}, slots=test_slots) - extension = cast(DummyExtension, app_settings.EXTENSIONS[5]) + extension = cast(DummyExtension, app_settings.EXTENSIONS[4]) # Verify on_component_input was called with correct args assert len(extension.calls["on_component_input"]) == 1 @@ -421,7 +386,7 @@ class TestExtensionHooks: slots={"content": "Some content"}, ) - extension = cast(DummyExtension, app_settings.EXTENSIONS[5]) + extension = cast(DummyExtension, app_settings.EXTENSIONS[4]) # Verify on_component_rendered was called with correct args assert len(extension.calls["on_component_rendered"]) == 1 @@ -450,7 +415,7 @@ class TestExtensionHooks: assert rendered == "Hello Some content!" - extension = cast(DummyExtension, app_settings.EXTENSIONS[5]) + extension = cast(DummyExtension, app_settings.EXTENSIONS[4]) # Verify on_slot_rendered was called with correct args assert len(extension.calls["on_slot_rendered"]) == 1 @@ -504,120 +469,6 @@ class TestExtensionHooks: rendered = TestComponent.render(args=(), kwargs={"name": "Test"}) assert rendered == "
OVERRIDDEN: Hello Test!
" - @djc_test(components_settings={"extensions": [DummyExtension]}) - def test_asset_hooks__inlined(self): - @register("test_comp_hooks") - class TestComponent(Component): - template = "Hello {{ name }}!" - js = "console.log('hi');" - css = "body { color: red; }" - - def get_template_data(self, args, kwargs, slots, context): - return {"name": kwargs.get("name", "World")} - - # Render the component to trigger all hooks - TestComponent.render(args=(), kwargs={"name": "Test"}) - - extension = cast(DummyExtension, app_settings.EXTENSIONS[5]) - - # on_template_loaded - assert len(extension.calls["on_template_loaded"]) == 1 - ctx1: OnTemplateLoadedContext = extension.calls["on_template_loaded"][0] - assert ctx1.component_cls == TestComponent - assert ctx1.content == "Hello {{ name }}!" - assert isinstance(ctx1.origin, Origin) - assert ctx1.origin.name.endswith("test_extension.py::TestComponent") - assert ctx1.name is None - - # on_template_compiled - assert len(extension.calls["on_template_compiled"]) == 1 - ctx2: OnTemplateCompiledContext = extension.calls["on_template_compiled"][0] - assert ctx2.component_cls == TestComponent - assert isinstance(ctx2.template, Template) - - # on_js_loaded - assert len(extension.calls["on_js_loaded"]) == 1 - ctx3: OnJsLoadedContext = extension.calls["on_js_loaded"][0] - assert ctx3.component_cls == TestComponent - assert ctx3.content == "console.log('hi');" - - # on_css_loaded - assert len(extension.calls["on_css_loaded"]) == 1 - ctx4: OnCssLoadedContext = extension.calls["on_css_loaded"][0] - assert ctx4.component_cls == TestComponent - assert ctx4.content == "body { color: red; }" - - @djc_test(components_settings={"extensions": [DummyExtension]}) - def test_asset_hooks__file(self): - @register("test_comp_hooks") - class TestComponent(Component): - template_file = "relative_file/relative_file.html" - js_file = "relative_file/relative_file.js" - css_file = "relative_file/relative_file.css" - - def get_template_data(self, args, kwargs, slots, context): - return {"name": kwargs.get("name", "World")} - - # Render the component to trigger all hooks - TestComponent.render(args=(), kwargs={"name": "Test"}) - - extension = cast(DummyExtension, app_settings.EXTENSIONS[5]) - - # on_template_loaded - # NOTE: The template file gets picked up by 'django.template.loaders.filesystem.Loader', - # as well as our own loader, so we get two calls here. - assert len(extension.calls["on_template_loaded"]) == 2 - ctx1: OnTemplateLoadedContext = extension.calls["on_template_loaded"][0] - assert ctx1.component_cls == TestComponent - assert ctx1.content == ( - '
\n' - ' {% csrf_token %}\n' - ' \n' - ' \n' - '
\n' - ) - assert isinstance(ctx1.origin, Origin) - assert ctx1.origin.name.endswith("relative_file.html") - assert ctx1.name == "relative_file/relative_file.html" - - # on_template_compiled - assert len(extension.calls["on_template_compiled"]) == 2 - ctx2: OnTemplateCompiledContext = extension.calls["on_template_compiled"][0] - assert ctx2.component_cls == TestComponent - assert isinstance(ctx2.template, Template) - - # on_js_loaded - assert len(extension.calls["on_js_loaded"]) == 1 - ctx3: OnJsLoadedContext = extension.calls["on_js_loaded"][0] - assert ctx3.component_cls == TestComponent - assert ctx3.content == 'console.log("JS file");\n' - - # on_css_loaded - assert len(extension.calls["on_css_loaded"]) == 1 - ctx4: OnCssLoadedContext = extension.calls["on_css_loaded"][0] - assert ctx4.component_cls == TestComponent - assert ctx4.content == ( - '.html-css-only {\n' - ' color: blue;\n' - '}\n' - ) - - @djc_test(components_settings={"extensions": [OverrideAssetExtension]}) - def test_asset_hooks_override(self): - @register("test_comp_override") - class TestComponent(Component): - template = "Hello {{ name }}!" - js = "console.log('hi');" - css = "body { color: red; }" - - def get_template_data(self, args, kwargs, slots, context): - return {"name": kwargs.get("name", "World")} - - # No need to render, accessing the attributes should trigger the hooks - assert TestComponent.template == "OVERRIDDEN TEMPLATE" - assert TestComponent.js == "OVERRIDDEN JS" - assert TestComponent.css == "OVERRIDDEN CSS" - @djc_test class TestExtensionViews: diff --git a/tests/test_signals.py b/tests/test_signals.py index 6dcabfe9..ef629bad 100644 --- a/tests/test_signals.py +++ b/tests/test_signals.py @@ -96,19 +96,3 @@ class TestTemplateSignal: templates_used = _get_templates_used_to_render(template) assert "slotted_template.html" in templates_used assert "simple_template.html" in templates_used - - @djc_test(parametrize=PARAMETRIZE_CONTEXT_BEHAVIOR) - @with_template_signal - def test_template_rendered_skipped_when_no_template(self, components_settings): - class EmptyComponent(Component): - pass - - registry.register("empty", EmptyComponent) - - template_str: types.django_html = """ - {% load component_tags %} - {% component 'empty' / %} - """ - template = Template(template_str, name="root") - templates_used = _get_templates_used_to_render(template) - assert templates_used == ["root"] diff --git a/tests/test_templatetags_extends.py b/tests/test_templatetags_extends.py index d668f1f3..74f2abe1 100644 --- a/tests/test_templatetags_extends.py +++ b/tests/test_templatetags_extends.py @@ -25,17 +25,6 @@ def gen_blocked_and_slotted_component(): return BlockedAndSlottedComponent -def gen_component_inside_include(): - class ComponentInsideInclude(Component): - template: types.django_html = """
Hello
""" - - class Media: - css = "style.css" - js = "script.js" - - return ComponentInsideInclude - - ####################### # TESTS ####################### @@ -547,112 +536,6 @@ class TestExtendsCompat: """ assertHTMLEqual(rendered, expected) - # In this case, `{% include %}` is NOT nested inside a `{% component %}` tag. - # We need to ensure that the component inside the `{% include %}` is rendered as if with deps_strategy="ignore", - # so the parent template decides how to render the JS/CSS. - # See https://github.com/django-components/django-components/issues/1296 - @djc_test(parametrize=PARAMETRIZE_CONTEXT_BEHAVIOR) - def test_component_with_media_inside_include(self, components_settings): - registry.register("test_component", gen_component_inside_include()) - - template: types.django_html = """ - {% load component_tags %} - - - {% include "component_inside_include_sub.html" %} - - - """ - - rendered_raw = Template(template).render(Context({"DJC_DEPS_STRATEGY": "ignore"})) - expected_raw = """ - - -
Hello
-
- - """ - assertHTMLEqual(rendered_raw, expected_raw) - - template_obj = Template(template) - context = Context() - rendered = template_obj.render(context) - - # NOTE: It's important that the - - - - """ - assertHTMLEqual(rendered, expected) - - # In this case, because `{% include %}` is rendered inside a `{% component %}` tag, - # then the component inside the `{% include %}` knows it's inside another component. - # So it's always rendered as if with deps_strategy="ignore". - # See https://github.com/django-components/django-components/issues/1296 - @djc_test(parametrize=PARAMETRIZE_CONTEXT_BEHAVIOR) - def test_component_with_media_inside_include_inside_component(self, components_settings): - registry.register("test_component", gen_component_inside_include()) - - @register("component_inside_include") - class CompInsideIncludeComponent(Component): - template: types.django_html = """ - - - {% include "component_inside_include_sub.html" %} - - - """ - - template: types.django_html = """ - {% load component_tags %} - - {% component "component_inside_include" / %} - - """ - - rendered_raw = Template(template).render(Context({"DJC_DEPS_STRATEGY": "ignore"})) - expected_raw = """ - - - -
Hello
-
- - - """ - assertHTMLEqual(rendered_raw, expected_raw) - - template_obj = Template(template) - context = Context() - rendered = template_obj.render(context) - expected = """ - - - -
Hello
-
- - - - - - """ - assertHTMLEqual(rendered, expected) - @djc_test(parametrize=PARAMETRIZE_CONTEXT_BEHAVIOR) def test_component_inside_block(self, components_settings): registry.register("slotted_component", gen_slotted_component())