Skip to content
Projeler
Gruplar
Parçacıklar
Yardım
Yükleniyor...
Oturum aç / Kaydol
Gezinmeyi değiştir
C
cpython
Proje
Proje
Ayrıntılar
Etkinlik
Cycle Analytics
Depo (repository)
Depo (repository)
Dosyalar
Kayıtlar (commit)
Dallar (branch)
Etiketler
Katkıda bulunanlar
Grafik
Karşılaştır
Grafikler
Konular (issue)
0
Konular (issue)
0
Liste
Pano
Etiketler
Kilometre Taşları
Birleştirme (merge) Talepleri
0
Birleştirme (merge) Talepleri
0
CI / CD
CI / CD
İş akışları (pipeline)
İşler
Zamanlamalar
Grafikler
Paketler
Paketler
Wiki
Wiki
Parçacıklar
Parçacıklar
Üyeler
Üyeler
Collapse sidebar
Close sidebar
Etkinlik
Grafik
Grafikler
Yeni bir konu (issue) oluştur
İşler
Kayıtlar (commit)
Konu (issue) Panoları
Kenar çubuğunu aç
Batuhan Osman TASKAYA
cpython
Commits
8506016f
Kaydet (Commit)
8506016f
authored
6 years ago
tarafından
Cheryl Sabella
Kaydeden (comit)
Terry Jan Reedy
6 years ago
Dosyalara gözat
Seçenekler
Dosyalara Gözat
İndir
Eposta Yamaları
Sade Fark
bpo-33628: IDLE: Minor code cleanup of codecontext.py and its tests (GH-7085)
üst
8ebf5ceb
No related merge requests found
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
62 additions
and
59 deletions
+62
-59
NEWS.txt
Lib/idlelib/NEWS.txt
+2
-0
codecontext.py
Lib/idlelib/codecontext.py
+38
-40
test_codecontext.py
Lib/idlelib/idle_test/test_codecontext.py
+20
-19
2018-05-23-19-51-07.bpo-33628.sLlFLO.rst
...NEWS.d/next/IDLE/2018-05-23-19-51-07.bpo-33628.sLlFLO.rst
+2
-0
No files found.
Lib/idlelib/NEWS.txt
Dosyayı görüntüle @
8506016f
...
...
@@ -3,6 +3,8 @@ Released on 2018-06-18?
======================================
bpo-33628: Cleanup codecontext.py and its test.
bpo-32831: Add docstrings and tests for codecontext.py.
Coverage is 100%. Patch by Cheryl Sabella.
...
...
This diff is collapsed.
Click to expand it.
Lib/idlelib/codecontext.py
Dosyayı görüntüle @
8506016f
...
...
@@ -23,9 +23,23 @@ UPDATEINTERVAL = 100 # millisec
FONTUPDATEINTERVAL
=
1000
# millisec
def
getspacesfirstword
(
s
,
c
=
re
.
compile
(
r"^(\s*)(\w*)"
)):
"Extract the beginning whitespace and first word from s."
return
c
.
match
(
s
)
.
groups
()
def
get_spaces_firstword
(
codeline
,
c
=
re
.
compile
(
r"^(\s*)(\w*)"
)):
"Extract the beginning whitespace and first word from codeline."
return
c
.
match
(
codeline
)
.
groups
()
def
get_line_info
(
codeline
):
"""Return tuple of (line indent value, codeline, block start keyword).
The indentation of empty lines (or comment lines) is INFINITY.
If the line does not start a block, the keyword value is False.
"""
spaces
,
firstword
=
get_spaces_firstword
(
codeline
)
indent
=
len
(
spaces
)
if
len
(
codeline
)
==
indent
or
codeline
[
indent
]
==
'#'
:
indent
=
INFINITY
opener
=
firstword
in
BLOCKOPENERS
and
firstword
return
indent
,
codeline
,
opener
class
CodeContext
:
...
...
@@ -42,15 +56,15 @@ class CodeContext:
self.textfont is the editor window font.
self.label displays the code context text above the editor text.
Initially None it is toggled via <<toggle-code-context>>.
Initially None
,
it is toggled via <<toggle-code-context>>.
self.topvisible is the number of the top text line displayed.
self.info is a list of (line number, indent level, line text,
block keyword) tuples for the block structure above topvisible.
s
self.info[0] is initialized
a 'dummy' line which
#
starts the toplevel 'block' of the module.
s
elf.info[0] is initialized with
a 'dummy' line which
starts the toplevel 'block' of the module.
self.t1 and self.t2 are two timer events on the editor text widget to
monitor for changes to the context text or editor font.
monitor for changes to the context text or editor font.
"""
self
.
editwin
=
editwin
self
.
text
=
editwin
.
text
...
...
@@ -94,23 +108,21 @@ class CodeContext:
# All values are passed through getint(), since some
# values may be pixel objects, which can't simply be added to ints.
widgets
=
self
.
editwin
.
text
,
self
.
editwin
.
text_frame
# Calculate the required
vertical padding
# Calculate the required
horizontal padding and border width.
padx
=
0
border
=
0
for
widget
in
widgets
:
padx
+=
widget
.
tk
.
getint
(
widget
.
pack_info
()[
'padx'
])
padx
+=
widget
.
tk
.
getint
(
widget
.
cget
(
'padx'
))
# Calculate the required border width
border
=
0
for
widget
in
widgets
:
border
+=
widget
.
tk
.
getint
(
widget
.
cget
(
'border'
))
self
.
label
=
tkinter
.
Label
(
self
.
editwin
.
top
,
text
=
"
\n
"
*
(
self
.
context_depth
-
1
),
anchor
=
W
,
justify
=
LEFT
,
font
=
self
.
textfont
,
bg
=
self
.
bgcolor
,
fg
=
self
.
fgcolor
,
width
=
1
,
#don't request more than we get
width
=
1
,
# Don't request more than we get.
padx
=
padx
,
border
=
border
,
relief
=
SUNKEN
)
# Pack the label widget before and above the text_frame widget,
# thus ensuring that it will appear directly above text_frame
# thus ensuring that it will appear directly above text_frame
.
self
.
label
.
pack
(
side
=
TOP
,
fill
=
X
,
expand
=
False
,
before
=
self
.
editwin
.
text_frame
)
else
:
...
...
@@ -118,21 +130,6 @@ class CodeContext:
self
.
label
=
None
return
"break"
def
get_line_info
(
self
,
linenum
):
"""Return tuple of (line indent value, text, and block start keyword).
If the line does not start a block, the keyword value is False.
The indentation of empty lines (or comment lines) is INFINITY.
"""
text
=
self
.
text
.
get
(
"
%
d.0"
%
linenum
,
"
%
d.end"
%
linenum
)
spaces
,
firstword
=
getspacesfirstword
(
text
)
opener
=
firstword
in
BLOCKOPENERS
and
firstword
if
len
(
text
)
==
len
(
spaces
)
or
text
[
len
(
spaces
)]
==
'#'
:
indent
=
INFINITY
else
:
indent
=
len
(
spaces
)
return
indent
,
text
,
opener
def
get_context
(
self
,
new_topvisible
,
stopline
=
1
,
stopindent
=
0
):
"""Return a list of block line tuples and the 'last' indent.
...
...
@@ -144,16 +141,17 @@ class CodeContext:
"""
assert
stopline
>
0
lines
=
[]
# The indentation level we are currently in
:
# The indentation level we are currently in
.
lastindent
=
INFINITY
# For a line to be interesting, it must begin with a block opening
# keyword, and have less indentation than lastindent.
for
linenum
in
range
(
new_topvisible
,
stopline
-
1
,
-
1
):
indent
,
text
,
opener
=
self
.
get_line_info
(
linenum
)
codeline
=
self
.
text
.
get
(
f
'{linenum}.0'
,
f
'{linenum}.end'
)
indent
,
text
,
opener
=
get_line_info
(
codeline
)
if
indent
<
lastindent
:
lastindent
=
indent
if
opener
in
(
"else"
,
"elif"
):
#
We also show the if statement
#
Also show the if statement.
lastindent
+=
1
if
opener
and
linenum
<
new_topvisible
and
indent
>=
stopindent
:
lines
.
append
((
linenum
,
indent
,
text
,
opener
))
...
...
@@ -172,19 +170,19 @@ class CodeContext:
the context label.
"""
new_topvisible
=
int
(
self
.
text
.
index
(
"@0,0"
)
.
split
(
'.'
)[
0
])
if
self
.
topvisible
==
new_topvisible
:
#
haven't scrolled
if
self
.
topvisible
==
new_topvisible
:
#
Haven't scrolled.
return
if
self
.
topvisible
<
new_topvisible
:
#
scroll down
if
self
.
topvisible
<
new_topvisible
:
#
Scroll down.
lines
,
lastindent
=
self
.
get_context
(
new_topvisible
,
self
.
topvisible
)
#
r
etain only context info applicable to the region
# between topvisible and new_topvisible
:
#
R
etain only context info applicable to the region
# between topvisible and new_topvisible
.
while
self
.
info
[
-
1
][
1
]
>=
lastindent
:
del
self
.
info
[
-
1
]
else
:
# self.topvisible > new_topvisible:
# scroll up
else
:
# self.topvisible > new_topvisible:
# Scroll up.
stopindent
=
self
.
info
[
-
1
][
1
]
+
1
#
r
etain only context info associated
# with lines above new_topvisible
:
#
R
etain only context info associated
# with lines above new_topvisible
.
while
self
.
info
[
-
1
][
0
]
>=
new_topvisible
:
stopindent
=
self
.
info
[
-
1
][
1
]
del
self
.
info
[
-
1
]
...
...
@@ -193,9 +191,9 @@ class CodeContext:
stopindent
)
self
.
info
.
extend
(
lines
)
self
.
topvisible
=
new_topvisible
#
empty lines in context pane:
#
Empty lines in context pane.
context_strings
=
[
""
]
*
max
(
0
,
self
.
context_depth
-
len
(
self
.
info
))
#
followed by the context hint lines:
#
Followed by the context hint lines.
context_strings
+=
[
x
[
2
]
for
x
in
self
.
info
[
-
self
.
context_depth
:]]
self
.
label
[
"text"
]
=
'
\n
'
.
join
(
context_strings
)
...
...
This diff is collapsed.
Click to expand it.
Lib/idlelib/idle_test/test_codecontext.py
Dosyayı görüntüle @
8506016f
...
...
@@ -96,8 +96,6 @@ class CodeContextTest(unittest.TestCase):
eq
(
self
.
root
.
tk
.
call
(
'after'
,
'info'
,
self
.
cc
.
t2
)[
1
],
'timer'
)
def
test_del
(
self
):
self
.
root
.
tk
.
call
(
'after'
,
'info'
,
self
.
cc
.
t1
)
self
.
root
.
tk
.
call
(
'after'
,
'info'
,
self
.
cc
.
t2
)
self
.
cc
.
__del__
()
with
self
.
assertRaises
(
TclError
)
as
msg
:
self
.
root
.
tk
.
call
(
'after'
,
'info'
,
self
.
cc
.
t1
)
...
...
@@ -135,21 +133,6 @@ class CodeContextTest(unittest.TestCase):
eq
(
toggle
(),
'break'
)
self
.
assertIsNone
(
cc
.
label
)
def
test_get_line_info
(
self
):
eq
=
self
.
assertEqual
gli
=
self
.
cc
.
get_line_info
# Line 1 is not a BLOCKOPENER.
eq
(
gli
(
1
),
(
codecontext
.
INFINITY
,
''
,
False
))
# Line 2 is a BLOCKOPENER without an indent.
eq
(
gli
(
2
),
(
0
,
'class C1():'
,
'class'
))
# Line 3 is not a BLOCKOPENER and does not return the indent level.
eq
(
gli
(
3
),
(
codecontext
.
INFINITY
,
' # Class comment.'
,
False
))
# Line 4 is a BLOCKOPENER and is indented.
eq
(
gli
(
4
),
(
4
,
' def __init__(self, a, b):'
,
'def'
))
# Line 8 is a different BLOCKOPENER and is indented.
eq
(
gli
(
8
),
(
8
,
' if a > b:'
,
'if'
))
def
test_get_context
(
self
):
eq
=
self
.
assertEqual
gc
=
self
.
cc
.
get_context
...
...
@@ -323,8 +306,8 @@ class CodeContextTest(unittest.TestCase):
class
HelperFunctionText
(
unittest
.
TestCase
):
def
test_get
spaces
firstword
(
self
):
get
=
codecontext
.
get
spaces
firstword
def
test_get
_spaces_
firstword
(
self
):
get
=
codecontext
.
get
_spaces_
firstword
test_lines
=
(
(
' first word'
,
(
' '
,
'first'
)),
(
'
\t
first word'
,
(
'
\t
'
,
'first'
)),
...
...
@@ -342,6 +325,24 @@ class HelperFunctionText(unittest.TestCase):
c
=
re
.
compile
(
r'^(\s*)([^\s]*)'
)),
(
' '
,
'(continuation)'
))
def
test_get_line_info
(
self
):
eq
=
self
.
assertEqual
gli
=
codecontext
.
get_line_info
lines
=
code_sample
.
splitlines
()
# Line 1 is not a BLOCKOPENER.
eq
(
gli
(
lines
[
0
]),
(
codecontext
.
INFINITY
,
''
,
False
))
# Line 2 is a BLOCKOPENER without an indent.
eq
(
gli
(
lines
[
1
]),
(
0
,
'class C1():'
,
'class'
))
# Line 3 is not a BLOCKOPENER and does not return the indent level.
eq
(
gli
(
lines
[
2
]),
(
codecontext
.
INFINITY
,
' # Class comment.'
,
False
))
# Line 4 is a BLOCKOPENER and is indented.
eq
(
gli
(
lines
[
3
]),
(
4
,
' def __init__(self, a, b):'
,
'def'
))
# Line 8 is a different BLOCKOPENER and is indented.
eq
(
gli
(
lines
[
7
]),
(
8
,
' if a > b:'
,
'if'
))
# Test tab.
eq
(
gli
(
'
\t
if a == b:'
),
(
1
,
'
\t
if a == b:'
,
'if'
))
if
__name__
==
'__main__'
:
unittest
.
main
(
verbosity
=
2
)
This diff is collapsed.
Click to expand it.
Misc/NEWS.d/next/IDLE/2018-05-23-19-51-07.bpo-33628.sLlFLO.rst
0 → 100644
Dosyayı görüntüle @
8506016f
IDLE: Cleanup codecontext.py and its test.
This diff is collapsed.
Click to expand it.
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment