Repository navigation
Description
Problem
async def is not represented anywhere in the emitted schema. git grep -i "is_async"
on main returns nothing under codeanalyzer/schema/ or codeanalyzer/syntactic_analysis/.
The builder does match ast.AsyncFunctionDef — but only to find callables, never to
record what it found; PyCallable.kind is set to the literal "function" either way.
Verified on main (6f02581), fixture method async def fetch(self):
method 'fetch' kind=function decorators=["trace('method')"]
Nothing distinguishes it from a sync method. The only way to recover async-ness is to
slice module.source[span.bytes] and re-parse the text the analyzer already parsed.
This also hides await sites, async generators, and async with / async for from
anyone reading the tree rather than the source.
Scope boundary
Adds an async marker to callables. Does not model await as a distinct CFG or DDG
node kind, does not add async-aware dataflow, and does not touch the decorator issues
(#127, #128, #129).
Goals
-
PyCallablecarries an async marker, available from L1 - Set for
async defat every depth: module-level, method, nested closure - Async generators (
async defcontainingyield) are not misreported - Projected into Neo4j as a property on
:PyCallable - Bump Neo4j
SCHEMA_VERSION(additive)
Caveats and known risks
- Schema v2 change — enters at
designing-cldk-changes. Additive and defaulted, so
monotonicity and existing consumers are unaffected. kindvs a boolean is the decision to settle.kindis already a discriminant
("function","class","module","external"); adding"async_function"to it
would break every consumer switching onkind, whereas a separate boolean leaves
kindalone. Pick one deliberately — do not do both.- Sibling analyzers. TypeScript has
asynctoo. The field name should be the
canonical cross-language one, decided once here rather than renamed later. @staticmethod/@classmethod/@propertyare in the same situation — recoverable
only by string-matchingdecorators. Deliberately out of scope, but the same decision
shape; worth noting so it is not re-derived later.
Definition of done
- The fixture emits the async marker set on
Account.fetchand unset onAccount.helper - A module-level
async defand a nestedasync defclosure both carry it - An async generator carries it and is not confused with a plain generator
analysis.json(-a 1) ⊆ ... ⊆ (-a 4)still holds- Neo4j exposes the property and a query can select async callables without touching source
Activity