-
Notifications
You must be signed in to change notification settings - Fork 176
PR: Remove strange indirections in pynamesdef & pyobjectsdef #602
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
It's nothing "mysterious". Just because the behavior is the same, doesn't mean they are semantically equivalent. Some functions can only work because rope can find the definition of objects/names (e.g. The rope code doesn't always distinguish them in implementations, but these are three conceptually different facets of objects that shouldn't be mixed together, therefore they have separate types. It's not often always necessary that rope treats the different facets differently, but it's often very necessary to understand the intent of the code when trying to comprehend what the code is trying to do. In a sense, it is kinda a form of lexical type hinting, with no strict runtime typing. Removing these distinctions may not cause rope to behave any differently, but the codebase will lose information about the original intent of the author; and if we want to add standard Also, my understanding from reading the git history is that part of the reason the original author made the pynames/pynamesdef and pyobjects/pyobjects def distinctions is because when it was originally implemented within the same module, it was causing pathological circular import issues. Trying to merge these modules again, you're likely going to hit the same issue again at some point. |
|
@lieryan I remain unconvinced. I am working on a proof that the supposedly important distinction is empty. This proof will involve a detailed examination of all the Please stay tuned. |
|
@lieryan I was mistaken. The present diffs do not suffice for the proof. |
|
@lieryan Hiding in plain sight in the diffs--the PR changes the qualifications of only 6 names: Surprise! Rope already explicitly distinguishes between three kinds of names. A full proof must examine how Rope uses these 6 names. |
|
@lieryan I am committed to convincing you that this PR (and others) are sound and that the old code is just plain wrong.
Unlike legislators and courts, Rope devs need not worry about "original intent" :-) Python has come a long way since Rope's early days.
Imo, this statement is mistaken, for two reasons. First, mypy is extraordinarily easy to use. Second, there is no lost information to re-discover! This PR and (the closed, still desirable) PR #539 will surely make mypy's task easier. BTW, after learning about postponed evaluations, I created Leo PR #3004. The PR changed 70 files for the better. The big surprise was that eliminating the I'll create a new PR that annotates at least the 6 classes whose qualifications this PR changes, namely AssignmentValue, DefinedName, EvaluatedName, ImportedModule, ImportedName, and UnboundName, QQQ I have a lot of experience with avoiding circular references. I'll create a new PR demonstrating that merging pynames/pynamesdef and pyobjects/pyobjectsdef can be done without fuss. Summary Too much respect for original intent and existing code is tying Rope's code into knots. It's time to move on. I'll create two new PRs that will show:
|
I doubt that any "proof" will convince you to eliminate empty distinctions. Still, I have enjoyed my investigations--they have deepened my understanding of Rope. Only the following files reference the 6 There is no need to discuss pynames.py and pynamesdef.py here. These files merely define the Some of these files have nothing directly to do with soi: pickle.py is a utility. codeassist.py, move.py, and rename.py are clients of soi: they use soi but have no effect on soi. The following files are involved with soi: builtins.py references only pyscopes.py references only evaluate.py: The soi.py contains only the following straightforward references to
Summary This analysis does not prove that this PR is sound. Happily, a clean bill of health from pyflakes and pytest should suffice! I have dug deep to convince myself that eliminating the empty distinctions between I don't expect this analysis to be completely persuasive. Perhaps yet another PR will (at last!!) put this debate to rest. |
rope/base/oi/soi/pynamesdef.py contains the following mysterious imports:
This PR suggests that these imports should be:
Failing unit tests highlight the ostensible reason for the
import *, namely even more mysterious indirections inrope.base.pyobjectsdef.The diffs are revealing. The old code (in
rope.base.pyobjectsdef) refers to a class X as if it resided inrope.base.pynamesdef. In fact, class X resides inrope.base.pynames.For each class X, cffs (global searches) reveal that there is only one class X anywhere in Rope with that name. There can be no doubt that the proposed code works exactly the same way as the legacy code.
What is going on???
I am at a loss for a reasonable explanation for the legacy code.
Could the misleading qualifications in
rope.base.pyobjectsdefbe a bizarre form of comment? If so, there are better solutions:rope.base.pyobjectsdef.rope.base.pyobjectsdef.rope.base.pynamesdef.Any of these fixes would be preferable to the present code.
@lieryan Do you have any explanation for these mysteries?
P.S. I am beginning to wonder whether the original author might have deliberately used weird constructions as a kind of old-fashioned unit test. 50 years ago, when I was a graduate student in CS at U.W. Wisconsin, the state of the art in testing compilers was to compile the compiler with itself. (The round-trip should be identical) Yes, such tests are woefully inadequate, but that was a long time ago.