Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/sage/rings/padics/factory.py
Original file line number Diff line number Diff line change
Expand Up @@ -283,9 +283,9 @@ def get_key_base(p, prec, type, print_mode, names, ram_name, print_pos, print_se
print_max_terms = padic_printing._printer_defaults.max_series_terms()

# We eliminate irrelevant print options (e.g. print_pos if p = 2)
if p == 2 or print_mode == 'digits':
if p == 2 or print_mode in {'digits', 'digits-unicode'}:
print_pos = True # we want this hard-coded so that we don't get duplicate parents if the keys differ.
if print_mode == 'digits':
if print_mode in {'digits', 'digits-unicode'}:
print_ram_name = None
print_alphabet = print_alphabet[:p]
else:
Expand Down
70 changes: 43 additions & 27 deletions src/sage/rings/padics/padic_printing.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ cdef enum print_modes:
val_unit
digits
bars
digits_unicode


def pAdicPrinter(ring, options={}):
Expand Down Expand Up @@ -118,7 +119,7 @@ class pAdicPrinterDefaults(SageObject):
``mode=None`` returns the current value.

The allowed values for mode are: ``'val-unit'``, ``'series'``,
``'terse'``, ``'digits'`` and ``'bars'``.
``'terse'``, ``'digits'``, ``'digits-unicode'`` and ``'bars'``.

EXAMPLES::

Expand All @@ -133,11 +134,11 @@ class pAdicPrinterDefaults(SageObject):
sage: padic_printing.mode('val-unit')
sage: Qp(13)(130)
13 * 10 + O(13^21)
sage: padic_printing.mode('digits')
sage: padic_printing.mode('digits-unicode')
sage: repr(Qp(17)(100))
'...5F'
'…0000000000000000005F'
sage: repr(Qp(17)(1000))
'...37E'
Copy link
Contributor

@user202729 user202729 Dec 17, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

leave this one test alone. We need something to at least ensure mode('digits') doesn't error out.

'…0000000000000000037E'
sage: padic_printing.mode('bars')
sage: repr(Qp(19)(1000))
'...2|14|12'
Expand All @@ -147,7 +148,7 @@ class pAdicPrinterDefaults(SageObject):
if mode is None:
return self._mode

if mode in ['val-unit', 'series', 'terse', 'digits', 'bars']:
if mode in ['val-unit', 'series', 'terse', 'digits', 'bars', 'digits-unicode']:
self._mode = mode
else:
raise ValueError("invalid printing mode")
Expand Down Expand Up @@ -177,7 +178,7 @@ class pAdicPrinterDefaults(SageObject):
def max_series_terms(self, max=None):
r"""
Controls the maximum number of terms shown when printing in
``'series'``, ``'digits'`` or ``'bars'`` mode.
``'series'``, ``'digits'``, ``'digits-unicode'`` or ``'bars'`` mode.

``max=None`` returns the current value.

Expand Down Expand Up @@ -276,7 +277,8 @@ class pAdicPrinterDefaults(SageObject):
def alphabet(self, alphabet=None):
r"""
Controls the alphabet used to translate `p`-adic digits into
strings (so that no separator need be used in ``'digits'`` mode).
strings (so that no separator need be used in ``'digits'``
or ``'digits-unicode'`` mode).

``alphabet`` should be passed in as a list or tuple.

Expand All @@ -285,9 +287,9 @@ class pAdicPrinterDefaults(SageObject):
EXAMPLES::

sage: padic_printing.alphabet("abc")
sage: padic_printing.mode('digits')
sage: padic_printing.mode('digits-unicode')
sage: repr(Qp(3)(1234))
'...bcaacab'
'…aaaaaaaaaaaaabcaacab'

sage: padic_printing.mode('series')
sage: padic_printing.alphabet(('0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'))
Expand Down Expand Up @@ -317,7 +319,8 @@ cdef class pAdicPrinter_class(SageObject):
attached

- ``mode`` -- the allowed values for mode are: ``'val-unit'``,
``'series'``, ``'terse'``, ``'digits'`` and ``'bars'``:
``'series'``, ``'terse'``, ``'digits'``, ``'digits-unicode'``
and ``'bars'``:

- ``'val-unit'`` -- elements are displayed as a power of the
uniformizer times a unit, which is displayed in terse mode
Expand All @@ -334,6 +337,9 @@ cdef class pAdicPrinter_class(SageObject):
extensions (or trivial extensions), elements are displayed as just
a string of `p`-adic digits, encoded using the 'alphabet' parameter

- ``'digits-unicode'`` -- like ``'digits'``, but uses the unicode
ellipsis character to indicate omitted leading digits

- ``'bars'`` -- like ``'digits'``, but uses a separator in order to
print a more canonical representation for each digit. This change
allows the use of this printing mode for unramified extensions and
Expand All @@ -351,7 +357,8 @@ cdef class pAdicPrinter_class(SageObject):
generator of this extension ring or field

- ``max_ram_terms`` -- controls the maximum number of terms shown when
printing in ``'series'``, ``'digits'`` or ``'bars'`` mode
printing in ``'series'``, ``'digits'``, ``'digits-unicode'`` or
``'bars'`` mode

- ``max_unram_terms`` -- for rings with non-prime residue fields,
controls how many terms appear in the coefficient of each pi^n when
Expand All @@ -364,7 +371,8 @@ cdef class pAdicPrinter_class(SageObject):
- ``sep`` -- controls the separator used in ``'bars'`` mode

- ``alphabet`` -- controls the alphabet used to translate `p`-adic digits
into strings (so that no separator need be used in ``'digits'`` mode)
into strings (so that no separator need be used in ``'digits'``
or ``'digits-unicode'`` mode)

- ``show_prec`` -- Specify how the precision is printed; it can be
``'none'``, ``'bigoh'`` or ``'dots'`` (the latter being not available
Expand Down Expand Up @@ -401,16 +409,19 @@ cdef class pAdicPrinter_class(SageObject):
self.mode = series
elif mode == 'terse':
self.mode = terse
elif mode == 'digits':
elif mode in {'digits', 'digits-unicode'}:
if len(self.alphabet) < self.prime_pow.prime or (not self.base and ring.absolute_f() != 1):
raise ValueError("digits printing mode only usable for totally ramified extensions with p at most the length of the alphabet (default 62). Try using print_mode = 'bars' instead.")
else:
self.mode = digits
if mode == 'digits-unicode':
self.mode = digits_unicode
else:
self.mode = digits
self.pos = True
elif mode == 'bars':
self.mode = bars
else:
raise ValueError("printing mode must be one of 'val-unit', 'series', 'terse', 'digits' or 'bars'")
raise ValueError("printing mode must be one of 'val-unit', 'series', 'terse', 'digits', 'digits-unicode' or 'bars'")
if ram_name is None:
self.ram_name = ring._uniformizer_print()
else:
Expand Down Expand Up @@ -546,7 +557,7 @@ cdef class pAdicPrinter_class(SageObject):
if lx != rx:
return richcmp_not_equal(lx, rx, op)

if self.mode != digits:
if self.mode != digits and self.mode != digits_unicode:
lx = self.ram_name
rx = other.ram_name
if lx != rx:
Expand All @@ -558,13 +569,13 @@ cdef class pAdicPrinter_class(SageObject):
if lx != rx:
return richcmp_not_equal(lx, rx, op)

if self.mode == digits:
if self.mode == digits or self.mode == digits_unicode:
lx = self.alphabet[:p]
rx = other.alphabet[:q]
if lx != rx:
return richcmp_not_equal(lx, rx, op)

if self.mode == series or self.mode == digits or self.mode == bars:
if self.mode == series or self.mode == digits or self.mode == digits_unicode or self.mode == bars:
lx = self.max_ram_terms
rx = other.max_ram_terms
if lx != rx:
Expand Down Expand Up @@ -781,6 +792,8 @@ cdef class pAdicPrinter_class(SageObject):
return 'terse'
elif self.mode == digits:
return 'digits'
elif self.mode == digits_unicode:
return 'digits-unicode'
elif self.mode == bars:
return 'bars'

Expand Down Expand Up @@ -869,7 +882,7 @@ cdef class pAdicPrinter_class(SageObject):
elif mode == 'bars':
_mode = bars
else:
raise ValueError("printing mode must be one of 'val-unit', 'series', 'terse', 'bars', or 'digits'")
raise ValueError("printing mode must be one of 'val-unit', 'series', 'terse', 'bars', 'digits' or 'digits-unicode'")
if pos is None:
_pos = self.pos
else:
Expand Down Expand Up @@ -903,11 +916,11 @@ cdef class pAdicPrinter_class(SageObject):
sage: print(a.str('series'))
3*7 + 7^3 + O(7^5)
sage: padic_printing.sep('')
sage: K = Qp(7, print_mode='digits')
sage: K = Qp(7, print_mode='digits-unicode')
sage: repr(K(1/2))
'...33333333333333333334'
'33333333333333333334'
sage: repr(K(1/42))
'...5555555555555555555.6'
'5555555555555555555.6'
sage: padic_printing.sep('|')
sage: repr(Qp(97, print_mode='bars')(1/13))
'...29|82|7|44|74|59|67|14|89|52|22|37|29|82|7|44|74|59|67|15'
Expand All @@ -916,9 +929,9 @@ cdef class pAdicPrinter_class(SageObject):

Check that :issue:`24843` is resolved::

sage: R = Zp(2, print_mode='digits', show_prec=True)
sage: R = Zp(2, print_mode='digits-unicode', show_prec=True)
sage: repr(R(0,10))
'...0000000000'
'0000000000'
"""
s = ""
if self.show_prec == "dots":
Expand All @@ -929,7 +942,7 @@ cdef class pAdicPrinter_class(SageObject):
return "0"
elif elt._is_inexact_zero():
prec = elt.precision_absolute()
if mode == digits and self.show_prec == "dots":
if (mode == digits or mode == digits_unicode) and self.show_prec == "dots":
if prec > 0:
s = (self.alphabet[0] * prec)
else:
Expand Down Expand Up @@ -960,7 +973,7 @@ cdef class pAdicPrinter_class(SageObject):
s = "%s * %s" % (ram_name, self._repr_spec(elt.unit_part(), do_latex, pos, terse, 1, ram_name))
else:
s = "%s^%s * %s" % (ram_name, elt.valuation(), self._repr_spec(elt.unit_part(), do_latex, pos, terse, 1, ram_name))
elif mode == digits:
elif mode == digits or mode == digits_unicode:
n = elt.valuation()
if self.base:
L = self.base_p_list(elt, True)
Expand Down Expand Up @@ -1030,7 +1043,10 @@ cdef class pAdicPrinter_class(SageObject):
s = self._repr_spec(elt, do_latex, pos, mode, 0, ram_name)

if self.show_prec == "dots":
s = "..." + s
if mode == digits_unicode:
s = u"\u2026" + s
else:
s = "..." + s
if self.show_prec == "bigoh":
if s == "":
s = "O(%s" % ram_name
Expand Down