mirror of
https://github.com/colbymchenry/codegraph.git
synced 2026-10-28 22:52:00 +08:00
Python calls through an attribute reach the method the code gives that attribute: `self.sink.stop()` follows `self.sink = Sink()`, a `sink: Sink` annotation, a typed `__init__` parameter, a factory's return type or what every `return` in it builds, and a base class's `__init__` in another file. Calls straight on a factory's result (`Client.from_env().send()`) resolve the same way, and a sync re-opens these answers when the factory or base they were read from changes. The native Python extractor now keeps a call's receiver text as the wasm one does, so `self.data.append(1)` is never a bare `append` that matches an unrelated project function. This includes all of PR 1704. Reworked from evidence-or-silence, which dropped about 3,000 correct Django links (`self.client.get()`, `self.engine.render_to_string()`). The reader now has three answers. A project class that has the method: that method. Evidence that rules project methods out: no edge, for a builtin, a class from outside the project built in a method or named by an annotation, an attribute only an outside base can give (Django's `TestCase` in an app), or a class without the method whose bases are all known. Nothing typed: the call is guessed by the name of its last link, read as written, as any receiver is, but only for an owner whose name holds the link's head noun (`self.session` for `SessionBase`, not `database.group_shopping_lists` for `GroupRepositoryAIProvider`) and never as the one method of a name; the guess records the files the reader looked at, so a sync re-opens it too. A class-body field an outside class builds (`author = models.ForeignKey(Author)`) may be a descriptor, so it is no evidence. A chain through an imported module (`os.path.exists()`) is the module's. In the shared scoring, a receiver that spells an owner's whole name (`client` for `Client`) outscores one that only shares its word (`RedisCacheClient`). A call through an imported value's attribute chain (`app.jinja_env.filters.keys()`) no longer links to the value's `jinja_env`. A/B against main with fresh indexes, every changed edge triaged, sites matched by position since the extractor now names these calls by their whole chain. Django: 3,317 calls linked that were not (`self.client.force_login()` to `ClientMixin`, `User.objects.create_user()` to `UserManager`, `self.stdout.write()` to `OutputWrapper`), 127 moved, nearly all to a more precise target (`self.site.register()` to `AdminSite.register` rather than the `register` decorator), and 134 removed: main's bare-name links on builtin values (`value.lower()` to the template filter, `.encode()` to a test password hasher) and calls on expressions such as `(q1 | q2).order_by()`, which now go unresolved as they do in the wasm engine. flask: 32 linked, 4 moved to `JSONProvider`. fastapi: 58 linked. mealie: 740 linked. Guesses still wrong, as main makes them for a plain receiver of the same name: fastapi's `request.headers.get()` to a telemetry `_HeadersGetter`, and about 20 of mealie's repository attributes to a controller. Go, C#, Ruby, Swift, Kotlin, Java and TS repositories are byte-identical, except excalidraw's 5 `props.onChange()` calls, which move between two unrelated `Props` interfaces. Indexing CPU: Django +7%, mealie +5%, fastapi flat; wall time unchanged within noise. Full suite on the merged tree: 7,999 passed, 0 failed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
77 lines
2.0 KiB
Python
77 lines
2.0 KiB
Python
"""Python torture fixture — decorators, self fn-refs, imports, shadowing."""
|
|
import os, sys
|
|
import os.path as osp
|
|
from collections import OrderedDict, defaultdict
|
|
from .relative import thing
|
|
from mypkg.handlers import target_cb
|
|
|
|
RETRY_LIMITS = {"a": 1}
|
|
API_BASE = "https://example.test"
|
|
x = compute(RETRY_LIMITS)
|
|
|
|
|
|
class Service(BaseService, mixins.LoggerMixin):
|
|
"""Class docs."""
|
|
|
|
def __init__(self, registry):
|
|
self.registry = registry
|
|
register(self.on_event)
|
|
queue(target_cb)
|
|
|
|
@staticmethod
|
|
def helper(arg):
|
|
return transform(arg)
|
|
|
|
async def run(self):
|
|
cfg = self.registry.lookup("x")
|
|
limit = RETRY_LIMITS
|
|
obj.method_chain().deep(cfg)
|
|
", ".join(cfg)
|
|
return await fetch(API_BASE)
|
|
|
|
def on_event(self):
|
|
pass
|
|
|
|
|
|
@app.route("/x")
|
|
def view():
|
|
def inner():
|
|
return API_BASE
|
|
return inner()
|
|
|
|
|
|
def shadowed():
|
|
API_BASE = "local"
|
|
return API_BASE
|
|
|
|
|
|
handlers = {"recv": target_cb}
|
|
callbacks = [target_cb, view]
|
|
|
|
# Initializer walks attributed to the assigned name (#693).
|
|
INIT_EAGER = helper()
|
|
INIT_LAMBDA = lambda: target_cb()
|
|
INIT_MAP = {"a": helper()}
|
|
init_a, init_b = helper(), view()
|
|
|
|
# --- call receivers (#1683) ---------------------------------------------------
|
|
def bucket_chains(d, k, v):
|
|
d.setdefault(k, []).append(v)
|
|
d.items().get(k)
|
|
make().run()
|
|
(lambda: make)()().run()
|
|
obj.make().run().again()
|
|
|
|
|
|
# --- non-call, non-identifier receivers (#66) ---------------------------------
|
|
def fabrication_shapes(rows_by_file, key):
|
|
# Attribute chain and subscript. Each must keep its receiver text as a
|
|
# qualifier — a bare `append`/`get` exact-matches an unrelated project
|
|
# function of that name. (The call-chain shape lives in bucket_chains
|
|
# above, which #1748 encodes as `<inner>().<method>` instead.)
|
|
self_like = rows_by_file
|
|
self_like.rows.append({"x": 1})
|
|
rows_by_file[key].append(2)
|
|
rows_by_file[key].get(key, None)
|
|
return rows_by_file
|