[{"data":1,"prerenderedAt":728},["ShallowReactive",2],{"navigation":3,"api-navigation":184,"\u002Flearn\u002Fconcepts\u002Fconfig-as-python":206,"docyard:crossref-index":727},[4,8,155,174,180],{"title":5,"path":6,"stem":7},"Getting Started","\u002Fgetting-started","1.getting-started",{"title":9,"path":10,"stem":11,"children":12},"Learn","\u002Flearn","2.learn",[13,15,66,99,133],{"title":9,"path":10,"stem":14},"2.learn\u002Findex",{"title":16,"path":17,"stem":18,"children":19},"Tutorials","\u002Flearn\u002Ftutorials","2.learn\u002F1.tutorials\u002Findex",[20,21,26,30,34,38,42,46,50,54,58,62],{"title":16,"path":17,"stem":18},{"title":22,"path":23,"stem":24,"icon":25},"Why Laco?","\u002Flearn\u002Ftutorials\u002Fwhy-laco","2.learn\u002F1.tutorials\u002F01.why-laco","i-lucide-notebook",{"title":27,"path":28,"stem":29,"icon":25},"First Steps with Laco","\u002Flearn\u002Ftutorials\u002Ffirst-steps","2.learn\u002F1.tutorials\u002F02.first-steps",{"title":31,"path":32,"stem":33,"icon":25},"Lazy Call and Partial","\u002Flearn\u002Ftutorials\u002Flazy-call-and-partial","2.learn\u002F1.tutorials\u002F03.lazy-call-and-partial",{"title":35,"path":36,"stem":37,"icon":25},"Hyperparameters and Interpolation","\u002Flearn\u002Ftutorials\u002Fhyperparameters-and-interpolation","2.learn\u002F1.tutorials\u002F04.hyperparameters-and-interpolation",{"title":39,"path":40,"stem":41,"icon":25},"Loading, Saving, and the CLI","\u002Flearn\u002Ftutorials\u002Floading-saving-cli","2.learn\u002F1.tutorials\u002F05.loading-saving-cli",{"title":43,"path":44,"stem":45,"icon":25},"Nested Configs and Containers","\u002Flearn\u002Ftutorials\u002Fnested-configs-and-containers","2.learn\u002F1.tutorials\u002F06.nested-configs-and-containers",{"title":47,"path":48,"stem":49,"icon":25},"Typed Groups and Schemas","\u002Flearn\u002Ftutorials\u002Ftyped-groups-and-schemas","2.learn\u002F1.tutorials\u002F07.typed-groups-and-schemas",{"title":51,"path":52,"stem":53,"icon":25},"Pipeline Configs","\u002Flearn\u002Ftutorials\u002Fpipeline-configs","2.learn\u002F1.tutorials\u002F08.pipeline-configs",{"title":55,"path":56,"stem":57,"icon":25},"Tasks and the App Loop","\u002Flearn\u002Ftutorials\u002Ftasks-and-app-loop","2.learn\u002F1.tutorials\u002F09.tasks-and-app-loop",{"title":59,"path":60,"stem":61,"icon":25},"Tracing","\u002Flearn\u002Ftutorials\u002Ftracing","2.learn\u002F1.tutorials\u002F10.tracing",{"title":63,"path":64,"stem":65,"icon":25},"Production Patterns","\u002Flearn\u002Ftutorials\u002Fproduction-patterns","2.learn\u002F1.tutorials\u002F11.production-patterns",{"title":67,"path":68,"stem":69,"children":70},"Concepts","\u002Flearn\u002Fconcepts","2.learn\u002F2.concepts\u002Findex",[71,72,76,80,84,88,92,95],{"title":67,"path":68,"stem":69},{"title":73,"path":74,"stem":75},"Config as Python","\u002Flearn\u002Fconcepts\u002Fconfig-as-python","2.learn\u002F2.concepts\u002F1.config-as-python",{"title":77,"path":78,"stem":79},"Lazy Construction","\u002Flearn\u002Fconcepts\u002Flazy-construction","2.learn\u002F2.concepts\u002F2.lazy-construction",{"title":81,"path":82,"stem":83},"Lie-Typing","\u002Flearn\u002Fconcepts\u002Flie-typing","2.learn\u002F2.concepts\u002F3.lie-typing",{"title":85,"path":86,"stem":87},"Interpolation","\u002Flearn\u002Fconcepts\u002Finterpolation","2.learn\u002F2.concepts\u002F4.interpolation",{"title":89,"path":90,"stem":91},"Typed Groups","\u002Flearn\u002Fconcepts\u002Ftyped-groups","2.learn\u002F2.concepts\u002F5.typed-groups",{"title":59,"path":93,"stem":94},"\u002Flearn\u002Fconcepts\u002Ftracing","2.learn\u002F2.concepts\u002F6.tracing",{"title":96,"path":97,"stem":98},"App Loop","\u002Flearn\u002Fconcepts\u002Fapp-loop","2.learn\u002F2.concepts\u002F7.app-loop",{"title":100,"path":101,"stem":102,"children":103},"How-To Guides","\u002Flearn\u002Fhow-to","2.learn\u002F3.how-to\u002Findex",[104,105,109,113,117,121,125,129],{"title":100,"path":101,"stem":102},{"title":106,"path":107,"stem":108},"Override Configs","\u002Flearn\u002Fhow-to\u002Foverride-configs","2.learn\u002F3.how-to\u002F1.override-configs",{"title":110,"path":111,"stem":112},"Safe Loading","\u002Flearn\u002Fhow-to\u002Fsafe-loading","2.learn\u002F3.how-to\u002F2.safe-loading",{"title":114,"path":115,"stem":116},"Custom Resolvers","\u002Flearn\u002Fhow-to\u002Fcustom-resolvers","2.learn\u002F3.how-to\u002F3.custom-resolvers",{"title":118,"path":119,"stem":120},"Lint and Strict Mode","\u002Flearn\u002Fhow-to\u002Flint-and-strict","2.learn\u002F3.how-to\u002F4.lint-and-strict",{"title":122,"path":123,"stem":124},"Publishing a reproducible app with laco app","\u002Flearn\u002Fhow-to\u002Flaco-app","2.learn\u002F3.how-to\u002F5.laco-app",{"title":126,"path":127,"stem":128},"Reproduce an Experiment","\u002Flearn\u002Fhow-to\u002Freproduce-experiment","2.learn\u002F3.how-to\u002F6.reproduce-experiment",{"title":130,"path":131,"stem":132},"Migrate from argparse","\u002Flearn\u002Fhow-to\u002Fmigrate-from-argparse","2.learn\u002F3.how-to\u002F7.migrate-from-argparse",{"title":134,"path":135,"stem":136,"children":137},"Examples Curriculum","\u002Flearn\u002Fexamples","2.learn\u002F4.examples\u002Findex",[138,139,143,147,151],{"title":134,"path":135,"stem":136},{"title":140,"path":141,"stem":142},"Foundation Examples","\u002Flearn\u002Fexamples\u002Ffoundations","2.learn\u002F4.examples\u002F1.foundations",{"title":144,"path":145,"stem":146},"Building Blocks","\u002Flearn\u002Fexamples\u002Fbuilding-blocks","2.learn\u002F4.examples\u002F2.building-blocks",{"title":148,"path":149,"stem":150},"Typed-Group Variants","\u002Flearn\u002Fexamples\u002Ftyped-variants","2.learn\u002F4.examples\u002F3.typed-variants",{"title":152,"path":153,"stem":154},"End-to-End Pipelines","\u002Flearn\u002Fexamples\u002Fpipelines","2.learn\u002F4.examples\u002F4.pipelines",{"title":156,"path":157,"stem":158,"children":159},"Resources","\u002Fresources","3.resources",[160,162,166,170],{"title":156,"path":157,"stem":161},"3.resources\u002Findex",{"title":163,"path":164,"stem":165},"Integrations","\u002Fresources\u002Fintegrations","3.resources\u002F1.integrations",{"title":167,"path":168,"stem":169},"Migration guide: Laco 0.x → 1.0","\u002Fresources\u002Fmigration-0.x-to-1.0","3.resources\u002F2.migration-0.x-to-1.0",{"title":171,"path":172,"stem":173},"Laco vs hydra-zen","\u002Fresources\u002Flaco-vs-hydra-zen","3.resources\u002F3.laco-vs-hydra-zen",{"title":175,"path":176,"stem":177,"children":178},"API Reference","\u002Fapi","4.api\u002Findex",[179],{"title":175,"path":176,"stem":177},{"title":181,"path":182,"stem":183},"Lazy Configuration for Python","\u002F","index",[185,188,191,194,197,200,203],{"title":186,"path":187},"cli","\u002Fapi\u002Fcli",{"title":189,"path":190},"compat","\u002Fapi\u002Fcompat",{"title":192,"path":193},"handler","\u002Fapi\u002Fhandler",{"title":195,"path":196},"keys","\u002Fapi\u002Fkeys",{"title":198,"path":199},"language","\u002Fapi\u002Flanguage",{"title":201,"path":202},"ops","\u002Fapi\u002Fops",{"title":204,"path":205},"utils","\u002Fapi\u002Futils",{"id":207,"title":73,"body":208,"description":302,"extension":722,"meta":723,"navigation":724,"path":74,"seo":725,"stem":75,"__hash__":726},"content\u002F2.learn\u002F2.concepts\u002F1.config-as-python.md",{"type":209,"value":210,"toc":713},"minimark",[211,215,238,243,255,262,285,288,296,345,348,399,406,420,448,462,508,519,523,628,639,643,691,709],[212,213,73],"h1",{"id":214},"config-as-python",[216,217,218],"blockquote",{},[219,220,221,225,226,229,225,232,234,235],"p",{},[222,223,224],"strong",{},"Tutorial:"," ",[227,228,22],"a",{"href":23},[222,230,231],{},"See also:",[227,233,81],{"href":82},", ",[227,236,237],{"href":176},"API: laco.load",[239,240,242],"h2",{"id":241},"why-python-files","Why Python Files?",[219,244,245,246,250,251,254],{},"Traditional config systems use YAML or JSON. Those formats can only represent\nprimitives, lists, and dicts. Referring to a class like ",[247,248,249],"code",{},"torch.nn.ReLU","\nrequires a magic string (",[247,252,253],{},"\"torch.nn.ReLU\"",") that silently breaks on rename.",[219,256,257,258,261],{},"Laco config files are real ",[247,259,260],{},".py"," files. You get:",[263,264,265,276,279,282],"ul",{},[266,267,268,269,271,272,275],"li",{},"Real imports: if ",[247,270,249],{}," is renamed, ",[247,273,274],{},"import"," fails loudly at load time",[266,277,278],{},"IDE go-to-definition, autocomplete, and refactoring on config targets",[266,280,281],{},"Arbitrary Python expressions for derived values",[266,283,284],{},"No separate config DSL to learn",[219,286,287],{},"The trade-off: configs are code, so the same discipline applies (version\ncontrol, code review, reproducibility via pinned deps).",[239,289,291,292,295],{"id":290},"how-lacoload-works","How ",[247,293,294],{},"laco.load"," Works",[297,298,303],"pre",{"className":299,"code":300,"language":301,"meta":302,"style":302},"language-python shiki shiki-themes material-theme-lighter github-light github-dark","cfg = laco.load(\"configs\u002Fmlp.py\")\n","python","",[247,304,305],{"__ignoreMap":302},[306,307,310,314,318,321,325,329,332,336,340,342],"span",{"class":308,"line":309},"line",1,[306,311,313],{"class":312},"su5hD","cfg ",[306,315,317],{"class":316},"smGrS","=",[306,319,320],{"class":312}," laco",[306,322,324],{"class":323},"sP7_E",".",[306,326,328],{"class":327},"slqww","load",[306,330,331],{"class":323},"(",[306,333,335],{"class":334},"sjJ54","\"",[306,337,339],{"class":338},"s_sjI","configs\u002Fmlp.py",[306,341,335],{"class":334},[306,343,344],{"class":323},")\n",[219,346,347],{},"Internally:",[349,350,351,357,368,381],"ol",{},[266,352,353,354,356],{},"The ",[247,355,260],{}," file is read and compiled.",[266,358,359,360,363,364,367],{},"A controlled ",[247,361,362],{},"exec"," runs the module in a namespace with ",[247,365,366],{},"_patch_import","\nactive, so relative imports within config packages resolve correctly.",[266,369,370,371,374,375,377,378,324],{},"Names in ",[247,372,373],{},"__all__"," (or all non-underscore names if ",[247,376,373],{}," is absent)\nare exported as keys in a ",[247,379,380],{},"DictConfig",[266,382,383,384,386,387,390,391,394,395,398],{},"Each exported value is recursively converted: ",[247,385,380],{}," nodes are\nspliced in; primitives are kept; other objects raise ",[247,388,389],{},"TypeError"," unless\nthey are ",[247,392,393],{},"LazyObject"," nodes produced by ",[247,396,397],{},"L.call"," and friends.",[239,400,353,402,405],{"id":401},"the-configs-protocol",[247,403,404],{},"configs:\u002F\u002F"," Protocol",[219,407,408,409,412,413,415,416,419],{},"Laco registers a path handler with ",[247,410,411],{},"expath"," so that ",[247,414,404],{}," URLs resolve\nagainst the installed ",[247,417,418],{},"laco.examples"," package:",[297,421,423],{"className":299,"code":422,"language":301,"meta":302,"style":302},"cfg = laco.load(\"configs:\u002F\u002Fexamples\u002Fmlp.py\")\n",[247,424,425],{"__ignoreMap":302},[306,426,427,429,431,433,435,437,439,441,444,446],{"class":308,"line":309},[306,428,313],{"class":312},[306,430,317],{"class":316},[306,432,320],{"class":312},[306,434,324],{"class":323},[306,436,328],{"class":327},[306,438,331],{"class":323},[306,440,335],{"class":334},[306,442,443],{"class":338},"configs:\u002F\u002Fexamples\u002Fmlp.py",[306,445,335],{"class":334},[306,447,344],{"class":323},[219,449,450,451,453,454,457,458,461],{},"Your own project can register additional ",[247,452,404],{}," namespaces via the\n",[247,455,456],{},"[project.entry-points.configs]"," table in ",[247,459,460],{},"pyproject.toml",":",[297,463,467],{"className":464,"code":465,"language":466,"meta":302,"style":302},"language-toml shiki shiki-themes material-theme-lighter github-light github-dark","[project.entry-points.configs]\nmy_project = \"my_project.configs\"\n","toml",[247,468,469,491],{"__ignoreMap":302},[306,470,471,474,478,480,483,485,488],{"class":308,"line":309},[306,472,473],{"class":323},"[",[306,475,477],{"class":476},"sbgvK","project",[306,479,324],{"class":312},[306,481,482],{"class":476},"entry-points",[306,484,324],{"class":312},[306,486,487],{"class":476},"configs",[306,489,490],{"class":323},"]\n",[306,492,494,497,499,502,505],{"class":308,"line":493},2,[306,495,496],{"class":312},"my_project ",[306,498,317],{"class":323},[306,500,501],{"class":334}," \"",[306,503,504],{"class":338},"my_project.configs",[306,506,507],{"class":334},"\"\n",[219,509,510,511,514,515,518],{},"Then ",[247,512,513],{},"laco.load(\"configs:\u002F\u002Fmy_project\u002Ftrain.py\")"," resolves to the\n",[247,516,517],{},"my_project\u002Fconfigs\u002Ftrain.py"," file inside the installed package.",[239,520,522],{"id":521},"yaml-round-trip","YAML Round-Trip",[297,524,526],{"className":299,"code":525,"language":301,"meta":302,"style":302},"cfg = laco.load(\"configs\u002Fmlp.py\")\nlaco.dump(cfg)           # → Hydra-compatible YAML string\nlaco.save(cfg, \"run\u002Fconfig.yaml\")   # → file on disk\ncfg2 = laco.load(\"run\u002Fconfig.yaml\") # ← load the YAML back\n",[247,527,528,550,572,601],{"__ignoreMap":302},[306,529,530,532,534,536,538,540,542,544,546,548],{"class":308,"line":309},[306,531,313],{"class":312},[306,533,317],{"class":316},[306,535,320],{"class":312},[306,537,324],{"class":323},[306,539,328],{"class":327},[306,541,331],{"class":323},[306,543,335],{"class":334},[306,545,339],{"class":338},[306,547,335],{"class":334},[306,549,344],{"class":323},[306,551,552,555,557,560,562,565,568],{"class":308,"line":493},[306,553,554],{"class":312},"laco",[306,556,324],{"class":323},[306,558,559],{"class":327},"dump",[306,561,331],{"class":323},[306,563,564],{"class":327},"cfg",[306,566,567],{"class":323},")",[306,569,571],{"class":570},"sutJx","           # → Hydra-compatible YAML string\n",[306,573,575,577,579,582,584,586,589,591,594,596,598],{"class":308,"line":574},3,[306,576,554],{"class":312},[306,578,324],{"class":323},[306,580,581],{"class":327},"save",[306,583,331],{"class":323},[306,585,564],{"class":327},[306,587,588],{"class":323},",",[306,590,501],{"class":334},[306,592,593],{"class":338},"run\u002Fconfig.yaml",[306,595,335],{"class":334},[306,597,567],{"class":323},[306,599,600],{"class":570},"   # → file on disk\n",[306,602,604,607,609,611,613,615,617,619,621,623,625],{"class":308,"line":603},4,[306,605,606],{"class":312},"cfg2 ",[306,608,317],{"class":316},[306,610,320],{"class":312},[306,612,324],{"class":323},[306,614,328],{"class":327},[306,616,331],{"class":323},[306,618,335],{"class":334},[306,620,593],{"class":338},[306,622,335],{"class":334},[306,624,567],{"class":323},[306,626,627],{"class":570}," # ← load the YAML back\n",[219,629,630,631,634,635,638],{},"YAML configs produced by ",[247,632,633],{},"laco.dump"," include a ",[247,636,637],{},"_laco_: 1"," schema-version\nmarker stripped on load. They are valid Hydra YAML and can be consumed by\nany Hydra application.",[239,640,642],{"id":641},"loadmode","LoadMode",[297,644,646],{"className":299,"code":645,"language":301,"meta":302,"style":302},"cfg = laco.load(\"configs\u002Fmlp.py\", mode=laco.LoadMode.SAFE)\n",[247,647,648],{"__ignoreMap":302},[306,649,650,652,654,656,658,660,662,664,666,668,670,674,676,678,680,683,685,689],{"class":308,"line":309},[306,651,313],{"class":312},[306,653,317],{"class":316},[306,655,320],{"class":312},[306,657,324],{"class":323},[306,659,328],{"class":327},[306,661,331],{"class":323},[306,663,335],{"class":334},[306,665,339],{"class":338},[306,667,335],{"class":334},[306,669,588],{"class":323},[306,671,673],{"class":672},"s99_P"," mode",[306,675,317],{"class":316},[306,677,554],{"class":327},[306,679,324],{"class":323},[306,681,642],{"class":682},"skxfh",[306,684,324],{"class":323},[306,686,688],{"class":687},"swQdS","SAFE",[306,690,344],{"class":323},[219,692,693,696,697,234,700,234,703,705,706,324],{},[247,694,695],{},"LoadMode.SAFE"," removes dangerous builtins (",[247,698,699],{},"open",[247,701,702],{},"eval",[247,704,362],{},", …) and\nenforces a module allowlist. Use it when loading configs from untrusted\nsources. See ",[227,707,708],{"href":111},"How-To: Safe Loading",[710,711,712],"style",{},"html pre.shiki code .su5hD, html code.shiki .su5hD{--shiki-light:#90A4AE;--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .smGrS, html code.shiki .smGrS{--shiki-light:#39ADB5;--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sP7_E, html code.shiki .sP7_E{--shiki-light:#39ADB5;--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .slqww, html code.shiki .slqww{--shiki-light:#6182B8;--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sjJ54, html code.shiki .sjJ54{--shiki-light:#39ADB5;--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .s_sjI, html code.shiki .s_sjI{--shiki-light:#91B859;--shiki-default:#032F62;--shiki-dark:#9ECBFF}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sbgvK, html code.shiki .sbgvK{--shiki-light:#E2931D;--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sutJx, html code.shiki .sutJx{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#6A737D;--shiki-default-font-style:inherit;--shiki-dark:#6A737D;--shiki-dark-font-style:inherit}html pre.shiki code .s99_P, html code.shiki .s99_P{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#E36209;--shiki-default-font-style:inherit;--shiki-dark:#FFAB70;--shiki-dark-font-style:inherit}html pre.shiki code .skxfh, html code.shiki .skxfh{--shiki-light:#E53935;--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .swQdS, html code.shiki .swQdS{--shiki-light:#E53935;--shiki-default:#005CC5;--shiki-dark:#79B8FF}",{"title":302,"searchDepth":574,"depth":574,"links":714},[715,716,718,720,721],{"id":241,"depth":493,"text":242},{"id":290,"depth":493,"text":717},"How laco.load Works",{"id":401,"depth":493,"text":719},"The configs:\u002F\u002F Protocol",{"id":521,"depth":493,"text":522},{"id":641,"depth":493,"text":642},"md",{},true,{"title":73,"description":302},"wBIpCVm38qbGUSsFQ4nwhSIntOg_ASL3Z63BoTQoP5E",{},1785687300469]