{LYN-2336} Fix: Python Console script help opens empty (#3060)

* {LYN-2336} Fix: Python Console script help opens empty

Fixes: Python Console: Script Help opens empty in AutomatedTesting project
This fixes the missing Python symbols in the Editor
This also fixes the PYI files to write out for the AutomatedTesting project

Signed-off-by: Jackson <23512001+jackalbe@users.noreply.github.com>

* Fixing proper symbol log execution times


Signed-off-by: Jackson <23512001+jackalbe@users.noreply.github.com>

* annotating input values with const

Signed-off-by: Jackson <23512001+jackalbe@users.noreply.github.com>
monroegm-disable-blank-issue-2
jackalbe 4 years ago committed by GitHub
parent 288d366c2a
commit 117bd0e680
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -90,6 +90,11 @@ namespace EditorPythonBindings
PythonSymbolEventBus::Handler::BusConnect(); PythonSymbolEventBus::Handler::BusConnect();
EditorPythonBindingsNotificationBus::Handler::BusConnect(); EditorPythonBindingsNotificationBus::Handler::BusConnect();
AZ::Interface<AzToolsFramework::EditorPythonConsoleInterface>::Register(this); AZ::Interface<AzToolsFramework::EditorPythonConsoleInterface>::Register(this);
if (PythonSymbolEventBus::GetTotalNumOfEventHandlers() > 1)
{
OnPostInitialize();
}
} }
void PythonLogSymbolsComponent::Deactivate() void PythonLogSymbolsComponent::Deactivate()
@ -111,6 +116,7 @@ namespace EditorPythonBindings
m_basePath = pythonSymbolsPath; m_basePath = pythonSymbolsPath;
} }
EditorPythonBindingsNotificationBus::Handler::BusDisconnect(); EditorPythonBindingsNotificationBus::Handler::BusDisconnect();
PythonSymbolEventBus::ExecuteQueuedEvents();
} }
void PythonLogSymbolsComponent::WriteMethod(AZ::IO::HandleType handle, AZStd::string_view methodName, const AZ::BehaviorMethod& behaviorMethod, const AZ::BehaviorClass* behaviorClass) void PythonLogSymbolsComponent::WriteMethod(AZ::IO::HandleType handle, AZStd::string_view methodName, const AZ::BehaviorMethod& behaviorMethod, const AZ::BehaviorClass* behaviorClass)
@ -206,12 +212,12 @@ namespace EditorPythonBindings
AZ::IO::FileIOBase::GetInstance()->Write(handle, buffer.c_str(), buffer.size()); AZ::IO::FileIOBase::GetInstance()->Write(handle, buffer.c_str(), buffer.size());
} }
void PythonLogSymbolsComponent::LogClass(AZStd::string_view moduleName, AZ::BehaviorClass* behaviorClass) void PythonLogSymbolsComponent::LogClass(const AZStd::string moduleName, const AZ::BehaviorClass* behaviorClass)
{ {
LogClassWithName(moduleName, behaviorClass, behaviorClass->m_name.c_str()); LogClassWithName(moduleName, behaviorClass, behaviorClass->m_name.c_str());
} }
void PythonLogSymbolsComponent::LogClassWithName(AZStd::string_view moduleName, AZ::BehaviorClass* behaviorClass, AZStd::string_view className) void PythonLogSymbolsComponent::LogClassWithName(const AZStd::string moduleName, const AZ::BehaviorClass* behaviorClass, const AZStd::string className)
{ {
Internal::FileHandle fileHandle(OpenModuleAt(moduleName)); Internal::FileHandle fileHandle(OpenModuleAt(moduleName));
if (fileHandle.IsValid()) if (fileHandle.IsValid())
@ -255,7 +261,11 @@ namespace EditorPythonBindings
} }
} }
void PythonLogSymbolsComponent::LogClassMethod(AZStd::string_view moduleName, AZStd::string_view globalMethodName, AZ::BehaviorClass* behaviorClass, AZ::BehaviorMethod* behaviorMethod) void PythonLogSymbolsComponent::LogClassMethod(
const AZStd::string moduleName,
const AZStd::string globalMethodName,
const AZ::BehaviorClass* behaviorClass,
const AZ::BehaviorMethod* behaviorMethod)
{ {
AZ_UNUSED(behaviorClass); AZ_UNUSED(behaviorClass);
Internal::FileHandle fileHandle(OpenModuleAt(moduleName)); Internal::FileHandle fileHandle(OpenModuleAt(moduleName));
@ -265,7 +275,7 @@ namespace EditorPythonBindings
} }
} }
void PythonLogSymbolsComponent::LogBus(AZStd::string_view moduleName, AZStd::string_view busName, AZ::BehaviorEBus* behaviorEBus) void PythonLogSymbolsComponent::LogBus(const AZStd::string moduleName, const AZStd::string busName, const AZ::BehaviorEBus* behaviorEBus)
{ {
if (behaviorEBus->m_events.empty()) if (behaviorEBus->m_events.empty())
{ {
@ -404,7 +414,7 @@ namespace EditorPythonBindings
} }
} }
void PythonLogSymbolsComponent::LogGlobalMethod(AZStd::string_view moduleName, AZStd::string_view methodName, AZ::BehaviorMethod* behaviorMethod) void PythonLogSymbolsComponent::LogGlobalMethod(const AZStd::string moduleName, const AZStd::string methodName, const AZ::BehaviorMethod* behaviorMethod)
{ {
Internal::FileHandle fileHandle(OpenModuleAt(moduleName)); Internal::FileHandle fileHandle(OpenModuleAt(moduleName));
if (fileHandle.IsValid()) if (fileHandle.IsValid())
@ -428,7 +438,10 @@ namespace EditorPythonBindings
} }
} }
void PythonLogSymbolsComponent::LogGlobalProperty(AZStd::string_view moduleName, AZStd::string_view propertyName, AZ::BehaviorProperty* behaviorProperty) void PythonLogSymbolsComponent::LogGlobalProperty(
const AZStd::string moduleName,
const AZStd::string propertyName,
const AZ::BehaviorProperty* behaviorProperty)
{ {
if (!behaviorProperty->m_getter || !behaviorProperty->m_getter->GetResult()) if (!behaviorProperty->m_getter || !behaviorProperty->m_getter->GetResult())
{ {

@ -51,12 +51,19 @@ namespace EditorPythonBindings
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
// PythonSymbolEventBus::Handler // PythonSymbolEventBus::Handler
void LogClass(AZStd::string_view moduleName, AZ::BehaviorClass* behaviorClass) override; void LogClass(const AZStd::string moduleName, const AZ::BehaviorClass* behaviorClass) override;
void LogClassWithName(AZStd::string_view moduleName, AZ::BehaviorClass* behaviorClass, AZStd::string_view className) override; void LogClassWithName(const AZStd::string moduleName, const AZ::BehaviorClass* behaviorClass, const AZStd::string className) override;
void LogClassMethod(AZStd::string_view moduleName, AZStd::string_view globalMethodName, AZ::BehaviorClass* behaviorClass, AZ::BehaviorMethod* behaviorMethod) override; void LogClassMethod(
void LogBus(AZStd::string_view moduleName, AZStd::string_view busName, AZ::BehaviorEBus* behaviorEBus) override; const AZStd::string moduleName,
void LogGlobalMethod(AZStd::string_view moduleName, AZStd::string_view methodName, AZ::BehaviorMethod* behaviorMethod) override; const AZStd::string globalMethodName,
void LogGlobalProperty(AZStd::string_view moduleName, AZStd::string_view propertyName, AZ::BehaviorProperty* behaviorProperty) override; const AZ::BehaviorClass* behaviorClass,
const AZ::BehaviorMethod* behaviorMethod) override;
void LogBus(const AZStd::string moduleName, const AZStd::string busName, const AZ::BehaviorEBus* behaviorEBus) override;
void LogGlobalMethod(const AZStd::string moduleName, const AZStd::string methodName, const AZ::BehaviorMethod* behaviorMethod) override;
void LogGlobalProperty(
const AZStd::string moduleName,
const AZStd::string propertyName,
const AZ::BehaviorProperty* behaviorProperty) override;
void Finalize() override; void Finalize() override;
AZStd::string FetchPythonTypeName(const AZ::BehaviorParameter& param) override; AZStd::string FetchPythonTypeName(const AZ::BehaviorParameter& param) override;

@ -394,7 +394,7 @@ namespace EditorPythonBindings
// log the bus symbol // log the bus symbol
AZStd::string subModuleName = pybind11::cast<AZStd::string>(thisBusModule.attr("__name__")); AZStd::string subModuleName = pybind11::cast<AZStd::string>(thisBusModule.attr("__name__"));
PythonSymbolEventBus::Broadcast(&PythonSymbolEventBus::Events::LogBus, subModuleName, ebusName, behaviorEBus); PythonSymbolEventBus::QueueBroadcast(&PythonSymbolEventBus::Events::LogBus, subModuleName, ebusName, behaviorEBus);
} }
} }

@ -756,7 +756,7 @@ namespace EditorPythonBindings
} }
AZStd::string subModuleName = pybind11::cast<AZStd::string>(subModule.attr("__name__")); AZStd::string subModuleName = pybind11::cast<AZStd::string>(subModule.attr("__name__"));
PythonSymbolEventBus::Broadcast(&PythonSymbolEventBus::Events::LogClassMethod, subModuleName, globalMethodName, behaviorClass, behaviorMethod); PythonSymbolEventBus::QueueBroadcast(&PythonSymbolEventBus::Events::LogClassMethod, subModuleName, globalMethodName, behaviorClass, behaviorMethod);
} }
else else
{ {
@ -782,7 +782,7 @@ namespace EditorPythonBindings
pybind11::setattr(subModule, constantPropertyName.c_str(), constantValue); pybind11::setattr(subModule, constantPropertyName.c_str(), constantValue);
AZStd::string subModuleName = pybind11::cast<AZStd::string>(subModule.attr("__name__")); AZStd::string subModuleName = pybind11::cast<AZStd::string>(subModule.attr("__name__"));
PythonSymbolEventBus::Broadcast(&PythonSymbolEventBus::Events::LogGlobalProperty, subModuleName, constantPropertyName, behaviorProperty); PythonSymbolEventBus::QueueBroadcast(&PythonSymbolEventBus::Events::LogGlobalProperty, subModuleName, constantPropertyName, behaviorProperty);
} }
} }
@ -809,11 +809,11 @@ namespace EditorPythonBindings
{ {
return ConstructPythonProxyObjectByTypename(behaviorClassName, pythonArgs); return ConstructPythonProxyObjectByTypename(behaviorClassName, pythonArgs);
}); });
PythonSymbolEventBus::Broadcast(&PythonSymbolEventBus::Events::LogClassWithName, subModuleName, behaviorClass, properSyntax); PythonSymbolEventBus::QueueBroadcast(&PythonSymbolEventBus::Events::LogClassWithName, subModuleName, behaviorClass, properSyntax);
} }
else else
{ {
PythonSymbolEventBus::Broadcast(&PythonSymbolEventBus::Events::LogClass, subModuleName, behaviorClass); PythonSymbolEventBus::QueueBroadcast(&PythonSymbolEventBus::Events::LogClass, subModuleName, behaviorClass);
} }
} }
} }

@ -153,7 +153,7 @@ namespace EditorPythonBindings
StaticPropertyHolderMapEntry& entry = iter->second; StaticPropertyHolderMapEntry& entry = iter->second;
entry.second->AddProperty(propertyName, behaviorProperty); entry.second->AddProperty(propertyName, behaviorProperty);
} }
PythonSymbolEventBus::Broadcast(&PythonSymbolEventBus::Events::LogGlobalProperty, scopeName, propertyName, behaviorProperty); PythonSymbolEventBus::QueueBroadcast(&PythonSymbolEventBus::Events::LogGlobalProperty, scopeName, propertyName, behaviorProperty);
} }
pybind11::module DetermineScope(pybind11::module scope, const AZStd::string& fullName) pybind11::module DetermineScope(pybind11::module scope, const AZStd::string& fullName)
@ -302,7 +302,7 @@ namespace EditorPythonBindings
// log global method symbol // log global method symbol
AZStd::string subModuleName = pybind11::cast<AZStd::string>(targetModule.attr("__name__")); AZStd::string subModuleName = pybind11::cast<AZStd::string>(targetModule.attr("__name__"));
PythonSymbolEventBus::Broadcast(&PythonSymbolEventBus::Events::LogGlobalMethod, subModuleName, methodName, behaviorMethod); PythonSymbolEventBus::QueueBroadcast(&PythonSymbolEventBus::Events::LogGlobalMethod, subModuleName, methodName, behaviorMethod);
} }
} }
@ -325,7 +325,7 @@ namespace EditorPythonBindings
// log global property symbol // log global property symbol
AZStd::string subModuleName = pybind11::cast<AZStd::string>(globalsModule.attr("__name__")); AZStd::string subModuleName = pybind11::cast<AZStd::string>(globalsModule.attr("__name__"));
PythonSymbolEventBus::Broadcast(&PythonSymbolEventBus::Events::LogGlobalProperty, subModuleName, propertyName, behaviorProperty); PythonSymbolEventBus::QueueBroadcast(&PythonSymbolEventBus::Events::LogGlobalProperty, subModuleName, propertyName, behaviorProperty);
if (behaviorProperty->m_getter && behaviorProperty->m_setter) if (behaviorProperty->m_getter && behaviorProperty->m_setter)
{ {
@ -377,7 +377,7 @@ namespace EditorPythonBindings
PythonProxyBusManagement::CreateSubmodule(parentModule); PythonProxyBusManagement::CreateSubmodule(parentModule);
Internal::RegisterPaths(parentModule); Internal::RegisterPaths(parentModule);
PythonSymbolEventBus::Broadcast(&PythonSymbolEventBus::Events::Finalize); PythonSymbolEventBus::QueueBroadcast(&PythonSymbolEventBus::Events::Finalize);
} }
} }
} }

@ -9,6 +9,14 @@
#include <AzCore/EBus/EBus.h> #include <AzCore/EBus/EBus.h>
namespace AZ
{
class BehaviorClass;
class BehaviorMethod;
class BehaviorEBus;
class BehaviorProperty;
}
namespace EditorPythonBindings namespace EditorPythonBindings
{ {
//! An interface to track exported Python symbols //! An interface to track exported Python symbols
@ -16,23 +24,39 @@ namespace EditorPythonBindings
: public AZ::EBusTraits : public AZ::EBusTraits
{ {
public: public:
// the symbols will be written out in the future
static const bool EnableEventQueue = true;
//! logs a behavior class type //! logs a behavior class type
virtual void LogClass(AZStd::string_view moduleName, AZ::BehaviorClass* behaviorClass) = 0; virtual void LogClass(const AZStd::string moduleName, const AZ::BehaviorClass* behaviorClass) = 0;
//! logs a behavior class type with an override to its name //! logs a behavior class type with an override to its name
virtual void LogClassWithName(AZStd::string_view moduleName, AZ::BehaviorClass* behaviorClass, AZStd::string_view className) = 0; virtual void LogClassWithName(
const AZStd::string moduleName,
const AZ::BehaviorClass* behaviorClass,
const AZStd::string className) = 0;
//! logs a static class method with a specified global method name //! logs a static class method with a specified global method name
virtual void LogClassMethod(AZStd::string_view moduleName, AZStd::string_view globalMethodName, AZ::BehaviorClass* behaviorClass, AZ::BehaviorMethod* behaviorMethod) = 0; virtual void LogClassMethod(
const AZStd::string moduleName,
const AZStd::string globalMethodName,
const AZ::BehaviorClass* behaviorClass,
const AZ::BehaviorMethod* behaviorMethod) = 0;
//! logs a behavior bus with a specified bus name //! logs a behavior bus with a specified bus name
virtual void LogBus(AZStd::string_view moduleName, AZStd::string_view busName, AZ::BehaviorEBus* behaviorEBus) = 0; virtual void LogBus(const AZStd::string moduleName, const AZStd::string busName, const AZ::BehaviorEBus* behaviorEBus) = 0;
//! logs a global method from the behavior context registry with a specified method name //! logs a global method from the behavior context registry with a specified method name
virtual void LogGlobalMethod(AZStd::string_view moduleName, AZStd::string_view methodName, AZ::BehaviorMethod* behaviorMethod) = 0; virtual void LogGlobalMethod(
const AZStd::string moduleName,
const AZStd::string methodName,
const AZ::BehaviorMethod* behaviorMethod) = 0;
//! logs a global property, enum, or constant from the behavior context registry with a specified property name //! logs a global property, enum, or constant from the behavior context registry with a specified property name
virtual void LogGlobalProperty(AZStd::string_view moduleName, AZStd::string_view propertyName, AZ::BehaviorProperty* behaviorProperty) = 0; virtual void LogGlobalProperty(
const AZStd::string moduleName,
const AZStd::string propertyName,
const AZ::BehaviorProperty* behaviorProperty) = 0;
//! signals the end of the logging of symbols //! signals the end of the logging of symbols
virtual void Finalize() = 0; virtual void Finalize() = 0;

@ -10,6 +10,7 @@
#include <EditorPythonBindings/EditorPythonBindingsBus.h> #include <EditorPythonBindings/EditorPythonBindingsBus.h>
#include <Source/PythonCommon.h> #include <Source/PythonCommon.h>
#include <Source/PythonSymbolsBus.h>
#include <pybind11/pybind11.h> #include <pybind11/pybind11.h>
#include <pybind11/embed.h> #include <pybind11/embed.h>
#include <pybind11/eval.h> #include <pybind11/eval.h>
@ -25,6 +26,7 @@
#include <AzCore/Serialization/SerializeContext.h> #include <AzCore/Serialization/SerializeContext.h>
#include <AzCore/Settings/SettingsRegistryMergeUtils.h> #include <AzCore/Settings/SettingsRegistryMergeUtils.h>
#include <AzCore/std/string/conversions.h> #include <AzCore/std/string/conversions.h>
#include <AzCore/std/smart_ptr/make_shared.h>
#include <AzCore/StringFunc/StringFunc.h> #include <AzCore/StringFunc/StringFunc.h>
#include <AzCore/Utils/Utils.h> #include <AzCore/Utils/Utils.h>
@ -39,7 +41,7 @@
namespace Platform namespace Platform
{ {
// Implemented in each different platform's implentation files, as it differs per platform. // Implemented in each different platform's implementation files, as it differs per platform.
bool InsertPythonBinaryLibraryPaths(AZStd::unordered_set<AZStd::string>& paths, const char* pythonPackage, const char* engineRoot); bool InsertPythonBinaryLibraryPaths(AZStd::unordered_set<AZStd::string>& paths, const char* pythonPackage, const char* engineRoot);
AZStd::string GetPythonHomePath(const char* pythonPackage, const char* engineRoot); AZStd::string GetPythonHomePath(const char* pythonPackage, const char* engineRoot);
} }
@ -225,6 +227,37 @@ namespace RedirectOutput
namespace EditorPythonBindings namespace EditorPythonBindings
{ {
// A stand in bus to capture the log symbol queue events
// so that when/if the PythonLogSymbolsComponent becomes
// active it can write out the python symbols to disk
class PythonSystemComponent::SymbolLogHelper final
: public PythonSymbolEventBus::Handler
{
public:
SymbolLogHelper()
{
PythonSymbolEventBus::Handler::BusConnect();
}
~SymbolLogHelper()
{
PythonSymbolEventBus::ExecuteQueuedEvents();
PythonSymbolEventBus::Handler::BusDisconnect();
}
void LogClass(const AZStd::string, const AZ::BehaviorClass*) override {}
void LogClassWithName(const AZStd::string, const AZ::BehaviorClass*, const AZStd::string) override {}
void LogClassMethod(
const AZStd::string,
const AZStd::string,
const AZ::BehaviorClass*,
const AZ::BehaviorMethod*) override {}
void LogBus(const AZStd::string, const AZStd::string, const AZ::BehaviorEBus*) override {}
void LogGlobalMethod(const AZStd::string, const AZStd::string, const AZ::BehaviorMethod*) override {}
void LogGlobalProperty(const AZStd::string, const AZStd::string, const AZ::BehaviorProperty*) override {}
void Finalize() override {}
};
void PythonSystemComponent::Reflect(AZ::ReflectContext* context) void PythonSystemComponent::Reflect(AZ::ReflectContext* context)
{ {
if (AZ::SerializeContext* serialize = azrtti_cast<AZ::SerializeContext*>(context)) if (AZ::SerializeContext* serialize = azrtti_cast<AZ::SerializeContext*>(context))
@ -471,8 +504,6 @@ namespace EditorPythonBindings
} }
} }
bool PythonSystemComponent::StartPythonInterpreter(const PythonPathStack& pythonPathStack) bool PythonSystemComponent::StartPythonInterpreter(const PythonPathStack& pythonPathStack)
{ {
AZStd::unordered_set<AZStd::string> pyPackageSites(pythonPathStack.begin(), pythonPathStack.end()); AZStd::unordered_set<AZStd::string> pyPackageSites(pythonPathStack.begin(), pythonPathStack.end());
@ -520,6 +551,11 @@ namespace EditorPythonBindings
AZStd::lock_guard<decltype(m_lock)> lock(m_lock); AZStd::lock_guard<decltype(m_lock)> lock(m_lock);
pybind11::gil_scoped_acquire acquire; pybind11::gil_scoped_acquire acquire;
if (EditorPythonBindings::PythonSymbolEventBus::GetTotalNumOfEventHandlers() == 0)
{
m_symbolLogHelper = AZStd::make_shared<PythonSystemComponent::SymbolLogHelper>();
}
// print Python version using AZ logging // print Python version using AZ logging
const int verRet = PyRun_SimpleStringFlags("import sys \nprint (sys.version) \n", nullptr); const int verRet = PyRun_SimpleStringFlags("import sys \nprint (sys.version) \n", nullptr);
AZ_Error("python", verRet == 0, "Error trying to fetch the version number in Python!"); AZ_Error("python", verRet == 0, "Error trying to fetch the version number in Python!");

@ -59,10 +59,13 @@ namespace EditorPythonBindings
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
private: private:
class SymbolLogHelper;
// handle multiple Python initializers and threads // handle multiple Python initializers and threads
AZStd::atomic_int m_initalizeWaiterCount {0}; AZStd::atomic_int m_initalizeWaiterCount {0};
AZStd::semaphore m_initalizeWaiter; AZStd::semaphore m_initalizeWaiter;
AZStd::recursive_mutex m_lock; AZStd::recursive_mutex m_lock;
AZStd::shared_ptr<SymbolLogHelper> m_symbolLogHelper;
enum class Result enum class Result
{ {

Loading…
Cancel
Save