Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Apply pyupgrade to project #2364

Merged
merged 1 commit into from
Oct 18, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
19 changes: 9 additions & 10 deletions codespell_lib/_codespell.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
Expand Down Expand Up @@ -29,12 +28,12 @@
# autogenerated by setuptools_scm
from ._version import __version__ as VERSION

word_regex_def = u"[\\w\\-'’`]+"
word_regex_def = "[\\w\\-'’`]+"
# While we want to treat characters like ( or " as okay for a starting break,
# these may occur unescaped in URIs, and so we are more restrictive on the
# endpoint. Emails are more restrictive, so the endpoint remains flexible.
uri_regex_def = (u"(\\b(?:https?|[ts]?ftp|file|git|smb)://[^\\s]+(?=$|\\s)|"
u"\\b[\\w.%+-]+@[\\w.-]+\\b)")
uri_regex_def = ("(\\b(?:https?|[ts]?ftp|file|git|smb)://[^\\s]+(?=$|\\s)|"
"\\b[\\w.%+-]+@[\\w.-]+\\b)")
encodings = ('utf-8', 'iso-8859-1')
USAGE = """
\t%prog [OPTIONS] [file1 file2 ... fileN]
Expand Down Expand Up @@ -83,7 +82,7 @@
# file1 .. fileN Files to check spelling


class QuietLevels(object):
class QuietLevels:
NONE = 0
ENCODING = 1
BINARY_FILE = 2
Expand All @@ -92,7 +91,7 @@ class QuietLevels(object):
FIXES = 16


class GlobMatch(object):
class GlobMatch:
def __init__(self, pattern):
if pattern:
# Pattern might be a list of comma-delimited strings
Expand All @@ -111,14 +110,14 @@ def match(self, filename):
return False


class Misspelling(object):
class Misspelling:
def __init__(self, data, fix, reason):
self.data = data
self.fix = fix
self.reason = reason


class TermColors(object):
class TermColors:
def __init__(self):
self.FILE = '\033[33m'
self.WWORD = '\033[31m'
Expand All @@ -132,7 +131,7 @@ def disable(self):
self.DISABLE = ''


class Summary(object):
class Summary:
def __init__(self):
self.summary = {}

Expand All @@ -152,7 +151,7 @@ def __str__(self):
width=15 - len(key)) for key in keys])


class FileOpener(object):
class FileOpener:
def __init__(self, use_chardet, quiet_level):
self.use_chardet = use_chardet
if use_chardet:
Expand Down
18 changes: 8 additions & 10 deletions codespell_lib/tests/test_basic.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
# -*- coding: utf-8 -*-

import contextlib
import inspect
import os
Expand All @@ -22,7 +20,7 @@ def test_constants():
assert EX_DATAERR == 65


class MainWrapper(object):
class MainWrapper:
"""Compatibility wrapper for when we used to return the count."""

def main(self, *args, count=True, std=False, **kwargs):
Expand Down Expand Up @@ -174,7 +172,7 @@ def test_interactivity(tmpdir, capsys):
with FakeStdin('0\n'): # blank input -> nothing
assert cs.main('-w', '-i', '3', f.name) == 0
assert cs.main(f.name) == 0
with open(f.name, 'r') as f_read:
Copy link
Collaborator

Choose a reason for hiding this comment

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

Not sure about this one either. What's wrong with the explicit 'r'? It echoes the 'w' below.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

'r' is the default, so is unnecessary:

https://docs.python.org/3/library/functions.html#open

It is conventional within the larger Python community to omit it. The goal of this PR is to update the code to follow wider community conventions.

with open(f.name) as f_read:
assert f_read.read() == 'awkward\n'
with open(f.name, 'w') as f:
f.write('ackward\n')
Expand All @@ -184,7 +182,7 @@ def test_interactivity(tmpdir, capsys):
assert code == 0
assert 'a valid option' in stdout
assert cs.main(f.name) == 0
with open(f.name, 'r') as f:
with open(f.name) as f:
assert f.read() == 'backward\n'
finally:
os.remove(f.name)
Expand Down Expand Up @@ -249,11 +247,11 @@ def test_exclude_file(tmpdir, capsys):
"""Test exclude file functionality."""
d = str(tmpdir)
with open(op.join(d, 'bad.txt'), 'wb') as f:
f.write('1 abandonned 1\n2 abandonned 2\n'.encode('utf-8'))
f.write(b'1 abandonned 1\n2 abandonned 2\n')
bad_name = f.name
assert cs.main(bad_name) == 2
with open(op.join(d, 'tmp.txt'), 'wb') as f:
f.write('1 abandonned 1\n'.encode('utf-8'))
f.write(b'1 abandonned 1\n')
assert cs.main(bad_name) == 2
assert cs.main('-x', f.name, bad_name) == 1

Expand All @@ -266,11 +264,11 @@ def test_encoding(tmpdir, capsys):
# with CaptureStdout() as sio:
assert cs.main(f.name) == 0
with open(f.name, 'wb') as f:
f.write(u'naïve\n'.encode('utf-8'))
f.write('naïve\n'.encode())
assert cs.main(f.name) == 0
assert cs.main('-e', f.name) == 0
with open(f.name, 'ab') as f:
f.write(u'naieve\n'.encode('utf-8'))
f.write(b'naieve\n')
assert cs.main(f.name) == 1
# Encoding detection (only try ISO 8859-1 because UTF-8 is the default)
with open(f.name, 'wb') as f:
Expand Down Expand Up @@ -395,7 +393,7 @@ def test_case_handling(tmpdir, capsys):
# with CaptureStdout() as sio:
assert cs.main(f.name) == 0
with open(f.name, 'wb') as f:
f.write('this has an ACII error'.encode('utf-8'))
f.write(b'this has an ACII error')
code, stdout, _ = cs.main(f.name, std=True)
assert code == 1
assert 'ASCII' in stdout
Expand Down
8 changes: 3 additions & 5 deletions codespell_lib/tests/test_dictionary.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
# -*- coding: utf-8 -*-

import glob
import os.path as op
import os
Expand Down Expand Up @@ -41,9 +39,9 @@

def test_dictionaries_exist():
"""Test consistency of dictionaries."""
doc_fnames = set(op.basename(f[0]) for f in _fnames_in_aspell)

Choose a reason for hiding this comment

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

This change kinda makes it less readable - have to look into the expression to see if it's a dict or set.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I suppose that is a matter of familiarity. Lots of Python projects I've worked on use both set and dict comprehension. Once the syntax is understood and familiar it is readable.

If the project has a policy against this syntax, let me know and I can revert those lines.

Copy link
Collaborator

Choose a reason for hiding this comment

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

The list()/set() part is a duplicate of #2085 and the # -*- coding: utf-8 -*- one is a duplicate of #2100.

Perhaps the list()/set() part is the most debatable. Links to relevant DeepSource.io pages:

  • 7. Not using literal syntax to initialize empty list/dict/tuple

    It is relatively slower to initialize an empty dictionary by calling dict() than using the empty literal, because the name dict must be looked up in the global scope in case it has been rebound. Same goes for the other two types — list() and tuple().

  • Consider using literal syntax to create the data structure — PTC-W0019

    DESCRIPTION

    Using the literal syntax can give minor performance bumps compared to using function calls to create dict, list and tuple.
    [...]
    This is because here, the name dict must be looked up in the global scope in case it has been rebound. Same goes for the other two types list() and tuple().

Copy link
Collaborator

Choose a reason for hiding this comment

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

I would revert these two lines in this merge request. Let's discuss them in #2085.
Thinking about it, list()/set() are easy to understand because they are English words, while the []/{} "syntax needs to be understood". While both are acceptable, []/{} reminds me of the arcane syntax of Perl. It reminds me that years ago, I would struggle to understand my own commented Perl scripts a few months after having written them, because of the syntax.

got_fnames = set(op.basename(f)
for f in glob.glob(op.join(_data_dir, '*.txt')))
doc_fnames = {op.basename(f[0]) for f in _fnames_in_aspell}
got_fnames = {op.basename(f)
for f in glob.glob(op.join(_data_dir, '*.txt'))}
assert doc_fnames == got_fnames


Expand Down