alexjbest / cluster-pictures

This package implements the machinery of cluster pictures of Maistret, Morgan, Dokchitser and Dokchitser in Sage.
https://alexjbest.github.io/cluster-pictures/
GNU General Public License v2.0
3 stars 4 forks source link

Fix ascii_art and unicode_art #36

Closed alexjbest closed 4 years ago

alexjbest commented 4 years ago

Currently ascii_art and unicode_art return strings, this is not correct and breaks if you try and print a list

see https://github.com/sagemath/sage/blob/f6b123f2bb70f27529526eaed2637eeab42ea7f0/src/sage/homology/chain_complex.py#L402 for an example?

why we should fix this, lists of clusters:

sage: from sage_cluster_pictures.cluster_pictures import Cluster
sage: p = 3
sage: x = polygen(Qp(p))
sage: R = Cluster.from_polynomial(x^6 + 2*x^3 + 4*x^2 + 4*x + 1)
sage: R
(● ● ● ● (● ●)_1/2)_0
sage: R.children()
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-8-98602d1f89e3> in <module>()
----> 1 R.children()

/Users/alex/sage/local/lib/python3.7/site-packages/IPython/core/displayhook.py in __call__(self, result)
    244             self.start_displayhook()
    245             self.write_output_prompt()
--> 246             format_dict, md_dict = self.compute_format_data(result)
    247             self.update_user_ns(result)
    248             self.fill_exec_result(result)

/Users/alex/sage/local/lib/python3.7/site-packages/IPython/core/displayhook.py in compute_format_data(self, result)
    148 
    149         """
--> 150         return self.shell.display_formatter.format(result)
    151 
    152     # This can be set to True by the write_output_prompt method in a subclass

/Users/alex/sage/local/lib/python3.7/site-packages/sage/repl/display/formatter.py in format(self, obj, include, exclude)
    200         """
    201         # First, use Sage rich output if there is any
--> 202         sage_format, sage_metadata = self.dm.displayhook(obj)
    203         assert PLAIN_TEXT in sage_format, 'plain text is always present'
    204         if not set(sage_format.keys()).issubset(self.default_mime()):

/Users/alex/sage/local/lib/python3.7/site-packages/sage/repl/rich_output/display_manager.py in displayhook(self, obj)
    809             return
    810         self._backend.set_underscore_variable(obj)
--> 811         plain_text, rich_output = self._rich_output_formatter(obj, dict())
    812         return self._backend.displayhook(plain_text, rich_output)
    813 

/Users/alex/sage/local/lib/python3.7/site-packages/sage/repl/rich_output/display_manager.py in _rich_output_formatter(self, obj, rich_repr_kwds)
    633         if rich_output is None:
    634             rich_output = self._preferred_text_formatter(
--> 635                 obj, plain_text=plain_text, **rich_repr_kwds)
    636         # promote output container types to backend-specific containers
    637         plain_text = self._promote_output(plain_text)

/Users/alex/sage/local/lib/python3.7/site-packages/sage/repl/rich_output/display_manager.py in _preferred_text_formatter(self, obj, plain_text, **kwds)
    530             return out
    531         if want == 'unicode_art' and OutputUnicodeArt in supported:
--> 532             out = self._backend.unicode_art_formatter(obj, **kwds)
    533             if type(out) is not OutputUnicodeArt:
    534                 raise OutputTypeException('backend returned wrong output type, require UnicodeArt')

/Users/alex/sage/local/lib/python3.7/site-packages/sage/repl/rich_output/backend_base.py in unicode_art_formatter(self, obj, **kwds)
    423             result = unicode_art(*obj, sep=' ')
    424         else:
--> 425             result = unicode_art(obj)
    426         from sage.repl.rich_output.output_basic import OutputUnicodeArt
    427         return OutputUnicodeArt(str(result))

/Users/alex/sage/local/lib/python3.7/site-packages/sage/typeset/unicode_art.py in unicode_art(*obj, **kwds)
    148         raise ValueError('unknown keyword arguments: {0}'.format(list(kwds)))
    149     if len(obj) == 1:
--> 150         return _unicode_art_factory.build(obj[0], baseline=baseline)
    151     if not isinstance(separator, UnicodeArt):
    152         separator = _unicode_art_factory.build(separator, baseline=sep_baseline)

/Users/alex/sage/local/lib/python3.7/site-packages/sage/typeset/character_art_factory.py in build(self, obj, baseline)
    127             return self.build_dict(obj, baseline)
    128         elif isinstance(obj, list):
--> 129             return self.build_list(obj, baseline)
    130         elif isinstance(obj, set):
    131             return self.build_set(obj, baseline)

/Users/alex/sage/local/lib/python3.7/site-packages/sage/typeset/character_art_factory.py in build_list(self, l, baseline)
    388                               baseline=0,
    389                               breakpoints=[1])
--> 390         repr_elems = self.concatenate(l, comma, nested=True)
    391         return self.build_container(
    392             repr_elems, self.left_square_bracket, self.right_square_bracket,

/Users/alex/sage/local/lib/python3.7/site-packages/sage/typeset/character_art_factory.py in concatenate(self, iterable, separator, empty, baseline, nested)
    475         top = separator._h - bot
    476         for obj in iterable:
--> 477             bot1 = obj.get_baseline()
    478             if bot1 > bot:
    479                 bot = bot1

AttributeError: 'str' object has no attribute 'get_baseline'
rbommel commented 4 years ago

Okay, not completely sure if I understand everything here, but if _asciiart() does not return a string anymore, then we would have to rewrite the LMFDB scripts.

alexjbest commented 4 years ago

I think it will still return something that coerces to a string, so we may have to add str(...) in a place or two, but I think being able to print the children or all descendants with ascii or unicode mode turned on without it erroring is worth the pain!