GTK Python gtk.TextBuffer(table=None) constructor error - python

I'm porting a Python GTK application from python2 to python3, using version 3.5.2. As part of this, I'm switching to updated GTK API calls. I need to call the gtk.TextBuffer constructor, described [here][1]. Following that documentation, I wrote:
tb = gtk.TextBuffer(table=text_tag_table)
This gives the following error:
*** TypeError: gobject `GtkTextBuffer' doesn't support property 'table'
I tried removing the table= part of the call:
gtk.TextBuffer(table=text_tag_table)
This gives:
*** TypeError: GObject.__init__() takes exactly 0 arguments (1 given)
I can call the constructor without arguments, e.g., tb = gtk.TextBuffer(). I tried setting the tag table manually, like this:
tb.set_property("tag-table", text_tag_table)
This gives a warning:
__main__:1: Warning: g_object_set_property: construct property "tag-table" for object 'GtkTextBuffer' can't be set after construction
It seems like the original constructor with the table= arg should work. Can anyone help me figure out why it throws a TypeError? I did confirm using pydb that text_tag_table is an object of the correct type:
(Pdb) p text_tag_table
<Gtk.TextTagTable object at 0x7fb723d6b288 (GtkTextTagTable at 0x2b2e8e0)>
Thanks very much in advance!

The fix for this was to use the new method:
tb = gtk.TextBuffer.new(table=text_tag_table)
I'm a bit surprised that this works, but it seems fine!

Related

Python OverflowError : in method 'get_GDSII_prisms', argument 3 of type 'int'

I'm a new user of a Python module called meep. I followed this tutorial and everything works fine. However, I tried to change something and I keep having the same error : OverflowError : in method 'get_GDSII_prisms', argument 3 of type 'int'
Here is the part of the code that causes trouble :
gdsII_file = 'coupler.gds'
UPPER_BRANCH_LAYER = 31
si_zmax = 10
si_zmin = -10
def test(p):
return mp.Medium(index=15)
upper_branch = mp.get_GDSII_prisms(test, gdsII_file, UPPER_BRANCH_LAYER, si_zmin, si_zmax)
The only change I made is that I put a function as first argument of get_GDSII_prisms instead of a mp.Medium instance (calling mp.get_GDSII_prisms(mp.Medium(index=15), gdsII_file, UPPER_BRANCH_LAYER, si_zmin, si_zmax doesn't create any trouble.) But this should work since every function of this module that takes a mp.Medium instance can also take a user-defined function. Moreover, I found it strange that Python finds an error on argument 3 whereas I only changed argument 1.
I looked on the internet in order to understand why I have this error and how to resolve it but I didn't found anything.
I'm using Python 3.8.5.
Thank you for your help!

GRPC Error: Parameter to MergeFrom() must be instance of same class

I have seen all previous questions about this, but nothing seems to be working on my end. I am trying to run a test that uses a protobuf generated file, called 'resource_pb2'. I am using Python 3.8 with grpc 1.33.2 and protobuf version 3.14.
When using a class from this protobuf generated file, my test fails with the following error:
Parameter to MergeFrom() must be instance of same class: expected RecognitionResource got RecognitionResource
I've checked the type and id's of all the "recognition resource" classes being called in that particular test, and I get the following:
<class 'resource_pb2.RecognitionResource'> 2069160783760
<class 'resource_pb2.RecognitionResource'> 2069160783760
<class 'resource_pb2.RecognitionResource'> 2069160783760
They are clearly all being called from the same source, so why is this issue occuring?
I had a similar issue and the reason was that I had made a mistake when passing parameters to the function.
The problem was solved when I realized about my bug and I invoked the function in the right way, with all required parameters properly set.
Hope it helps.

Typing NamedTuple as a class to include argument hints in PyCharm

EDIT: Type[X] does type hint to the class itself. The repl now has an example of that, too. PyCharm just doesn't use the __init__ information within the class to type hint an initialization elsewhere. If anyone knows why that is, I'll accept that answer. The below question is now just for context:
Let's say I have the following code:
from typing import NamedTuple, Type
class SubTuple(NamedTuple):
a: str
b: int
def get_tuple_type() -> Type[SubTuple]:
return SubTuple
test_tuple = get_tuple_type()
test_tuple_instance = test_tuple('test', 1)
Is there a way to type hint so that PyCharm will give me argument hints? Right now it gives me this:
which is rather useless. Hilariously, it does know the arguments, because when I type:
test_tuple.
it recommends all of the fields in the SubTuple. It just won't recommend them to me when I go to create an instance of the thing.
Also, https://repl.it/repls/BurdensomeInnocentKnowledge just so that you can see that the above code actually does work. The repl IDE also has no idea what to do with this thing, and is recommending that I call .a and .b on the class itself, which leads me to believe this might just be a general issue with what I'm trying to do in Python?
EDIT: I'm using Python 3.7; updated code to include what I've tried. It has the same result. Will update the repl, too.
This is a bug in PyCharm's static type checker, there are a few open bugs about NamedTuple on JetBrains bugtracker. The most up-to-date thread on the NamedTuple datatype is PY-18246. Fixes have been rolled out during 2020 but this specific case of correctly inferring the NamedTuple members after typing a class object has neither been reported nor solved.
The warning has also changed, if you try the same code with PyCharm 2020.3.3 Pro you'll get a different hint.
I tried checking the code with Mypy and it works correctly without any warnings. If you try causing an error by changing the types:
variable = test_tuple(1, 'test')
Mypy warns and correctly hints you about it:
error: Argument 1 to "SubTuple" has incompatible type "int"; expected "str"
error: Argument 2 to "SubTuple" has incompatible type "str"; expected "int"
Found 2 errors in 1 file (checked 1 source file)
Is there a way to type hint so that PyCharm will give me argument hints?
You are already type hinting correctly as PEP 484 recommends. If you use the Mypy static type checker it works, as for PyCharm it's a matter of waiting for a bug fix. There's nothing wrong with your type hinting and it shouldn't be changed in this case.

WebKit2.JavascriptResult.get_value() throws exception "TypeError: Couldn't find foreign struct converter for 'JavaScriptCore.Value'".

I am writing a python3 + webkit2 + gtk3 based GUI. Everything works fine, but when I tried to use WebKit2.WebView.run_javascript_finish() in a callback function, getting the return (a WebKit2.JavascriptResult objetc), e extrat the value with WebKit2.JavascriptResult.get_value(), I received a "TypeError: Couldn't find foreign struct converter for 'JavaScriptCore.Value'".
I have a "from gi.repository import JavaScriptCore" on the imports, and I dont know why this error is occuring.
ps: Sorry about my terrible english.
Unfortunately, using the JavaScriptCore library isn't supported in Python.
The definitions in gi.repository.JavaScriptCore only include opaque definitions for JavaScriptCore.Value and JavaScriptCore.GlobalContext in order to provide type information for functions that use those types; as you can verify by looking in /usr/share/gir-1.0/JavaScriptCore-4.0.gir. But as you've discovered, you can't actually call those functions because there's no information on how to convert those types to native Python objects.
I recommend writing a function in C which takes in your WebKit2.JavaScriptResult and fetches whatever information you need from it, and then exporting that function in its own private GIR library. So you would not use any JavaScriptCore types in your Python code. This is what it might look like:
from gi.repository import MyAppPrivate
# ...
def on_javascript_finish(obj, res):
result = obj.run_javascript_finish(res)
my_real_results = MyAppPrivate.process(result)

How to handle PyObjC method that returns NSError?

I am trying to get my PyObjC app to record audio when the user clicks a button. I am attempting to use the AVAuidioRecorder class. My code is:
#IBAction
def startRecording_(self, sender):
audioPath = '~/Desktop/recordTest.mp3'
audioPathStr = NSString.stringByExpandingTildeInPath(audioPath)
audioURL = NSURL.fileURLWithPath_(audioPathStr)
audioSettings = {'AVFormatIDKey': 'kAudioFormatAppleIMA4', 'AVSampleRateKey': 1600.0, 'AVNumberOfChannelsKey': 1 }
audioDict = NSDictionary.dictionaryWithDictionary_(audioSettings)
(recorder, error) = AVAudioRecorder.alloc().initWithURL_settings_error_(audioURL, audioDict, objc.nil)
recorder.record()
When I run the above code, I get the following error:
<type 'exceptions.TypeError'>: 'NoneType' object is not iterable
It seems that the initWithURL_settings_error_ method is expecting an iterable object as its third parameter. However, I thought when I use a PyObjC method that calls for an error parameter, I can pass objc.nil or None to that parameter.
When I use a similar syntax on an NSString method:
(names, error) = NSString.stringWithContentsOfFile_encoding_error_(u"/usr/share/dict/propernames", NSASCIIStringEncoding, objc.nil)
the code runs.
Why does my call to the AVAudioRecord method not work? Is it because the method calls for an outError while the NSString method calls for an error?
The code doesn't work with this AVFoundation class because PyObjC does not have metadata descriptions for that framework. It therefore does know what kind of argument the last argument is, it only knows that it is pointer to an object but doesn't know that it is used as a pass-by-reference output argument.
To manually inspect what PyObjC knows about this argument::
>> import AVFoundation
>>> AVFoundation.AVAudioRecorder.initWithURL_settings_error_.__metadata__( ['arguments'][-1]
{'null_accepted': True, 'already_retained': False, 'type': '^#', 'already_cfretained': False}
The type should have been "o^#" here.
This is with Apple's build of PyObjC: you can use "import AVFoundation" with that build, and that will use the BridgeSupport data files inside the AVFoundation framework. Sadly enough that data is incomplete and doesn't have information on this method and that's why the type is wrong here.
It is fairly easy to fix this for this particular method by using PyObjCs metadata API:
import objc
objc.registerMetaDataForSelector(b"AVAudioRecorder", b"initWithURL:settings:error:",
dict(
arguments={
4: dict(type_modifier=objc._C_OUT),
}
))
Fixing the metadata for all of AVFoundation will be more work :-(

Categories