algorand / pyteal

Algorand Smart Contracts in Python
https://pyteal.readthedocs.io
MIT License
285 stars 131 forks source link

Best Guess Sourcemapping when Partially Enabled #688

Closed tzaffi closed 1 year ago

tzaffi commented 1 year ago

As of #687, to enable source mapping one must import FeatureGates from feature_gates and then call FeaturGates.set_sourcemap_enabled(True). One must do this before any PyTeal imports as the NatalStackFrame embedded in Expr's needs to be aware of the feature gate at construction time. Furthermore, as some expressions are statically derived at PyTeal's importation, these end up lacking any stack frame information.

This PR aims to ameliorate this situation by providing stand-in PyTealFrame's in the case that this has happened. In such cases, a warning is printed out alerting of the fact that FeatureGate must be imported and enabled before the PyTeal imports, but everything else proceeds as before.

For example, I've temporarily modified the AlgoBank example to illustrate what occurs in such a case. In particular, we will see the following error messages:

❯ python algobank.py
-------------------
WARNING: Error retrieving the best frame for source mapping.
This may occur because FeatureGates was imported and `FeatureGates.set_sourcemap_enabled(True)` called _AFTER_ pyteal was imported.
error: expected to have some frames but currently self._frames=[]

-------------------
WARNING: Error retrieving the best frame for source mapping.
This may occur because FeatureGates was imported and `FeatureGates.set_sourcemap_enabled(True)` called _AFTER_ pyteal was imported.
error: expected to have some frames but currently self._frames=[]

... more similar errors ...

-----------------
WARNING: Source mapping is unknown for the following:
TealLine(21: int NoOp // PyTeal: router.compile(version=6, optimize=OptimizeOptions(scratch_slots=True), with_sourcemaps=True, annotate_teal=True))

-----------------
WARNING: Source mapping is unknown for the following:
TealLine(42: int NoOp // PyTeal: router.compile(version=6, optimize=OptimizeOptions(scratch_slots=True), with_sourcemaps=True, annotate_teal=True))

-----------------
WARNING: Source mapping is unknown for the following:
TealLine(63: int NoOp // PyTeal: router.compile(version=6, optimize=OptimizeOptions(scratch_slots=True), with_sourcemaps=True, annotate_teal=True))

-----------------
WARNING: Source mapping is unknown for the following:
TealLine(70: int OptIn // PyTeal: router.compile(version=6, optimize=OptimizeOptions(scratch_slots=True), with_sourcemaps=True, annotate_teal=True))

... more similar errors ...
bbroder-algo commented 1 year ago

this is good an earlier idea I had was to just check sys.modules for pyteal in feature_gates and error out if it's there, but this is more complicated and better-er