This issue tracker has been migrated to GitHub ,
and is currently read-only.
For more information,
see the GitHub FAQs in the Python's Developer Guide.
Created on 2013年06月21日 01:33 by brett.cannon, last changed 2022年04月11日 14:57 by admin. This issue is now closed.
| Files | ||||
|---|---|---|---|---|
| File name | Uploaded | Description | Edit | |
| simple_diamond_example.py | rhettinger, 2013年06月21日 22:22 | Simple diamond example | ||
| Messages (12) | |||
|---|---|---|---|
| msg191550 - (view) | Author: Brett Cannon (brett.cannon) * (Python committer) | Date: 2013年06月21日 01:33 | |
class A: pass class B(A): pass sup = super(B, B()) isinstance(sup, A) # returns False Why is that? Is there an explicit reason to prevent that isinstance check from working? How about just for ABCs? Either way it's annoying that at least for ABCs you can't check against a super object. |
|||
| msg191559 - (view) | Author: Antoine Pitrou (pitrou) * (Python committer) | Date: 2013年06月21日 08:52 | |
Does anyone actually check for instance-ness of super objects? I would never have thought of such an idiom. |
|||
| msg191581 - (view) | Author: Brett Cannon (brett.cannon) * (Python committer) | Date: 2013年06月21日 13:55 | |
So I have a use case for this actually. =) http://bugs.python.org/issue17621 is about trying to finally add a lazy mixin to importlib so people stop asking for it. I have a version already written externally at https://code.google.com/p/importers/source/browse/importers/lazy.py. Part of the trick of making it work is having a way to drop the lazy mixin from the loader MRO for all future uses (which is important for reloads) is to assign __loader__ to super(Mixin, self). The problem is that if you use isinstance on that loader with any of the ABCs in importlib.abc it will always come back false no matter whether the interface is actually implemented or not. While I consider it a marginal thing for people to do (importlib.abc is for making sure people implement the right methods and providing default implementations, not for interface checking), I'm sure someone will do it and I would like one less possible warning in any future docs about this lazy mixin regarding isinstance checks. |
|||
| msg191582 - (view) | Author: Antoine Pitrou (pitrou) * (Python committer) | Date: 2013年06月21日 14:02 | |
> http://bugs.python.org/issue17621 is about trying to finally add a > lazy mixin to importlib so people stop asking for it. I have a > version already written externally at > https://code.google.com/p/importers/source/browse/importers/lazy.py. > Part of the trick of making it work is having a way to drop the lazy > mixin from the loader MRO for all future uses (which is important > for reloads) is to assign __loader__ to super(Mixin, self). That sounds like a better job for a proxy rather than a mixin. |
|||
| msg191590 - (view) | Author: Brett Cannon (brett.cannon) * (Python committer) | Date: 2013年06月21日 15:01 | |
On Fri, Jun 21, 2013 at 10:02 AM, Antoine Pitrou <report@bugs.python.org>wrote: > > Antoine Pitrou added the comment: > > > http://bugs.python.org/issue17621 is about trying to finally add a > > lazy mixin to importlib so people stop asking for it. I have a > > version already written externally at > > https://code.google.com/p/importers/source/browse/importers/lazy.py. > > Part of the trick of making it work is having a way to drop the lazy > > mixin from the loader MRO for all future uses (which is important > > for reloads) is to assign __loader__ to super(Mixin, self). > > That sounds like a better job for a proxy rather than a mixin. > I'm attracted to the idea of making a loader lazy by simply doing something like ``class LazySourceFileLoader(LazyMixin, SourceFileLoader): ...``. The key thing is that it doesn't require proxying the constructor in situations like PathEntryFinder where the finder is going to be making your loader instance (or at least calling the object). I mean you could override __call__ to store the arguments and then simply use them when needed to construct the real loader, but I don't know if that makes the code simpler without actually coding it up. |
|||
| msg191592 - (view) | Author: Antoine Pitrou (pitrou) * (Python committer) | Date: 2013年06月21日 15:11 | |
> I'm attracted to the idea of making a loader lazy by simply doing > something > like ``class LazySourceFileLoader(LazyMixin, SourceFileLoader): > ...``. But then you have to make a specific Lazy subclass for each delegated loader implementation. With a proxy class you would simply proxy each loader instance: existing_loader = SourceFileLoader(...) lazy_loader = LazyLoader(existing_loader) ... |
|||
| msg191602 - (view) | Author: Brett Cannon (brett.cannon) * (Python committer) | Date: 2013年06月21日 17:51 | |
On Fri, Jun 21, 2013 at 11:11 AM, Antoine Pitrou <report@bugs.python.org>wrote: > > Antoine Pitrou added the comment: > > > I'm attracted to the idea of making a loader lazy by simply doing > > something > > like ``class LazySourceFileLoader(LazyMixin, SourceFileLoader): > > ...``. > > But then you have to make a specific Lazy subclass for each delegated > loader implementation. With a proxy class you would simply proxy each > loader instance: > > existing_loader = SourceFileLoader(...) > lazy_loader = LazyLoader(existing_loader) > ... But the point I tried to make earlier is that approach doesn't work directly when you are creating the loader instances dynamically within a finder. E.g. FileFinder ( http://docs.python.org/3/library/importlib.html#importlib.machinery.FileFinder) instantiates the loader for you. Now you could tweak things to make this work, but it isn't quite as straightforward as you suggest because of this need to have a callable for finders to use to create new loaders: class LazyProxy(importlib.abc.Loader): def __init__(self, loader): self.loader = loader def __call__(self, *args, **kwargs): self.args = args self.kwargs = kwargs return self def load_module(self, fullname): # XXX ignoring sys.modules details, e.g. if module already existed. lazy_module = LazyModule(fullname, proxy=self, name=fullname) sys.modules[fullname] = lazy_module return lazy_module class LazyModule(types.ModuleType): def __init__(*args, proxy, name, **kwargs): self.__proxy = proxy self.__name = name super().__init__(*args, **kwargs) def __getattribute__(self, attr): self.__class__ = Module state = self.__dict__.copy() loader = self.__proxy.loader(*self.proxy.args, **self.proxy.kwargs) # XXX ignoring sys.modules details, e.g. removing module on load failure. loader.load_module(self.__name) self.__dict__.update(state) return getattr(module, attr) That's all totally untested (not even verified to compile) but I think that would do what you are suggesting. |
|||
| msg191605 - (view) | Author: Raymond Hettinger (rhettinger) * (Python committer) | Date: 2013年06月21日 19:22 | |
I'm not sure this is a theoretically sound idea. Do you know what CLOS does in the same circumstance? |
|||
| msg191607 - (view) | Author: Brett Cannon (brett.cannon) * (Python committer) | Date: 2013年06月21日 19:57 | |
I have no idea what CLOS does in this situation. I'm fine with this never being changed, but I wanted to at least file the bug to have the discussion in case it ever comes up again. |
|||
| msg191615 - (view) | Author: Raymond Hettinger (rhettinger) * (Python committer) | Date: 2013年06月21日 22:22 | |
> I have no idea what CLOS does in this situation. No worries, I was just curious whether you knew whether this was a solved problem in Dylan or CLOS or some other language. When faced with a diamond diagram, what are the semantics for isinstance(super_instance, cls)? I worked on it for a little bit and came up with the following: def super_isinstance(super_inst, cls): 'Is the cls in the mro somewhere after the current class?' mro = super_inst.__self__.__class__.__mro__ thisclass = super_inst.__thisclass__ return cls in mro and mro.index(thisclass) < mro.index(cls) |
|||
| msg191619 - (view) | Author: Brett Cannon (brett.cannon) * (Python committer) | Date: 2013年06月21日 22:40 | |
That solution looks right. Problem is that it would need to either go directly into isinstance() or type would need to grow an __instancecheck__ to deal with this case since you can't override isinstance from the instance end. That I'm not sure people are okay with. |
|||
| msg363542 - (view) | Author: Brett Cannon (brett.cannon) * (Python committer) | Date: 2020年03月06日 20:21 | |
After 6 years and no really movement I don't think we are going to bother to change the semantics for this. :) |
|||
| History | |||
|---|---|---|---|
| Date | User | Action | Args |
| 2022年04月11日 14:57:47 | admin | set | github: 62475 |
| 2020年03月06日 20:21:57 | brett.cannon | set | status: open -> closed resolution: wont fix messages: + msg363542 stage: test needed -> resolved |
| 2014年02月06日 19:02:54 | brett.cannon | unlink | issue17621 dependencies |
| 2013年06月22日 09:44:49 | Arfrever | set | nosy:
+ Arfrever |
| 2013年06月21日 22:40:13 | brett.cannon | set | messages: + msg191619 |
| 2013年06月21日 22:35:08 | brett.cannon | link | issue17621 dependencies |
| 2013年06月21日 22:22:49 | rhettinger | set | files:
+ simple_diamond_example.py messages: + msg191615 |
| 2013年06月21日 19:57:06 | brett.cannon | set | messages: + msg191607 |
| 2013年06月21日 19:22:20 | rhettinger | set | nosy:
+ rhettinger messages: + msg191605 |
| 2013年06月21日 17:51:13 | brett.cannon | set | messages: + msg191602 |
| 2013年06月21日 15:11:22 | pitrou | set | messages: + msg191592 |
| 2013年06月21日 15:01:38 | brett.cannon | set | messages: + msg191590 |
| 2013年06月21日 14:02:22 | pitrou | set | messages: + msg191582 |
| 2013年06月21日 13:55:49 | brett.cannon | set | priority: normal -> low messages: + msg191581 |
| 2013年06月21日 08:52:45 | pitrou | set | nosy:
+ pitrou, benjamin.peterson messages: + msg191559 |
| 2013年06月21日 01:33:23 | brett.cannon | create | |