After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 602830 - Improve support for overrides
Improve support for overrides
Status: RESOLVED FIXED
Product: pygi
Classification: Deprecated
Component: general
unspecified
Other All
: High normal
: 0.6
Assigned To: Simon van der Linden
pygi-maint
Depends on: 603036 603536
Blocks:
 
 
Reported: 2009-11-24 13:58 UTC by Johan (not receiving bugmail) Dahlin
Modified: 2010-02-03 19:36 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
Remove trailing whitespace (864 bytes, patch)
2009-11-24 13:58 UTC, Johan (not receiving bugmail) Dahlin
committed Details | Review
Add a new decorators file (1.70 KB, patch)
2009-11-24 13:58 UTC, Johan (not receiving bugmail) Dahlin
reviewed Details | Review
Do not always override the __new__ methods (908 bytes, patch)
2009-11-24 13:58 UTC, Johan (not receiving bugmail) Dahlin
rejected Details | Review
Override Gdk.Rectangle constructor and __repr__ (1.76 KB, patch)
2009-11-24 13:58 UTC, Johan (not receiving bugmail) Dahlin
reviewed Details | Review
Pythonify. Avoid ; and () around if statements (1.43 KB, patch)
2009-11-24 14:02 UTC, Johan (not receiving bugmail) Dahlin
committed Details | Review
Another idea (draft) (5.84 KB, patch)
2009-11-25 22:28 UTC, Simon van der Linden
needs-work Details | Review
Restore the overrides modules (7.49 KB, patch)
2009-11-27 22:04 UTC, Simon van der Linden
reviewed Details | Review
Restore the overrides modules (7.86 KB, patch)
2009-12-01 22:29 UTC, Simon van der Linden
none Details | Review
Refactore the overrides modules, with tests (13.71 KB, patch)
2010-01-05 21:28 UTC, Simon van der Linden
committed Details | Review

Description Johan (not receiving bugmail) Dahlin 2009-11-24 13:58:42 UTC
We should improve the support for overrides, for instance
it should be possible to overriden constructors and __repr__
methods.

This series will also include two patches for cleaning up
trailing whitespace and other non-pythonic things
Comment 1 Johan (not receiving bugmail) Dahlin 2009-11-24 13:58:45 UTC
Created attachment 148387 [details] [review]
Remove trailing whitespace
Comment 2 Johan (not receiving bugmail) Dahlin 2009-11-24 13:58:49 UTC
Created attachment 148388 [details] [review]
Add a new decorators file

With one decorator so far, used to override classes/methods
Comment 3 Johan (not receiving bugmail) Dahlin 2009-11-24 13:58:53 UTC
Created attachment 148389 [details] [review]
Do not always override the __new__ methods

If it's implemented in a subclass, let the subclass __new__
class method be called instead
Comment 4 Johan (not receiving bugmail) Dahlin 2009-11-24 13:58:57 UTC
Created attachment 148390 [details] [review]
Override Gdk.Rectangle constructor and __repr__

Increases PyGTK compatibility by allow keyword
arguments to the constructor and adds a nicer __repr__
Comment 5 Johan (not receiving bugmail) Dahlin 2009-11-24 14:02:41 UTC
Created attachment 148391 [details] [review]
Pythonify. Avoid ; and () around if statements
Comment 6 Simon van der Linden 2009-11-24 14:07:47 UTC
Review of attachment 148387 [details] [review]:

OK.
Comment 7 Simon van der Linden 2009-11-24 14:20:06 UTC
Review of attachment 148391 [details] [review]:

OK.
Comment 8 Tomeu Vizoso 2009-11-24 17:11:44 UTC
Review of attachment 148388 [details] [review]:

::: gi/decorators.py
@@ +4,3 @@
+# Copyright (C) 2009 Johan Dahlin <johan@gnome.org>
+#
+#   decorators.py: decoratores used in PyGI

typo
Comment 9 Tomeu Vizoso 2009-11-24 17:14:19 UTC
Review of attachment 148390 [details] [review]:

Thanks!
Comment 10 Simon van der Linden 2009-11-25 09:23:18 UTC
Can we imagine a more elegant way to define overrides? (with a metaclass maybe?)
Comment 11 Simon van der Linden 2009-11-25 22:28:39 UTC
Created attachment 148491 [details] [review]
Another idea (draft)

Here is another idea. I put a ModuleProxy instance in front of the DynamicModule instance and the OverridesModule instance, so that the OverridesModule can actually be a real module, and "import" the DynamicModule instance.

There are still a couple of issues to be resolved (not particular to that implementation):
 - when one overrides a registered wrapper, the overrides type must be registered instead. I added the override decorator for that; it needs a support in C (and could be completely implemented in C actually)
 - in metaclasses, the comparison of the names to avoid doing the initialization stuff on the subclass doesn't work when the subclass has the same name. This must be changed to allow overriding.

And probably some other subtle issues...
Comment 12 Simon van der Linden 2009-11-27 22:04:26 UTC
Created attachment 148624 [details] [review]
Restore the overrides modules

A complete implementation.
Comment 13 Simon van der Linden 2009-11-27 22:08:03 UTC
Review of attachment 148389 [details] [review]:

This has been fixed by bug 603036.
Comment 14 Simon van der Linden 2009-11-27 22:09:23 UTC
Review of attachment 148390 [details] [review]:

Waiting for discussion about the other implementation.
Comment 15 Simon van der Linden 2009-11-27 22:09:45 UTC
Review of attachment 148388 [details] [review]:

Ditto.
Comment 16 Tomeu Vizoso 2009-11-28 17:18:02 UTC
Review of attachment 148624 [details] [review]:

I'm fine with it but would be nice if Johan gave it a look and said if it matches his needs. Though I would like to see this committed soonish because I have work to do with overrides.
Comment 17 Johan (not receiving bugmail) Dahlin 2009-11-30 21:24:43 UTC
Review of attachment 148624 [details] [review]:

::: gi/module.py
@@ -77,3 +77,3 @@
 class DynamicModule(object):
-        path = repository.get_typelib_path(self.__namespace__)
-    def __str__(self):
+        self.__namespace__ = namespace
+    def __init__(self, namespace):

Excessive use of _

@@ -86,3 +82,3 @@
         if not info:
         info = repository.find_by_name(self.__namespace__, name)
-            raise AttributeError("%r object has no attribute %r" % (
+            raise AttributeError

Could use a better exception string

@@ -161,6 +156,9 @@
-    def __members__(self):
-        r = []
-        for type_info in repository.get_infos(self.__namespace__):
... 3 more ...
+        self.__name__ = name
+        return "<DynamicModule %r from %r>" % (self.__namespace__, path)
+
... 6 more ...

Why the excessive use of _ ?

@@ -161,6 +156,15 @@
-    @property
-        return r
-    def __members__(self):
... 3 more ...
+        return "<DynamicModule %r from %r>" % (self.__namespace__, path)
+        path = repository.get_typelib_path(self.__namespace__)
+
... 12 more ...

Will the ModuleProxy ever proxy more than two modules?

attr = getattr(self._proxy_module, name, None)
if attr is None:
   attr = getattr(self._generated_module, name, None)

if attr is None:
   raise AttributeError(..)
return attr

@@ -161,6 +156,16 @@
-        for type_info in repository.get_infos(self.__namespace__):
-        return r
-            r.append(type_info.get_name())
... 3 more ...
+        path = repository.get_typelib_path(self.__namespace__)
+
+    def __repr__(self):
... 13 more ...

You shouldn't call hasattr and then getattr, better to just do one getattr call and pass in None as the default argument.

@@ -161,6 +156,18 @@
-        r = []
-            r.append(type_info.get_name())
-        return r
... 3 more ...
+        self.__name__ = name
+
+        path = repository.get_typelib_path(self.__namespace__)
... 15 more ...

Ditto

@@ -161,6 +156,27 @@
-        r = []
-            r.append(type_info.get_name())
-        return r
... 3 more ...
+class ModuleProxy(object):
+
+        path = repository.get_typelib_path(self.__namespace__)
... 24 more ...

There's no need for this, python will update __dict__ for you after a successful call to __getattr__

::: gi/overrides/Gdk.py
@@ -6,1 +16,1 @@
 

Can you please implement __repr__ here as well, as I did in my patch?
And add a test case that it actually works.

@@ +18,1 @@
+__export__ = [Rectangle]

Perhaps __overridden__ = [] or even __all__ = [] ?
Comment 18 Johan (not receiving bugmail) Dahlin 2009-11-30 21:24:44 UTC
Review of attachment 148624 [details] [review]:

::: gi/module.py
@@ -77,3 +77,3 @@
 class DynamicModule(object):
-        path = repository.get_typelib_path(self.__namespace__)
-    def __str__(self):
+        self.__namespace__ = namespace
+    def __init__(self, namespace):

Excessive use of _

@@ -86,3 +82,3 @@
         if not info:
         info = repository.find_by_name(self.__namespace__, name)
-            raise AttributeError("%r object has no attribute %r" % (
+            raise AttributeError

Could use a better exception string

@@ -161,6 +156,9 @@
-    def __members__(self):
-        r = []
-        for type_info in repository.get_infos(self.__namespace__):
... 3 more ...
+        self.__name__ = name
+        return "<DynamicModule %r from %r>" % (self.__namespace__, path)
+
... 6 more ...

Why the excessive use of _ ?

@@ -161,6 +156,15 @@
-        r = []
-            r.append(type_info.get_name())
-        return r
... 3 more ...
+    def __init__(self, name, namespace, modules):
+
+        path = repository.get_typelib_path(self.__namespace__)
... 12 more ...

Will the ModuleProxy ever proxy more than two modules?

attr = getattr(self._proxy_module, name, None)
if attr is None:
   attr = getattr(self._generated_module, name, None)

if attr is None:
   raise AttributeError(..)
return attr

@@ -161,6 +156,16 @@
-    @property
-        return r
-    def __members__(self):
... 3 more ...
+        return "<DynamicModule %r from %r>" % (self.__namespace__, path)
+        path = repository.get_typelib_path(self.__namespace__)
+
... 13 more ...

You shouldn't call hasattr and then getattr, better to just do one getattr call and pass in None as the default argument.

@@ -161,6 +156,18 @@
-        r = []
-        return r
-            r.append(type_info.get_name())
... 3 more ...
+
+
+        path = repository.get_typelib_path(self.__namespace__)
... 15 more ...

Ditto

@@ -161,6 +156,27 @@
-        r = []
-            r.append(type_info.get_name())
-        return r
... 3 more ...
+                    attribute = None
+
+        path = repository.get_typelib_path(self.__namespace__)
... 24 more ...

There's no need for this, python will update __dict__ for you after a successful call to __getattr__

::: gi/overrides/Gdk.py
@@ -6,1 +16,1 @@
 

Can you please implement __repr__ here as well, as I did in my patch?
And add a test case that it actually works.

@@ +18,1 @@
+__export__ = [Rectangle]

Perhaps __overridden__ = [] or even __all__ = [] ?
Comment 19 Simon van der Linden 2009-12-01 22:29:13 UTC
Created attachment 148865 [details] [review]
Restore the overrides modules
Comment 20 Simon van der Linden 2010-01-05 21:28:06 UTC
Created attachment 150859 [details] [review]
Refactore the overrides modules, with tests
Comment 21 Simon van der Linden 2010-01-22 12:43:18 UTC
Review of attachment 150859 [details] [review]:

Committed as eaf7cb8e.
Comment 22 Simon van der Linden 2010-01-22 21:40:07 UTC
Damn, I forgot to add gi/overrides/TestGI.py to the patch. Need to fix that.
Comment 23 Simon van der Linden 2010-02-03 19:36:24 UTC
Fixed in commit 5106523a.