Is there a nice way to switch between 2 different packages providing the same APIs?
Mark
m.n.summerfield at googlemail.com
Fri Jul 6 08:33:38 EDT 2018
On Friday, July 6, 2018 at 1:22:46 PM UTC+1, Bev in TX wrote:
> > On Jul 6, 2018, at 3:14 AM, Mark via Python-list <python-list at python.org> wrote:
> >
> > In the end I changed to a completely different approach.
> >
> > I now have two parallel directories, one with PySide-based code and the other with auto-generated PyQt-based code. And I created a tiny script to copy the PySide code to the PyQt directory & do the necessary changes. (I can post the script if anyone's interested.)
>
> I am interested.
> >
> > This means that there are no import hacks and no (manual) duplication, while still being easy to test using either binding library.
> > --
> > https://mail.python.org/mailman/listinfo/python-list
>
> Bev in TX
OK, here're the details. Note that the paths are hard-coded (but could easily be configurable using argparse).
I assume: (1) the source dir is 'app'; (2) the dest dir is 'app-pyqt'; (3) there is a file called app/Uniform.py with this content:
#!/usr/bin/env python3
# Uniform.py
import PySide2.QtCore
from PySide2.shiboken2 import isValid as isObjectAlive
VERSION_STR = (f'PySide2 {PySide2.__version__} / '
f'Qt {PySide2.QtCore.__version__}')
I then run pyside2pyqt.py in the dir *above* app and app-pyqt:
#!/usr/bin/env python3
import contextlib
import os
import shutil
SRC = 'app'
DST = 'app-pyqt'
UNIFORM_FILE = 'Uniform.py'
def main():
with contextlib.suppress(FileNotFoundError):
shutil.rmtree(DST)
shutil.copytree(SRC, DST, ignore=shutil.ignore_patterns(
'__pycache__', UNIFORM_FILE))
for root, _, files in os.walk(DST):
for name in files:
if name.endswith(('.py', '.pyw')):
filename = os.path.join(root, name)
with open(filename, 'rt', encoding='utf-8') as file:
text = file.read().replace('PySide2', 'PyQt5')
with open(filename, 'wt', encoding='utf-8') as file:
for line in text.splitlines():
if 'pyside2pyqt: DELETE' not in line:
print(line, file=file)
with open(os.path.join(DST, UNIFORM_FILE), 'wt',
encoding='utf-8') as file:
file.write(UNIFORM)
UNIFORM = '''#!/usr/bin/env python3
import PyQt5.QtCore
import PyQt5.sip
VERSION_STR = (f'PyQt5 {PyQt5.QtCore.PYQT_VERSION_STR} / '
f'Qt {PyQt5.QtCore.QT_VERSION_STR}')
def isObjectAlive(obj):
return not PyQt5.sip.isdeleted(obj)
'''
if __name__ == '__main__':
main()
The reaons for being able to delete lines is that the APIs aren't identical. For example, PySide2's QStyleHints has a setCursorFlashTime() method; but PyQt5's doesn't. So for any lines you don't want copied just add the comment, e.g.:
style_hints = self.styleHints() # pyside2pyqt: DELETE
style_hints.setCursorFlashTime(0) # pyside2pyqt: DELETE
I'm sure someone could come up with a more generalized script, but this is sufficient for my needs.
More information about the Python-list
mailing list