• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

PyMassSpec / notebook2script / 14915518696

08 May 2025 08:28PM UTC coverage: 90.698% (-0.3%) from 90.96%
14915518696

push

github

web-flow
Updated files with 'repo_helper'. (#53)

Co-authored-by: repo-helper[bot] <74742576+repo-helper[bot]@users.noreply.github.com>

156 of 172 relevant lines covered (90.7%)

0.91 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

96.72
/notebook2script/pointless.py
1
#!/usr/bin/env python3
2
#
3
#  pointless.py
4
"""
5
Ensure pointless statements in scripts are converted
6
into print function calls
7
"""  # noqa: D400
8
#
9
#    Copyright (C) 2020 Dominic Davis-Foster
10
#
11
#    Based on pylint
12
#    Copyright (c) 2006-2016 LOGILAB S.A. (Paris, FRANCE) <contact@logilab.fr>
13
#    Copyright (c) 2008 Fabrice Douchant <Fabrice.Douchant@logilab.fr>
14
#    Copyright (c) 2009 Mads Kiilerich <mads@kiilerich.com>
15
#    Copyright (c) 2009 Vincent
16
#    Copyright (c) 2010 Daniel Harding <dharding@gmail.com>
17
#    Copyright (c) 2010 Julien Jehannet <julien.jehannet@logilab.fr>
18
#    Copyright (c) 2011-2014 Google, Inc.
19
#    Copyright (c) 2012 David Pursehouse <david.pursehouse@sonymobile.com>
20
#    Copyright (c) 2012 FELD Boris <lothiraldan@gmail.com>
21
#    Copyright (c) 2012 JT Olds <jtolds@xnet5.com>
22
#    Copyright (c) 2012 Kevin Jing Qiu <kevin.jing.qiu@gmail.com>
23
#    Copyright (c) 2012-2014 Google, Inc.
24
#    Copyright (c) 2013 buck@yelp.com <buck@yelp.com>
25
#    Copyright (c) 2013-2020 Claudiu Popa <pcmanticore@gmail.com>
26
#    Copyright (c) 2014 Alexandru Coman <fcoman@bitdefender.com>
27
#    Copyright (c) 2014 Arun Persaud <arun@nubati.net>
28
#    Copyright (c) 2014 Brett Cannon <brett@python.org>
29
#    Copyright (c) 2014 Dan Goldsmith <djgoldsmith@googlemail.com>
30
#    Copyright (c) 2014 Daniel Harding <dharding@living180.net>
31
#    Copyright (c) 2014 Ricardo Gemignani <ricardo.gemignani@gmail.com>
32
#    Copyright (c) 2014, 2016-2020 Claudiu Popa <pcmanticore@gmail.com>
33
#    Copyright (c) 2014-2015 Michal Nowikowski <godfryd@gmail.com>
34
#    Copyright (c) 2014-2020 Claudiu Popa <pcmanticore@gmail.com>
35
#    Copyright (c) 2015 Aru Sahni <arusahni@gmail.com>
36
#    Copyright (c) 2015 Cosmin Poieana <cmin@ropython.org>
37
#    Copyright (c) 2015 Dmitry Pribysh <dmand@yandex.ru>
38
#    Copyright (c) 2015 Florian Bruhin <me@the-compiler.org>
39
#    Copyright (c) 2015 Ionel Cristian Maries <contact@ionelmc.ro>
40
#    Copyright (c) 2015 Michael Kefeder <oss@multiwave.ch>
41
#    Copyright (c) 2015 Mihai Balint <balint.mihai@gmail.com>
42
#    Copyright (c) 2015 Nick Bastin <nick.bastin@gmail.com>
43
#    Copyright (c) 2015 Radu Ciorba <radu@devrandom.ro>
44
#    Copyright (c) 2015 Simu Toni <simutoni@gmail.com>
45
#    Copyright (c) 2015 Stephane Wirtel <stephane@wirtel.be>
46
#    Copyright (c) 2015 Steven Myint <hg@stevenmyint.com>
47
#    Copyright (c) 2015-2016 Florian Bruhin <me@the-compiler.org>
48
#    Copyright (c) 2016 Alan Evangelista <alanoe@linux.vnet.ibm.com>
49
#    Copyright (c) 2016 Alex Jurkiewicz <alex@jurkiewi.cz>
50
#    Copyright (c) 2016 Elias Dorneles <eliasdorneles@gmail.com>
51
#    Copyright (c) 2016 Florian Bruhin <git@the-compiler.org>
52
#    Copyright (c) 2016 Glenn Matthews <glenn@e-dad.net>
53
#    Copyright (c) 2016 Jakub Wilk <jwilk@jwilk.net>
54
#    Copyright (c) 2016 Moises Lopez <moylop260@vauxoo.com>
55
#    Copyright (c) 2016 Yannack <yannack@users.noreply.github.com>
56
#    Copyright (c) 2016, 2018 Jakub Wilk <jwilk@jwilk.net>
57
#    Copyright (c) 2016, 2019 Ashley Whetter <ashley@awhetter.co.uk>
58
#    Copyright (c) 2016-2017 Łukasz Rogalski <rogalski.91@gmail.com>
59
#    Copyright (c) 2017 Daniel Miller <millerdev@gmail.com>
60
#    Copyright (c) 2017 danields <danields761@gmail.com>
61
#    Copyright (c) 2017 Jacques Kvam <jwkvam@gmail.com>
62
#    Copyright (c) 2017 Ned Batchelder <ned@nedbatchelder.com>
63
#    Copyright (c) 2017 Pierre Sassoulas <pierre.sassoulas@cea.fr>
64
#    Copyright (c) 2017 Roman Ivanov <me@roivanov.com>
65
#    Copyright (c) 2017 ttenhoeve-aa <ttenhoeve@appannie.com>
66
#    Copyright (c) 2017, 2019 hippo91 <guillaume.peillex@gmail.com>
67
#    Copyright (c) 2017-2018 Bryce Guinta <bryce.paul.guinta@gmail.com>
68
#    Copyright (c) 2017-2018 Hugo <hugovk@users.noreply.github.com>
69
#    Copyright (c) 2017-2018 Ville Skyttä <ville.skytta@iki.fi>
70
#    Copyright (c) 2017-2019 hippo91 <guillaume.peillex@gmail.com>
71
#    Copyright (c) 2018 Chris Lamb <chris@chris-lamb.co.uk>
72
#    Copyright (c) 2018 Gary Tyler McLeod <mail@garytyler.com>
73
#    Copyright (c) 2018 glmdgrielson <32415403+glmdgrielson@users.noreply.github.com>
74
#    Copyright (c) 2018 Jason Owen <jason.a.owen@gmail.com>
75
#    Copyright (c) 2018 kapsh <kapsh@kap.sh>
76
#    Copyright (c) 2018 Lucas Cimon <lucas.cimon@gmail.com>
77
#    Copyright (c) 2018 Matus Valo <matusvalo@users.noreply.github.com>
78
#    Copyright (c) 2018 Mike Frysinger <vapier@gmail.com>
79
#    Copyright (c) 2018 Natalie Serebryakova <natalie.serebryakova@Natalies-MacBook-Pro.local>
80
#    Copyright (c) 2018 Nick Drozd <nicholasdrozd@gmail.com>
81
#    Copyright (c) 2018 Randall Leeds <randall@bleeds.info>
82
#    Copyright (c) 2018 Sergei Lebedev <185856+superbobry@users.noreply.github.com>
83
#    Copyright (c) 2018 SergeyKosarchuk <sergeykosarchuk@gmail.com>
84
#    Copyright (c) 2018 ssolanki <sushobhitsolanki@gmail.com>
85
#    Copyright (c) 2018 Steven M. Vascellaro <svascellaro@gmail.com>
86
#    Copyright (c) 2018 Sushobhit <31987769+sushobhit27@users.noreply.github.com>
87
#    Copyright (c) 2018 Yuval Langer <yuvallanger@mail.tau.ac.il>
88
#    Copyright (c) 2018, 2020 Anthony Sottile <asottile@umich.edu>
89
#    Copyright (c) 2018-2019 Ashley Whetter <ashley@awhetter.co.uk>
90
#    Copyright (c) 2018-2019 Nick Drozd <nicholasdrozd@gmail.com>
91
#    Copyright (c) 2018-2019 Ville Skyttä <ville.skytta@iki.fi>
92
#    Copyright (c) 2018-2020 Pierre Sassoulas <pierre.sassoulas@gmail.com>
93
#    Copyright (c) 2019 Andres Perez Hortal <andresperezcba@gmail.com>
94
#    Copyright (c) 2019 Ashley Whetter <ashley@awhetter.co.uk>
95
#    Copyright (c) 2019 Bruno P. Kinoshita <kinow@users.noreply.github.com>
96
#    Copyright (c) 2019 Dan Hemberger <846186+hemberger@users.noreply.github.com>
97
#    Copyright (c) 2019 Daniel Draper <Germandrummer92@users.noreply.github.com>
98
#    Copyright (c) 2019 Fantix King <fantix@uchicago.edu>
99
#    Copyright (c) 2019 Hugo van Kemenade <hugovk@users.noreply.github.com>
100
#    Copyright (c) 2019 Hugues <hugues.bruant@affirm.com>
101
#    Copyright (c) 2019 jab <jab@users.noreply.github.com>
102
#    Copyright (c) 2019 Janne Rönkkö <jannero@users.noreply.github.com>
103
#    Copyright (c) 2019 Nicolas Dickreuter <dickreuter@gmail.com>
104
#    Copyright (c) 2019 Nikita Sobolev <mail@sobolevn.me>
105
#    Copyright (c) 2019 Niko Wenselowski <niko@nerdno.de>
106
#    Copyright (c) 2019 Oisín Moran <OisinMoran@users.noreply.github.com>
107
#    Copyright (c) 2019 Peter Kolbus <peter.kolbus@gmail.com>
108
#    Copyright (c) 2019 Pierre Sassoulas <pierre.sassoulas@gmail.com>
109
#    Copyright (c) 2019 Robert Schweizer <robert_schweizer@gmx.de>
110
#    Copyright (c) 2019 syutbai <syutbai@gmail.com>
111
#    Copyright (c) 2019 Thomas Hisch <t.hisch@gmail.com>
112
#    Copyright (c) 2019 Trevor Bekolay <tbekolay@gmail.com>
113
#    Copyright (c) 2019 Ville Skyttä <ville.skytta@iki.fi>
114
#    Copyright (c) 2020 Anthony Sottile <asottile@umich.edu>
115
#    Copyright (c) 2020 anubh-v <anubhav@u.nus.edu>
116
#    Copyright (c) 2020 Anubhav <35621759+anubh-v@users.noreply.github.com>
117
#    Copyright (c) 2020 Benny <benny.mueller91@gmail.com>
118
#    Copyright (c) 2020 bernie gray <bfgray3@users.noreply.github.com>
119
#    Copyright (c) 2020 Gabriel R Sezefredo <g@briel.dev>
120
#    Copyright (c) 2020 Pierre Sassoulas <pierre.sassoulas@gmail.com>
121
#
122
#    See https://github.com/PyCQA/pylint/blob/master/COPYING for more details.
123
#
124
#    This program is free software; you can redistribute it and/or modify
125
#    it under the terms of the GNU General Public License version 2 as
126
#    published by the Free Software Foundation.
127
#
128
#    This program is distributed in the hope that it will be useful,
129
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
130
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
131
#    GNU General Public License for more details.
132
#
133
#    You should have received a copy of the GNU General Public License
134
#    along with this program; if not, write to the Free Software
135
#    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
136
#
137

138
# TODO: not all statements that need to be made into prints are being picked up.
139
#  Include a list of those and convert manually
140

141
# stdlib
142
import contextlib
1✔
143
import sys
1✔
144
import warnings
1✔
145
from typing import Any, Iterable, Iterator, List, Optional
1✔
146

147
# 3rd party
148
from astroid import Expr  # type: ignore[import-untyped]
1✔
149
from domdf_python_tools.paths import PathPlus
1✔
150
from pylint import reporters  # type: ignore[import-untyped]
1✔
151
from pylint.lint.pylinter import PyLinter  # type: ignore[import-untyped]
1✔
152
from pylint.utils import utils  # type: ignore[import-untyped]
1✔
153

154
# this package
155
from notebook2script import pointless_checker
1✔
156

157
__all__ = ["Pointless", "fix_import_path"]
1✔
158

159

160
class Pointless(PyLinter):
1✔
161
        """
162
        Checker for pointless statements.
163
        """
164

165
        def __init__(self):
1✔
166
                super().__init__()
1✔
167
                self.load_default_plugins()
1✔
168
                self.enable("pointless-statement")
1✔
169
                self.initialize()
1✔
170
                self.statements = []
1✔
171

172
        def load_default_plugins(self) -> None:  # noqa: D102
1✔
173
                pointless_checker.initialize(self)
1✔
174
                reporters.initialize(self)
1✔
175
                # Make sure to load the default reporter, because
176
                # the option has been set before the plugins had been loaded.
177
                if not self.reporter:
1✔
178
                        self._load_reporter()
1✔
179

180
        def process_file(self, filename: str) -> None:  # noqa: D102
1✔
181
                self.statements = []
1✔
182

183
                with fix_import_path([filename]):
1✔
184
                        self._check_files(self.get_ast, self._iterate_file_descrs([filename]))
1✔
185

186
                path = PathPlus(filename)
1✔
187
                file_lines = path.read_lines()
1✔
188

189
                for node in self.statements:
1✔
190

191
                        if node.tolineno != node.lineno:
1✔
192
                                warnings.warn("Currently unable to convert this statement")
×
193

194
                        else:
195
                                value = node.value.as_string()
1✔
196
                                col = node.col_offset
1✔
197
                                lineno = node.lineno - 1
1✔
198

199
                                line = file_lines[lineno]
1✔
200
                                line_pre_statement = line[:col]
1✔
201
                                line_post_statement = line[col + len(value):]
1✔
202
                                # print(f"{line_pre_statement}print({value}){line_post_statement}")
203
                                file_lines[lineno] = f"{line_pre_statement}print({value}){line_post_statement}"
1✔
204

205
                if file_lines[-1]:
1✔
206
                        # ensure there's a newline at the end
207
                        file_lines.append('')
×
208

209
                # print("\n".join(file_lines))
210
                path.write_lines(file_lines)
1✔
211

212
        def add_message(
1✔
213
                        self,
214
                        msgid: Any,
215
                        line: Optional[Any] = None,
216
                        node: Optional[Expr] = None,
217
                        *args,
218
                        **kwargs,
219
                        ) -> None:
220
                """Adds a message given by ID or name.
221

222
                If provided, the message string is expanded using args.
223

224
                AST checkers must provide the node argument (but may optionally
225
                provide line if the line number is different), raw and token checkers
226
                must provide the line argument.
227
                """
228

229
                self.statements.append(node)
1✔
230
                # super().add_message(msgid, line, node, args, confidence, col_offset)
231

232

233
def _patch_sys_path(args: Iterable[str]) -> List[str]:
1✔
234
        original = list(sys.path)
1✔
235
        changes = []
1✔
236
        seen = set()
1✔
237
        for arg in args:
1✔
238
                path = utils.get_python_path(arg)
1✔
239
                if path not in seen:
1✔
240
                        changes.append(path)
1✔
241
                        seen.add(path)
1✔
242

243
        sys.path[:] = changes + sys.path
1✔
244
        return original
1✔
245

246

247
@contextlib.contextmanager
1✔
248
def fix_import_path(args: Iterable[str]) -> Iterator[None]:
1✔
249
        """
250
        Prepare sys.path for running the linter checks.
251

252
        Within this context, each of the given arguments is importable.
253
        Paths are added to sys.path in corresponding order to the arguments.
254
        We avoid adding duplicate directories to sys.path.
255
        `sys.path` is reset to its original value upon exiting this context.
256
        """
257

258
        original = _patch_sys_path(args)
1✔
259
        try:
1✔
260
                yield
1✔
261
        finally:
262
                sys.path[:] = original
1✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc