#12940 Strict type validation and improved Enum error handling for Python GRPC

- Implemented strict parsing in 'writeToField' handlers to reject values with trailing garbage (e.g. '100.5test' for double, '0.99' for int/enum).
- Improved 'AppEnum' validation error message to list all valid options when an invalid value is provided.
- Added new test file 'test_validation_types_issue_12940.py' verifying strict type validation for double, int, and enum fields.
This commit is contained in:
Kristian Bendiksen committed 2026-01-21 08:41:09 +01:00
1 parent 71fa7d2c26
commit d06280cca8
5 files changed
+259 -1

No files matched your search

@@ -169,6 +169,10 @@ void PdmFieldScriptingCapabilityIOHandler<bool>::writeToField( bool&
formatString.arg( errorMessageContainer->currentArgument ).arg( errorMessageContainer->currentCommand );
errorMessageContainer->addError( errorMessage );
}
else
{
errorMessageContainer->checkForExtraCharactersAfterValue( inputStream );
}
fieldValue = evaluatesToTrue;
}
@@ -201,6 +205,10 @@ void PdmFieldScriptingCapabilityIOHandler<double>::writeToField( double&
inputStream.setStatus( QTextStream::Ok );
}
else
{
errorMessageContainer->checkForExtraCharactersAfterValue( inputStream );
}
}
void PdmFieldScriptingCapabilityIOHandler<double>::readFromField( const double& fieldValue,
@@ -213,3 +221,37 @@ void PdmFieldScriptingCapabilityIOHandler<double>::readFromField( const double&
outputStream.setRealNumberNotation( QTextStream::ScientificNotation );
outputStream << fieldValue;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void PdmFieldScriptingCapabilityIOHandler<int>::writeToField( int& fieldValue,
QTextStream& inputStream,
PdmScriptIOMessages* errorMessageContainer,
bool stringsAreQuoted )
{
inputStream >> fieldValue;
if ( inputStream.status() == QTextStream::ReadCorruptData )
{
errorMessageContainer->addError( "Argument value is unreadable in the argument: \"" +
errorMessageContainer->currentArgument + "\" in the command: \"" +
errorMessageContainer->currentCommand + "\"" );
inputStream.setStatus( QTextStream::Ok );
}
else
{
errorMessageContainer->checkForExtraCharactersAfterValue( inputStream );
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void PdmFieldScriptingCapabilityIOHandler<int>::readFromField( const int& fieldValue,
QTextStream& outputStream,
bool quoteStrings,
bool quoteNonBuiltins )
{
outputStream << fieldValue;
}
@@ -279,6 +279,19 @@ struct PdmFieldScriptingCapabilityIOHandler<double>
bool quoteNonBuiltins = false );
};
template <>
struct PdmFieldScriptingCapabilityIOHandler<int>
{
static void writeToField( int& fieldValue,
QTextStream& inputStream,
PdmScriptIOMessages* errorMessageContainer,
bool stringsAreQuoted = true );
static void readFromField( const int& fieldValue,
QTextStream& outputStream,
bool quoteStrings = true,
bool quoteNonBuiltins = false );
};
template <typename T>
struct PdmFieldScriptingCapabilityIOHandler<AppEnum<T>>
{
@@ -308,8 +321,19 @@ struct PdmFieldScriptingCapabilityIOHandler<AppEnum<T>>
{
// Unexpected enum value
// Error message
QStringList validOptions;
for ( size_t i = 0; i < fieldValue.size(); ++i )
{
validOptions.append( fieldValue.text( fieldValue.fromIndex( i ) ) );
}
errorMessageContainer->addError( "Failed to set enum text value \"" + accumulatedFieldValue +
"\" for the command: \"" + errorMessageContainer->currentCommand + "\"" );
"\" for the command: \"" + errorMessageContainer->currentCommand +
"\". Valid options are: " + validOptions.join( ", " ) );
}
else
{
errorMessageContainer->checkForExtraCharactersAfterValue( inputStream );
}
}
@@ -108,3 +108,22 @@ void PdmScriptIOMessages::skipLineWithLineNumberCount( QTextStream& inputStream
inputStream.readLine();
m_currentLineNumber++;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void PdmScriptIOMessages::checkForExtraCharactersAfterValue( QTextStream& inputStream )
{
skipWhiteSpaceWithLineNumberCount( inputStream );
if ( !inputStream.atEnd() )
{
// Check if the next character is a valid delimiter (for command syntax) or garbage
QChar nextChar = peekNextChar( inputStream );
// Valid delimiters: comma, close paren, close bracket (for array), or end of stream
if ( !( nextChar == QChar( ',' ) || nextChar == QChar( ')' ) || nextChar == QChar( ']' ) || nextChar.isNull() ) )
{
addError( "Extra characters found after value in argument: \"" + currentArgument + "\" in the command: \"" +
currentCommand + "\"" );
}
}
}
@@ -65,6 +65,8 @@ public:
QChar readCharWithLineNumberCount( QTextStream& inputStream );
QChar peekNextChar( QTextStream& inputStream );
void checkForExtraCharactersAfterValue( QTextStream& inputStream );
QString currentCommand;
QString currentArgument;
std::vector<std::pair<MessageType, QString>> m_messages;