12
12
from __future__ import annotations
13
13
from ._core import (
14
14
GenEvent ,
15
- ReaderAscii ,
16
- ReaderAsciiHepMC2 ,
17
- ReaderLHEF ,
18
- ReaderHEPEVT ,
15
+ ReaderAscii as ReaderAsciiBase ,
16
+ ReaderAsciiHepMC2 as ReaderAsciiHepMC2Base ,
17
+ ReaderLHEF as ReaderLHEFBase ,
18
+ ReaderHEPEVT as ReaderHEPEVTBase ,
19
19
WriterAscii ,
20
20
WriterAsciiHepMC2 ,
21
21
WriterHEPEVT ,
38
38
]
39
39
40
40
41
- class _Iter :
42
- def __init__ (self , parent : Any ):
43
- self .parent = parent
44
-
45
- def __next__ (self ) -> GenEvent :
46
- evt = GenEvent ()
47
- success = self .parent .read_event (evt )
48
- if self .parent .failed ():
49
- if success : # indicates EOF
50
- raise StopIteration
51
- raise IOError ("error reading event" )
52
- return evt
53
-
54
- def __iter__ (self ) -> "_Iter" :
55
- return self
56
-
57
- next = __next__
58
-
59
-
60
41
def _enter (self : Any ) -> Any :
61
42
return self
62
43
@@ -71,49 +52,68 @@ def _exit_flush(self: Any, type: Exception, value: str, tb: Any) -> bool:
71
52
return False
72
53
73
54
74
- def _iter (self : Any ) -> _Iter :
75
- return _Iter (self )
76
-
77
-
78
- def _read (self : Any ) -> Optional [GenEvent ]:
79
- evt = GenEvent ()
80
- success = self .read_event (evt )
81
- if self .failed ():
82
- if success : # indicates EOF
83
- return None
84
- raise IOError ("error reading event" )
85
- return evt if success else None
86
-
87
-
88
55
def _read_event_lhef_patch (self : Any , evt : GenEvent ) -> bool :
89
56
failed = self ._read_event_unpatched (evt )
90
57
if failed and self .failed (): # probably EOF
91
58
return True
92
59
return not failed
93
60
94
61
62
+ class _Iter :
63
+ def __init__ (self , reader : Any ):
64
+ self .reader = reader
65
+
66
+ def __next__ (self ) -> GenEvent :
67
+ evt = self .reader .read ()
68
+ if evt is None :
69
+ raise StopIteration
70
+ return evt
71
+
72
+ def __iter__ (self ) -> "_Iter" :
73
+ return self
74
+
75
+ next = __next__
76
+
77
+
78
+ class ReaderMixin :
79
+ def read (self ) -> Optional [GenEvent ]:
80
+ assert hasattr (self , "failed" )
81
+ assert hasattr (self , "read_event" )
82
+ if self .failed ():
83
+ # usually this means EOF was reached previously
84
+ return None
85
+ evt = GenEvent ()
86
+ success = self .read_event (evt )
87
+ # workaround for bug in HepMC3, which reports success even if
88
+ # the next section of the file does not contain any event data
89
+ if len (evt .particles ) == 0 :
90
+ success = False
91
+ return evt if success else None
92
+
93
+ def __iter__ (self : Any ) -> _Iter :
94
+ return _Iter (self )
95
+
96
+ __enter__ = _enter
97
+ __exit__ = _exit_close
98
+
99
+
95
100
# add contextmanager interface to IO classes
96
- ReaderAscii .__enter__ = _enter
97
- ReaderAscii .__exit__ = _exit_close
98
- ReaderAscii .__iter__ = _iter
99
- ReaderAscii .read = _read
100
-
101
- ReaderAsciiHepMC2 .__enter__ = _enter
102
- ReaderAsciiHepMC2 .__exit__ = _exit_close
103
- ReaderAsciiHepMC2 .__iter__ = _iter
104
- ReaderAsciiHepMC2 .read = _read
105
-
106
- ReaderLHEF .__enter__ = _enter
107
- ReaderLHEF .__exit__ = _exit_close
108
- ReaderLHEF .__iter__ = _iter
109
- ReaderLHEF ._read_event_unpatched = ReaderLHEF .read_event
110
- ReaderLHEF .read_event = _read_event_lhef_patch
111
- ReaderLHEF .read = _read
112
-
113
- ReaderHEPEVT .__enter__ = _enter
114
- ReaderHEPEVT .__exit__ = _exit_close
115
- ReaderHEPEVT .__iter__ = _iter
116
- ReaderHEPEVT .read = _read
101
+ class ReaderAscii (ReaderAsciiBase , ReaderMixin ): # type:ignore
102
+ pass
103
+
104
+
105
+ class ReaderAsciiHepMC2 (ReaderAsciiHepMC2Base , ReaderMixin ): # type:ignore
106
+ pass
107
+
108
+
109
+ class ReaderLHEF (ReaderLHEFBase , ReaderMixin ): # type:ignore
110
+ _read_event_unpatched = ReaderLHEFBase .read_event
111
+ read_event = _read_event_lhef_patch
112
+
113
+
114
+ class ReaderHEPEVT (ReaderHEPEVTBase , ReaderMixin ): # type:ignore
115
+ pass
116
+
117
117
118
118
WriterAscii .__enter__ = _enter
119
119
WriterAscii .__exit__ = _exit_close
@@ -256,6 +256,7 @@ def open_file() -> Any:
256
256
self ._file = open_file ()
257
257
self ._ios = pyiostream (self ._file )
258
258
259
+ Reader : Optional [Any ] = None
259
260
if format is None :
260
261
# auto-detect
261
262
if not self ._file .seekable ():
@@ -305,9 +306,7 @@ def open_file() -> Any:
305
306
else :
306
307
raise ValueError (f"mode must be 'r' or 'w', got { mode !r} " )
307
308
308
- def __enter__ (self ) -> HepMCFile :
309
- return self
310
-
309
+ __enter__ = _enter
311
310
__exit__ = _exit_close
312
311
313
312
def __iter__ (self ) -> Any :
@@ -331,7 +330,7 @@ def write(self, event: GenEvent) -> None:
331
330
332
331
def close (self ) -> None :
333
332
if self ._reader :
334
- self ._reader .close ()
333
+ self ._reader .close () # type:ignore
335
334
if self ._writer :
336
335
self ._writer .close ()
337
336
self ._ios .flush ()
0 commit comments