gh-118500: Add pdb support for zipapp (#118501) · python/cpython@4e2caf2 (original) (raw)

`@@ -120,7 +120,10 @@ def find_function(funcname, filename):

`

120

120

`try:

`

121

121

`fp = tokenize.open(filename)

`

122

122

`except OSError:

`

123

``

`-

return None

`

``

123

`+

lines = linecache.getlines(filename)

`

``

124

`+

if not lines:

`

``

125

`+

return None

`

``

126

`+

fp = io.StringIO(''.join(lines))

`

124

127

`funcdef = ""

`

125

128

`funcstart = None

`

126

129

`# consumer of this info expects the first line to be 1

`

`@@ -237,6 +240,44 @@ def namespace(self):

`

237

240

` )

`

238

241

``

239

242

``

``

243

`+

class _ZipTarget(_ExecutableTarget):

`

``

244

`+

def init(self, target):

`

``

245

`+

import runpy

`

``

246

+

``

247

`+

self._target = os.path.realpath(target)

`

``

248

`+

sys.path.insert(0, self._target)

`

``

249

`+

try:

`

``

250

`+

_, self._spec, self._code = runpy._get_main_module_details()

`

``

251

`+

except ImportError as e:

`

``

252

`+

print(f"ImportError: {e}")

`

``

253

`+

sys.exit(1)

`

``

254

`+

except Exception:

`

``

255

`+

traceback.print_exc()

`

``

256

`+

sys.exit(1)

`

``

257

+

``

258

`+

def repr(self):

`

``

259

`+

return self._target

`

``

260

+

``

261

`+

@property

`

``

262

`+

def filename(self):

`

``

263

`+

return self._code.co_filename

`

``

264

+

``

265

`+

@property

`

``

266

`+

def code(self):

`

``

267

`+

return self._code

`

``

268

+

``

269

`+

@property

`

``

270

`+

def namespace(self):

`

``

271

`+

return dict(

`

``

272

`+

name='main',

`

``

273

`+

file=os.path.normcase(os.path.abspath(self.filename)),

`

``

274

`+

package=self._spec.parent,

`

``

275

`+

loader=self._spec.loader,

`

``

276

`+

spec=self._spec,

`

``

277

`+

builtins=builtins,

`

``

278

`+

)

`

``

279

+

``

280

+

240

281

`class _PdbInteractiveConsole(code.InteractiveConsole):

`

241

282

`def init(self, ns, message):

`

242

283

`self._message = message

`

`@@ -1076,7 +1117,7 @@ def lineinfo(self, identifier):

`

1076

1117

`if f:

`

1077

1118

`fname = f

`

1078

1119

`item = parts[1]

`

1079

``

`-

answer = find_function(item, fname)

`

``

1120

`+

answer = find_function(item, self.canonic(fname))

`

1080

1121

`return answer or failed

`

1081

1122

``

1082

1123

`def checkline(self, filename, lineno):

`

`@@ -2282,7 +2323,10 @@ def main():

`

2282

2323

`if not opts.args:

`

2283

2324

`parser.error("no module or script to run")

`

2284

2325

`file = opts.args.pop(0)

`

2285

``

`-

target = _ScriptTarget(file)

`

``

2326

`+

if file.endswith('.pyz'):

`

``

2327

`+

target = _ZipTarget(file)

`

``

2328

`+

else:

`

``

2329

`+

target = _ScriptTarget(file)

`

2286

2330

``

2287

2331

`sys.argv[:] = [file] + opts.args # Hide "pdb.py" and pdb options from argument list

`

2288

2332

``