Skip to content

gh-132775: Add _PyObject_GetXIDataWithFallback() #133482

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

ericsnowcurrently
Copy link
Member

@ericsnowcurrently ericsnowcurrently commented May 6, 2025

(This is based on gh-133481, thus only the last commit.)

Comment on lines 481 to 482
#ifdef Py_DEBUG
Py_UNREACHABLE();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The #ifdef looks like a typo.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's there to make sure we abort on debug builds, but we have a fallback for non-debug builds.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd prefer an explicit Py_FatalError() then. I think I can see this usage only in crossinterp.c (here, L1673, L1700).

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My intention is to not crash under normal usage, which is what Py_FatalError() would do.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ah, Py_FatalError() instead of Py_UNREACHABLE()? I'm okay with that. It really should be unreachable through.

Copy link
Contributor

@neonene neonene May 13, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I strongly prefer that Py_UNREACHABLE() be used when we care about the C compiler's optimization on non-debug builds (with no fallback). I won't be surprised even if it stops the abortion on debug builds in the future. Also, the double Py_DEBUG checks seem unnatural to me.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's fair. I'll switch it to explicitly Py_FatalError().

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks. This is off-topic, but would one of the coming PRs address #133107 (comment)?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I'll be addressing that.

@ericsnowcurrently ericsnowcurrently force-pushed the add-pyobject-getxidata-with-fallback branch 2 times, most recently from 04308b9 to b9f1eea Compare May 13, 2025 00:08
@ericsnowcurrently ericsnowcurrently force-pushed the add-pyobject-getxidata-with-fallback branch from b9f1eea to 55ccaa0 Compare May 13, 2025 00:46
@ericsnowcurrently ericsnowcurrently marked this pull request as ready for review May 13, 2025 00:47
Comment on lines +1342 to +1343
EXCEPTION,
OBJECT,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: indent. Also, cls is undefined at L726, 732:

assert not hasattr(mod, func.__name__), (cls, getattr(mod, func.__name__))

# Currently the "extra" attrs are not preserved
# (via __reduce__).
self.assertIs(type(exc1), type(exc2))
#self.assert_exc_equal(grouped1, grouped2)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this still intentionally commented out? The assertion passed for me.

def assert_equal_or_equalish(self, obj, expected):
cls = type(expected)
if cls.__eq__ is not object.__eq__:
# assert cls not in (types.MethodType, types.BuiltinMethodType, types.MethodWrapperType), cls
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ditto. See also:

L757:

#        self.assert_roundtrip_equal(defs.TOP_FUNCTIONS)

L844, 997, 1463:

#            UnicodeError: (None, msg, None, None, None),

Py_FatalError("unsupported xidata fallback option");
#endif
_PyErr_SetString(tstate, PyExc_SystemError,
"unsuppocted xidata fallback option");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: unsuppo"c"ted

}

int
_PyObject_GetXIDataWithFallback(PyThreadState *tstate,
Copy link
Contributor

@neonene neonene May 15, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we replace the long name with _PyObject_GetXIData? I feel the existing _PyObject_GetXIData could be longer (e.g. _PyObject_GetXIDataNoFallback), as it is unpopular at all in newer PRs.

UPDATE: No, _PyObject_GetXIData should remain as-is.

Copy link
Contributor

@neonene neonene May 16, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure whether the fallback parameter is needed. Does this function support the following?

  • call getdata.basic() under the _PyXIDATA_FULL_FALLBACK case
  • call getdata.fallback() under the _PyXIDATA_XIDATA_ONLY case

UPDATE: Yes, they are necessary.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I take back the questions in this topic. Sorry for the noise.

(I currently interpret getdata.fallback as getdata.(with)fallback that can pass an option to tuple's items, and WithFallback as _PyFunction_GetXIData and _PyPickle_GetXIData.)

Comment on lines +147 to +150
typedef struct {
xidatafunc basic;
xidatafbfunc fallback;
} _PyXIData_getdata_t;
Copy link
Contributor

@neonene neonene May 16, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does the layout imply that it would accept two functions in the future? If exclusive, is there any reason why it cannot be a void pointer (or xidatafunc) with a flag? (The C compilers could verify xidatafbfunc at REGISTER_FALLBACK().)

E: No change request from me as long as there are only two options.

typedef int (*xidatafunc)(PyThreadState *tstate, PyObject *, _PyXIData_t *);
typedef int xidata_fallback_t;
#define _PyXIDATA_XIDATA_ONLY (0)
#define _PyXIDATA_FULL_FALLBACK (1)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe flags like 0b111?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants