Comments (8)
I also encountered this error.
Maybe it's because line 1307 in get_node, sometimes it enlarges the dictionary.
from pyan.
Have the same issue - did you find a work around?
from pyan.
Good catch. I agree with @zkkzhangkangkang's static analysis, get_node
seems to be the only place called by collapse_inner
that could cause this.
The reason then must be that the parent node being looked up by get_parent_node
does not already exist - and no other nodes with the same short name exist, since a new entry is being added to self.nodes
, changing the dictionary size. This shouldn't happen for the use case of collapse_inner
, but apparently does. :)
For testing, do any of you have a minimal working example, or a public project, that reproduces the bug? This would help me see why the parent node isn't getting defined.
As a fallback solution, it is possible to postpone the update of self.nodes
until the loop in collapse_inner
has completed, but that complicates the code, and makes the implementation hard to explain (so by ZoP §17, probably a bad idea). We would need something like this pattern:
def get_node(..., stash=None):
...
target = stash or self.nodes
if name in target:
target[name].append(n)
else:
target[name] = [n]
return n
...
def collapse_inner(...):
stash = {}
def unstash():
nonlocal stash
for name in stash:
if name in self.nodes:
self.nodes[name].extend(stash[name])
# TODO: probably need to drop duplicates - list(set(...))?
else:
self.nodes[name] = stash[name]
stash = {}
handled = set()
while True:
for name in self.nodes:
if name in ('lambda', 'listcomp', 'setcomp', 'dictcomp', 'genexpr'):
for n in self.nodes[name]:
if n not in handled:
....
# use the stash option here
handled.add(n)
if not stash:
break
unstash()
from pyan.
@Technologicat, I was using a large DNN code base, but here is one minimal set that causes this. It seems a combination of __init__.py
and this additional file causes the error.
Notes:
a) If I rename __init__.py
to a.py
it works
b) If I change the 2nd argument of f.py to not involve the for iteration it works
c) The example is nonsensical - I just made sure it runs
command and output:
find . -iname "*.py" | xargs pyan3 --colored --no-defines
Traceback (most recent call last):
File "/Users/pp/anaconda3/envs/ml/bin/pyan3", line 11, in <module>
sys.exit(main())
File "/Users/pp/anaconda3/envs/ml/lib/python3.7/site-packages/pyan/main.py", line 109, in main
v = CallGraphVisitor(filenames, logger)
File "/Users/pp/anaconda3/envs/ml/lib/python3.7/site-packages/pyan/analyzer.py", line 77, in __init__
self.process()
File "/Users/pp/anaconda3/envs/ml/lib/python3.7/site-packages/pyan/analyzer.py", line 87, in process
self.postprocess()
File "/Users/pp/anaconda3/envs/ml/lib/python3.7/site-packages/pyan/analyzer.py", line 154, in postprocess
self.collapse_inner()
File "/Users/pp/anaconda3/envs/ml/lib/python3.7/site-packages/pyan/analyzer.py", line 1562, in collapse_inner
for name in self.nodes:
RuntimeError: dictionary changed size during iteration
from pyan.
Another, more legitimate example that is equally nonsensical, but is structured correctly. Same issue.
pyan.zip
from pyan.
@pliablepixels As you may have guessed, I'm busy right now, but I'll have a look as soon as I have time. Having an example that reproduces the bug should make this much easier. Thanks for the MWE!
from pyan.
It looks like this PR fixes the issue: https://github.com/Technologicat/pyan/pull/24/files
from pyan.
Yes, it should work now.
(collapse_inner
now iterates over 'list(self.nodes), not
self.nodes`.)
from pyan.
Related Issues (20)
- Breaking the fork HOT 3
- Pyan crashes when i give filename or don't give HOT 4
- Dash (-) in directory names is not escaped/quoted in DOT identifiers HOT 1
- __init__() got multiple values for argument 'root' HOT 8
- Integrate modvis.py to main pyan executable
- BrokenPipeError
- Call graph from file contents
- Different order for edges between different calls when several source files are provided
- got multiple values for argument 'root' after upgrade 1.1.1 -> 1.20 HOT 5
- Feature Suggestion: Customize depth (level) of generated graph
- Sphinx integration HOT 1
- FileNotFoundError: [Errno 2] No such file or directory: '' HOT 2
- Tutorial or document
- Is the project still maintained? HOT 4
- Would like to generate call graph for a very basic file HOT 2
- What is "dot"? HOT 1
- Call graphs are wrong -- don't respect namespaces
- [question] What is the intended purpose of white module nodes?
- cannot have a file called “Graph.py” that has module level call to a known function HOT 1
- Unable to use Pyan HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from pyan.