Skip to content

Commit

Permalink
Merge pull request #23 from isuthermography/master
Browse files Browse the repository at this point in the history
Pull in updated Qt support, dpi_kwargs, etc.
  • Loading branch information
sdh4 authored Aug 7, 2024
2 parents 139168b + 009026c commit f41249f
Show file tree
Hide file tree
Showing 10 changed files with 200 additions and 67 deletions.
86 changes: 43 additions & 43 deletions .github/workflows/push-to-pypi.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ jobs:
publish-to-pypi:
name: >-
Publish Python distribution to PyPI
if: startsWith(github.ref, 'refs/tags/') # only publish to PyPI on tag pushes
#if: startsWith(github.ref, 'refs/tags/') # only publish to PyPI on tag pushes
needs:
- build
runs-on: ubuntu-latest
Expand All @@ -60,45 +60,45 @@ jobs:
- name: Publish distribution to PyPI
uses: pypa/gh-action-pypi-publish@release/v1

github-release:
name: >-
Sign the Python distribution with Sigstore
and upload them to GitHub Release
needs:
- publish-to-pypi
runs-on: ubuntu-latest

permissions:
contents: write # IMPORTANT: mandatory for making GitHub Releases
id-token: write # IMPORTANT: mandatory for sigstore

steps:
- name: Download all the dists
uses: actions/download-artifact@v4
with:
name: python-package-distributions
path: dist/
- name: Sign the dists with Sigstore
uses: sigstore/[email protected]
with:
inputs: >-
./dist/*.tar.gz
./dist/*.whl
- name: Create GitHub Release
env:
GITHUB_TOKEN: ${{ github.token }}
run: >-
gh release create
'${{ github.ref_name }}'
--repo '${{ github.repository }}'
--notes ""
- name: Upload artifact signatures to GitHub Release
env:
GITHUB_TOKEN: ${{ github.token }}
# Upload to GitHub Release using the `gh` CLI.
# `dist/` contains the built packages, and the
# sigstore-produced signatures and certificates.
run: >-
gh release upload
'${{ github.ref_name }}' dist/**
--repo '${{ github.repository }}'
# github-release:
# name: >-
# Sign the Python distribution with Sigstore
# and upload them to GitHub Release
# needs:
# - publish-to-pypi
# runs-on: ubuntu-latest
#
# permissions:
# contents: write # IMPORTANT: mandatory for making GitHub Releases
# id-token: write # IMPORTANT: mandatory for sigstore
#
# steps:
# - name: Download all the dists
# uses: actions/download-artifact@v4
# with:
# name: python-package-distributions
# path: dist/
# - name: Sign the dists with Sigstore
# uses: sigstore/[email protected]
# with:
# inputs: >-
# ./dist/*.tar.gz
# ./dist/*.whl
# - name: Create GitHub Release
# env:
# GITHUB_TOKEN: ${{ github.token }}
# run: >-
# gh release create
# '${{ github.ref_name }}'
# --repo '${{ github.repository }}'
# --notes ""
# - name: Upload artifact signatures to GitHub Release
# env:
# GITHUB_TOKEN: ${{ github.token }}
# # Upload to GitHub Release using the `gh` CLI.
# # `dist/` contains the built packages, and the
# # sigstore-produced signatures and certificates.
# run: >-
# gh release upload
# '${{ github.ref_name }}' dist/**
# --repo '${{ github.repository }}'
69 changes: 60 additions & 9 deletions dataguzzler_python/Qt.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,11 @@
both PySide2 and PyQt5, plus easy extensibility to PySide6 and PyQt6 """

import sys
import os
import os.path
import importlib
import threading
import pkgutil

from dataguzzler_python import QtConfig
from dataguzzler_python import context
Expand All @@ -23,34 +26,76 @@ def Import_SubModule(qtmodname):
return module


# Check if SpatialNDE2 is built for Qt5 versus Qt6
spatialnde2_loader = pkgutil.get_loader("spatialnde2")
spatialnde2_qt_version=None
if spatialnde2_loader is not None:
spatialnde2_path = spatialnde2_loader.get_filename()
spatialnde2_dirpath = os.path.dirname(spatialnde2_path)
compile_definitions_path = os.path.join(spatialnde2_dirpath, "compile_definitions.txt")
with open(compile_definitions_path, "r") as fh:
compile_definitions_str = fh.read()
pass
_spatialnde2_qt6_enabled = "-DSNDE_ENABLE_QT6=1" in compile_definitions_str
if _spatialnde2_qt6_enabled:
spatialnde2_qt_version="6"
pass
else:
spatialnde2_qt_version="5"
pass
pass




pyside_loaded = "PySide2" in sys.modules
pyqt_loaded = "PyQt5" in sys.modules
pyside2_loaded = "PySide2" in sys.modules
pyside6_loaded = "PySide6" in sys.modules
pyqt5_loaded = "PyQt5" in sys.modules
pyqt6_loaded = "PyQt6" in sys.modules

selected_bindings = None

if not(pyside_loaded ^ pyqt_loaded) and QtConfig.prefer_pyqt:
selected_bindings = "PyQt5"
if not(pyside2_loaded or pyside6_loaded or pyqt5_loaded or pyqt6_loaded) and QtConfig.prefer_pyqt:
if spatialnde2_qt_version=="6":
selected_bindings="PyQt6"
pass
else:
selected_bindings = "PyQt5"
pass
pass
elif not(pyside_loaded ^ pyqt_loaded):
elif not(pyside2_loaded or pyside6_loaded or pyqt5_loaded or pyqt6_loaded):
selected_bindings = "PySide2"
if spatialnde2_qt_version=="6":
selected_bindings = "PySide6"
pass
pass
else:
if pyside_loaded:
if pyside2_loaded:
selected_bindings = "PySide2"
pass
else:
elif pyside6_loaded:
selected_bindings = "PySide6"
pass
elif pyqt5_loaded:
selected_bindings = "PyQt5"
pass
elif pyqt6_loaded:
selected_bindings = "PyQt6"
pass
else:
selected_bindings = "PySide2"
pass
pass

if selected_bindings is None:
raise ImportError(f"No suitable Qt Python bindings found; suggest installing PySide2 or PySide6 depending on the version of Qt that your SpatialNDE2 uses.")

if threading.current_thread() is not threading.main_thread():
raise RuntimeError("Qt may only be imported from main thread")

Qt = None


try:
Qt = importlib.import_module(selected_bindings)
pass
Expand All @@ -59,9 +104,15 @@ def Import_SubModule(qtmodname):
if selected_bindings == "PySide2":
alternative_bindings = "PyQt5"
pass
else:
elif selected_bindings == "PyQt5":
alternative_bindings = "PySide2"
pass
elif selected_bindings == "PySide6":
alternative_bindings = "PyQt6"
pass
elif selected_bindings == "PyQt6":
alternative_bindings = "PySide6"
pass
try:
Qt = importlib.import_module(alternative_bindings)
selected_bindings = alternative_bindings
Expand All @@ -78,7 +129,7 @@ def Import_SubModule(qtmodname):
Import_SubModule("QtWidgets")
Import_SubModule("QtGui")

if selected_bindings=="PyQt5":
if selected_bindings=="PyQt5" or selected_bindings == "PyQt6":
QtSlot = QtCore.pyqtSlot
QtSignal = QtCore.pyqtSignal
pass
Expand Down
2 changes: 1 addition & 1 deletion dataguzzler_python/QtConfig.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
# This module is basically a way to pass parameters to Qt5.py prior to import
# This module is basically a way to pass parameters to Qt.py prior to import

prefer_pyqt = False
6 changes: 3 additions & 3 deletions dataguzzler_python/QtWrapper.py
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ def __set__(self,obj,value):
pass
return descriptor_wrapper(doc)

def qt5unwrap(wrapperobj):
def qtunwrap(wrapperobj):
return object.__getattribute__(wrapperobj,"_wrappedobj")


Expand Down Expand Up @@ -142,9 +142,9 @@ def QtCensorObj(sourcecontext,destcontext,attrname,obj):
return attemptunwrap(obj,destcontext)

if objclass is QtWrapper:
# pre-wrapped qt5 object
# pre-wrapped qt object
if destcontext is main_thread_context:
return qt5unwrap(obj)
return qtunwrap(obj)
else:
# already wrapped
return obj
Expand Down
4 changes: 3 additions & 1 deletion dataguzzler_python/configfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,9 @@ def __init__(self,name,path,sourcetext,sourcetext_context,parentmodule):
self.parentmodule=parentmodule


(self.sourceast,self.globalparams,self.assignable_param_types) = scan_source(self.path,self.sourcetext)
(self.sourceast,self.globalparams,self.assignable_param_types,dpi_args,dpi_kwargs) = scan_source(self.path,self.sourcetext)
if dpi_args or dpi_kwargs:
raise ValueError("dpi_args and dpi_kwargs not supported in .dgp files")

pass

Expand Down
45 changes: 43 additions & 2 deletions dataguzzler_python/configfile_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ def scan_source(sourcepath,sourcetext):

globalparams=set([])

dpi_args=False

dpi_kwargs=False

cnt=0
while cnt < len(sourceast.body):
entry=sourceast.body[cnt]
Expand All @@ -41,6 +45,14 @@ def scan_source(sourcepath,sourcetext):
# Treat None as str -- we probably want a filename or similar
assignable_param_types[entry.targets[0].id] = str
pass

if entry.targets[0].id=="dpi_args":
dpi_args=True
pass

if entry.targets[0].id=="dpi_kwargs":
dpi_kwargs=True
pass
pass

# print entry.targets
Expand All @@ -54,7 +66,7 @@ def scan_source(sourcepath,sourcetext):
cnt+=1
pass

return (sourceast,globalparams,assignable_param_types)
return (sourceast,globalparams,assignable_param_types,dpi_args,dpi_kwargs)

def modify_source_overriding_parameters(sourcepath,sourceast,paramdict_keys,mode):
"""Reads in the given syntax tree. Removes assignments of given
Expand All @@ -72,6 +84,33 @@ def modify_source_overriding_parameters(sourcepath,sourceast,paramdict_keys,mode
sourcepath="<unknown>"
pass

# Remove assignments of dpi_args and/or dpi_kwargs
gotdpiargs=0
gotdpikwargs=0
cnt=0

while cnt < len(sourceast.body):
entry=sourceast.body[cnt]
if entry.__class__.__name__=="Assign" and len(entry.targets)==1 and entry.targets[0].__class__.__name__=="Name":
# print entry.targets
if entry.targets[0].id=="dpi_args":
del sourceast.body[cnt]
gotdpiargs+=1
continue # bypass cnt increment below
if entry.targets[0].id=="dpi_kwargs":
del sourceast.body[cnt]
gotdpikwargs+=1
continue # bypass cnt increment below
pass
cnt+=1
pass

if gotdpiargs > 1:
raise ValueError("Overridden parameter dpi_args in %s is not simply assigned exactly once at top level" % (sourcepath))
if gotdpikwargs > 1:
raise ValueError("Overridden parameter dpi_kwargs in %s is not simply assigned exactly once at top level" % (sourcepath))

# Remove simple assignments of paramdict entries
for paramkey in paramdict_keys:
gotassigns=0
cnt=0
Expand All @@ -88,8 +127,10 @@ def modify_source_overriding_parameters(sourcepath,sourceast,paramdict_keys,mode
cnt+=1
pass

if gotassigns != 1:
if gotdpikwargs==0 and gotassigns != 1:
raise ValueError("Overridden parameter %s in %s is not simply assigned exactly once at top level" % (paramkey,sourcepath))
if gotdpikwargs==1 and gotassigns > 1:
raise ValueError("Overridden parameter %s in %s is simply assigned more than once at top level" % (paramkey,sourcepath))
pass

if mode == "main_thread":
Expand Down
26 changes: 24 additions & 2 deletions dataguzzler_python/dgpy.py
Original file line number Diff line number Diff line change
Expand Up @@ -344,7 +344,7 @@ class threadsafe(object,metaclass=abc.ABCMeta):

# include() function for config files and modules

def include(includepackage,includeurl=None,**kwargs):
def include(includepackage,includeurl,*args,**kwargs):
"""Include a sub-config file as if it were
inserted in your main config file.
Expand Down Expand Up @@ -390,12 +390,22 @@ def include(includepackage,includeurl=None,**kwargs):
includefh.close()
#code = compile(includestr,includepath,'exec')

(includeast,globalparams,assignable_param_types) = scan_source(includepath,includetext)
(includeast,globalparams,assignable_param_types,dpi_args,dpi_kwargs) = scan_source(includepath,includetext)
code = modify_source_overriding_parameters(includepath,includeast,kwargs,mode="all")

localkwargs = { varname: kwargs[varname] for varname in kwargs if varname not in globalparams }
globalkwargs = { varname: kwargs[varname] for varname in kwargs if varname in globalparams }

if dpi_args:
localkwargs["dpi_args"]=args
pass
elif len(args) > 0:
raise ValueError(f"Positional parameters provided to a .dpi file {includepath:s} that does not take dpi_args")

if dpi_kwargs:
localkwargs["dpi_kwargs"]=kwargs
pass

function_code = modify_source_into_function_call(code,localkwargs)


Expand All @@ -407,9 +417,21 @@ def include(includepackage,includeurl=None,**kwargs):

localvars.update(localkwargs) # include any explicitly passed local parameters

if dpi_args:
localvars["dpi_args"]=args
pass
elif len(args) > 0:
raise ValueError(f"Positional parameters provided to a .dpi file {includepath:s} that does not take dpi_args")

if dpi_kwargs:
localvars["dpi_kwargs"]=kwargs
pass

# update global dictionary according to explicitly passed global parameters
module.__dict__.update(globalkwargs)



# Run the include file code
exec(exec_code,module.__dict__,localvars)

Expand Down
Loading

0 comments on commit f41249f

Please sign in to comment.