int ( PyCallable callable, PyFunction.Modifier modifier, boolean isConstructorCall, boolean isByInstance, boolean isByClass ) { int implicit_offset = 0; boolean firstIsArgsOrKwargs = false; final PyParameter[] parameters = callable.getParameterList().getParameters(); if (parameters.length > 0) { final PyParameter first = parameters[0]; final PyNamedParameter named = first.getAsNamed(); if (named != null && (named.isPositionalContainer() || named.isKeywordContainer())) { firstIsArgsOrKwargs = true; } } if (!firstIsArgsOrKwargs && (isByInstance || isConstructorCall)) { implicit_offset += 1; } PyFunction method = callable.asMethod(); if (method == null) return implicit_offset; if (PyUtil.isNewMethod(method)) { return isConstructorCall ? 1 : 0; } if (!isByInstance && !isByClass && PyUtil.isInitMethod(method)) { return 1; } // decorators? if (modifier == PyFunction.Modifier.STATICMETHOD) { if (isByInstance && implicit_offset > 0) implicit_offset -= 1; // might have marked it as implicit 'self' } else if (modifier == PyFunction.Modifier.CLASSMETHOD) { if (!isByInstance) implicit_offset += 1; // Both Foo.method() and foo.method() have implicit the first arg } return implicit_offset; }