Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions README/ReleaseNotes/v642/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,10 @@ Replace `obj.Connect(signal, "TPyDispatcher", disp, "Dispatch()")` with

* Reading a collection without its dictionary no longer crashes when the elements hold a `std::string` or a `TString`. The emulated collection proxy relocated its elements with a raw memory copy when its buffer had to grow, which corrupts an object that points into itself, such as a `std::string` using the small string optimization; the invalid pointer was then freed when the object was destroyed. Such elements are now destroyed and reconstructed at the new location instead. This affected for instance a `std::vector<std::pair<std::string,double>>` read back without a dictionary.

### RFile

RFile, ROOT's modern interface to ROOT file, has moved out of the `ROOT::Experimental` namespace.

### RNTupleProcessor

The RNTupleProcessor is a new, standalone interface for creating *chains* (similar to TTree's `TChain`) and *joins* (similar to TTree friends) from RNTuples in a composable way, and iterating over their entries.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ def __call__(self, namecycle):

key = self._rfile.GetKeyInfo(namecycle)
if key:
obj = ROOT.Experimental.Internal.RFile_GetObjectFromKey(self._rfile, key)
obj = ROOT.Internal.RFile_GetObjectFromKey(self._rfile, key)
return ROOT._cppyy.bind_object(obj, key.GetClassName())
# No key
return None
Expand Down Expand Up @@ -151,7 +151,7 @@ def _ListKeys(rfile, basePath="", **kwargs):
print(key.GetPath())
~~~
"""
from ROOT.Experimental import RFile
from ROOT import RFile

listObjects = kwargs['listObjects'] if 'listObjects' in kwargs else True
listDirs = kwargs['listDirs'] if 'listDirs' in kwargs else False
Expand All @@ -162,7 +162,7 @@ def _ListKeys(rfile, basePath="", **kwargs):
return iter


@pythonization("RFile", ns="ROOT::Experimental")
@pythonization("RFile", ns="ROOT")
def pythonize_rfile(klass):
# Explicitly prevent to create a RFile via ctor
klass.__init__ = _RFileInit
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -234,9 +234,6 @@ def _RNTupleWriter_Append(model, *args):
model = model.Clone()
import ROOT

if len(args) > 1 and isinstance(args[1], ROOT.Experimental.RFile):
return RNTupleContextWrapper(ROOT.Experimental.RNTupleWriter_Append(model, *args), "RNTupleWriter", on_ctx_exit = _RNTupleWriter_exit)

return RNTupleContextWrapper(ROOT.RNTupleWriter._Append(model, *args), "RNTupleWriter", on_ctx_exit = _RNTupleWriter_exit)


Expand Down
10 changes: 4 additions & 6 deletions io/io/inc/ROOT/RFile.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ class TKey;
class TTree;

namespace ROOT {
namespace Experimental {

class RKeyInfo;
class RFile;
Expand Down Expand Up @@ -59,7 +58,7 @@ std::pair<std::string_view, std::string_view> DecomposePath(std::string_view pat
class RFileKeyIterable;

/**
\class ROOT::Experimental::RKeyInfo
\class ROOT::RKeyInfo
\ingroup io_files
\brief Information about an RFile object's Key.

Expand All @@ -69,8 +68,8 @@ Querying this information can be done via RFile::ListKeys(). Reading an object's
doesn't deserialize the full object, so it's a relatively lightweight operation.
*/
class RKeyInfo final {
friend class ROOT::Experimental::RFile;
friend class ROOT::Experimental::RFileKeyIterable;
friend class ROOT::RFile;
friend class ROOT::RFileKeyIterable;

public:
enum class ECategory : std::uint16_t {
Expand Down Expand Up @@ -186,7 +185,7 @@ public:
};

/**
\class ROOT::Experimental::RFile
\class ROOT::RFile
\ingroup io_files
\brief An interface to read from, or write to, a ROOT file, as well as performing other common operations.

Expand Down Expand Up @@ -434,7 +433,6 @@ public:
void Print(std::ostream &out = std::cout) const;
};

} // namespace Experimental
} // namespace ROOT

#endif
30 changes: 15 additions & 15 deletions io/io/src/RFile.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,14 @@
#include <algorithm>
#include <cstring>

ROOT::RLogChannel &ROOT::Experimental::Internal::RFileLog()
ROOT::RLogChannel &ROOT::Internal::RFileLog()
{
static ROOT::RLogChannel sLog("ROOT.File");
return sLog;
}

using ROOT::Experimental::RFile;
using ROOT::Experimental::Internal::RFileLog;
using ROOT::RFile;
using ROOT::Internal::RFileLog;

namespace {
enum class ENameCycleError {
Expand Down Expand Up @@ -190,7 +190,7 @@ static std::string ReconstructFullKeyPath(const TKey &key)
}

/////////////////////////////////////////////////////////////////////////////////////////////////
std::pair<std::string_view, std::string_view> ROOT::Experimental::Detail::DecomposePath(std::string_view path)
std::pair<std::string_view, std::string_view> ROOT::Detail::DecomposePath(std::string_view path)
{
auto lastSlashIdx = path.rfind('/');
if (lastSlashIdx == std::string_view::npos)
Expand Down Expand Up @@ -399,14 +399,14 @@ void RFile::PutUntyped(std::string_view pathSV, const std::type_info &type, cons
}
}

ROOT::Experimental::RFileKeyIterable::RIterator::RIterStackElem::RIterStackElem(TIterator *it, const std::string &path)
ROOT::RFileKeyIterable::RIterator::RIterStackElem::RIterStackElem(TIterator *it, const std::string &path)
: fIter(it), fDirPath(path)
{
}

ROOT::Experimental::RFileKeyIterable::RIterator::RIterStackElem::~RIterStackElem() = default;
ROOT::RFileKeyIterable::RIterator::RIterStackElem::~RIterStackElem() = default;

ROOT::Experimental::RFileKeyIterable::RIterator::RIterator(TIterator *iter, Pattern_t pattern, std::uint32_t flags)
ROOT::RFileKeyIterable::RIterator::RIterator(TIterator *iter, Pattern_t pattern, std::uint32_t flags)
: fPattern(pattern), fFlags(flags)
{
if (iter) {
Expand All @@ -425,17 +425,17 @@ ROOT::Experimental::RFileKeyIterable::RIterator::RIterator(TIterator *iter, Patt
}
}

ROOT::Experimental::RFileKeyIterable::RIterator ROOT::Experimental::RFileKeyIterable::begin() const
ROOT::RFileKeyIterable::RIterator ROOT::RFileKeyIterable::begin() const
{
return {fFile->GetListOfKeys()->MakeIterator(), fPattern, fFlags};
}

ROOT::Experimental::RFileKeyIterable::RIterator ROOT::Experimental::RFileKeyIterable::end() const
ROOT::RFileKeyIterable::RIterator ROOT::RFileKeyIterable::end() const
{
return {nullptr, fPattern, fFlags};
}

void ROOT::Experimental::RFileKeyIterable::RIterator::Advance()
void ROOT::RFileKeyIterable::RIterator::Advance()
{
fCurKey = nullptr;

Expand Down Expand Up @@ -498,7 +498,7 @@ void ROOT::Experimental::RFileKeyIterable::RIterator::Advance()
}
}

ROOT::Experimental::RKeyInfo ROOT::Experimental::RFileKeyIterable::RIterator::operator*()
ROOT::RKeyInfo ROOT::RFileKeyIterable::RIterator::operator*()
{
if (fIterStack.empty())
throw ROOT::RException(R__FAIL("tried to dereference an invalid iterator"));
Expand Down Expand Up @@ -547,7 +547,7 @@ void RFile::Close()
fFile.reset();
}

ROOT::Experimental::RKeyInfo::RKeyInfo(const TKey &key)
ROOT::RKeyInfo::RKeyInfo(const TKey &key)
: fPath(ReconstructFullKeyPath(key)),
fTitle(key.GetTitle()),
fClassName(key.GetClassName()),
Expand All @@ -560,7 +560,7 @@ ROOT::Experimental::RKeyInfo::RKeyInfo(const TKey &key)
{
}

std::optional<ROOT::Experimental::RKeyInfo> RFile::GetKeyInfo(std::string_view path) const
std::optional<ROOT::RKeyInfo> RFile::GetKeyInfo(std::string_view path) const
{
const TKey *key = GetTKey(path);
if (!key)
Expand All @@ -570,13 +570,13 @@ std::optional<ROOT::Experimental::RKeyInfo> RFile::GetKeyInfo(std::string_view p
return keyInfo;
}

void *ROOT::Experimental::Internal::RFile_GetObjectFromKey(RFile &file, const RKeyInfo &key)
void *ROOT::Internal::RFile_GetObjectFromKey(RFile &file, const RKeyInfo &key)
{
void *obj = file.GetUntyped(key.GetPath(), key.GetClassName().c_str());
return obj;
}

TFile *ROOT::Experimental::Internal::GetRFileTFile(RFile &file)
TFile *ROOT::Internal::GetRFileTFile(RFile &file)
{
return file.fFile.get();
}
Expand Down
16 changes: 8 additions & 8 deletions io/io/test/rfile.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,10 @@

#include "RFileTestIncludes.hxx"

using ROOT::Experimental::RFile;
using ROOT::RFile;
using ROOT::TestSupport::FileRaii;

static std::string JoinKeyNames(const ROOT::Experimental::RFileKeyIterable &iterable)
static std::string JoinKeyNames(const ROOT::RFileKeyIterable &iterable)
{
auto beg = iterable.begin();
if (beg == iterable.end())
Expand All @@ -32,7 +32,7 @@ static std::string JoinKeyNames(const ROOT::Experimental::RFileKeyIterable &iter

TEST(RFile, DecomposePath)
{
using ROOT::Experimental::Detail::DecomposePath;
using ROOT::Detail::DecomposePath;

auto Pair = [](std::string_view a, std::string_view b) { return std::make_pair(a, b); };

Expand Down Expand Up @@ -648,7 +648,7 @@ TEST(RFile, GetAfterOverwriteNoBackup)
auto ss = file->Get<std::string>("s");
EXPECT_EQ(*ss, s);

std::vector<ROOT::Experimental::RKeyInfo> keys;
std::vector<ROOT::RKeyInfo> keys;
for (const auto &key : file->ListKeys())
keys.push_back(key);

Expand Down Expand Up @@ -778,7 +778,7 @@ TEST(RFile, RNTuple)
auto model = ROOT::RNTupleModel::Create();
*model->MakeField<float>("x") = 42;

auto writer = ROOT::Experimental::RNTupleWriter_Append(std::move(model), "data", *file);
auto writer = ROOT::RNTupleWriter::Append(std::move(model), "data", *file);
writer->Fill();
}

Expand Down Expand Up @@ -808,7 +808,7 @@ TEST(RFile, TTreeRead)
}

{
auto file = ROOT::Experimental::RFile::Open(fileGuard.GetPath());
auto file = ROOT::RFile::Open(fileGuard.GetPath());
auto tree = file->Get<TTree>("tree");
ASSERT_NE(tree, nullptr);
EXPECT_EQ(tree->GetEntries(), 10);
Expand Down Expand Up @@ -838,7 +838,7 @@ TEST(RFile, TTreeReadAfterClose)
}

{
auto file = ROOT::Experimental::RFile::Open(fileGuard.GetPath());
auto file = ROOT::RFile::Open(fileGuard.GetPath());
auto tree = file->Get<TTree>("tree");
file.reset(); // close the file
ASSERT_NE(tree, nullptr);
Expand Down Expand Up @@ -867,7 +867,7 @@ TEST(RFile, TTreeNoDoubleFree)
EXPECT_EQ(TTreeDestructorCounter::GetTimesDestructed(), 1);

{
auto file = ROOT::Experimental::RFile::Open(fileGuard.GetPath());
auto file = ROOT::RFile::Open(fileGuard.GetPath());
auto tree = file->Get<TTreeDestructorCounter>("tree");
file.reset(); // close the file (does not delete the three)
// tree is deleted here
Expand Down
22 changes: 10 additions & 12 deletions io/io/test/rfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@

import ROOT

RFile = ROOT.Experimental.RFile


class RFileTests(unittest.TestCase):
def test_open_for_reading(self):
Expand All @@ -19,7 +17,7 @@
hist.FillRandom("gaus", 100)
tfile.WriteObject(hist, "hist")

with RFile.Open(fileName) as rfile:
with ROOT.RFile.Open(fileName) as rfile:
hist = rfile.Get("hist")
self.assertNotEqual(hist, None)
self.assertEqual(rfile.Get[ROOT.TH1D]("inexistent"), None)
Expand All @@ -39,7 +37,7 @@

fileName = "test_rfile_writeread_py.root"
try:
with RFile.Recreate(fileName) as rfile:
with ROOT.RFile.Recreate(fileName) as rfile:
hist = ROOT.TH1D("hist", "", 100, -10, 10)
hist.FillRandom("gaus", 10)
rfile.Put("hist", hist)
Expand All @@ -48,7 +46,7 @@
with self.assertRaises(ROOT.RException):
rfile.Put("hist/2", hist)

with RFile.Open(fileName) as rfile:
with ROOT.RFile.Open(fileName) as rfile:
hist = rfile.Get("hist")
self.assertNotEqual(hist, None)

Expand All @@ -60,7 +58,7 @@

fileName = "test_rfile_getkeyinfo_py.root"
try:
with RFile.Recreate(fileName) as rfile:
with ROOT.RFile.Recreate(fileName) as rfile:
hist = ROOT.TH1D("hist", "", 100, -10, 10)
hist.FillRandom("gaus", 10)
rfile.Put("hist", hist)
Expand All @@ -69,7 +67,7 @@
rfile.Put("foo/bar/hist2", hist)
rfile.Put("foo/hist2", hist)

with RFile.Open(fileName) as rfile:
with ROOT.RFile.Open(fileName) as rfile:
key = rfile.GetKeyInfo("hist")
self.assertEqual(key.GetPath(), "hist")
self.assertEqual(key.GetClassName(), "TH1D")
Expand All @@ -85,7 +83,7 @@

fileName = "test_rfile_listkeys_py.root"
try:
with RFile.Recreate(fileName) as rfile:
with ROOT.RFile.Recreate(fileName) as rfile:
hist = ROOT.TH1D("hist", "", 100, -10, 10)
hist.FillRandom("gaus", 10)
rfile.Put("hist", hist)
Expand All @@ -94,7 +92,7 @@
rfile.Put("foo/bar/hist2", hist)
rfile.Put("foo/hist2", hist)

with RFile.Open(fileName) as rfile:
with ROOT.RFile.Open(fileName) as rfile:
keys = [key.GetPath() for key in rfile.ListKeys()]
self.assertEqual(keys, ["hist", "foo/hist", "foo/bar/hist", "foo/bar/hist2", "foo/hist2"])

Expand Down Expand Up @@ -128,7 +126,7 @@
def test_putUnsupportedType(self):
fileName = "test_rfile_putunsupported_py.root"
try:
with RFile.Recreate(fileName) as rfile:
with ROOT.RFile.Recreate(fileName) as rfile:
# Storing integers is unsupported
with self.assertRaises(TypeError):
rfile.Put("foo", 2)
Expand All @@ -143,7 +141,7 @@
# Storing strings is supported
rfile.Put("str", "foobar")

with RFile.Open(fileName) as rfile:
with ROOT.RFile.Open(fileName) as rfile:
self.assertEqual(rfile.Get("str"), b"foobar")
finally:
os.remove(fileName)
Expand All @@ -153,7 +151,7 @@

fileName = "test_rfile_gettree_py.root"
try:
with ROOT.TFile.Open(fileName, "RECREATE") as file:

Check failure on line 154 in io/io/test/rfile.py

View workflow job for this annotation

GitHub Actions / ruff

ruff (F841)

io/io/test/rfile.py:154:59: F841 Local variable `file` is assigned to but never used help: Remove assignment to unused variable `file`
tree = ROOT.TTree("tree", "tree")
x = array("i", [0])
tree.Branch("myColumn", x, "myColumn/I")
Expand All @@ -162,7 +160,7 @@
tree.Fill()
tree.Write()

with RFile.Open(fileName) as rfile:
with ROOT.RFile.Open(fileName) as rfile:
tree = rfile.Get("tree")
self.assertIsNot(tree, None)
self.assertEqual(tree.GetEntries(), 10)
Expand Down
Loading
Loading