forked from Ghini/ghini.desktop
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Starting at porting py2 pygtk to py3 PyGObject
Steps here: - ran remove_utf-8.py (included here) via find for all .py files. - ran pygi-convert.sh via find also - ran $ 2to3 -f all . > refact_2to3.txt (included here) to capture the diff of the changes to be made. - ran $ 2to3 -w -f all . and copied the messages to refact_2to3_messages.txt (included here)
- Loading branch information
Showing
116 changed files
with
20,884 additions
and
4,391 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,3 @@ | ||
# -*- coding: utf-8 -*- | ||
# | ||
# Copyright (c) 2005,2006,2007,2008,2009 Brett Adams <[email protected]> | ||
# Copyright (c) 2012-2017 Mario Frasca <[email protected]> | ||
# Copyright 2017 Jardín Botánico de Quito | ||
|
@@ -82,9 +80,9 @@ def pb_release(): | |
os.pathsep, os.environ['PATH']) | ||
|
||
|
||
# if not hasattr(gtk.Widget, 'set_tooltip_markup'): | ||
# if not hasattr(Gtk.Widget, 'set_tooltip_markup'): | ||
# msg = _('Ghini requires GTK+ version 2.12 or greater') | ||
# utils.message_dialog(msg, gtk.MESSAGE_ERROR) | ||
# utils.message_dialog(msg, Gtk.MessageType.ERROR) | ||
# sys.exit(1) | ||
|
||
# make sure we look in the lib path for modules | ||
|
@@ -130,18 +128,18 @@ def quit(): | |
""" | ||
Stop all tasks and quit Ghini. | ||
""" | ||
import gtk | ||
from gi.repository import Gtk | ||
import bauble.utils as utils | ||
try: | ||
import bauble.task as task | ||
except Exception, e: | ||
except Exception as e: | ||
logger.error('bauble.quit(): %s' % utils.utf8(e)) | ||
else: | ||
task.kill() | ||
try: | ||
save_state() | ||
gtk.main_quit() | ||
except RuntimeError, e: | ||
Gtk.main_quit() | ||
except RuntimeError as e: | ||
# in case main_quit is called before main, e.g. before | ||
# bauble.main() is called | ||
sys.exit(1) | ||
|
@@ -161,14 +159,14 @@ def command_handler(cmd, arg): | |
:type arg: list | ||
""" | ||
logger.debug('entering ui.command_handler %s %s' % (cmd, arg)) | ||
import gtk | ||
from gi.repository import Gtk | ||
import bauble.utils as utils | ||
import bauble.pluginmgr as pluginmgr | ||
global last_handler | ||
handler_cls = None | ||
try: | ||
handler_cls = pluginmgr.commands[cmd] | ||
except KeyError, e: | ||
except KeyError as e: | ||
if cmd is None: | ||
utils.message_dialog(_('No default handler registered')) | ||
else: | ||
|
@@ -190,11 +188,11 @@ def command_handler(cmd, arg): | |
gui.window.add_accel_group(handler_view.accel_group) | ||
try: | ||
last_handler(cmd, arg) | ||
except Exception, e: | ||
except Exception as e: | ||
msg = utils.xml_safe(e) | ||
logger.error('bauble.command_handler(): %s' % msg) | ||
utils.message_details_dialog( | ||
msg, traceback.format_exc(), gtk.MESSAGE_ERROR) | ||
msg, traceback.format_exc(), Gtk.MessageType.ERROR) | ||
|
||
|
||
conn_default_pref = "conn.default" | ||
|
@@ -212,16 +210,16 @@ def main(uri=None): | |
:type uri: str | ||
""" | ||
# TODO: it would be nice to show a Tk dialog here saying we can't | ||
# import gtk...but then we would have to include all of the Tk libs in | ||
# import Gtk...but then we would have to include all of the Tk libs in | ||
# with the win32 batteries-included installer | ||
try: | ||
import gtk | ||
import gobject | ||
except ImportError, e: | ||
print _('** Error: could not import gtk and/or gobject') | ||
print e | ||
from gi.repository import Gtk | ||
from gi.repository import GObject | ||
except ImportError as e: | ||
print(_('** Error: could not import gtk and/or gobject')) | ||
print(e) | ||
if sys.platform == 'win32': | ||
print _('Please make sure that GTK_ROOT\\bin is in your PATH.') | ||
print(_('Please make sure that GTK_ROOT\\bin is in your PATH.')) | ||
sys.exit(1) | ||
|
||
# create the user directory | ||
|
@@ -282,30 +280,30 @@ def main(uri=None): | |
else: | ||
logger.debug('not registering sentry client') | ||
|
||
except Exception, e: | ||
except Exception as e: | ||
logger.warning("can't configure sentry client") | ||
logger.debug("%s(%s)" % (type(e).__name__, e)) | ||
|
||
import gtk.gdk | ||
import pygtk | ||
import Gtk.gdk | ||
import gi | ||
if not paths.main_is_frozen(): | ||
pygtk.require("2.0") | ||
gi.require_version("Gtk", "3.0") | ||
|
||
display = gtk.gdk.display_get_default() | ||
display = Gdk.Display.get_default() | ||
if display is None: | ||
print _("**Error: Ghini must be run in a windowed environment.") | ||
print(_("**Error: Ghini must be run in a windowed environment.")) | ||
sys.exit(1) | ||
|
||
import bauble.pluginmgr as pluginmgr | ||
import bauble.utils as utils | ||
|
||
# initialize threading | ||
gobject.threads_init() | ||
GObject.threads_init() | ||
|
||
try: | ||
import bauble.db as db | ||
except Exception, e: | ||
utils.message_dialog(utils.xml_safe(e), gtk.MESSAGE_ERROR) | ||
except Exception as e: | ||
utils.message_dialog(utils.xml_safe(e), Gtk.MessageType.ERROR) | ||
sys.exit(1) | ||
|
||
# declare module level variables | ||
|
@@ -330,26 +328,26 @@ def main(uri=None): | |
break | ||
else: | ||
uri = conn_name = None | ||
except err.VersionError, e: | ||
except err.VersionError as e: | ||
logger.warning("%s(%s)" % (type(e), e)) | ||
db.open(uri, False) | ||
break | ||
except (err.EmptyDatabaseError, err.MetaTableError, | ||
err.VersionError, err.TimestampError, | ||
err.RegistryError), e: | ||
err.RegistryError) as e: | ||
logger.info("%s(%s)" % (type(e), e)) | ||
open_exc = e | ||
# reopen without verification so that db.Session and | ||
# db.engine, db.metadata will be bound to an engine | ||
db.open(uri, False) | ||
break | ||
except err.DatabaseError, e: | ||
except err.DatabaseError as e: | ||
logger.debug("%s(%s)" % (type(e).__name__, e)) | ||
open_exc = e | ||
except Exception, e: | ||
except Exception as e: | ||
msg = _("Could not open connection.\n\n%s") % e | ||
utils.message_details_dialog(msg, traceback.format_exc(), | ||
gtk.MESSAGE_ERROR) | ||
Gtk.MessageType.ERROR) | ||
uri = None | ||
else: | ||
db.open(uri, True, True) | ||
|
@@ -371,7 +369,7 @@ def main(uri=None): | |
gui = ui.GUI() | ||
|
||
def _post_loop(): | ||
gtk.gdk.threads_enter() | ||
Gdk.threads_enter() | ||
try: | ||
if isinstance(open_exc, err.DatabaseError): | ||
msg = _('Would you like to create a new Ghini database at ' | ||
|
@@ -388,32 +386,32 @@ def _post_loop(): | |
pluginmgr.init() | ||
# set the default connection | ||
prefs[conn_default_pref] = conn_name | ||
except Exception, e: | ||
except Exception as e: | ||
utils.message_details_dialog(utils.xml_safe(e), | ||
traceback.format_exc(), | ||
gtk.MESSAGE_ERROR) | ||
Gtk.MessageType.ERROR) | ||
logger.error("%s(%s)" % (type(e).__name__, e)) | ||
else: | ||
pluginmgr.init() | ||
except Exception, e: | ||
except Exception as e: | ||
logger.warning("%s\n%s(%s)" | ||
% (traceback.format_exc(), type(e).__name__, e)) | ||
msg = utils.utf8("%s(%s)" % (type(e).__name__, e)) | ||
utils.message_dialog(msg, gtk.MESSAGE_WARNING) | ||
utils.message_dialog(msg, Gtk.MessageType.WARNING) | ||
gui.get_view().update() | ||
gtk.gdk.threads_leave() | ||
Gdk.threads_leave() | ||
|
||
gobject.idle_add(_post_loop) | ||
GObject.idle_add(_post_loop) | ||
logger.info('This version installed on: %s; ' | ||
'This version installed at: %s; ' | ||
'Latest published version: %s; ' | ||
'Publication date: %s' % | ||
(bauble.installation_date, __file__, bauble.release_version, bauble.release_date, )) | ||
|
||
gui.show() | ||
gtk.threads_enter() | ||
gtk.main() | ||
Gtk.threads_enter() | ||
Gtk.main() | ||
active_view = gui.get_view() | ||
if active_view: | ||
active_view.cancel_threads() | ||
gtk.threads_leave() | ||
Gtk.threads_leave() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,3 @@ | ||
# -*- coding: utf-8 -*- | ||
# | ||
# Copyright (c) 2005,2006,2007,2008,2009 Brett Adams <[email protected]> | ||
# Copyright (c) 2012-2015 Mario Frasca <[email protected]> | ||
# | ||
|
@@ -20,7 +18,7 @@ | |
# | ||
# assistant.py | ||
# | ||
# Descriptions: use gtk.Assistant to create a new database wizard | ||
# Descriptions: use Gtk.Assistant to create a new database wizard | ||
# | ||
# issue #29: implement the assistant | ||
# |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,3 @@ | ||
# -*- coding: utf-8 -*- | ||
# | ||
# Copyright (c) 2005,2006,2007,2008,2009 Brett Adams <[email protected]> | ||
# Copyright (c) 2012-2017 Mario Frasca <[email protected]> | ||
# | ||
|
@@ -59,12 +57,12 @@ def __init__(self, values, empty_to_none=False, strict=True, | |
except TypeError: | ||
raise EnumError(_('Enum requires string values (or None)')) | ||
if set(type(x) for x in values if x is not None) - \ | ||
set([type(''), type(u'')]) != set(): | ||
set([type(''), type('')]) != set(): | ||
raise EnumError(_('Enum requires string values (or None)')) | ||
if len(values) != len(set(values)): | ||
raise EnumError(_('Enum requires the values to be different')) | ||
self.translations = dict((v, v) for v in values) | ||
for key, value in translations.iteritems(): | ||
for key, value in translations.items(): | ||
self.translations[key] = value | ||
if empty_to_none and None not in values: | ||
raise EnumError(_('You have configured empty_to_none=True but ' | ||
|
@@ -112,7 +110,7 @@ class DateTime(types.TypeDecorator): | |
_rx_tz = re.compile('[+-]') | ||
|
||
def process_bind_param(self, value, dialect): | ||
if not isinstance(value, basestring): | ||
if not isinstance(value, str): | ||
return value | ||
try: | ||
DateTime._dayfirst | ||
|
@@ -140,7 +138,7 @@ class Date(types.TypeDecorator): | |
impl = types.Date | ||
|
||
def process_bind_param(self, value, dialect): | ||
if not isinstance(value, basestring): | ||
if not isinstance(value, str): | ||
return value | ||
try: | ||
Date._dayfirst | ||
|
Oops, something went wrong.
ffac89e
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.
hi. any reason to start this port 2→3 from scratch?
ffac89e
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 spent a fair amount of time looking into Ghini#432 Ghini#403 (the windows installer being the big one) and had no luck with the libchamplain/clutter issue I mentioned. (see: here. Also see: libshumate and issue1 but all that is GTK4 and not much use right now.).
So, with some spare time during a COVID lock down (and perhaps naively), I decided to go back to a version I knew worked and work forward from there. Trying for a more modest python 3 version and checking in mac and windows (including packaging as soon as I thought it practical) as I went. Was mostly a proof of concept. I had read that it wasn't possible (or at least worth while) to package PyGObject for windows, see here, and this would be a deal breaker for me. I had also been unable to get py2exe working in mingw at all but had also seen some pyinstaller commits that seemed to be aimed at mingw pygobject projects etc.. In the end the packaging portion was relatively easy! (see
.appveyor.yml
,ghini.spec
etc.). So concept proved. Where to from here? I'm not really sure to be honest. I haven't looked at this or v3.1 in some time now.ffac89e
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.
you see, the difficulties with making an old Desktop, Gtk2, Glade, Python2, SqlAlchemy program work on modern OS can in my opinion only be solved by dropping all those now outdated choices. you may have seen "ghini reloaded" and the web instances I had started to create, hoping to raise some interest among users.
both ghini-3.1 and ghini-1.0 have serious trouble with threading and concurrency, partially "solved" using the
fibra
module, which was unpublished until I put it in pip, and which has never been included in Debian.fibra
implements a cooperative concurrency model, resembling early Windows 3, something rather insulting to programmers, and not only this century. however, if you look at your logs I'm sure you will see loads of complaints about objects being closed in a thread while they belong to an other. I have not solved this, and I think it's giving more trouble in Python3 that it was doing in Python2.thus "ghini reloaded".
for which I have no users who showed any commitment.