[{"data":1,"prerenderedAt":1985},["ShallowReactive",2],{"navigation":3,"\u002Fdocs\u002Fpython":135,"\u002Fdocs\u002Fpython-surround":1980},[4],{"title":5,"path":6,"stem":7,"children":8,"page":134},"Docs","\u002Fdocs","docs",[9,13,17,21,25,29,33,37,41,45,49,53,57,61,70,74,78,82,86,90,94,98,102,106,110,114,118,122,126,130],{"title":10,"path":11,"stem":12},"AI harnesses: LLM tools, MCP servers and agents","\u002Fdocs\u002Fai-tools","docs\u002Fai-tools",{"title":14,"path":15,"stem":16},"Architecture","\u002Fdocs\u002Farchitecture","docs\u002Farchitecture",{"title":18,"path":19,"stem":20},"Web \u002F native bridges","\u002Fdocs\u002Fbridges","docs\u002Fbridges",{"title":22,"path":23,"stem":24},"Broadcast channels and tests","\u002Fdocs\u002Fchannels-and-tests","docs\u002Fchannels-and-tests",{"title":26,"path":27,"stem":28},"CLI reference","\u002Fdocs\u002Fcli","docs\u002Fcli",{"title":30,"path":31,"stem":32},"Completeness: how far an answer reaches","\u002Fdocs\u002Fcompleteness","docs\u002Fcompleteness",{"title":34,"path":35,"stem":36},"Configuration","\u002Fdocs\u002Fconfiguration","docs\u002Fconfiguration",{"title":38,"path":39,"stem":40},"External systems","\u002Fdocs\u002Fexternal","docs\u002Fexternal",{"title":42,"path":43,"stem":44},"Generated, copied and vendored files","\u002Fdocs\u002Fgenerated","docs\u002Fgenerated",{"title":46,"path":47,"stem":48},"Installing and updating cg","\u002Fdocs\u002Finstall","docs\u002Finstall",{"title":50,"path":51,"stem":52},"Java","\u002Fdocs\u002Fjava","docs\u002Fjava",{"title":54,"path":55,"stem":56},"Kotlin","\u002Fdocs\u002Fkotlin","docs\u002Fkotlin",{"title":58,"path":59,"stem":60},"Known limitations","\u002Fdocs\u002Flimitations","docs\u002Flimitations",{"title":62,"path":63,"stem":64,"children":65},"MCP server","\u002Fdocs\u002Fmcp","docs\u002Fmcp",[66],{"title":67,"path":68,"stem":69},"code-graph MCP: sample outputs (real calls via the MCP Python SDK stdio client)","\u002Fdocs\u002Fmcp\u002Fsample_outputs","docs\u002Fmcp\u002Fsample_outputs",{"title":71,"path":72,"stem":73},"Rust, C and C++","\u002Fdocs\u002Fnative","docs\u002Fnative",{"title":75,"path":76,"stem":77},"Port gaps: cg parity","\u002Fdocs\u002Fparity","docs\u002Fparity",{"title":79,"path":80,"stem":81},"PHP","\u002Fdocs\u002Fphp","docs\u002Fphp",{"title":83,"path":84,"stem":85},"Planned changes","\u002Fdocs\u002Fplans","docs\u002Fplans",{"title":87,"path":88,"stem":89},"Platform-specific code","\u002Fdocs\u002Fplatforms","docs\u002Fplatforms",{"title":91,"path":92,"stem":93},"Protocol links","\u002Fdocs\u002Fprotocols","docs\u002Fprotocols",{"title":95,"path":96,"stem":97},"Python","\u002Fdocs\u002Fpython","docs\u002Fpython",{"title":99,"path":100,"stem":101},"Quick start","\u002Fdocs\u002Fquickstart","docs\u002Fquickstart",{"title":103,"path":104,"stem":105},"Graph schema","\u002Fdocs\u002Fschema","docs\u002Fschema",{"title":107,"path":108,"stem":109},"Attack surface","\u002Fdocs\u002Fsurface","docs\u002Fsurface",{"title":111,"path":112,"stem":113},"Swift","\u002Fdocs\u002Fswift","docs\u002Fswift",{"title":115,"path":116,"stem":117},"TypeScript \u002F JavaScript frameworks","\u002Fdocs\u002Fts-frameworks","docs\u002Fts-frameworks",{"title":119,"path":120,"stem":121},"How we validate","\u002Fdocs\u002Fvalidation","docs\u002Fvalidation",{"title":123,"path":124,"stem":125},"Validation log","\u002Fdocs\u002Fvalidation-log","docs\u002Fvalidation-log",{"title":127,"path":128,"stem":129},"Value facts and resolutions","\u002Fdocs\u002Fvalue-facts","docs\u002Fvalue-facts",{"title":131,"path":132,"stem":133},"Visual view","\u002Fdocs\u002Fviz","docs\u002Fviz",false,{"id":136,"title":95,"body":137,"description":1974,"extension":1975,"meta":1976,"navigation":1977,"path":96,"seo":1978,"stem":97,"__hash__":1979},"docs\u002Fdocs\u002Fpython.md",{"type":138,"value":139,"toc":1960},"minimark",[140,181,186,207,363,379,383,389,400,423,457,513,517,625,647,651,665,766,770,779,811,818,868,872,925,929,1013,1017,1024,1118,1160,1303,1340,1362,1382,1386,1426,1461,1465,1497,1703,1747,1754,1883,1886,1922,1947,1951,1956],[141,142,143,144,148,149,153,154,158,159,161,162,165,166,169,170,173,174,177,178,180],"p",{},"What ",[145,146,147],"code",{},".py"," adds beyond ",[150,151,152],"a",{"href":47},"Install",", ",[150,155,157],{"href":156},"\u002Fdocs\u002Fcli#query-targets-specs","CLI specs",", and ",[150,160,103],{"href":104},": source roots and module names, reference ",[145,163,164],{},"how"," values, and FastAPI \u002F Starlette \u002F Flask route ids.\nThe parser is the stdlib ",[145,167,168],{},"ast"," module. A checkout needs no virtualenv, and the project is never imported.\nWhy a file is unmapped: ",[145,171,172],{},"cg coverage",". The ",[145,175,176],{},"python.source_roots"," key: ",[150,179,34],{"href":35},".",[182,183,185],"h2",{"id":184},"source-roots","Source roots",[141,187,188,189,191,192,195,196,198,199,202,203,206],{},"A source root is a directory imported by top-level name.\nThe plugin runs on any repo with ",[145,190,147],{}," files outside dependency, build, and cache directories.\nDetection records a reason per root. Roots in ",[145,193,194],{},".cg.yaml"," replace detection (",[145,197,180],{}," is the indexed root).\n",[145,200,201],{},"cg index --python-root"," (repeatable) overrides the file for one run. Paths stay inside the indexed root.\n",[145,204,205],{},"sys.path"," edits at run time are not evaluated.",[208,209,210,226],"table",{},[211,212,213],"thead",{},[214,215,216,220,223],"tr",{},[217,218,219],"th",{},"evidence",[217,221,222],{},"example",[217,224,225],{},"reason",[227,228,229,248,285,306,329,348],"tbody",{},[214,230,231,235,244],{},[232,233,234],"td",{},"indexed root",[232,236,237,240,241],{},[145,238,239],{},"app\u002Fviews.py"," → ",[145,242,243],{},"app.views",[232,245,246],{},[145,247,234],{},[214,249,250,253,282],{},[232,251,252],{},"packaging config",[232,254,255,256,259,260,259,263,266,267,270,271,274,275,278,279],{},"setuptools, hatch, poetry, pdm, maturin ",[145,257,258],{},"package-dir"," \u002F ",[145,261,262],{},"where",[145,264,265],{},"sources","; ",[145,268,269],{},"setup.cfg","; a literal ",[145,272,273],{},"package_dir="," or ",[145,276,277],{},"find_packages"," in ",[145,280,281],{},"setup.py",[232,283,284],{},"the key that matched",[214,286,287,298,301],{},[232,288,289,153,292,153,295],{},[145,290,291],{},"src\u002F",[145,293,294],{},"lib\u002F",[145,296,297],{},"python\u002F",[232,299,300],{},"conventional directories that are not packages",[232,302,303],{},[145,304,305],{},"lib\u002F directory",[214,307,308,311,324],{},[232,309,310],{},"nested project, depth ≤ 4",[232,312,313,153,316,153,318,320,321],{},[145,314,315],{},"pyproject.toml",[145,317,281],{},[145,319,269],{},", or ",[145,322,323],{},"manage.py",[232,325,326],{},[145,327,328],{},"nested project (backend\u002Fmanage.py)",[214,330,331,334,343],{},[232,332,333],{},"PEP 420",[232,335,336,339,340],{},[145,337,338],{},"plugins\u002Facme\u002Fcore\u002Fbase.py"," imported as ",[145,341,342],{},"acme.core.base",[232,344,345],{},[145,346,347],{},"namespace package acme",[214,349,350,353,358],{},[232,351,352],{},"package parent",[232,354,355],{},[145,356,357],{},"services\u002Fbilling\u002Fbilling\u002F__init__.py",[232,359,360],{},[145,361,362],{},"parent of top-level package billing",[141,364,365,366,368,369,372,373,375,376,180],{},"A ",[145,367,258],{}," map (",[145,370,371],{},"{\"core\" = \"lib\"}",") makes ",[145,374,294],{}," hold package ",[145,377,378],{},"core",[182,380,382],{"id":381},"module-names","Module names",[141,384,385,386,388],{},"A file under two roots gets one canonical name: the root whose top-level name the project's imports use most, and the deepest root on a tie.\nThe other names stay aliases, so both spellings resolve to the same node.\n",[145,387,172],{}," reports modules whose imports used more than one name.",[141,390,391,392,395,396,399],{},"When two trees claim one name (often ",[145,393,394],{},"tests"," in a monorepo), the tree with the most import evidence keeps it, then a tree with no other importable name, then the shallower root.\nThe others are named from the indexed root (",[145,397,398],{},"svc-b.tests.conftest","). Relative imports inside each tree still resolve.",[141,401,402,403,153,406,409,410,413,414,417,418,420,421,180],{},"A path that is not an importable name (",[145,404,405],{},"my-scripts\u002Frun.py",[145,407,408],{},"alembic\u002Fversions\u002F1a2b_add.py",") is ",[145,411,412],{},"unmapped"," (",[150,415,416],{"href":31},"Completeness",").\nWith configured roots, files outside them are ",[145,419,412],{}," too, and the coverage hint names ",[145,422,176],{},[424,425,430],"pre",{"className":426,"code":427,"language":428,"meta":429,"style":429},"language-console shiki shiki-themes cg-light cg-light cg-dark","$ cg coverage --db out\u002Fproj.db\ncoverage proj: python 3 exact\n  python source roots: lib\u002F (detected: lib\u002F directory; parent of top-level package core, 3 modules)\n","console","",[145,431,432,445,451],{"__ignoreMap":429},[433,434,437,441],"span",{"class":435,"line":436},"line",1,[433,438,440],{"class":439},"sZ_TN","$",[433,442,444],{"class":443},"snmWg"," cg coverage --db out\u002Fproj.db\n",[433,446,448],{"class":435,"line":447},2,[433,449,450],{"class":443},"coverage proj: python 3 exact\n",[433,452,454],{"class":435,"line":453},3,[433,455,456],{"class":443},"  python source roots: lib\u002F (detected: lib\u002F directory; parent of top-level package core, 3 modules)\n",[141,458,459,460,463,464,413,467,153,470,153,473,476,477,413,480,153,483,153,486,153,489,153,492,495,496,153,499,153,502,505,506,509,510,180],{},"A layout that only uses the indexed root keeps that short output (",[145,461,462],{},"--all-files"," shows the root).\nIndex stats: ",[145,465,466],{},"roots_mode",[145,468,469],{},"detected",[145,471,472],{},"configured",[145,474,475],{},"flag","), ",[145,478,479],{},"source_roots",[145,481,482],{},"path",[145,484,485],{},"origin",[145,487,488],{},"why",[145,490,491],{},"modules",[145,493,494],{},"package"," for a mapped directory), ",[145,497,498],{},"roots_warnings",[145,500,501],{},"roots_ambiguous",[145,503,504],{},"module_name_collisions",".\nMCP ",[145,507,508],{},"coverage(json_output=true)"," adds ",[145,511,512],{},"python_source_roots",[182,514,516],{"id":515},"resolution","Resolution",[208,518,519,532],{},[211,520,521],{},[214,522,523,526,529],{},[217,524,525],{},"layer",[217,527,528],{},"what",[217,530,531],{},"label",[227,533,534,554,573,595,608],{},[214,535,536,539,548],{},[232,537,538],{},"parser",[232,540,541,542,544,545],{},"stdlib ",[145,543,168],{}," of the running interpreter. Coverage calls this parser ",[145,546,547],{},"exact",[232,549,550,551],{},"parsed, or listed by ",[145,552,553],{},"cg coverage --details",[214,555,556,559,566],{},[232,557,558],{},"imports",[232,560,561,562,565],{},"relative imports, ",[145,563,564],{},"__init__"," re-exports, aliases, function-local imports",[232,567,568,259,570],{},[145,569,547],{},[145,571,572],{},"resolved",[214,574,575,578,591],{},[232,576,577],{},"calls",[232,579,580,259,583,586,587,590],{},[145,581,582],{},"self",[145,584,585],{},"cls"," with MRO, annotations, constructor results, ",[145,588,589],{},"super()",", a few container generics",[232,592,593],{},[145,594,572],{},[214,596,597,600,603],{},[232,598,599],{},"fallback",[232,601,602],{},"the one method of that name in the project",[232,604,605],{},[145,606,607],{},"heuristic",[214,609,610,613,619],{},[232,611,612],{},"wrappers",[232,614,615,618],{},[145,616,617],{},"sync_to_async(f)(...)"," and the same shape",[232,620,621,622],{},"a call to ",[145,623,624],{},"f",[141,626,627,628,631,632,635,636,639,640,153,643,646],{},"These stay unresolved or heuristic: untyped parameters, ",[145,629,630],{},"**kwargs",", decorators that change the signature, ",[145,633,634],{},"getattr(obj, name)",", and a table filled in a loop or in another function.\nA decorator registration or ",[145,637,638],{},"registry[key] = fn"," whose caller is outside the graph is a blind spot (",[145,641,642],{},"python_decorator_registration",[145,644,645],{},"python_registry_assignment",").",[182,648,650],{"id":649},"query-specs","Query specs",[141,652,653,656,657,660,661,664],{},[145,654,655],{},"Class.method"," and ",[145,658,659],{},"Class::method"," follow ",[150,662,663],{"href":156},"query targets",". Python-only shapes:",[208,666,667,677],{},[211,668,669],{},[214,670,671,674],{},[217,672,673],{},"spec or id",[217,675,676],{},"selects",[227,678,679,698,719,732,752],{},[214,680,681,695],{},[232,682,683,153,686,153,689,153,692],{},[145,684,685],{},"module:pkg.mod",[145,687,688],{},"function:pkg.fn",[145,690,691],{},"method:pkg.Class.method",[145,693,694],{},"class:pkg.Class",[232,696,697],{},"the declaration",[214,699,700,711],{},[232,701,702,153,705,153,708],{},[145,703,704],{},"script:\u003Cmodule>",[145,706,707],{},"script:console_scripts:\u003Cname>",[145,709,710],{},"script:\u003Cgroup>:\u003Cname>",[232,712,713,714,718],{},"a program entry (",[150,715,717],{"href":716},"#entry-points-and-function-references","below",")",[214,720,721,726],{},[232,722,723],{},[145,724,725],{},"field:\u003CClass>.\u003Cattr>",[232,727,728,729,718],{},"a stored attribute (",[150,730,717],{"href":731},"#stored-attributes",[214,733,734,739],{},[232,735,736],{},[145,737,738],{},"route:GET \u002Fapi\u002Fv1\u002Fitems\u002F{id}",[232,740,741,742,153,745,748,749],{},"FastAPI, Starlette, or Flask. A host is part of the id: ",[145,743,744],{},"route:GET \u002F @api.example.org",[145,746,747],{},"route:GET \u002F @api.*",". The displayed name stays ",[145,750,751],{},"GET \u002F",[214,753,754,759],{},[232,755,756],{},[145,757,758],{},"test:\u003Cmodule>.\u003CClass>.\u003Cmethod>",[232,760,761,762,765],{},"a pytest or unittest case (",[145,763,764],{},"attrs.params"," on a parameterised case)",[182,767,769],{"id":768},"stored-attributes","Stored attributes",[141,771,772,774,775,778],{},[145,773,725],{}," is a stored attribute (",[145,776,777],{},"property: stored","):",[780,781,782,794],"ul",{},[783,784,785,786,789,790,793],"li",{},"instance attributes assigned as ",[145,787,788],{},"self.x"," in any method (",[145,791,792],{},"declared: self",");",[783,795,796,797,800,801,153,804,158,807,810],{},"annotated class attributes, such as dataclass, pydantic, or attrs fields (",[145,798,799],{},"declared: class","). ",[145,802,803],{},"ClassVar",[145,805,806],{},"Final",[145,808,809],{},"InitVar"," are excluded.",[141,812,813,814,817],{},"Plain class assignments stay constants or descriptors. Methods, properties, and nested classes are never fields.\nDjango model fields stay the Django plugin's own ",[145,815,816],{},"field:"," nodes.",[141,819,820,259,823,826,827,259,830,413,833,835,836,839,840,842,843,320,846,849,850,853,854,857,858,153,861,864,865,180],{},[145,821,822],{},"cg readers Class.attr",[145,824,825],{},"cg writers Class.attr"," list ",[145,828,829],{},"READS_PROP",[145,831,832],{},"WRITES_PROP",[145,834,572],{},", attr ",[145,837,838],{},"receiver",") when the receiver's class is known: ",[145,841,582],{},", an annotated parameter, ",[145,844,845],{},"c = Cart()",[145,847,848],{},"self.app.name",".\nAn unknown receiver adds no edge. Writes are assignment, augmented assignment, ",[145,851,852],{},"del",", in-place list \u002F dict \u002F set \u002F deque methods (",[145,855,856],{},"via: mutating","), and item assignment (",[145,859,860],{},"self.cache[k] = v",[145,862,863],{},"via: item",").\nTest-code accesses are ",[145,866,867],{},"TEST_USES",[182,869,871],{"id":870},"mail-and-sms-clients","Mail and SMS clients",[141,873,874,153,877,153,880,153,883,886,887,890,891,894,895,898,899,886,902,656,905,908,909,912,913,413,916,800,918,656,921,924],{},[145,875,876],{},"SendGridAPIClient(key).send",[145,878,879],{},"twilio.rest.Client(sid, token).messages.create",[145,881,882],{},"PostmarkClient",[145,884,885],{},"resend.Emails.send",",\n",[145,888,889],{},"vonage.Client"," and Django ",[145,892,893],{},"EMAIL_BACKEND = \"anymail.backends.\u003Cesp>.EmailBackend\""," with ",[145,896,897],{},"ANYMAIL"," (used by ",[145,900,901],{},"send_mail",[145,903,904],{},"send_mass_mail",[145,906,907],{},"EmailMessage.send",") are ",[145,910,911],{},"external:saas:\u003Cprovider>"," systems with the key source on\n",[145,914,915],{},"CREDENTIAL_FROM",[150,917,38],{"href":39},[145,919,920],{},"messagebird",[145,922,923],{},"plivo"," clients are the same kind of system.",[182,926,928],{"id":927},"push-firebase-kubernetes-docker-and-key-management","Push, Firebase, Kubernetes, Docker and key management",[141,930,931,413,934,153,937,153,940,153,943,153,946,949,950,259,953,153,956,153,959,413,962,965,966,949,969,413,972,153,975,476,978,153,981,259,984,987,988,991,992,153,995,153,998,153,1001,153,1004,987,1007,1010,1011,646],{},[145,932,933],{},"firebase_admin",[145,935,936],{},"messaging.send",[145,938,939],{},"firestore.client().collection(...)",[145,941,942],{},"auth.verify_id_token",[145,944,945],{},"db.reference",[145,947,948],{},"storage.bucket","),\n",[145,951,952],{},"apns2",[145,954,955],{},"aioapns",[145,957,958],{},"pywebpush",[145,960,961],{},"kubernetes",[145,963,964],{},"client.CoreV1Api().list_namespaced_pod"," after ",[145,967,968],{},"config.load_incluster_config()",[145,970,971],{},"docker",[145,973,974],{},"from_env()",[145,976,977],{},"DockerClient(base_url=...)",[145,979,980],{},"boto3.client('kms')",[145,982,983],{},"google.cloud.secretmanager",[145,985,986],{},"kms"," and\n",[145,989,990],{},"azure.keyvault.*"," are ",[145,993,994],{},"external:gcp:*",[145,996,997],{},"external:saas:*",[145,999,1000],{},"external:k8s:*",[145,1002,1003],{},"external:docker:*",[145,1005,1006],{},"external:aws:kms",[145,1008,1009],{},"external:azure:keyvault"," systems (",[150,1012,38],{"href":39},[182,1014,1016],{"id":1015},"entry-points-and-function-references","Entry points and function references",[141,1018,1019,1020,1023],{},"A function used as a value gets ",[145,1021,1022],{},"REFERENCES_FN"," from the function, method, class, or module that mentions it.",[208,1025,1026,1036],{},[211,1027,1028],{},[214,1029,1030,1034],{},[217,1031,1032],{},[145,1033,164],{},[217,1035,222],{},[227,1037,1038,1068,1089,1104],{},[214,1039,1040,1045],{},[232,1041,1042],{},[145,1043,1044],{},"collection",[232,1046,1047,153,1050,153,1053,259,1056,259,1059,259,1062,259,1065],{},[145,1048,1049],{},"CHECKS = (check_size, check_owner)",[145,1051,1052],{},"HANDLERS = {\"create\": on_create}",[145,1054,1055],{},".append",[145,1057,1058],{},".add",[145,1060,1061],{},".insert",[145,1063,1064],{},".extend",[145,1066,1067],{},".setdefault",[214,1069,1070,1075],{},[232,1071,1072],{},[145,1073,1074],{},"callback",[232,1076,1077,153,1080,153,1083,153,1086],{},[145,1078,1079],{},"executor.submit(job)",[145,1081,1082],{},"sorted(items, key=by_name)",[145,1084,1085],{},"Thread(target=worker)",[145,1087,1088],{},"signal.connect(receiver)",[214,1090,1091,1096],{},[232,1092,1093],{},[145,1094,1095],{},"assignment",[232,1097,1098,153,1101],{},[145,1099,1100],{},"handler = on_create",[145,1102,1103],{},"self.hook = fallback",[214,1105,1106,1111],{},[232,1107,1108],{},[145,1109,1110],{},"decorator",[232,1112,1113,1114,1117],{},"a local ",[145,1115,1116],{},"@retry"," references the function it wraps",[141,1119,1120,1121,153,1124,409,1127,894,1130,1133,1134,1136,1137,259,1140,1143,1144,894,1146,1149,1150,1153,1154,656,1157,180],{},"A call through that table (",[145,1122,1123],{},"HANDLERS[kind](e)",[145,1125,1126],{},"for check in CHECKS",[145,1128,1129],{},"CALLS",[145,1131,1132],{},"via=\"collection\""," at ",[145,1135,572],{},", one edge per function the table can hold.\nElements are followed through copies, ",[145,1138,1139],{},"list()",[145,1141,1142],{},"sorted()",", filtering comprehensions, and a helper that returns the collection or a constant key of it. Those steps chain.\nA loop over a list of instances calls the method each item's class has. Items of unknown type add no edge. A local decorator also gets ",[145,1145,1129],{},[145,1147,1148],{},"via=\"decorator\"",".\n",[145,1151,1152],{},"impact"," prints ",[145,1155,1156],{},"(ref: collection | callback | assignment | decorator)",[145,1158,1159],{},"(call through a collection)",[208,1161,1162,1175],{},[211,1163,1164],{},[214,1165,1166,1169,1172],{},[217,1167,1168],{},"source",[217,1170,1171],{},"id",[217,1173,1174],{},"entry",[227,1176,1177,1200,1219,1247,1265,1288],{},[214,1178,1179,1184,1188],{},[232,1180,1181],{},[145,1182,1183],{},"if __name__ == \"__main__\"",[232,1185,1186],{},[145,1187,704],{},[232,1189,1190,1193,1194,274,1197],{},[145,1191,1192],{},"main"," — ",[145,1195,1196],{},"python -m pkg.mod",[145,1198,1199],{},"python file.py",[214,1201,1202,1207,1212],{},[232,1203,1204],{},[145,1205,1206],{},"pkg\u002F__main__.py",[232,1208,1209],{},[145,1210,1211],{},"script:pkg.__main__",[232,1213,1214,1193,1216],{},[145,1215,1192],{},[145,1217,1218],{},"python -m pkg",[214,1220,1221,1239,1243],{},[232,1222,1223,259,1226,1229,1230,1233,1234,278,1237],{},[145,1224,1225],{},"[project.scripts]",[145,1227,1228],{},"[project.gui-scripts]",", Poetry, Flit, setup.cfg ",[145,1231,1232],{},"console_scripts",", a literal ",[145,1235,1236],{},"entry_points",[145,1238,281],{},[232,1240,1241],{},[145,1242,707],{},[232,1244,1245],{},[145,1246,1192],{},[214,1248,1249,1256,1260],{},[232,1250,1251,1252,1255],{},"other groups (",[145,1253,1254],{},"[project.entry-points.\u003Cgroup>]",", Poetry plugins, setup.cfg \u002F setup.py groups)",[232,1257,1258],{},[145,1259,710],{},[232,1261,1262],{},[145,1263,1264],{},"public_api",[214,1266,1267,1280,1283],{},[232,1268,1269,1270,153,1273,153,1276,1279],{},"FastMCP ",[145,1271,1272],{},"@mcp.tool()",[145,1274,1275],{},"mcp.tool()(fn)",[145,1277,1278],{},"add_tool",", resources, prompts",[232,1281,1282],{},"the function",[232,1284,1285],{},[145,1286,1287],{},"message_handler",[214,1289,1290,1296,1298],{},[232,1291,1292,1293],{},"click, asyncclick, rich-click, cloup, typer, Flask ",[145,1294,1295],{},"@app.cli.command()",[232,1297,1282],{},[232,1299,1300],{},[145,1301,1302],{},"cli_command",[141,1304,1305,1308,1309,894,1311,1314,1315,1318,1319,153,1322,1325,1326,1328,1329,1332,1333,1336,1337,1339],{},[145,1306,1307],{},"pkg.mod:func"," is ",[145,1310,1129],{},[145,1312,1313],{},"via=\"entry_point\"",".\nA class target references that class's methods. A module target references its public functions. A typer or click object runs its registered commands.\nA local wrapper that registers the function it decorates passes the entry on to every function it wraps.\nTargets that cannot be resolved increment ",[145,1316,1317],{},"entry_points_unresolved"," (samples in the stats).\nAn external decorator with a receiver (",[145,1320,1321],{},"@app.route",[145,1323,1324],{},"@bus.subscribe",") is a ",[145,1327,607],{}," reference (",[145,1330,1331],{},"registry=\"external\"",").\nViews Django already wires through ",[145,1334,1335],{},"urls.py"," keep the route edge.\nCode that runs because a module was imported is not its own entry. Entry points computed by executing ",[145,1338,281],{}," are not read.",[424,1341,1343],{"className":426,"code":1342,"language":428,"meta":429,"style":429},"$ cg impact checks.check_size --db out\u002Fchecks.db\n  d=1 [function] checks.validate  (call through a collection)\n  d=3 [script] console script checks\n",[145,1344,1345,1352,1357],{"__ignoreMap":429},[433,1346,1347,1349],{"class":435,"line":436},[433,1348,440],{"class":439},[433,1350,1351],{"class":443}," cg impact checks.check_size --db out\u002Fchecks.db\n",[433,1353,1354],{"class":435,"line":447},[433,1355,1356],{"class":443},"  d=1 [function] checks.validate  (call through a collection)\n",[433,1358,1359],{"class":435,"line":453},[433,1360,1361],{"class":443},"  d=3 [script] console script checks\n",[141,1363,1364,1365,153,1368,153,1371,153,1374,153,1377,153,1379,180],{},"Plugin stats: ",[145,1366,1367],{},"references",[145,1369,1370],{},"decorator_calls",[145,1372,1373],{},"script_entries",[145,1375,1376],{},"registrations",[145,1378,1317],{},[145,1380,1381],{},"references_superseded",[182,1383,1385],{"id":1384},"tests-pytest-and-unittest","Tests (pytest and unittest)",[141,1387,1388,1389,153,1392,153,1395,158,1398,1401,1402,153,1405,153,1407,320,1410,1412,1413,1416,1417,153,1419,158,1422,1425],{},"Files pytest would collect are test code: ",[145,1390,1391],{},"python_files",[145,1393,1394],{},"python_classes",[145,1396,1397],{},"python_functions",[145,1399,1400],{},"testpaths"," from ",[145,1403,1404],{},"pytest.ini",[145,1406,315],{},[145,1408,1409],{},"tox.ini",[145,1411,269],{},", plus unittest cases.\n",[145,1414,1415],{},"cg tests"," lists direct and transitive tests. ",[145,1418,1152],{},[145,1420,1421],{},"callers",[145,1423,1424],{},"reaches"," count application callers only.",[141,1427,1428,1429,153,1432,1435,1436,1149,1439,1441,1442,1445,1446,656,1448,413,1451,153,1454,153,1457,1460],{},"Fixture chains, Django \u002F DRF \u002F FastAPI \u002F Flask HTTP test requests, and a subprocess that starts a project program (",[145,1430,1431],{},"TEST_CALLS",[145,1433,1434],{},"via: subprocess",", helpers followed up to 5 calls) are in ",[150,1437,394],{"href":1438},"\u002Fdocs\u002Fchannels-and-tests#tests",[145,1440,172],{}," adds a ",[145,1443,1444],{},"python tests:"," line: cases per framework, test files, fixtures, HTTP test requests, and how many reached a route.\nThe plugin stats carry the same under ",[145,1447,394],{},[145,1449,1450],{},"subprocess",[145,1452,1453],{},"linked",[145,1455,1456],{},"outside_project",[145,1458,1459],{},"unresolved",", with samples).",[182,1462,1464],{"id":1463},"web-routes","Web routes",[141,1466,1467,1468,259,1471,274,1474,1477,1478,1481,1482,1485,1486,1489,1490,1493,1494,180],{},"A project that depends on or imports ",[145,1469,1470],{},"fastapi",[145,1472,1473],{},"starlette",[145,1475,1476],{},"flask"," gets ",[145,1479,1480],{},"route:"," nodes and ",[145,1483,1484],{},"ROUTES_TO"," the handler.\nThe app, router, or blueprint is whatever the code assigns, returns, or receives (",[145,1487,1488],{},"create_app()",", a parameter, a pytest fixture of that name).\nA Flask subclass defined inside a function is a factory. Paths come from literals, f-strings, module constants, and settings attributes (",[145,1491,1492],{},"settings.API_V1_STR","). An unevaluable piece is ",[145,1495,1496],{},"{?}",[208,1498,1499,1509],{},[211,1500,1501],{},[214,1502,1503,1506],{},[217,1504,1505],{},"framework",[217,1507,1508],{},"what becomes a route",[227,1510,1511,1541,1582,1632,1671],{},[214,1512,1513,1516],{},[232,1514,1515],{},"FastAPI",[232,1517,1518,259,1521,1524,1525,153,1528,153,1531,153,1534,1537,1538],{},[145,1519,1520],{},"@router.get",[145,1522,1523],{},"post"," \u002F …, ",[145,1526,1527],{},"api_route",[145,1529,1530],{},"add_api_route",[145,1532,1533],{},"@app.websocket",[145,1535,1536],{},"include_router"," prefixes, ",[145,1539,1540],{},"dependencies=",[214,1542,1543,1546],{},[232,1544,1545],{},"Starlette",[232,1547,1548,153,1551,153,1554,153,1557,153,1560,153,1563,1566,1567,240,1570,1573,1574,1577,1578,1581],{},[145,1549,1550],{},"Route",[145,1552,1553],{},"Mount",[145,1555,1556],{},"WebSocketRoute",[145,1558,1559],{},"Router",[145,1561,1562],{},"add_route",[145,1564,1565],{},"HTTPEndpoint"," (one route per method). ",[145,1568,1569],{},"{id:int}",[145,1571,1572],{},"{id}",". ",[145,1575,1576],{},"Host(\"api.example.com\", …)"," sets ",[145,1579,1580],{},"host",", not the path",[214,1583,1584,1587],{},[232,1585,1586],{},"Flask",[232,1588,1589,153,1592,153,1595,153,1598,1601,1602,1605,1606,240,1609,153,1611,240,1614,1617,1618,1621,1622,413,1625,1628,1629,718],{},[145,1590,1591],{},"@bp.route",[145,1593,1594],{},"@bp.get",[145,1596,1597],{},"add_url_rule",[145,1599,1600],{},"MethodView.as_view",", nested ",[145,1603,1604],{},"register_blueprint"," (the registration prefix replaces the blueprint's). ",[145,1607,1608],{},"\u003Cint:id>",[145,1610,1572],{},[145,1612,1613],{},"\u003Cpath:p>",[145,1615,1616],{},"{p*}",". The endpoint name is what ",[145,1619,1620],{},"url_for"," takes. Built-in ",[145,1623,1624],{},"GET \u002Fstatic\u002F{filename}",[145,1626,1627],{},"static: true","; none when ",[145,1630,1631],{},"static_folder=None",[214,1633,1634,1637],{},[232,1635,1636],{},"class views",[232,1638,1639,1640,1643,1644,1647,1648,259,1651,1654,1655,259,1658,413,1661,153,1664,1667,1668],{},"fastapi-utils \u002F fastapi-restful ",[145,1641,1642],{},"@cbv",", classy-fastapi ",[145,1645,1646],{},"Routable",", flask-restful \u002F flask-restx ",[145,1649,1650],{},"add_resource",[145,1652,1653],{},"@ns.route",", Flask ",[145,1656,1657],{},"View",[145,1659,1660],{},"MethodView",[145,1662,1663],{},"methods",[145,1665,1666],{},"dispatch_request","), Flask-Classful ",[145,1669,1670],{},"X.register",[214,1672,1673,1676],{},[232,1674,1675],{},"Django",[232,1677,1678,1681,1682,1685,1686,1689,1690,1693,1694,153,1697,1700,1701,718],{},[145,1679,1680],{},"http_route"," (urls, django-ninja, DRF), ",[145,1683,1684],{},"websocket"," (Channels), ",[145,1687,1688],{},"queue_job"," (Celery), ",[145,1691,1692],{},"listener"," (signals), ",[145,1695,1696],{},"management_command",[145,1698,1699],{},"admin_panel",". GraphQL root fields are protocol endpoints (",[150,1702,91],{"href":92},[141,1704,1705,1706,1709,1710,1713,1714,1717,1718,656,1720,1723,1724,1727,1728,153,1731,1734,1735,1738,1739,1742,1743,1746],{},"A router or blueprint no app includes keeps its routes with ",[145,1707,1708],{},"mounted: false"," and no entry point.\nA ",[145,1711,1712],{},"for"," over a literal list of ",[145,1715,1716],{},"(path, view)"," is unrolled, one registration per element.\n",[145,1719,1580],{},[145,1721,1722],{},"subdomain"," are route attributes and part of the node id, so the same method and path on two hosts are two nodes.\n",[145,1725,1726],{},"add_url_rule(..., endpoint=\"index\")"," without a view takes ",[145,1729,1730],{},"@app.endpoint(\"index\")",[145,1732,1733],{},"view_functions[\"index\"]",", or another rule with that endpoint (",[145,1736,1737],{},"endpoint_alias",").\nA blueprint registered twice (",[145,1740,1741],{},"name=",", another ",[145,1744,1745],{},"url_prefix",") gets both sets of routes.",[141,1748,1749,1750,1753],{},"Access for ",[145,1751,1752],{},"cg routes --unguarded",":",[208,1755,1756,1765],{},[211,1757,1758],{},[214,1759,1760,1762],{},[217,1761,1168],{},[217,1763,1764],{},"recorded as",[227,1766,1767,1799,1836,1854,1865],{},[214,1768,1769,1787],{},[232,1770,1771,259,1774,1777,1778,1781,1782,1784,1785],{},[145,1772,1773],{},"Depends",[145,1775,1776],{},"Security",", including ",[145,1779,1780],{},"Annotated"," aliases and ",[145,1783,1540],{}," on the route, router, or ",[145,1786,1536],{},[232,1788,1789,1573,1792,1795,1796],{},[145,1790,1791],{},"attrs.access",[145,1793,1794],{},"Depends(RoleChecker(\"admin\"))"," is read from ",[145,1797,1798],{},"__call__",[214,1800,1801,1814],{},[232,1802,1803,1804,153,1807,153,1810,1813],{},"statuses, security schemes (",[145,1805,1806],{},"OAuth2PasswordBearer",[145,1808,1809],{},"HTTPBearer",[145,1811,1812],{},"APIKeyHeader","), headers, nested dependencies to depth 4",[232,1815,1816,1573,1819,1822,1823,1308,1826,1829,1830,320,1833],{},[145,1817,1818],{},"checks",[145,1820,1821],{},"auto_error=False"," does not reject. ",[145,1824,1825],{},"effect",[145,1827,1828],{},"rejects"," (401 \u002F 403), ",[145,1831,1832],{},"raises",[145,1834,1835],{},"reads",[214,1837,1838,1841],{},[232,1839,1840],{},"a rejecting dependency, whatever its name",[232,1842,1843,1844,1847,1848,153,1851,718],{},"an auth guard (",[145,1845,1846],{},"auth_by: dependency check","). A status raised in a helper it calls counts (",[145,1849,1850],{},"checks.checked_in",[145,1852,1853],{},"in \u003Chelper>",[214,1855,1856,1862],{},[232,1857,1858,1859],{},"Flask decorators such as ",[145,1860,1861],{},"@login_required",[232,1863,1864],{},"access on that view",[214,1866,1867,1877],{},[232,1868,1869,1872,1873,1876],{},[145,1870,1871],{},"app.add_middleware(X)"," when ",[145,1874,1875],{},"X"," is a project class, or a library class named like access control",[232,1878,1879,1882],{},[145,1880,1881],{},"via: middleware"," on that app's routes. CORS and GZip are skipped",[141,1884,1885],{},"Checks written in the handler body are not guards.",[141,1887,1888,153,1891,1894,1895,1898,1899,1902,1903,153,1906,1909,1910,1913,1914,1917,1918,1921],{},[145,1889,1890],{},"TestClient(app)",[145,1892,1893],{},"app.test_client()",", and fixtures that return one link to the route (",[145,1896,1897],{},"TEST_HTTP","), so ",[145,1900,1901],{},"cg tests \u003Chandler>"," lists them.\nWhen several routes fit, cg narrows by the request host (",[145,1904,1905],{},"subdomain=",[145,1907,1908],{},"base_url=",", a ",[145,1911,1912],{},"Host"," header, an absolute URL), then by routes the same test function registered, then the same module.\nA request that still has more than three candidates is dropped. An all-parameter route needs one literal segment unless that test registered it.\n",[145,1915,1916],{},"app.dependency_overrides[dep] = fake"," (in the test, a fixture it uses, or at module level) sets ",[145,1919,1920],{},"dependency_overrides"," on the edge.",[141,1923,1924,1925,1928,1929,1932,1933,1936,1937,656,1940,413,1943,646],{},"Sanic, Litestar, and Bottle decorators stay the ",[145,1926,1927],{},"python_decorator_routes"," blind spot.\nA pluggy-style registry that returns views, and a route added by an unknown library call, stay unmodelled.\nDjango ",[145,1930,1931],{},"include()"," targets and ",[145,1934,1935],{},"urlpatterns"," built in a loop are blind spots ",[145,1938,1939],{},"django_unresolved_include",[145,1941,1942],{},"django_dynamic_urlpatterns",[150,1944,1946],{"href":1945},"\u002Fdocs\u002Fcompleteness#blind-spots","blind spots",[182,1948,1950],{"id":1949},"validation","Validation",[141,1952,1953,1954,180],{},"Public-corpus counts for source roots, references, tests, and these routes are in ",[150,1955,119],{"href":120},[1957,1958,1959],"style",{},"html pre.shiki code .sZ_TN, html code.shiki .sZ_TN{--shiki-light:#71717A;--shiki-default:#71717A;--shiki-dark:#A1A1AA}html pre.shiki code .snmWg, html code.shiki .snmWg{--shiki-light:#27272A;--shiki-default:#27272A;--shiki-dark:#E4E4E7}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);}",{"title":429,"searchDepth":1961,"depth":447,"links":1962},4,[1963,1964,1965,1966,1967,1968,1969,1970,1971,1972,1973],{"id":184,"depth":447,"text":185},{"id":381,"depth":447,"text":382},{"id":515,"depth":447,"text":516},{"id":649,"depth":447,"text":650},{"id":768,"depth":447,"text":769},{"id":870,"depth":447,"text":871},{"id":927,"depth":447,"text":928},{"id":1015,"depth":447,"text":1016},{"id":1384,"depth":447,"text":1385},{"id":1463,"depth":447,"text":1464},{"id":1949,"depth":447,"text":1950},"What .py adds beyond Install, CLI specs, and Graph schema: source roots and module names, reference how values, and FastAPI \u002F Starlette \u002F Flask route ids.\nThe parser is the stdlib ast module. A checkout needs no virtualenv, and the project is never imported.\nWhy a file is unmapped: cg coverage. The python.source_roots key: Configuration.","md",{},true,{"title":95,"description":1974},"rNdOodh1nc94-P8Oz9XW2hKUcmfOLt70gKmeB5_CVe0",[1981,1983],{"title":91,"path":92,"stem":93,"description":1982,"children":-1},"cg pairs a sender with the code that receives it: HTTP, channels, Nest messages, job queues,\nevents, bridges, and named endpoints of messaging protocols. impact, reaches, path and\ndownstream cross those edges in one repo and, after cg link, between two. cg protocols\nlists endpoints with senders, receivers, guards and checks.",{"title":99,"path":100,"stem":101,"description":1984,"children":-1},"Install cg, index a sample, ask four questions, and connect an agent. Python 3.11+.",1792170235407]