add codespell to pyproject.toml

calibre will probably never fully compliant with codespell
this setting is only to easily find common typo errors
by filtring a great range of false-positives, but not all
This commit is contained in:
un-pogaz 2025-03-23 13:59:14 +01:00
parent bc29562c0c
commit d176b3a7cf
30 changed files with 135 additions and 48 deletions

View File

@ -496,7 +496,7 @@
:: improved recipes :: improved recipes
- Jot Down - Jot Down
- Various Russian and Ukranian news sources - Various Russian and Ukrainian news sources
- Nautilus Magazine - Nautilus Magazine
- Süddeutsche Zeitung - Süddeutsche Zeitung
- The India Forum - The India Forum
@ -974,7 +974,7 @@
- Fix a regression in 7.0 caused by a regression in Qt that would result in calibre hanging rarely when using the cover browser view - Fix a regression in 7.0 caused by a regression in Qt that would result in calibre hanging rarely when using the cover browser view
- [2049992] Fix custom template functions not useable in save to disk templates - [2049992] Fix custom template functions not usable in save to disk templates
- Fix a regression in 7.2 that caused the popup used for editing fields in the book list to be mis-positioned on very wide monitors - Fix a regression in 7.2 that caused the popup used for editing fields in the book list to be mis-positioned on very wide monitors

View File

@ -402,7 +402,7 @@ V. General Format of a .ZIP file
13 - Acorn Risc 14 - VFAT 13 - Acorn Risc 14 - VFAT
15 - alternate MVS 16 - BeOS 15 - alternate MVS 16 - BeOS
17 - Tandem 18 - OS/400 17 - Tandem 18 - OS/400
19 - OS/X (Darwin) 20 thru 255 - unused 19 - OS/X (Darwin) 20 through 255 - unused
The lower byte indicates the ZIP specification version The lower byte indicates the ZIP specification version
(the version of this document) supported by the software (the version of this document) supported by the software
@ -719,7 +719,7 @@ V. General Format of a .ZIP file
The Header ID field indicates the type of data that is in The Header ID field indicates the type of data that is in
the following data block. the following data block.
Header ID's of 0 thru 31 are reserved for use by PKWARE. Header ID's of 0 through 31 are reserved for use by PKWARE.
The remaining ID's can be used by third party vendors for The remaining ID's can be used by third party vendors for
proprietary usage. proprietary usage.
@ -1769,7 +1769,7 @@ Example: 0x02, 0x42, 0x01, 0x13
This would generate the original bit length array of: This would generate the original bit length array of:
(3, 3, 3, 3, 3, 2, 4, 4) (3, 3, 3, 3, 3, 2, 4, 4)
There are 8 codes in this table for the values 0 thru 7. Using There are 8 codes in this table for the values 0 through 7. Using
the algorithm to obtain the Shannon-Fano codes produces: the algorithm to obtain the Shannon-Fano codes produces:
Reversed Order Original Reversed Order Original
@ -1909,8 +1909,8 @@ The bit lengths for the literal tables are sent first with the number
of entries sent described by the 5 bits sent earlier. There are up of entries sent described by the 5 bits sent earlier. There are up
to 286 literal characters; the first 256 represent the respective 8 to 286 literal characters; the first 256 represent the respective 8
bit character, code 256 represents the End-Of-Block code, the remaining bit character, code 256 represents the End-Of-Block code, the remaining
29 codes represent copy lengths of 3 thru 258. There are up to 30 29 codes represent copy lengths of 3 through 258. There are up to 30
distance codes representing distances from 1 thru 32k as described distance codes representing distances from 1 through 32k as described
below. below.
Length Codes Length Codes
@ -2221,7 +2221,7 @@ keys, based on random data, to render a plaintext attack on the
data ineffective. data ineffective.
Read the 12-byte encryption header into Buffer, in locations Read the 12-byte encryption header into Buffer, in locations
Buffer(0) thru Buffer(11). Buffer(0) through Buffer(11).
loop for i <- 0 to 11 loop for i <- 0 to 11
C <- buffer(i) ^ decrypt_byte() C <- buffer(i) ^ decrypt_byte()

View File

@ -74,6 +74,93 @@ docstring-quotes = 'single'
inline-quotes = 'single' inline-quotes = 'single'
multiline-quotes = 'single' multiline-quotes = 'single'
[tool.codespell]
# calibre will probably never fully compliant with codespell
# this setting is only to easily find common typo errors
# by filtring a great range of false-positives, but not all
# (if codespell could per-file-ignores words, its be nicer)
count = false
summary = false
quiet-level = 3
regex = '''\b(?<!&)(?<!&amp;)[\w\-']+(?!&(amp;)?)\b'''
builtin = [
'clear',
'rare',
'informal',
]
ignore-words-list = [
"alo",
"ans",
"clen",
"eto",
"fo",
"nam",
"nd",
"som",
"te",
"atLeast",
"Implementor",
"implementor",
"Implementors",
"implementors",
"missings",
"re-use",
"re-used",
"re-using",
"succeded",
]
uri-ignore-words-list = '*'
skip = [
"*.svg",
"*.rcc",
"*_ui.py",
"./src/calibre/ebooks/rtf2xml/char_set.py",
"./src/calibre/ebooks/unihandecode/*",
"./src/calibre/ebooks/html_entities.h",
"./src/calibre/ebooks/html_entities.py",
"./src/calibre/utils/icu_test.py",
"./src/calibre/utils/search_query_parser_test.py",
"./Changelog.old.txt",
"./COPYRIGHT",
"./LICENSE",
"./LICENSE.rtf",
"./pyproject.toml",
"./session.vim",
"./build/*",
"./docs/*",
"./nbproject/*",
"./recipes/*",
"./translations/*",
"./tags/*",
"./manual/generated/*",
"./manual/locale/*",
"./resources/dictionaries/*",
"./resources/localization/*",
"./resources/hyphenation/*",
"./resources/mathjax/*",
"./resources/builtin_recipes.xml",
"./resources/changelog.json",
"./resources/editor.js",
"./resources/editor-functions.json",
"./resources/mime.types",
"./resources/piper-voices.json",
"./resources/stylelint-bundle.min.js",
"./resources/user-manual-translation-stats.json",
"./resources/template-functions.json",
"./resources/viewer.js",
"./resources/viewer.html",
"./resources/content-server/index-generated.html",
"./setup/installer/*",
"./setup/pyqt_enums/*",
"./setup/lc_data.py",
"./setup/linux-installer.py",
"./src/css_selectors/*",
"./src/polyglot/*",
"./src/templite/*",
"./src/tinycss/*",
"./src/unicode_names/*",
]
[tool.flynt] [tool.flynt]
line-length = 400 # over value to catch every case line-length = 400 # over value to catch every case
transform-format = false # don't transform already existing format call transform-format = false # don't transform already existing format call

View File

@ -61,7 +61,7 @@ class ESPN(BasicNewsRecipe):
def get_browser(self): def get_browser(self):
br = BasicNewsRecipe.get_browser(self) br = BasicNewsRecipe.get_browser(self)
if False and self.username and self.password: if False and self.username and self.password:
# ESPN has changed to a JS based login system, cant be bothered # ESPN has changed to a JS based login system, can't be bothered
# revering it # revering it
br.set_handle_refresh(False) br.set_handle_refresh(False)
url = ('https://r.espn.go.com/members/v3_1/login') url = ('https://r.espn.go.com/members/v3_1/login')

View File

@ -71,7 +71,7 @@ class ft(BasicNewsRecipe):
# def get_browser(self, *args, **kw): # def get_browser(self, *args, **kw):
# br = super().get_browser(*args, **kw) # br = super().get_browser(*args, **kw)
# if self.username and self.password: # if self.username and self.password:
# # ft.com uses a CAPTCHA on its login page so this sadly doesnt work # # ft.com uses a CAPTCHA on its login page so this sadly doesn't work
# br.open('https://accounts.ft.com/login?location=https%3A%2F%2Fwww.ft.com') # br.open('https://accounts.ft.com/login?location=https%3A%2F%2Fwww.ft.com')
# br.select_form(id='email-form') # br.select_form(id='email-form')
# br['email'] = self.username # br['email'] = self.username

View File

@ -77,7 +77,7 @@ class IndependentAustralia(BasicNewsRecipe):
businessArticles = [] businessArticles = []
lifeArticles = [] lifeArticles = []
australiaArticles = [] australiaArticles = []
# Loop thru the articles in all feeds to find articles with base categories in it # Loop through the articles in all feeds to find articles with base categories in it
for curfeed in feeds: for curfeed in feeds:
delList = [] delList = []
for a, curarticle in enumerate(curfeed.articles): for a, curarticle in enumerate(curfeed.articles):

View File

@ -107,7 +107,7 @@ class SatMagazine(BasicNewsRecipe):
title_number = 0 title_number = 0
# Goes thru all the articles one by one and sort them out # Goes through all the articles one by one and sort them out
for article in articles: for article in articles:
title = self.tag_to_string(article) title = self.tag_to_string(article)

View File

@ -57,7 +57,7 @@ def get_dist(base, which, bitness):
def shutdown_allowed(which, bitness): def shutdown_allowed(which, bitness):
# The ARM64 VM is extremely flakey often booting up to a non-functional # The ARM64 VM is extremely flakey often booting up to a non-functional
# state so dont shut it down as it seems to be more stable once bootup is # state so dont shut it down as it seems to be more stable once boot-up is
# done. # done.
return bitness != 'arm64' return bitness != 'arm64'

View File

@ -3474,7 +3474,7 @@ class Cache:
self._add_extra_files(dest_id, {q: BytesIO(cdata)}, replace=False, auto_rename=True) self._add_extra_files(dest_id, {q: BytesIO(cdata)}, replace=False, auto_rename=True)
break break
for key in self.field_metadata: # loop thru all defined fields for key in self.field_metadata: # loop through all defined fields
fm = self.field_metadata[key] fm = self.field_metadata[key]
if not fm['is_custom']: if not fm['is_custom']:
continue continue

View File

@ -119,7 +119,7 @@ class Notes:
def path_for_resource(self, resource_hash: str) -> str: def path_for_resource(self, resource_hash: str) -> str:
hashalg, digest = resource_hash.split(':', 1) hashalg, digest = resource_hash.split(':', 1)
prefix = digest[:2] prefix = digest[:2]
# Cant use colons in filenames on windows safely # Can't use colons in filenames on windows safely
return os.path.join(self.resources_dir, prefix, f'{hashalg}-{digest}') return os.path.join(self.resources_dir, prefix, f'{hashalg}-{digest}')
def remove_resources(self, conn, note_id, resources_to_potentially_remove, delete_from_link_table=True): def remove_resources(self, conn, note_id, resources_to_potentially_remove, delete_from_link_table=True):

View File

@ -299,7 +299,7 @@
DEVICE_FLAG_BROKEN_MTPGETOBJPROPLIST | DEVICE_FLAG_BROKEN_MTPGETOBJPROPLIST |
DEVICE_FLAG_PLAYLIST_SPL_V1 }, DEVICE_FLAG_PLAYLIST_SPL_V1 },
// YP-F3 is NOT MTP - USB mass storage // YP-F3 is NOT MTP - USB mass storage
// From a rouge .INF file // From a rogue .INF file
// this device ID seems to have been recycled for: // this device ID seems to have been recycled for:
// the Samsung SGH-A707 Cingular cellphone // the Samsung SGH-A707 Cingular cellphone
// the Samsung L760-V cellphone // the Samsung L760-V cellphone
@ -1183,7 +1183,7 @@
DEVICE_FLAG_BROKEN_MTPGETOBJPROPLIST_ALL }, DEVICE_FLAG_BROKEN_MTPGETOBJPROPLIST_ALL },
// From: Willy Gardiol (web) <willy@gardiol.org> // From: Willy Gardiol (web) <willy@gardiol.org>
// Spurious errors for getting all objects, lead me to believe // Spurious errors for getting all objects, lead me to believe
// this flag atleast is needed // this flag at least is needed
{ "Nokia", 0x0421, "5800 XpressMusic v2", 0x0155, { "Nokia", 0x0421, "5800 XpressMusic v2", 0x0155,
DEVICE_FLAG_BROKEN_MTPGETOBJPROPLIST_ALL }, DEVICE_FLAG_BROKEN_MTPGETOBJPROPLIST_ALL },
// Yet another version... I think // Yet another version... I think

View File

@ -51,7 +51,7 @@ def read_variable_len_data(data, header):
header['tagx_block_size'] = 0 header['tagx_block_size'] = 0
trailing_bytes = data[idxt_offset+idxt_size:] trailing_bytes = data[idxt_offset+idxt_size:]
if trailing_bytes.rstrip(b'\0'): if trailing_bytes.rstrip(b'\0'):
raise ValueError('Traling bytes after last IDXT entry: {!r}'.format(trailing_bytes.rstrip(b'\0'))) raise ValueError('Trailing bytes after last IDXT entry: {!r}'.format(trailing_bytes.rstrip(b'\0')))
header['indices'] = indices header['indices'] = indices

View File

@ -101,7 +101,7 @@ div#book-inner {{ margin-top: 0; margin-bottom: 0; }}</style><script type="text/
# encoding quirks # encoding quirks
'<p>A\xa0nbsp;&nbsp;': '<p>A\xa0nbsp;&nbsp;':
'<p><span class="koboSpan" id="kobo.1.1">A&#160;nbsp;&#160;</span></p>', '<p><span class="koboSpan" id="kobo.1.1">A&#160;nbsp;&#160;</span></p>',
'<div><script>1 < 2 & 3</script>': # escaping with cdata note that kepubify doesnt do this '<div><script>1 < 2 & 3</script>': # escaping with cdata note that kepubify doesn't do this
'<div><script><![CDATA[1 < 2 & 3]]></script></div>', '<div><script><![CDATA[1 < 2 & 3]]></script></div>',
# CSS filtering # CSS filtering

View File

@ -732,21 +732,21 @@ class Region:
class Page: class Page:
def __init__(self, page, font_map, opts, log, idc): def __init__(self, page, font_map, opts, log, idc):
def text_cmp(frst, secnd): def text_cmp(first, second):
# Compare 2 text objects. # Compare 2 text objects.
# Order by line (top/bottom) then left # Order by line (top/bottom) then left
if (frst.top <= secnd.top and frst.bottom >= secnd.bottom-BOTTOM_FACTOR) \ if (first.top <= second.top and first.bottom >= second.bottom-BOTTOM_FACTOR) \
or (secnd.top <= frst.top and secnd.bottom >= frst.bottom-BOTTOM_FACTOR): or (second.top <= first.top and second.bottom >= first.bottom-BOTTOM_FACTOR):
# Overlap = same line # Overlap = same line
if frst.left < secnd.left: if first.left < second.left:
return -1 return -1
elif frst.left == secnd.left: elif first.left == second.left:
return 0 return 0
return 1 return 1
# Different line so sort into line number # Different line so sort into line number
if frst.bottom < secnd.bottom: if first.bottom < second.bottom:
return -1 return -1
elif frst.bottom == secnd.bottom: elif first.bottom == second.bottom:
return 0 return 0
return 1 return 1

View File

@ -121,7 +121,7 @@ class ListNumbers:
return 'ordered' return 'ordered'
# sys.stderr.write('module is list_numbers\n') # sys.stderr.write('module is list_numbers\n')
# sys.stderr.write('method is __determine type\n') # sys.stderr.write('method is __determine type\n')
# sys.stderr.write('Couldn\'t get type of list\n') # sys.stderr.write("Couldn't get type of list\n")
# must be some type of ordered list -- just a guess! # must be some type of ordered list -- just a guess!
return 'unordered' return 'unordered'

View File

@ -1776,7 +1776,7 @@ def raise_and_focus(self: QWidget) -> None:
def raise_without_focus(self: QWidget) -> None: def raise_without_focus(self: QWidget) -> None:
if QApplication.instance().platformName() == 'wayland': if QApplication.instance().platformName() == 'wayland':
# On fucking Wayland, we cant raise a dialog without also giving it # On fucking Wayland, we can't raise a dialog without also giving it
# keyboard focus. What a joke. # keyboard focus. What a joke.
self.raise_and_focus() self.raise_and_focus()
else: else:

View File

@ -288,10 +288,10 @@ class AutoAdder(QObject):
if duplicates: if duplicates:
paths, formats, metadata = [], [], [] paths, formats, metadata = [], [], []
for p, f, mis in duplicates: for p, f, mi in duplicates:
paths.extend(p) paths.extend(p)
formats.extend(f) formats.extend(f)
metadata.extend(mis) metadata.extend(mi)
dups = [(mic, mic.cover, [p]) for mic, p in zip(metadata, paths)] dups = [(mic, mic.cover, [p]) for mic, p in zip(metadata, paths)]
d = DuplicatesQuestion(m.db, dups, parent=gui) d = DuplicatesQuestion(m.db, dups, parent=gui)
dups = tuple(d.duplicates) dups = tuple(d.duplicates)

View File

@ -485,7 +485,7 @@ class CentralContainer(QWidget):
def read_settings(self): def read_settings(self):
before = self.serialized_settings() before = self.serialized_settings()
# sadly self.size() doesnt always return sensible values so look at # sadly self.size() doesn't always return sensible values so look at
# the size of the main window which works perfectly for width, not so # the size of the main window which works perfectly for width, not so
# perfectly for height # perfectly for height
sz = self.size() sz = self.size()

View File

@ -287,7 +287,7 @@ class NoteEditorWidget(EditorWidget):
def do_insert_image(self): def do_insert_image(self):
# See https://bugreports.qt.io/browse/QTBUG-118537 # See https://bugreports.qt.io/browse/QTBUG-118537
# for why we cant have a nice margin for floating images # for why we can't have a nice margin for floating images
d = AskImage(self.images, self.db) d = AskImage(self.images, self.db)
if d.exec() == QDialog.DialogCode.Accepted and d.current_digest: if d.exec() == QDialog.DialogCode.Accepted and d.current_digest:
ir = self.images[d.current_digest] ir = self.images[d.current_digest]

View File

@ -153,14 +153,14 @@ def send_mails(jobnames, callback, attachments, to_s, subjects,
attachments, to_s, subjects, texts, attachment_names): attachments, to_s, subjects, texts, attachment_names):
description = _('Email %(name)s to %(to)s') % dict(name=name, to=to) description = _('Email %(name)s to %(to)s') % dict(name=name, to=to)
if isinstance(to, str) and (is_for_kindle(to) or '@pbsync.com' in to): if isinstance(to, str) and (is_for_kindle(to) or '@pbsync.com' in to):
# The PocketBook service is a total joke. It cant handle # The PocketBook service is a total joke. It can't handle
# non-ascii, filenames that are long enough to be split up, commas, and # non-ascii, filenames that are long enough to be split up, commas, and
# the good lord alone knows what else. So use a random filename # the good lord alone knows what else. So use a random filename
# containing only 22 English letters and numbers # containing only 22 English letters and numbers
# #
# And since this email is only going to be processed by automated # And since this email is only going to be processed by automated
# services, make the subject+text random too as at least the amazon # services, make the subject+text random too as at least the amazon
# service cant handle non-ascii text. I dont know what baboons # service can't handle non-ascii text. I dont know what baboons
# these companies employ to write their code. It's the height of # these companies employ to write their code. It's the height of
# irony that they are called "tech" companies. # irony that they are called "tech" companies.
# https://bugs.launchpad.net/calibre/+bug/1989282 # https://bugs.launchpad.net/calibre/+bug/1989282

View File

@ -36,7 +36,7 @@ class FTSDialog(Dialog):
l = QVBoxLayout(self) l = QVBoxLayout(self)
self.fat_warning = fw = QLabel( self.fat_warning = fw = QLabel(
f'<span style="color:red; font-weight: bold">{_("WARNING")}:</span> ' + f'<span style="color:red; font-weight: bold">{_("WARNING")}:</span> ' +
_('The calibre library is on a FAT drive, indexing more than a few hundred books wont work.') + _("The calibre library is on a FAT drive, indexing more than a few hundred books won't work.") +
f' <a href="xxx" style="text-decoration: none">{_("Learn more")}</a>') f' <a href="xxx" style="text-decoration: none">{_("Learn more")}</a>')
# fw.setVisible(False) # fw.setVisible(False)
fw.linkActivated.connect(self.show_fat_details) fw.linkActivated.connect(self.show_fat_details)

View File

@ -359,7 +359,7 @@ class VLTabs(QTabBar): # {{{
def lock_tab(self): def lock_tab(self):
gprefs['vl_tabs_closable'] = False gprefs['vl_tabs_closable'] = False
self.setTabsClosable(False) self.setTabsClosable(False)
# Workaround for Qt bug where it doesnt recalculate the tab size after locking # Workaround for Qt bug where it doesn't recalculate the tab size after locking
for idx in range(self.count()): for idx in range(self.count()):
self.setTabButton(idx, QTabBar.ButtonPosition.RightSide, None) self.setTabButton(idx, QTabBar.ButtonPosition.RightSide, None)
self.setTabButton(idx, QTabBar.ButtonPosition.LeftSide, None) self.setTabButton(idx, QTabBar.ButtonPosition.LeftSide, None)

View File

@ -268,7 +268,7 @@ class MarkdownHighlighter(QSyntaxHighlighter):
elif emphasis: elif emphasis:
self.setFormat(self.offset+offset+ match.start(), match.end() - match.start(), self.MARKDOWN_KWS_FORMAT['Italic']) self.setFormat(self.offset+offset+ match.start(), match.end() - match.start(), self.MARKDOWN_KWS_FORMAT['Italic'])
def recusive(match, extra_offset, bold, emphasis): def recursive(match, extra_offset, bold, emphasis):
apply(match, bold, emphasis) apply(match, bold, emphasis)
if bold and emphasis: if bold and emphasis:
return # max deep => return, do not process extra Bold/Italic return # max deep => return, do not process extra Bold/Italic
@ -278,17 +278,17 @@ class MarkdownHighlighter(QSyntaxHighlighter):
self._highlightBoldEmphasis(sub_txt, cursor, bf, sub_offset, bold, emphasis) self._highlightBoldEmphasis(sub_txt, cursor, bf, sub_offset, bold, emphasis)
for mo in re.finditer(self.MARKDOWN_KEYS_REGEX['Italic'],text): for mo in re.finditer(self.MARKDOWN_KEYS_REGEX['Italic'],text):
recusive(mo, 1, bold, True) recursive(mo, 1, bold, True)
found = True found = True
for mo in re.finditer(self.MARKDOWN_KEYS_REGEX['uItalic'],text): for mo in re.finditer(self.MARKDOWN_KEYS_REGEX['uItalic'],text):
recusive(mo, 1, bold, True) recursive(mo, 1, bold, True)
found = True found = True
for mo in re.finditer(self.MARKDOWN_KEYS_REGEX['Bold'],text): for mo in re.finditer(self.MARKDOWN_KEYS_REGEX['Bold'],text):
recusive(mo, 2, True, emphasis) recursive(mo, 2, True, emphasis)
found = True found = True
for mo in re.finditer(self.MARKDOWN_KEYS_REGEX['uBold'],text): for mo in re.finditer(self.MARKDOWN_KEYS_REGEX['uBold'],text):
recusive(mo, 2, True, emphasis) recursive(mo, 2, True, emphasis)
found = True found = True
for mo in re.finditer(self.MARKDOWN_KEYS_REGEX['BoldItalic'],text): for mo in re.finditer(self.MARKDOWN_KEYS_REGEX['BoldItalic'],text):

View File

@ -25,7 +25,7 @@ JS_IDENT = JS_IDENT_START + '(?:' + JS_IDENT_PART + ')*'
class JavascriptLexer(RegexLexer): class JavascriptLexer(RegexLexer):
''' '''
For JavaScript source code. This is based on the pygments JS highlighter, For JavaScript source code. This is based on the pygments JS highlighter,
bu that does not handle multi-line comments in streaming mode, so we had to but that does not handle multi-line comments in streaming mode, so we had to
modify it. modify it.
''' '''

View File

@ -83,7 +83,7 @@ def parse_uri(uri, parse_query=True, unquote_func=unquote):
try: try:
query = MultiDict.create_from_query_string(qs) query = MultiDict.create_from_query_string(qs)
except Exception: except Exception:
raise HTTPSimpleResponse(http_client.BAD_REQUEST, 'Unparseable query string') raise HTTPSimpleResponse(http_client.BAD_REQUEST, 'Unparsable query string')
else: else:
query = None query = None

View File

@ -192,7 +192,7 @@ class SetGlobalsNode(Node):
class StringCompareNode(Node): class StringCompareNode(Node):
def __init__(self, line_number, operator, left, right): def __init__(self, line_number, operator, left, right):
Node.__init__(self, line_number, 'comparision: ' + operator) Node.__init__(self, line_number, 'comparison: ' + operator)
self.node_type = self.NODE_COMPARE_STRING self.node_type = self.NODE_COMPARE_STRING
self.operator = operator self.operator = operator
self.left = left self.left = left

View File

@ -743,7 +743,7 @@ class SMTP:
>>> tolist=["one@one.org","two@two.org","three@three.org","four@four.org"] >>> tolist=["one@one.org","two@two.org","three@three.org","four@four.org"]
>>> msg = '''\\ >>> msg = '''\\
... From: Me@my.org ... From: Me@my.org
... Subject: testin'... ... Subject: testing...
... ...
... This is a test ''' ... This is a test '''
>>> s.sendmail("me@my.org",tolist,msg) >>> s.sendmail("me@my.org",tolist,msg)

View File

@ -446,7 +446,7 @@ def next_screen_location():
current_pos = Math.ceil(current_scroll_offset()) current_pos = Math.ceil(current_scroll_offset())
ans = limit if current_pos < limit else -1 ans = limit if current_pos < limit else -1
if cols_per_screen is 1 and ans is not -1 and ans - current_pos < col_size: if cols_per_screen is 1 and ans is not -1 and ans - current_pos < col_size:
ans = -1 # cant scroll partial columns ans = -1 # can't scroll partial columns
return ans return ans

View File

@ -145,7 +145,7 @@ class ReadUI:
try: try:
result = JSON.parse(xhr.responseText) result = JSON.parse(xhr.responseText)
except Exception: except Exception:
return self.show_error(_('Failed to parse profiles'), _('Unparseable data received for profiles')) return self.show_error(_('Failed to parse profiles'), _('Unparsable data received for profiles'))
proceed(result) proceed(result)
).send() ).send()

View File

@ -134,7 +134,7 @@ def range_extents(q, in_flow_mode):
rect = boundary_node.getBoundingClientRect() rect = boundary_node.getBoundingClientRect()
if not is_start: if not is_start:
ans.selected_prev = True ans.selected_prev = True
# we cant use getBoundingClientRect as the node might be split # we can't use getBoundingClientRect as the node might be split
# among multiple columns # among multiple columns
else if node.getClientRects: else if node.getClientRects:
rects = node.getClientRects() rects = node.getClientRects()