Skip to content

Commit 97d792a

Browse files
[fixed #13] recursion/overflow error potentially fixed
- eq comparison is now self._name instead of the Name attribute - iteration check now uses len() - CollectionViewer no longer iterates itself - multiple skip inputs allowed - 'found' object prevents duplicate items (but potentially new ones)
1 parent 037d68d commit 97d792a

File tree

2 files changed

+38
-16
lines changed

2 files changed

+38
-16
lines changed

pyvba/browser.py

Lines changed: 34 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
from pyvba.viewer import Viewer, FunctionViewer, CollectionViewer
2+
from collections import OrderedDict
23

34
# used to skip predetermined objects by exact name
4-
# fixme: remove extra parameters
5-
skip = ['Application', 'Parent', 'Units', 'Parameters']
5+
skip = ['Application', 'Parent']
6+
7+
# store a dictionary of the discovered items
8+
found = OrderedDict()
69

710

8-
# TODO: fix infinite recursion issue
911
class Browser(Viewer):
1012
def __init__(self, app, name: str, parent: Viewer = None):
1113
"""Create a browser from an application string or win32com object.
@@ -38,18 +40,26 @@ def from_viewer(viewer, parent=None):
3840
else Browser(viewer.com, viewer.name, viewer.parent if parent is None else parent)
3941

4042
@staticmethod
41-
def skip(item: str):
42-
"""Adds a keyword to the skip list."""
43+
def clr_found():
44+
"""Clears the stored dictionary of items browsed."""
45+
global found
46+
found = OrderedDict()
47+
48+
@staticmethod
49+
def skip(*item: str):
50+
"""Add one or more keywords to the skip list."""
4351
global skip
44-
if item not in skip:
45-
skip.append(item)
52+
for i in item:
53+
if i not in skip:
54+
skip.append(i)
4655

4756
@staticmethod
48-
def rm_skip(item: str):
49-
"""Remove a keyword from the skip list."""
57+
def rm_skip(*item: str):
58+
"""Remove one or more keywords from the skip list."""
5059
global skip
51-
if item in skip:
52-
skip.remove(item)
60+
for i in item:
61+
if i not in skip:
62+
skip.remove(i)
5363

5464
@staticmethod
5565
def clr_skip():
@@ -66,8 +76,9 @@ def all(self) -> dict:
6676

6777
def _generate(self):
6878
"""Iterates through all objects when called upon."""
69-
global skip
79+
global skip, found
7080

81+
# iterate through items
7182
for name in self._objects + [i.name for i in self._methods]:
7283
if name in skip:
7384
continue
@@ -83,6 +94,17 @@ def _generate(self):
8394
self._errors[name] = e.args
8495
continue
8596

97+
# add items to the 'found' dictionary
98+
for name, value in self._all.items():
99+
if isinstance(value, Viewer):
100+
if value.type not in found:
101+
found[value.type] = []
102+
103+
if value not in found[value.type]:
104+
found[value.type].append(value)
105+
else:
106+
self._all[name] = found[value.type].index(value)
107+
86108
def search(self, name: str, exact: bool = False):
87109
"""Return a dictionary in format {path: item} matching the name.
88110

pyvba/viewer.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ def __init__(self, app, name: str = None, parent: object = None):
4242
self._errors = {}
4343

4444
def __eq__(self, other):
45-
return other.type == self._type and other.getattr('Name') == self.getattr('Name')
45+
return other.type == self._type and other.name == self._name
4646

4747
def __getattr__(self, item):
4848
return self.getattr(item)
@@ -58,7 +58,7 @@ def ensure_dispatch(com):
5858
"""
5959
try:
6060
app = EnsureDispatch(com)
61-
except AttributeError:
61+
except (AttributeError, TypeError):
6262
# Remove cache and try again.
6363
module_list = [m.__name__ for m in sys.modules.values()]
6464
for module in module_list:
@@ -75,7 +75,7 @@ def gettype(obj, item: str = None, parent: object = None):
7575
return FunctionViewer(obj, item)
7676
elif 'win32com' in repr(obj) or 'COMObject' in repr(obj):
7777
try:
78-
_ = [e for e in obj]
78+
_ = len(obj)
7979
return CollectionViewer(obj, item, parent)
8080
except (TypeError, AttributeError):
8181
return Viewer(obj, item, parent)
@@ -187,7 +187,7 @@ def __init__(self, obj, name: str = None, parent: object = None):
187187
super().__init__(obj, name, parent)
188188

189189
self._count = len(self._com)
190-
self._items = [Viewer.gettype(i, name, self) for i in self._com]
190+
self._items = [Viewer.gettype(i, name, self) for i in self._com if i is not super()._com]
191191

192192
def __str__(self):
193193
return super().__str__().replace('Viewer', 'CollectionViewer')

0 commit comments

Comments
 (0)