Skip to content

Conversation

rboston628
Copy link
Contributor

Description of work

Summary of work

Fixes #xxxx.

Further detail of work

To test:


Reviewer

Please comment on the points listed below (full description).
Your comments will be used as part of the gatekeeper process, so please comment clearly on what you have checked during your review. If changes are made to the PR during the review process then your final comment will be the most important for gatekeepers. In this comment you should make it clear why any earlier review is still valid, or confirm that all requested changes have been addressed.

Code Review

  • Is the code of an acceptable quality?
  • Does the code conform to the coding standards?
  • Are the unit tests small and test the class in isolation?
  • If there is GUI work does it follow the GUI standards?
  • If there are changes in the release notes then do they describe the changes appropriately?
  • Do the release notes conform to the release notes guide?

Functional Tests

  • Do changes function as described? Add comments below that describe the tests performed?
  • Do the changes handle unexpected situations, e.g. bad input?
  • Has the relevant (user and developer) documentation been added/updated?

Does everything look good? Mark the review as Approve. A member of @mantidproject/gatekeepers will take care of it.

Gatekeeper

If you need to request changes to a PR then please add a comment and set the review status to "Request changes". This will stop the PR from showing up in the list for other gatekeepers.

@sf1919
Copy link
Contributor

sf1919 commented Apr 25, 2025

Is it still planned for this to go into v6.13?

@github-actions github-actions bot added the Has Conflicts Used by the bot to label pull requests that have conflicts label May 1, 2025
Copy link

github-actions bot commented May 1, 2025

👋 Hi, @rboston628,

Conflicts have been detected against the base branch. Please rebase your branch against the base branch.

@sf1919
Copy link
Contributor

sf1919 commented May 1, 2025

As this is failing tests and further commit(s) are expected we won't re-run any tests on the new Linux nodes.

Copy link

This pull request has been automatically marked as stale because it has not had activity in 3 months. It will be closed in 7 days if no further activity occurs.
Allowing pull requests to close as stale helps us filter out old work that is no longer relevant and helps developers focus on reviewing current work.
All pull requests closed by this bot act like normal pull requests; they can be searched for, commented on or reopened at any point.
If these changes are still relevant then please comment and tag @mantidproject/gatekeepers to highlight that it needs to have a reviewer assigned.

@github-actions github-actions bot added the Stale This label is automatically applied to issues that are automatically closed by the stale bot label Jul 31, 2025
Copy link

github-actions bot commented Aug 7, 2025

This pull request has been closed automatically. If these changes are still relevant then please re-open this pull request with a comment and tag @mantidproject/gatekeepers to highlight it needs to have a reviewer assigned.

@github-actions github-actions bot closed this Aug 7, 2025
@rboston628 rboston628 reopened this Aug 15, 2025
@rboston628 rboston628 force-pushed the patch-new-properties-with-values branch from 4c80143 to af07b39 Compare August 15, 2025 20:38
@github-actions github-actions bot removed the Has Conflicts Used by the bot to label pull requests that have conflicts label Aug 15, 2025
@rboston628
Copy link
Contributor Author

@coderabbitai full review

Copy link

coderabbitai bot commented Aug 15, 2025

✅ Actions performed

Full review triggered.

Copy link

coderabbitai bot commented Aug 15, 2025

📝 Walkthrough

Summary by CodeRabbit

  • New Features

    • Added support for displaying map values as concise and pretty strings.
    • Enabled JSON encoding for map-based properties.
    • Exposed a dictionary property (int keys to lists of ints) to Python.
  • Refactor

    • Extended internal helpers to handle map types consistently with existing list behavior.
  • Style

    • Minor test comment cleanup for clarity.
  • Tests

    • No behavioral changes; existing tests unchanged.

Walkthrough

  • Extended PropertyHelper with std::map support: toString and toPrettyString for maps; toValue for maps throws boost::bad_lexical_cast; += addingOperator for maps throws NotImplementedError.
  • Added encodeAsJson overload to serialize std::map<KeyType, ValueType> to Json::Value objects.
  • Explicitly instantiated PropertyWithValue<std::map<int, std::vector>> in C++.
  • Exposed the same map type to Python via PropertyWithValueExporter as "IntVectorIntDictionaryPropertyWithValue".
  • Minor test file change: comments reformatted; no test logic changes.

Tip

🔌 Remote MCP (Model Context Protocol) integration is now available!

Pro plan users can now connect to remote MCP servers from the Integrations page. Connect with popular remote MCPs such as Notion and Linear to add more context to your reviews and chats.

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch patch-new-properties-with-values

🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR/Issue comments)

Type @coderabbitai help to get the list of available commands.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Status, Documentation and Community

  • Visit our Status Page to check the current availability of CodeRabbit.
  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (2)
Framework/Kernel/inc/MantidKernel/PropertyHelper.h (2)

67-79: Trailing delimiter in map toString output

toString(std::map<...>) currently appends the delimiter after the last entry. Other toString overloads avoid trailing delimiters. Suggest aligning for consistency:

-template <typename K, typename V>
-std::string toString(const std::map<K, V> &value, const std::string &delimiter = ",") {
-  std::stringstream result;
-  // std::size_t vsize = value.size();
-  for (auto it = value.begin(); it != value.end(); it++) {
-    result << "(" << toString(it->first) << ":";
-    result << toString(it->second) << ")";
-    result << delimiter;
-  }
-  return result.str();
-}
+template <typename K, typename V>
+std::string toString(const std::map<K, V> &value, const std::string &delimiter = ",") {
+  std::stringstream result;
+  for (auto it = value.begin(); it != value.end();) {
+    result << "(" << toString(it->first) << ":" << toString(it->second) << ")";
+    if (++it != value.end()) {
+      result << delimiter;
+    }
+  }
+  return result.str();
+}

346-349: Intentional: += not implemented for maps

Throwing NotImplementedError for std::map aligns with the current semantics for unsupported types. Consider documenting intended future behavior (merge vs append) if map support is planned beyond stringification/JSON encoding.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 39e6714 and af07b39.

📒 Files selected for processing (5)
  • Framework/Kernel/inc/MantidKernel/PropertyHelper.h (4 hunks)
  • Framework/Kernel/inc/MantidKernel/PropertyWithValueJSON.h (1 hunks)
  • Framework/Kernel/src/PropertyWithValue.cpp (1 hunks)
  • Framework/Kernel/test/PropertyWithValueTest.h (1 hunks)
  • Framework/PythonInterface/mantid/kernel/src/Exports/PropertyWithValue.cpp (1 hunks)
🔇 Additional comments (4)
Framework/Kernel/test/PropertyWithValueTest.h (1)

210-211: Comment reflow is fine; no behavioral impact

This is a pure comment reformat with no effect on test behavior. Safe change.

Framework/Kernel/src/PropertyWithValue.cpp (1)

97-98: Explicit instantiation added — consider ensuring headers cover std::map

The instantiation looks correct and aligns with the new Python export. To avoid relying on transitive includes, ensure is included in a translation unit that sees this instantiation (here or via included headers) to prevent potential compile errors on stricter toolchains.

If needed, add near the includes:

#include <map>
Framework/PythonInterface/mantid/kernel/src/Exports/PropertyWithValue.cpp (1)

43-49: Python export added — add include to avoid transitive include dependency

The new export is consistent with existing patterns. To avoid relying on transitive includes, please include in this file (or ensure the exporter header includes it), since std::map<int, std::vector<int>> is referenced.

#include <map>
Framework/Kernel/inc/MantidKernel/PropertyHelper.h (1)

236-239: Intentional: disallow string-to-map conversion

Throwing boost::bad_lexical_cast for std::map parsing is a clear contract and prevents ambiguous string parsing. Looks good.

Comment on lines +131 to +141
template <typename K, typename V>
std::string toPrettyString(const std::map<K, V> &value, size_t maxLength = 0, bool collapseLists = true,
const std::string &delimiter = "\n", const std::string & = "+") {
std::stringstream retVal;
retVal << "{";
for (auto it = value.begin(); it != value.end(); it++) {
retVal << toString(it->first) << ":" << toPrettyString(it->second, maxLength, collapseLists) << delimiter << " ";
}
return Strings::shorten(retVal.str(), maxLength);
}

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Bug: toPrettyString(std::map<...>) misses closing brace and adds trailing delimiter

The output starts with “{” but never closes it, and it always appends the delimiter after the last item. Fix both and avoid trailing space:

-template <typename K, typename V>
-std::string toPrettyString(const std::map<K, V> &value, size_t maxLength = 0, bool collapseLists = true,
-                           const std::string &delimiter = "\n", const std::string & = "+") {
-  std::stringstream retVal;
-  retVal << "{";
-  for (auto it = value.begin(); it != value.end(); it++) {
-    retVal << toString(it->first) << ":" << toPrettyString(it->second, maxLength, collapseLists) << delimiter << " ";
-  }
-  return Strings::shorten(retVal.str(), maxLength);
-}
+template <typename K, typename V>
+std::string toPrettyString(const std::map<K, V> &value, size_t maxLength = 0, bool collapseLists = true,
+                           const std::string &delimiter = "\n", const std::string & = "+") {
+  std::stringstream retVal;
+  retVal << "{";
+  for (auto it = value.begin(); it != value.end();) {
+    retVal << toString(it->first) << ":" << toPrettyString(it->second, maxLength, collapseLists);
+    if (++it != value.end()) {
+      retVal << delimiter << " ";
+    }
+  }
+  retVal << "}";
+  return Strings::shorten(retVal.str(), maxLength);
+}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
template <typename K, typename V>
std::string toPrettyString(const std::map<K, V> &value, size_t maxLength = 0, bool collapseLists = true,
const std::string &delimiter = "\n", const std::string & = "+") {
std::stringstream retVal;
retVal << "{";
for (auto it = value.begin(); it != value.end(); it++) {
retVal << toString(it->first) << ":" << toPrettyString(it->second, maxLength, collapseLists) << delimiter << " ";
}
return Strings::shorten(retVal.str(), maxLength);
}
template <typename K, typename V>
std::string toPrettyString(const std::map<K, V> &value, size_t maxLength = 0, bool collapseLists = true,
const std::string &delimiter = "\n", const std::string & = "+") {
std::stringstream retVal;
retVal << "{";
for (auto it = value.begin(); it != value.end();) {
retVal << toString(it->first) << ":"
<< toPrettyString(it->second, maxLength, collapseLists);
if (++it != value.end()) {
retVal << delimiter << " ";
}
}
retVal << "}";
return Strings::shorten(retVal.str(), maxLength);
}
🤖 Prompt for AI Agents
In Framework/Kernel/inc/MantidKernel/PropertyHelper.h around lines 131-141, the
map overload of toPrettyString opens a "{" but never appends the closing "}" and
always writes the delimiter (and a trailing space) after the last element;
update the implementation to iterate without adding the delimiter after the
final entry (for example detect last element with std::prev(value.end()) or
build the first-item flag and prepend delimiters for subsequent items), avoid
adding the extra trailing space, then append the closing "}" before calling
Strings::shorten; ensure the function returns the shortened full string
including the trailing brace.

Comment on lines +152 to +164
/**
* Encode a std::map value as a Json::Value dictionaryValue type
* @param mapValue The C++ value to encode
* @return A new Json::Value
*/
template <typename KeyType, typename ValueType> Json::Value encodeAsJson(const std::map<KeyType, ValueType> &mapValue) {
Json::Value jsonDictionary(Json::objectValue);
for (const auto &element : mapValue) {
jsonDictionary[element.first] = encodeAsJson(element.second);
}
return jsonDictionary;
}

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Bug: Using non-string map keys for Json::Value object indexing

jsonDictionary[element.first] will select the array-indexing overload when KeyType is an integer (e.g., std::map<int, ...>). This is invalid for Json::objectValue and will assert/fail. JSON object keys must be strings.

Convert keys to strings before indexing. Example fix:

-template <typename KeyType, typename ValueType> Json::Value encodeAsJson(const std::map<KeyType, ValueType> &mapValue) {
-  Json::Value jsonDictionary(Json::objectValue);
-  for (const auto &element : mapValue) {
-    jsonDictionary[element.first] = encodeAsJson(element.second);
-  }
-  return jsonDictionary;
-}
+template <typename KeyType, typename ValueType>
+Json::Value encodeAsJson(const std::map<KeyType, ValueType> &mapValue) {
+  Json::Value jsonDictionary(Json::objectValue);
+  for (const auto &element : mapValue) {
+    std::ostringstream keyStream;
+    keyStream << element.first; // supports numeric and streamable key types
+    jsonDictionary[keyStream.str()] = encodeAsJson(element.second);
+  }
+  return jsonDictionary;
+}

And ensure the following headers are available in this TU:

#include <map>
#include <sstream>
🤖 Prompt for AI Agents
In Framework/Kernel/inc/MantidKernel/PropertyWithValueJSON.h around lines
152-164, the template uses jsonDictionary[element.first] which will pick the
array-index overload when KeyType is non-string (e.g. int) and is invalid for
Json::objectValue; convert the map key to a std::string before indexing (e.g.
use std::ostringstream or std::to_string for arithmetic types) and assign the
encoded value to jsonDictionary[stringKey]; also ensure the translation unit
includes <map> and <sstream> (or <string>) so key-to-string conversion compiles.

@github-actions github-actions bot removed the Stale This label is automatically applied to issues that are automatically closed by the stale bot label Aug 16, 2025
Copy link

👋 Hi, @rboston628,

Conflicts have been detected against the base branch. Please rebase your branch against the base branch.

@github-actions github-actions bot added the Has Conflicts Used by the bot to label pull requests that have conflicts label Aug 22, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Has Conflicts Used by the bot to label pull requests that have conflicts
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants