Example #1
0
bool Property::isCollection() const /* override */
{
	// Get the attribute
	PyScript::ScriptErrorPrint errorHandler;
	PyScript::ScriptObject attribute = impl_->pythonObject_.getAttribute(impl_->key_.c_str(), errorHandler);
	assert(attribute.exists());
	if (!attribute.exists())
	{
		return false;
	}

	return PythonType::scriptTypeToTypeId(attribute) == TypeId::getType<Collection>();
}
Example #2
0
bool Property::isMethod() const /* override */
{
	// Get the attribute
	PyScript::ScriptErrorPrint errorHandler;
	PyScript::ScriptObject attribute = impl_->pythonObject_.getAttribute(impl_->key_.c_str(), errorHandler);
	assert(attribute.exists());
	if (!attribute.exists())
	{
		return false;
	}

	// Checks if the attribute is "callable", it may be:
	// - an instance with a __call__ attribute
	// or
	// - a type with a tp_call member, such as
	// -- a method on a class
	// -- a function/lambda type
	return attribute.isCallable();
}
Example #3
0
Variant Property::invoke(const ObjectHandle& object, const IDefinitionManager& definitionManager,
                         const ReflectedMethodParameters& parameters) /* override */
{
	const bool callable = this->isMethod();
	assert(callable);
	if (!callable)
	{
		return Variant();
	}

	auto pTypeConverters = impl_->get<PythonType::Converters>();
	assert(pTypeConverters != nullptr);

	// Parse arguments
	auto tuple = PyScript::ScriptTuple::create(parameters.size());
	size_t i = 0;

	for (auto itr = parameters.cbegin(); (i < parameters.size()) && (itr != parameters.cend()); ++i, ++itr)
	{
		auto parameter = (*itr);
		PyScript::ScriptObject scriptObject;
		const bool success = pTypeConverters->toScriptType(parameter, scriptObject);
		assert(success);
		tuple.setItem(i, scriptObject);
	}

	PyScript::ScriptArgs args = PyScript::ScriptArgs(tuple.get(), PyScript::ScriptObject::FROM_BORROWED_REFERENCE);

	// Call method
	PyScript::ScriptErrorPrint errorHandler;
	const bool allowNullMethod = false;
	PyScript::ScriptObject returnValue =
	impl_->pythonObject_.callMethod(impl_->key_.c_str(), args, errorHandler, allowNullMethod);

	// Return value
	Variant result;

	if (returnValue.exists())
	{
		const bool success = pTypeConverters->toVariant(returnValue, result, object, impl_->key_);
		assert(success);
	}

	return result;
}
Example #4
0
size_t Property::parameterCount() const /* override */
{
	PyScript::ScriptObject attribute =
	impl_->pythonObject_.getAttribute(impl_->key_.c_str(), PyScript::ScriptErrorPrint());
	assert(attribute.exists());
	if (!attribute.exists())
	{
		return 0;
	}

	if (!attribute.isCallable())
	{
		return 0;
	}

	// -- Old-style class instance.__call__(self)
	if (PyScript::ScriptInstance::check(attribute))
	{
		auto callObject = attribute.getAttribute("__call__", PyScript::ScriptErrorClear());
		if (!callObject.exists())
		{
			return 0;
		}

		// Convert __call__(self) method object to a function()
		auto methodObject = PyScript::ScriptMethod::create(callObject);
		assert(methodObject.exists());

		auto functionObject = methodObject.function();
		assert(functionObject.exists());

		// Convert function to code and get arg count
		auto codeObject = functionObject.code();
		assert(codeObject.exists());

		const auto argCount = codeObject.argCount();

		// Methods subtract 1 argument for "self".
		const int selfArg = 1;
		assert(argCount > 0);
		return (argCount - selfArg);
	}

	// -- Old-style class constructor instance(self)
	if (PyScript::ScriptClass::check(attribute))
	{
		auto initObject = attribute.getAttribute("__init__", PyScript::ScriptErrorClear());
		if (!initObject.exists())
		{
			// Default __init__(self)
			return 0;
		}

		// Convert __init__(self) method object to a function()
		auto methodObject = PyScript::ScriptMethod::create(initObject);
		assert(methodObject.exists());

		auto functionObject = methodObject.function();
		assert(functionObject.exists());

		// Convert function to code and get arg count
		auto codeObject = functionObject.code();
		assert(codeObject.exists());

		const auto argCount = codeObject.argCount();

		// Methods subtract 1 argument for "self".
		const int selfArg = 1;
		assert(argCount > 0);
		return (argCount - selfArg);
	}

	// -- Method like self.function(self)
	auto methodObject = PyScript::ScriptMethod::create(attribute);
	if (methodObject.exists())
	{
		// Convert self.function() method object to a function()
		auto functionObject = methodObject.function();
		assert(functionObject.exists());

		// Convert function to code and get arg count
		auto codeObject = functionObject.code();
		assert(codeObject.exists());

		const auto argCount = codeObject.argCount();

		// Methods subtract 1 argument for "self".
		const int selfArg = 1;
		assert(argCount > 0);
		return (argCount - selfArg);
	}

	// -- Plain function or lambda type
	auto functionObject = PyScript::ScriptFunction::create(attribute);
	if (functionObject.exists())
	{
		auto codeObject = functionObject.code();
		assert(codeObject.exists());
		return codeObject.argCount();
	}

	// -- New-style class instance.__call__(self)
	auto callObject = attribute.getAttribute("__call__", PyScript::ScriptErrorClear());

	// Convert __call__(self) method object to a function()
	methodObject = PyScript::ScriptMethod::create(callObject);
	if (methodObject.exists())
	{
		// Convert function to code and get arg count
		functionObject = methodObject.function();
		assert(functionObject.exists());

		auto codeObject = functionObject.code();
		assert(codeObject.exists());

		const auto argCount = codeObject.argCount();

		// Methods subtract 1 argument for "self".
		const int selfArg = 1;
		assert(argCount > 0);
		return (argCount - selfArg);
	}

	// -- New-style class constructor instance.__init__(self)
	auto initObject = attribute.getAttribute("__init__", PyScript::ScriptErrorClear());

	// Convert __init__(self) method object to a function()
	methodObject = PyScript::ScriptMethod::create(initObject);
	if (methodObject.exists())
	{
		// Convert function to code and get arg count
		functionObject = methodObject.function();
		assert(functionObject.exists());

		auto codeObject = functionObject.code();
		assert(codeObject.exists());

		const auto argCount = codeObject.argCount();

		// Methods subtract 1 argument for "self".
		const int selfArg = 1;
		assert(argCount > 0);
		return (argCount - selfArg);
	}

	// Default __init__(self)
	return 0;
}