Question: I want to be able to distinguish some native class like _functools.partial (code, code) from some user-class like: class MyClass: pass  I want to test this from within Python (so not using the CPython API or so). But it's ok if this only works with CPython. It should work for CPython >=3.6. How? More specifically, I want to distinguish objects where its __dict__/__slots__ will not give me all the object attributes. This is usually the case for native types such as _functools.partial where the func, args, keywords are not in __dict__ (and __slots__ does not exist). I think basically I want to check if the type defines some custom Py_tp_members (but not derived from __slots__ (see)).  Some background / ideas which might be helpful to get to an answer:  functools.partial.__dict__ is usually empty or None. functools.partial.__slots__ only exists if Python uses the pure Python implementation, which is usually not the case. functools.partial.__getstate__() exists since Python >=3.11 and will return __dict__ (and maybe __slots__), so in case of the native partial, it will be empty or None. (Not sure if this is really correct. See CPython issue #125094.) functools.partial.__dir__(functools.partial) also does not cover func and co? However, dir(functools.partial) does? Side question: What is the builtin dir doing differently? Where is the exact code of the builtin dir which covers this case? I assume it iterates through the Py_tp_members, maybe also Py_tp_methods? I initially thought that maybe __dictoffset__ gives me some hint, but that turned out to be wrong. The builtin dir could probably be used in any case. The inspect.getmembers (or also inspect.getmembers_static) might tell me what I need to know.   Why do I need that? We need to define our own custom hash (not __hash__) for any type of object, in a stable way (that the hash does not change across Python versions), and in a meaningful way (that the hash contains all relevant state). So far, we iterate over __getstate__(), or __dict__/__slots__, which works fine for most cases, except now for functools.partial, and likely for other native types. So the idea was, add a check if we have a native type, and if so, fallback to using dir, as that seems to work fine even in those cases. See Sisyphus issue #207 and Sisyphus get_object_state and Sisyphus sis_hash_helper.

Answer: While playing around, I noticed that all entries in Py_tp_members will always become corresponding member descriptors in the type. And you can check for those, via inspect.ismemberdescriptor (which just checks isinstance(object, types.MemberDescriptorType)). I think this type of descriptor would not be used otherwise. So that allows to implement such a check. Note, instead of calling this is_native_type or so, I call this type_has_native_members, to be more specific about what it actually checks (and what I want here). (But "being a native type" was anyway somewhat not well defined in the first place. I just was not sure how to properly define it.) import inspect def type_has_native_members(cls): if hasattr(cls, "__slots__"): return False for key in dir(cls): value = getattr(cls, key, None) if inspect.ismemberdescriptor(value): return True return False # --------------- # some tests: import functools assert type_has_native_members(functools.partial) class Foo: pass assert not type_has_native_members(Foo)