GNOME Bugzilla – Bug 647249
Memory Error when trying to instantiate a disguised struct
Last modified: 2014-01-04 16:55:19 UTC
I tried to use GDateTime with python (ubuntu natty) and got the following error: $ python Python 2.7.1+ (r271:86832, Mar 24 2011, 00:39:14) [GCC 4.5.2] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> import gi >>> from gi.repository import GLib >>> GLib.DateTime() Traceback (most recent call last):
+ Trace 226660
MemoryError >>>
This cannot work, so we should be giving a better error message (and probably having an override for __init__). Note that in GDateTime's case, it is a boxed but for some reason g-i doesn't realize. See https://bugzilla.gnome.org/show_bug.cgi?id=647250
GLib.DateTime should probably just map to datetime.datetime
(In reply to comment #2) > GLib.DateTime should probably just map to datetime.datetime Which can be done by marking it as a foreign type in gobject-introspection, see how cairo.context is handled for an example.
(In reply to comment #3) > (In reply to comment #2) > > GLib.DateTime should probably just map to datetime.datetime > > Which can be done by marking it as a foreign type in gobject-introspection, see > how cairo.context is handled for an example. Actually it can't unless we all agree that it should be tagged as foreign in glib. Perhaps we should extend is_foreign to overrides so we can override some bits in python that might not be applicable to all of gi.
i get the same error when i try to create a GTimeZone. >>> tz = GLib.TimeZone() Traceback (most recent call last):
+ Trace 226843
MemoryError
I don't understand why eg GDate works, but GDateTime and GTimeZone not.
Annotations issues which don't list the true size of the struct so we can't malloc it. Use GLib.TimeZone.new, new_utc or new_local. These structs which pretend to be ref counted objects are hard to deal with in a generic way.
doesn't work with new: >>> from gi.repository import GLib >>> t = GLib.TimeZone.new() Traceback (most recent call last):
+ Trace 226878
>>> t = GLib.TimeZone().new() Traceback (most recent call last): File "<stdin>", line 1, in <module> MemoryError >>> t = GLib.TimeZone().new Traceback (most recent call last): File "<stdin>", line 1, in <module> MemoryError
I can confirm that with pygobject 3.2.0 the issues mentioned in comment 7 still remain.
These now seem to work: tz = GLib.TimeZone.new('foo') dt = GLib.DateTime.new(tz, 2013, 2, 28, 0, 0, 0.0) dt.format('%a %A %b %B %c %C %d %e %F') 'Thu Thursday Feb February Thu Feb 28 00:00:00 2013 20 28 28 2013-02-28' Perhaps the __new__ of these structures could be overridden to use "new" and this bug can be closed out.
Created attachment 236984 [details] Script to show memory errors in structs It seems there are a few of these so instead of specific overrides a general solution should be worked on. I think raising an exception listing the other available constructors would be a good idea. Something like: >>> dt = GLib.DateTime() ValueError: DateTime cannot be created directly. Please use one of the following class methods: new, new_local, new_now, new_now_local, ... The attached script shows the follow have the same problem: | GLib.Bytes | MemoryError | | GLib.Checksum | MemoryError | | GLib.DateTime | MemoryError | | GLib.HashTable | MemoryError | | GLib.IOChannel | TypeError | | GLib.MarkupParseContext | MemoryError | | GLib.MatchInfo | MemoryError | | GLib.Regex | MemoryError | | GLib.Thread | MemoryError | | GLib.TimeZone | MemoryError | | GLib.VariantType | MemoryError | | Gtk.CssSection | MemoryError | | Gtk.Gradient | MemoryError | | Gtk.PaperSize | MemoryError | | Gtk.RecentInfo | MemoryError | | Gtk.SelectionData | MemoryError | | Gtk.SymbolicColor | MemoryError | | Gtk.TargetList | MemoryError | | Gtk.TreeRowReference | MemoryError | | Gdk.FrameTimings | MemoryError |
The fix for this ends up looking exactly like the fix for bug 639972, except for Boxed not Struct. The only addition I would make (in both cases) is to add a more explicit instruction to help the API user out: ValueError: Cannot create GLib.DateTime, try using a constructor such as: GLib.DateTime.new(...) Listing all the available constructors would be too much work and the above gives enough of a hint that most people can figure out how to proceed on their own.
I've committed a change where we now get a TypeError similar to how disguised structs are handled but for boxed and union based objects. The error message gives a nice clue to look at the help which lists out available constructors: https://git.gnome.org/browse/pygobject/commit/?id=e835984 We now have all the breadcrumbs in place so at least a developer can figure stuff out a little easier: % ipython >>> from gi.repository import GLib >>> tz = GLib.TimeZone() TypeError: boxed cannot be created directly; try using a constructor, see: help(GLib.TimeZone) >>> GLib.TimeZone? :Constructors: new(identifier:str=None) new_local() new_utc() >>> tz = GLib.TimeZone.new_local() >>> tz <GTimeZone at 0x2e8f600> I'm going to leave this ticket open pending work on the idea that the default constructor could also dispatch to other constructors based on keyword arguments (essentially constructor overloading based upon keywords passed).
Dispatching constructor related work will occur in bug 721226.
*** Bug 680140 has been marked as a duplicate of this bug. ***