Skip to content
This repository was archived by the owner on Jan 11, 2025. It is now read-only.

Commit fe93f8a

Browse files
committed
Fix: Properly render boxes on Windows terminals.
1 parent 2f51300 commit fe93f8a

File tree

2 files changed

+71
-17
lines changed

2 files changed

+71
-17
lines changed

sources/python3/devshim/todo.rst

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,11 @@ Fixes and Minor Improvements
1111
* Pull from https://github.com/indygreg/python-build-standalone/releases/latest
1212
for multiple platforms.
1313

14-
* Fix rendering of Unicode box segment characters on terminals that do not
15-
support the UTF-8 encoding properly.
16-
- https://github.com/rprichard/winpty/issues/38
17-
- https://github.com/rprichard/winpty/issues/105
14+
* Replace ``build`` with ``pyproject-hooks`` for use in both :file:`develop.py`
15+
and for building sdists and wheels from the package. Removes an additional
16+
subprocess layer caused by calling ``build`` or ``pip`` and will allow us to
17+
get around Pip's build tracking when building wheels from source in the build
18+
support side cache for the CPython TRACEREFS case.
1819

1920
Virtual Environments Improvements
2021
================================================================================

sources/python3/devshim/user_interface.py

Lines changed: 66 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -31,27 +31,80 @@ def render_boxed_title( title, supplement = None ):
3131
__.eprint( format_boxed_title( specific_title ) )
3232

3333

34-
def format_boxed_title( title ):
34+
def format_boxed_title( title, gravity = 2 ):
3535
''' Formats box around title as string. '''
3636
columns_count = int( __.current_process_environment.get( 'COLUMNS', 79 ) )
3737
icolumns_count = columns_count - 2
38-
content_template = (
39-
'\N{BOX DRAWINGS DOUBLE VERTICAL}{fill}'
40-
'\N{BOX DRAWINGS DOUBLE VERTICAL}' )
38+
table = _acquire_rectangle_construction_characters( gravity )
39+
content_template = '{vertical}{fill}{vertical}'
4140
return '\n'.join( (
4241
'',
43-
'\N{BOX DRAWINGS DOUBLE DOWN AND RIGHT}{fill}'
44-
'\N{BOX DRAWINGS DOUBLE DOWN AND LEFT}'.format(
45-
fill = '\N{BOX DRAWINGS DOUBLE HORIZONTAL}' * icolumns_count ),
46-
content_template.format( fill = ' ' * icolumns_count ),
47-
content_template.format( fill = title.center( icolumns_count ) ),
48-
content_template.format( fill = ' ' * icolumns_count ),
49-
'\N{BOX DRAWINGS DOUBLE UP AND RIGHT}{fill}'
50-
'\N{BOX DRAWINGS DOUBLE UP AND LEFT}'.format(
51-
fill = '\N{BOX DRAWINGS DOUBLE HORIZONTAL}' * icolumns_count ),
42+
'{suprasinistral}{fill}{supradextral}'.format(
43+
fill = table[ 'horizontal' ] * icolumns_count, **table ),
44+
content_template.format( fill = ' ' * icolumns_count, **table ),
45+
content_template.format(
46+
fill = title.center( icolumns_count ), **table ),
47+
content_template.format( fill = ' ' * icolumns_count, **table ),
48+
'{infrasinistral}{fill}{infradextral}'.format(
49+
fill = table[ 'horizontal' ] * icolumns_count, **table ),
5250
'', ) )
5351

5452

53+
_ascii_rectangular_elements_single = __.DictionaryProxy( dict(
54+
horizontal = '-',
55+
vertical = '|',
56+
infrasinistral = '+',
57+
infradextral = '+',
58+
suprasinistral = '+',
59+
supradextral = '+',
60+
) )
61+
_ascii_rectangular_elements_double = __.DictionaryProxy( dict(
62+
horizontal = '=',
63+
vertical = '|',
64+
infrasinistral = '+',
65+
infradextral = '+',
66+
suprasinistral = '+',
67+
supradextral = '+',
68+
) )
69+
_unicode_rectangular_elements_single = __.DictionaryProxy( dict(
70+
horizontal = '\N{BOX DRAWINGS LIGHT HORIZONTAL}',
71+
vertical = '\N{BOX DRAWINGS LIGHT VERTICAL}',
72+
infrasinistral = '\N{BOX DRAWINGS LIGHT UP AND RIGHT}',
73+
infradextral = '\N{BOX DRAWINGS LIGHT UP AND LEFT}',
74+
suprasinistral = '\N{BOX DRAWINGS LIGHT DOWN AND RIGHT}',
75+
supradextral = '\N{BOX DRAWINGS LIGHT DOWN AND LEFT}',
76+
) )
77+
_unicode_rectangular_elements_double = __.DictionaryProxy( dict(
78+
horizontal = '\N{BOX DRAWINGS DOUBLE HORIZONTAL}',
79+
vertical = '\N{BOX DRAWINGS DOUBLE VERTICAL}',
80+
infrasinistral = '\N{BOX DRAWINGS DOUBLE UP AND RIGHT}',
81+
infradextral = '\N{BOX DRAWINGS DOUBLE UP AND LEFT}',
82+
suprasinistral = '\N{BOX DRAWINGS DOUBLE DOWN AND RIGHT}',
83+
supradextral = '\N{BOX DRAWINGS DOUBLE DOWN AND LEFT}',
84+
) )
85+
86+
87+
def _acquire_rectangle_construction_characters( gravity ):
88+
''' Returns dictionary of characters for rectangle construction. '''
89+
# TODO: Validate gravity argument. Should maybe be an enumeration.
90+
from os import name as os_class
91+
# Detecting whether a terminal can support and properly render Unicode code
92+
# points that have been encoded as UTF-8 is a mess on Windows. For example,
93+
# see these Winpty issues:
94+
# https://github.com/rprichard/winpty/issues/38
95+
# https://github.com/rprichard/winpty/issues/105
96+
# So, we always default to ASCII facsimiles, assuming that we do not wish
97+
# to try using Windows code page 850 (or similar), as that is likely not
98+
# the assigned character set.
99+
# TODO: Detect other cases, such as 'LC_' variables which indicate an
100+
# encoding other than UTF-8.
101+
if 'nt' == os_class:
102+
if 1 == gravity: return _ascii_rectangular_elements_single
103+
return _ascii_rectangular_elements_double
104+
if 1 == gravity: return _unicode_rectangular_elements_single
105+
return _unicode_rectangular_elements_double
106+
107+
55108
def generate_cli_functions( shell_name, function_name, with_completions ):
56109
''' Generates CLI functions for use of development shim.
57110

0 commit comments

Comments
 (0)