| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent a73a6a3 commit e6d9756
2 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -99,6 +99,7 @@ | |||
| 99 | 99 | import collections | |
| 100 | 100 | import collections.abc | |
| 101 | 101 | import contextlib | |
| 102 | + import weakref | ||
| 102 | 103 | ||
| 103 | 104 | from . import ElementPath | |
| 104 | 105 | ||
@@ -1223,13 +1224,14 @@ def iterparse(source, events=None, parser=None): | |||
| 1223 | 1224 | # parser argument of iterparse is removed, this can be killed. | |
| 1224 | 1225 | pullparser = XMLPullParser(events=events, _parser=parser) | |
| 1225 | 1226 | ||
| 1226 | - def iterator(source): | ||
| 1227 | + if not hasattr(source, "read"): | ||
| 1228 | + source = open(source, "rb") | ||
| 1229 | + close_source = True | ||
| 1230 | + else: | ||
| 1227 | 1231 | close_source = False | |
| 1232 | + | ||
| 1233 | + def iterator(source): | ||
| 1228 | 1234 | try: | |
| 1229 | - if not hasattr(source, "read"): | ||
| 1230 | - source = open(source, "rb") | ||
| 1231 | - close_source = True | ||
| 1232 | - yield None | ||
| 1233 | 1235 | while True: | |
| 1234 | 1236 | yield from pullparser.read_events() | |
| 1235 | 1237 | # load event buffer | |
@@ -1239,18 +1241,23 @@ def iterator(source): | |||
| 1239 | 1241 | pullparser.feed(data) | |
| 1240 | 1242 | root = pullparser._close_and_return_root() | |
| 1241 | 1243 | yield from pullparser.read_events() | |
| 1242 | - it.root = root | ||
| 1244 | + it = wr() | ||
| 1245 | + if it is not None: | ||
| 1246 | + it.root = root | ||
| 1243 | 1247 | finally: | |
| 1244 | 1248 | if close_source: | |
| 1245 | 1249 | source.close() | |
| 1246 | 1250 | ||
| 1247 | 1251 | class IterParseIterator(collections.abc.Iterator): | |
| 1248 | 1252 | __next__ = iterator(source).__next__ | |
| 1249 | - it = IterParseIterator() | ||
| 1250 | - it.root = None | ||
| 1251 | - del iterator, IterParseIterator | ||
| 1252 | 1253 | ||
| 1253 | - next(it) | ||
| 1254 | + def __del__(self): | ||
| 1255 | + if close_source: | ||
| 1256 | + source.close() | ||
| 1257 | + | ||
| 1258 | + it = IterParseIterator() | ||
| 1259 | + wr = weakref.ref(it) | ||
| 1260 | + del IterParseIterator | ||
| 1254 | 1261 | return it | |
| 1255 | 1262 | ||
| 1256 | 1263 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,4 @@ | |||
| 1 | + Avoid reference cycle in ElementTree.iterparse. The iterator returned by | ||
| 2 | + ``ElementTree.iterparse`` may hold on to a file descriptor. The reference | ||
| 3 | + cycle prevented prompt clean-up of the file descriptor if the returned | ||
| 4 | + iterator was not exhausted. | ||
| Back | FazBrowse Home | New Git URL |
0 commit comments