Bug 33013

Summary: context.get_source().get_surface() fails with "SystemError: NULL object passed to Py_BuildValue"
Product: pycairo Reporter: kriomant
Component: generalAssignee: Steve Chaplin <d74n5pohf9>
Status: RESOLVED FIXED QA Contact:
Severity: major    
Priority: medium    
Version: unspecified   
Hardware: x86 (IA32)   
OS: Linux (All)   
Whiteboard:
i915 platform: i915 features:

Description kriomant 2011-01-12 00:08:02 UTC
Following script:

surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, 10, 10)
context = cairo.Context(surface)
source_surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, 10, 10)
context.set_source_surface(source_surface)
context.get_source().get_surface()

fails with:

Traceback (most recent call last):
  File "bug.py", line 7, in <module>
    context.get_source().get_surface()
SystemError: NULL object passed to Py_BuildValue

Reason:

get_source passes NULL to PycairoPattern_FromPattern:

static PyObject *
pycairo_get_source (PycairoContext *o) {
  return PycairoPattern_FromPattern (
           cairo_pattern_reference (cairo_get_source (o->ctx)), NULL);
}

PycairoPattern_FromPattern stores NULL to "base" field:

PyObject *
PycairoPattern_FromPattern (cairo_pattern_t *pattern, PyObject *base) {
  ...
  Py_XINCREF(base);
  ((PycairoPattern *)o)->base = base;
  ...
}

get_surface returns "base" field:

static PyObject *
surface_pattern_get_surface (PycairoSurfacePattern *o) {
  return Py_BuildValue("O", o->base);
}
Comment 1 Steve Chaplin 2011-03-27 20:40:08 UTC
Thanks for the bug report, its now fixed in git.
I had assumed the only way to create a surface pattern was using cairo.SurfacePattern() but as your example shows you can bypass this by calling
context.set_source_surface() and
pattern = context.get_source()

Use of freedesktop.org services, including Bugzilla, is subject to our Code of Conduct. How we collect and use information is described in our Privacy Policy.