-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
Refactor the complete ObjectHolder logic! #8885
Conversation
81dc7ba
to
1d232ef
Compare
1d232ef
to
45f7c51
Compare
This pull request introduces 1 alert and fixes 2 when merging 45f7c51 into 1086305 - view on LGTM.com new alerts:
fixed alerts:
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like the ideas, and in general I'm in favor for this, but I do think that InterpreterHeldObject
is looking at the problem backwards. The Build layer should be unaware of details of the Interpreter, just like the various *.Holder
classes are supposed to abstract the Build layer in the interpreter. I think it would be better to have a BuildObject
base class in the build
module, and have the interpreter holders act on that instead of the other way around.
There's also a bunch of conflicts that are going to pop up from my qt rework, which fixes most of the Generator and GeneratedList cludge that we have right now.
What dcbaker said. I always get confused which way around the ownership/inheritance arrows go in UML diagrams but |
The main reason why I want something like
Yeah, I know... But with such a big PR, conflicts will be unavoidable. |
Anyway, looks like I have some bad commits in my history. I will clean this up once the Qt module changes have landed. |
On the other hand this is too loose. The real limitation is that an ExecutableHolder can only hold an Executable. Dunno if that is doable with Mypy, though. Alternatively can't you specify that type to be an union of Executable, SharedLibrary etc? |
@jpakkane yeah, you can do that with mypy. We actually already do that, you use a Generic with specializations: T = typing.TypeVar('T')
class Holder(typing.Generic[T]):
pass
class ExecutableHolder(Holder[build.Executable]):
pass But you can constrain Holdable = typing.TypeVar('Holdable', BuildObject, str, covariant=True)
class Holder(typing.Generic[Holdable]):
pass
class ExecutableHolder(Holder[build.Executable]): # this is fine, assuming build.Executable = class Executable(BuildObject)
pass
class BytesHolder(Holder[bytes]): # mypy error
pass |
The other problem is that The current constraint of |
You wouldn't use |
@dcbaker So, we should list all possible base classes in the |
Yes, that should work. Though having a shared base class would make that easier, and I like the idea of all class Holdable(metaclass=abc.ABCMeta):
pass
@Holdable.register
class Target
pass |
I'm not a fan of overuse of inheritance, which this thing is approaching. A union type better describes the property of "this can be any of these unrelated types A, B and C". Sadly Python's syntax for that is not the greatest because it is basically a duck typed language. |
Well, the shared base class is what I was trying to achieve with From the current options, I would say I like the |
I'm fine with a base class, but that should be part of build and not part of the mesonlib or the interpreter, at least, that's my take. Maybe others have other opinions. |
Also, I forgot to mention that this PR turns off the type annotations for the |
Would it help if we had holders for everything, btw? I've really wanted to add a ListHolder, StringHolder, NumberHolder, BoolHolder, and DictHolder for a long time now... |
This was also my plan add the beginning of the refactoring, but for this we need the fundamentals from this PR.
This way we can also extract the custom logic for these basic types from InterpreterBase.
Also on where to put the base class: It can basically only be mesonlib because mesonlib.File is also a held object. And mesonlib cant depend on build.
--
Sent from my Android device with K-9 Mail. Please excuse my brevity.
|
Honest question, is there any reason |
OK, the Also, maybe I am doing something wrong, but using |
It's not really nice that one needs to add code and inheritance levels just to work around the limitations of some tool like this. :( |
Renamed Sorry @dcbaker, moving I am going to leave |
@mensinda I guess then let's go ahead and rebase and merge this. |
4331f9e
to
1ff6c83
Compare
Yeah, let's hope that the CI stays green. |
This pull request introduces 1 alert and fixes 2 when merging 1ff6c83 into 79fec1c - view on LGTM.com new alerts:
fixed alerts:
|
As a side-effect from mesonbuild#8885 `find_program()` returns now `Executable` objects when `meson.override_find_program` is called with an executable target. To resolve this conflict the missing methods from `ExternalProgram` are added to `BuildTarget`.
As a side-effect from mesonbuild#8885 `find_program()` returns now `Executable` objects when `meson.override_find_program` is called with an executable target. To resolve this conflict the missing methods from `ExternalProgram` are added to `BuildTarget`.
As a side-effect from mesonbuild#8885 `find_program()` returns now `Executable` objects when `meson.override_find_program` is called with an executable target. To resolve this conflict the missing methods from `ExternalProgram` are added to `BuildTarget`.
As a side-effect from #8885 `find_program()` returns now `Executable` objects when `meson.override_find_program` is called with an executable target. To resolve this conflict the missing methods from `ExternalProgram` are added to `BuildTarget`.
OK, first of all, this PR ended up being a lot more involved (read bigger) than anticipated. At the same time, I don't think that it would be a good idea to split this PR, since doing this refactoring half-baked can get really complicated really fast. With this current, admittedly huge, PR, there is a clear before and after state.
Still, sorry for this big PR...
This PR is a complete overhaul of the
ObjectHolder
/holderify
/unholder
mechanism:Now all objects that can be held by an
ObjectHolder
must be derived fromInterpreterHeldObject
. Additionally,ObjectHolder
now directly inherits fromInterpreterObject
. Non-Object holders can be differentiated by inheriting fromMesonInterpreterObject
. They must not directly inherit fromInterpreterObject
.This setup ensures that it can always be checked whether an object is present in its "held" or "raw" state. The dummy
MesonInterpreterObject
class ensures that non-ObjectHolders (likeMesonMain
) are not affected by this change.The next big change in this PR is a clear separation where
ObjectHolder
s and the plain objects are used. Additionally,InterpreterBase
is now the sole instance in charge of holderifying and unholderifying objects. It is also the only class that should now deal withObjectHolder
s. Called functions and methods will now always receive the "raw" objects instead ofObjectHolder
s. Additionally, interpreter functions and methods now must not returnObjectHolder
s (as in, doing so is now a hard error).Code example before:
Code example after: