How to access QString for QGIS-2.14 in PyQt4 - python

This is a bit QGIS specific, but figure it's kind of low level so I've posted here. I can definitely move this over to gis.stackexchange.com if that's better.
Trying to use QgsRasterCalculator, which seems to want a QString type object for a couple of arguments. I try to create a QString (like described here) but get:
import PyQt4
PyQt4.QtCore.QString('foo')
Traceback (most recent call last):
File "<input>", line 1, in <module>
AttributeError: 'module' object has no attribute 'QString'
So I try to use a regular string for my first argument (calc = QgsRasterCalculator( 'demffac > 120', newStreams, 'GTiff', rFac.extent(), rFac.crs().authid(), rFac.height(), rFac.width(), entries)), I got:
Traceback (most recent call last):
File "<input>", line 1, in <module>
TypeError: arguments did not match any overloaded call:
QgsRasterCalculator(QString, QString, QString, QgsRectangle, int, int, list-of-QgsRasterCalculatorEntry): argument 5 has unexpected type 'unicode'
QgsRasterCalculator(QString, QString, QString, QgsRectangle, QgsCoordinateReferenceSystem, int, int, list-of-QgsRasterCalculatorEntry): argument 5 has unexpected type 'unicode'
QgsRasterCalculator(QgsRasterCalculator): argument 1 has unexpected type 'str'
I'm using QGIS 2.14, which has been documented as using QString (as I understand it). I've tried to use the sip package to reset (per these instructions) but QGIS's python console doesn't seem to want to change (ValueError: API 'QString' has already been set to version 2).
Any way to make my QgsRasterCalculator() call work? Thanks for any info!
/==================EDIT: screen grab of my QGIS's responses to suggestions=========
/==================
Version info:
from PyQt4.QtCore import QT_VERSION_STR
from PyQt4.pyqtconfig import Configuration
print("Qt version:", QT_VERSION_STR)
('Qt version:', '4.8.5')
cfg = Configuration()
print("SIP version:", cfg.sip_version_str)
('SIP version:', '4.14.7')
print("PyQt version:", cfg.pyqt_version_str)
('PyQt version:', '4.10.2')

Looking more closely at the traceback, it seems that QgsRasterCalculator does not require the use of QString. This is proved by the fact that you passed python strings for the first three arguments, and the error message does not complain about them at all. Rather, it complains about the fifth argument, which must be either an int or QgsCoordinateReferenceSystem object, whereas you seem to be passing in unicode or str objects. Why are you passing in the return value of rFac.crs().authid()? Surely you should be passing in rFac.crs(), rather than authid() (which is documented as returning a string).
With regard to potential issues with QString:
When used with Python2, PyQt4 most definitely does have the QString class - unless you take explicit steps to change that by using the sip module. The code at the beginning of your question is not what you actually ran, because it does not raise that specific error:
Python 2.7.15 (default, Jun 27 2018, 13:05:28)
[GCC 8.1.1 20180531] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import PyQt4
>>> PyQt4.QtCore.QString('foo')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'module' object has no attribute 'QtCore'
If you import the QtCore module properly, the code works fine:
>>> from PyQt4 import QtCore
>>> QtCore.QString('foo')
PyQt4.QtCore.QString(u'foo')
Note that it never makes sense to import the PyQt4 package on its own. It is just an empty namespace which (for performance reasons) imports the other modules lazily. You must therefore always import the Qt modules explicitly as I have done above.
PS:
In the second half of your question, it seems that the PyQt APIs have somehow already been changed to version 2, which will switch off support for QString. To switch it back on, you would need to do:
import sip
sip.setapi('QString', 1)
However, this step must be done before any other PyQt modules are imported.

Related

What is wrong with my call to checkodesol in sympy?

I am learning sympy, and wanted to verify the solution to an ODE. I do not yet quite understand sympy naming conventions.
Instead of doing the standard methods of loading all packages at the top, I wanted to just import sympy and then use explicit long name to reference any other name inside sympy. On latest conda python
Python 3.7.3 (default, Mar 27 2019, 22:11:17)
[GCC 7.3.0] :: Anaconda, Inc. on linux
When typing
import sympy
x = sympy.symbols('x')
y = sympy.Function('y')
ode = sympy.Eq(sympy.Derivative(y(x),x),1+2*x)
sol = sympy.dsolve(ode,y(x))
sympy.solvers.ode.checkodesol(ode,sol)
And the above gives error
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: module 'sympy.solvers.solvers' has no attribute 'ode'
But from the page https://docs.sympy.org/latest/modules/solvers/ode.html
It says
But if I do the following, it works
from sympy import checkodesol
checkodesol(ode,sol)
(True, 0)
But I do not want to import checkodesol explicitly. I want to just import sympy and then use the long name to call checkodesol or any other sympy sub packages, as this makes it more clear to me in the code where each function is coming from (at the cost of a little extra typing)
The question is, why using sympy.solvers.ode.checkodesol does not work?
At the very top of the documentation you linked to, it says
These are functions that are imported into the global namespace with
from sympy import *. These functions (unlike Hint Functions, below)
are intended for use by ordinary users of SymPy.
Then you can use checkodesol(ode, sol) directly.
If you do import sympy, then you need to call
sympy.checkodesol(ode, sol)

Strange import error in Emscripten cross-compiled CPython

I am porting CPython to Emscripten, and it builds successfully. However, when I try to run the python.asm.js through Node.js, I get a very strange error inside the Py_InitializeEx(0) call:
Traceback (most recent call last):
File "/lib/python2.7/site.py", line 62, in <module>
import os
File "/lib/python2.7/os.py", line 44, in <module>
from posix import *
TypeError: 'NotImplementedType' object does not support indexing
The error is generated from PySequence_GetItem in Objects/abstract.c, but I don't understand how the execution gets there. If I do import posix before the line that causes the error, the import posix statement finish successfully, and I can call functions in the posix module. Thus, the error is related to from <module> import * line. How is PySequence_GetItem related to from <module> import * statement, and what could be the reasons for the error?
If you want to reproduce the problem, I released the code on GitHub
While investigating what is going wrong, I switched off the optimization (compiled and linked with -O0). The resulting JS executable also failed, but with a different error:
Invalid function pointer '495' called with signature 'iii'. Perhaps this is
an invalid value (e.g. caused by calling a virtual method on a NULL pointer)?
Or calling a function with an incorrect type, which will fail? (it is worth
building your source files with -Werror (warnings are errors), as warnings can
indicate undefined behavior which can cause this)
This pointer might make sense in another type signature:
ii: _dict_keys iiii: 0 i: undefined iiiii: 0 viii: 0 vii: 0 vi: 0 v: 0
495
495
I looked through Emscripten's settings.js for options related to function pointers, and found EMULATE_FUNCTION_POINTER_CASTS which fixed the problem.

comtypes: in call_with_inout, ctypes TypeError: 'c_double' object is not iterable

Im working with Agilent IVI drivers in Python 2.7.9 and can't seem to get 'proven' code to work on a particular Windows 7 machine. It executes successfully on other machines.
While this issue seems rather limited to one instrument, it appears to be a broader Python issue, so I turn to Stack Overflow for help. Any help or insight would be great.
The following code
# Import the TLB
from comtypes.client import GetModule, CreateObject
GetModule('AgInfiniium.dll')
# Pull in the coefficients and classes, we'll need those
from comtypes.gen.AgilentInfiniiumLib import *
# Instantiate the driver
OScope = CreateObject('AgilentInfiniium.AgilentInfiniium')
# Make constants of our settings
Address = "TCPIP0::10.254.0.222::INSTR"
resetOScope = False
# Open a connection to the scope
OScope.Initialize(Address,False,resetOScope,'')
# Make a measurement
print OScope.Measurements.Item("Channel1").ReadWaveformMeasurement(
MeasFunction=AgilentInfiniiumMeasurementAmplitude, MaxTime=10)
yields the following error:
Traceback (most recent call last):
File "P:\Aperture\Validation\WMI_BGA_Board\TestMatrixCode\scopeTest2.py", line 29, in <module>
print OScope.Measurements.Item("Channel1").ReadWaveformMeasurement(MeasFunction=AgilentInfiniiumMeasurementAmplitude ,MaxTime=10)
File "C:\Python27\lib\site-packages\comtypes-1.1.0-py2.7.egg\comtypes\__init__.py", line 656, in call_with_inout
rescode = list(rescode)
TypeError: 'c_double' object is not iterable
In my limited debugging attempts, I have seen that this call_with_inout
function tries to convert my Python arguments into arguments for the following C++ function:
public void ReadWaveformMeasurement(
AgilentInfiniiumMeasurementEnum MeasFunction,
AgilentInfiniiumTimeOutEnum MaxTime,
ref double pMeasurement)
It's creating some kind of variable for the pMeasurement pointer that ends up being type c_double, and then complains that it's not iterable.
At this point, this seems like it's local to this machine. I've gone to the extent of uninstalling Python, reinstalling the Agilent driver, and trying two versions of comtypes (1.1.0 and 1.1.1). Yet the problem persists. Any ideas? Thanks.

Is it possible to remove a method from a module?

Can I remove a method from a ready module in python? Recently i was trying to write a python code in a browser based trading platform where in they allow usto import python 'time' package but the time package didn't have sleep() method. While i was trying to import sleep method it gave me attribute error. On asking the technical support people of that platform i got to know that they don't support sleep() method. I am just wondering how could we do that? is it just deleting the method from the package? Or are there any better ways?
It is possible to remove methods (functions) from a name space at run time.
This is called monkey patching. Example in an interactive session:
Python 2.7.6 (default, Mar 22 2014, 22:59:56)
[GCC 4.8.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import time
>>> time.sleep(2)
>>> del time.sleep
>>> time.sleep(2)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'module' object has no attribute 'sleep'
But back to your original question: I believe that on the platform you are using they might have replaced several standard library modules (including the time module) with customized versions. So you should ask them how you can achieve the delay you want without having to resort to busy waiting.
import time
time.sleep(1)
del time.sleep
time.sleep(1)
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-6-07a34f5b1e42> in <module>()
----> 1 time.sleep(1)
AttributeError: 'module' object has no attribute 'sleep'
If you don't have the time.sleep method, you can easily write your own (albeit not likely as precise or efficient):
def sleep(seconds):
a = time.time()
b = time.time()
while b - a < seconds:
b = time.time()
Here are some tests for precision that I ran (only a print statement to see how often it went into the loop):
>>> sleep(1)
2.86102294922e-06
0.0944359302521
0.14835691452
0.198939800262
0.249089956284
0.299441814423
0.349442958832
0.398970842361
0.449244022369
0.498914003372
0.549893856049
0.600338935852
0.648976802826
0.700131893158
0.750012874603
0.800500869751
0.850263834
0.900727987289
0.950336933136
1.00087189674
The precision stays at 100th mile seconds precision. :)
You might not have the method either because they modified the source code, or ran some things on the interpreter before your code began executed (using the del keyword like in the other answers).

Sample application using python-gdl

I'm trying to use python-gdl (python bindings for gdl library, which features some docking windows for gtk+2). Even the origianl C gdl itself is awfully documented; its python bindings seems very unstable. Could you suggest any sample program, written in python-gdl and working?
I've tried to use the one described here and here, but it would fail with ugly:
Traceback (most recent call last):
File "gdl_test.py", line 17, in <module>
item1 = gdl.DockItem('item1', 'Item 1', gtk.STOCK_OPEN, gdl.DOCK_ITEM_BEH_NORMAL)
TypeError: Gdl.DockItem.__init__() takes at most 3 arguments (4 given)
The python bindings don't even seem to provide the constructor signatures: e.g.
>>> help(gdl.DockItem.__init__)
Help on wrapper_descriptor:
__init__(...)
x.__init__(...) initializes x; see x.__class__.__doc__ for signature
>>> help(gdl.DockItem.__doc__)
no Python documentation found for "Object GdlDockItem\n\nSignals from GdlDockItem:\n dock-drag-begin ()\n dock-drag-motion (gint, gint)\n dock-drag-end (gboolean)\n selected ()\n\nProperties from GdlDockItem:\n orientation -> GtkOrientation: Orientation\n
...more bloody mess here...
Is this project completely dead and just deceives naive programmers with false promises?

Categories