I am embedding Python 3.0.1 on Windows, using MSVC 2008 sp1. I do not pass FILE* structs to Python, so I think compiler version differences is not a problem.

The following code has a problem, in that the "txt" string that comes out at the end only contains the character literal 1, followed by a terminating zero. I have tried it both with "u" and "s" format (changing between wchar_t * and char * for the out arg). Curiously, the result is the same -- a one-character string with ASCII 1 as the only character.

Am I doing something wrong, or is this totally bustigated? (And what happened to PyString_xxx ? Not there in 3.0 headers).

static void FormatError(wchar_t const *path, wchar_t *oError, size_t errBufSize)
  PyObject *ptype, *pvalue, *ptraceback;
  PyErr_Fetch(&ptype, &pvalue, &ptraceback);
  if (ptype == 0) ptype = Py_None;
  if (pvalue == 0) pvalue = Py_None;
  if (ptraceback == 0) ptraceback = Py_None;
  PyObject *a = 0, *b = 0, *c = 0;
  a = Py_BuildValue("OOO", ptype, pvalue, ptraceback);
  if (a == NULL)
    swprintf(oError, errBufSize, L"Unknown error in script %s.", path);
  b = PyObject_Repr(a);
  wchar_t const *txt = 0;
  c = Py_BuildValue("(u)", b);
  PyArg_ParseTuple(c, "u", &txt);
  if (txt == NULL)
    goto unknown_error;
  swprintf(oError, errBufSize, L"%s", txt);
  goto end;

I'd appreciate any help or pointers you might suggest (including pointers to other forums where Python devs might hang out).

On line 22 you have the incorrect format string for the argument b. The format string should be "(O)" as the argument is a Python object and not a null terminated wchar_t buffer.

However, it seems that all you are trying to do is get a wchar_t buffer from the repr object. This should work: wchar_t *txt = PyUnicode_AsWideChar(b);

the argument is a Python object and not a null terminated wchar_t buffer

Ah! So the type is not that of the object I pass in; it's of the pointer I pass in. That clarifies things.
I had already discovered the change from PyString -> PyUnicode in 3.0, but my confusion was why the above code didn't work as I expected it to. Now I know. Thanks for your help!