Пример #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>();
}
Пример #2
0
	PropertyIterator(IComponentContext& context, const PyScript::ScriptObject& pythonObject,
	                 const PyScript::ScriptDict& metaDataDict)
	    : context_(context), object_(pythonObject), metaDataDict_(metaDataDict)
	{
		if (object_.get() == nullptr)
		{
			return;
		}

		// Get a list of strings appropriate for object arguments
		PyScript::ScriptObject dir = object_.getDir(PyScript::ScriptErrorPrint());
		if (dir.get() != nullptr)
		{
			iterator_ = dir.getIter(PyScript::ScriptErrorPrint());
		}
	}
Пример #3
0
std::string DefinitionDetails::generateName( const PyScript::ScriptObject & object )
{
	PyScript::ScriptErrorPrint errorHandler;
	std::string typeName;

	if (PyScript::ScriptType::check( object ))
	{
		// Type type
		// type.__module__ + type.__name__ + id( object )
		PyScript::ScriptType scriptType(
			reinterpret_cast<PyTypeObject*>( object.get() ), PyScript::ScriptObject::FROM_BORROWED_REFERENCE );

		scriptType.getAttribute( "__module__", typeName, errorHandler );
		typeName += '.';
		typeName += scriptType.name();
	}
	else
	{
		// Class or None type
		// __module__ + __name__ + id( object )
		typeName = object.str( errorHandler ).c_str();
	}

	// Add an address in case there are multiple classes/types with the same
	// name in the same file.
	// E.g.
	// # module "Test"
	// class A( object ):
	//     class InnerClass( object ):
	//         pass
	//     pass
	// class B( object ):
	//     class InnerClass( object ): # different type with the name "Test.InnerClass"
	//         pass
	//     pass
	typeName += " at ";
	typeName += std::to_string( object.id().asUnsignedLongLong(
		PyScript::ScriptErrorRetain() ) );

	// Check for overflow
	assert( !PyScript::Script::hasError() );
#if defined( _DEBUG )
	PyScript::Script::clearError();
#endif // defined( _DEBUG )

	return typeName;
}
Пример #4
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;
}
Пример #5
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();
}
Пример #6
0
bool NoneConverter::toVariant(const PyScript::ScriptObject& inObject, Variant& outVariant) /* override */
{
	// Check for types.NoneType
	if (!inObject.isNone())
	{
		return false;
	}

	outVariant = Variant(nullptr);
	return true;
}
Пример #7
0
DefinitionDetails::DefinitionDetails(IComponentContext& context, const PyScript::ScriptObject& pythonObject)
    : context_(context), name_(DefinitionDetails::generateName(pythonObject)), pythonObject_(pythonObject),
      metaData_(MetaNone())
{
	assert(!name_.empty());

	// Assume that _metaData is not modified after creation
	const char* metaDataName = "_metaData";
	const auto metaDataAttribute = pythonObject.getAttribute(metaDataName, PyScript::ScriptErrorClear());
	metaDataDict_ = PyScript::ScriptDict::create(metaDataAttribute);

	attachListenerHooks(pythonObject_);
}
Пример #8
0
bool PrimitiveConverter< T >::toVariant( const PyScript::ScriptObject & inObject,
	Variant & outVariant ) /* override */
{
	T value;
	const bool result = inObject.convertTo( value, PyScript::ScriptErrorClear() );
	if (!result)
	{
		return false;
	}

	outVariant = Variant( value );
	return true;
}
Пример #9
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;
}