Skip to content

Commit

Permalink
Add annotation info to dispatcher object.
Browse files Browse the repository at this point in the history
This exposes the annotation information via a method on the
dispatcher. It also removes markup specific information from the
annotation dictionary and delegates the responsibility of
performing markup to the consumer. As a result the HTML annotation
path is now split from that which generates the annotation
dictionary which means annotations are easier to consume and don't
involve files.
  • Loading branch information
stuartarchibald committed Apr 5, 2018
1 parent 85178eb commit c764e86
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 17 deletions.
56 changes: 39 additions & 17 deletions numba/annotations/type_annotations.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

from collections import Mapping, defaultdict, OrderedDict
from contextlib import closing
import copy
import inspect
import os
import re
Expand Down Expand Up @@ -147,6 +148,39 @@ def annotate(self):
return io.getvalue()

def html_annotate(self, outfile):
# ensure that annotation information is assembled
self.annotate_raw()
# make a deep copy ahead of the pending mutations
func_data = copy.deepcopy(self.func_data)
def add_in_nbsp(key):
for this_func in func_data.values():
if key in this_func:
idents = {}
for line, amount in this_func[key].items():
idents[line] = ' ' * amount
this_func[key] = idents
add_in_nbsp('python_indent')
add_in_nbsp('ir_indent')

try:
from jinja2 import Template
except ImportError:
raise ImportError("please install the 'jinja2' package")

root = os.path.join(os.path.dirname(__file__))
template_filename = os.path.join(root, 'template.html')
with open(template_filename, 'r') as template:
html = template.read()

template = Template(html)
rendered = template.render(func_data=func_data)
outfile.write(rendered)

def annotate_raw(self):
"""
This returns "raw" annotation information i.e. it has no output format
specific markup included.
"""
python_source = SourceLines(self.func_id.func)
ir_lines = self.prepare_annotations()
line_nums = [num for num in python_source]
Expand All @@ -160,7 +194,7 @@ def add_ir_line(func_data, line):
line_type = 'pyobject'
func_data['ir_lines'][num].append((line_str, line_type))
indent_len = len(_getindent(line))
func_data['ir_indent'][num].append(' ' * indent_len)
func_data['ir_indent'][num] += indent_len

func_key = (self.func_id.filename + ':' + str(self.func_id.firstlineno + 1),
self.signature)
Expand All @@ -173,7 +207,7 @@ def add_ir_line(func_data, line):
if num not in ir_lines.keys():
continue
func_data['ir_lines'][num] = []
func_data['ir_indent'][num] = []
func_data['ir_indent'][num] = 0
for line in ir_lines[num]:
add_ir_line(func_data, line)
if line.strip().endswith('pyobject'):
Expand Down Expand Up @@ -211,31 +245,19 @@ def add_ir_line(func_data, line):
for num in line_nums:
func_data['python_lines'].append((num, python_source[num].strip()))
indent_len = len(_getindent(python_source[num]))
func_data['python_indent'][num] = ' ' * indent_len
func_data['python_indent'][num] = indent_len
func_data['python_tags'][num] = ''
func_data['ir_lines'][num] = []
func_data['ir_indent'][num] = []
func_data['ir_indent'][num] = 0

for line in ir_lines[num]:
add_ir_line(func_data, line)
if num in lifted_lines:
func_data['python_tags'][num] = 'lifted_tag'
elif line.strip().endswith('pyobject'):
func_data['python_tags'][num] = 'object_tag'
return self.func_data

try:
from jinja2 import Template
except ImportError:
raise ImportError("please install the 'jinja2' package")

root = os.path.join(os.path.dirname(__file__))
template_filename = os.path.join(root, 'template.html')
with open(template_filename, 'r') as template:
html = template.read()

template = Template(html)
rendered = template.render(func_data=TypeAnnotation.func_data)
outfile.write(rendered)

def __str__(self):
return self.annotate()
Expand Down
11 changes: 11 additions & 0 deletions numba/dispatcher.py
Original file line number Diff line number Diff line change
Expand Up @@ -375,6 +375,17 @@ def inspect_cfg(self, signature=None, show_wrapper=None):
return dict((sig, self.inspect_cfg(sig, show_wrapper=show_wrapper))
for sig in self.signatures)

def get_annotation_info(self, signature=None):
"""
Gets the annotation information for the function specified by
signature. If no signature is supplied a dictionary of signature to
annotation information is returned.
"""
if signature is not None:
cres = self.overloads[signature]
return cres.type_annotation.annotate_raw()
return dict((sig, self.annotate(sig)) for sig in self.signatures)

def _explain_ambiguous(self, *args, **kws):
"""
Callback for the C _Dispatcher object.
Expand Down

0 comments on commit c764e86

Please sign in to comment.