mirror of
https://github.com/kuhyx/WUT_Computer_Science.git
synced 2026-07-04 20:23:04 +02:00
Run autopep8 on code
This commit is contained in:
parent
7435a26030
commit
6c55a51756
195
main.py
195
main.py
@ -21,30 +21,33 @@ Does not work if no Start (Should print out NO START FOUND)
|
||||
Does not work if no End (Should print out NO END FOUND)
|
||||
Does not work if no path (Should print out NO PATH FOUND)
|
||||
"""
|
||||
|
||||
|
||||
|
||||
|
||||
import heapq
|
||||
|
||||
|
||||
class MazeSolver:
|
||||
|
||||
# self corresponds to "this" in js, it refers to object of MazeSolver class
|
||||
def __init__(self, maze):
|
||||
# assign readed maze 2D array to parameter from class MazeSolver
|
||||
self.maze = maze
|
||||
self.start, self.end = self.find_start_and_end()
|
||||
# self corresponds to "this" in js, it refers to object of MazeSolver class
|
||||
def __init__(self, maze):
|
||||
# assign readed maze 2D array to parameter from class MazeSolver
|
||||
self.maze = maze
|
||||
self.start, self.end = self.find_start_and_end()
|
||||
|
||||
# go through each character in 2D array and find one that corresponds to Start/End character
|
||||
# go through each character in 2D array and find one that corresponds to
|
||||
# Start/End character
|
||||
|
||||
def find_start_and_end(self):
|
||||
start = end = None
|
||||
for row in range(len(self.maze)):
|
||||
for col in range(len(self.maze[row])):
|
||||
if self.maze[row][col] == 'S':
|
||||
start = (row, col)
|
||||
elif self.maze[row][col] == 'E':
|
||||
end = (row, col)
|
||||
if start != None and end != None:
|
||||
return start, end
|
||||
print(f"DID NOT FOUND START OR END, Start: {start}, End: {end}")
|
||||
def find_start_and_end(self):
|
||||
start = end = None
|
||||
for row in range(len(self.maze)):
|
||||
for col in range(len(self.maze[row])):
|
||||
if self.maze[row][col] == 'S':
|
||||
start = (row, col)
|
||||
elif self.maze[row][col] == 'E':
|
||||
end = (row, col)
|
||||
if start is not None and end is not None:
|
||||
return start, end
|
||||
print(f"DID NOT FOUND START OR END, Start: {start}, End: {end}")
|
||||
|
||||
# Go through each neighboor
|
||||
# N
|
||||
@ -52,94 +55,102 @@ class MazeSolver:
|
||||
# N
|
||||
# If it is not a "wall" (#) add its position to list of neighbors
|
||||
|
||||
def get_neighbors(self, position):
|
||||
row, col = position
|
||||
neighbors = []
|
||||
if row > 0 and self.maze[row - 1][col] != '#':
|
||||
neighbors.append((row - 1, col))
|
||||
if col > 0 and self.maze[row][col - 1] != '#':
|
||||
neighbors.append((row, col - 1))
|
||||
if row < len(self.maze) - 1 and self.maze[row + 1][col] != '#':
|
||||
neighbors.append((row + 1, col))
|
||||
if col < len(self.maze[row]) - 1 and self.maze[row][col + 1] != '#':
|
||||
neighbors.append((row, col + 1))
|
||||
return neighbors
|
||||
def get_neighbors(self, position):
|
||||
row, col = position
|
||||
neighbors = []
|
||||
if row > 0 and self.maze[row - 1][col] != '#':
|
||||
neighbors.append((row - 1, col))
|
||||
if col > 0 and self.maze[row][col - 1] != '#':
|
||||
neighbors.append((row, col - 1))
|
||||
if row < len(self.maze) - 1 and self.maze[row + 1][col] != '#':
|
||||
neighbors.append((row + 1, col))
|
||||
if col < len(self.maze[row]) - 1 and self.maze[row][col + 1] != '#':
|
||||
neighbors.append((row, col + 1))
|
||||
return neighbors
|
||||
|
||||
# find path through maze
|
||||
|
||||
def solve(self):
|
||||
queue = []
|
||||
# set means that values inside can not repeat
|
||||
visited = set()
|
||||
# https://docs.python.org/3/library/heapq.html
|
||||
# push onto the queue (which becomes heapq), element containinig values
|
||||
# we use heapq so the element with lowest heurisitc value will always be at the top of heap
|
||||
heapq.heappush(
|
||||
queue, (self.heuristicEuclidean(self.start), self.start, [self.start]))
|
||||
def solve(self):
|
||||
queue = []
|
||||
# set means that values inside can not repeat
|
||||
visited = set()
|
||||
# https://docs.python.org/3/library/heapq.html
|
||||
# push onto the queue (which becomes heapq), element containinig values
|
||||
# we use heapq so the element with lowest heurisitc value will always
|
||||
# be at the top of heap
|
||||
heapq.heappush(
|
||||
queue, (self.heuristicEuclidean(
|
||||
self.start), self.start, [
|
||||
self.start]))
|
||||
|
||||
# go through queue until it's empty
|
||||
# find neighbour (which is not wall) closests to END point (based on heuristic)
|
||||
# go there and repeat
|
||||
# if cannot find path it starts over but skips the path that lead it to dead end
|
||||
while queue:
|
||||
# pop first element of heap
|
||||
# first value is skipped and we only save current position and path on heap
|
||||
_, current, path = heapq.heappop(queue)
|
||||
# if we already visited current skip code and go to next iteration
|
||||
if current in visited:
|
||||
continue
|
||||
# go through queue until it's empty
|
||||
# find neighbour (which is not wall) closests to END point (based on heuristic)
|
||||
# go there and repeat
|
||||
# if cannot find path it starts over but skips the path that lead it to
|
||||
# dead end
|
||||
while queue:
|
||||
# pop first element of heap
|
||||
# first value is skipped and we only save current position and path
|
||||
# on heap
|
||||
_, current, path = heapq.heappop(queue)
|
||||
# if we already visited current skip code and go to next iteration
|
||||
if current in visited:
|
||||
continue
|
||||
# if we found the end return path
|
||||
if current == self.end:
|
||||
return path
|
||||
visited.add(current)
|
||||
for neighbor in self.get_neighbors(current):
|
||||
if neighbor not in visited:
|
||||
new_path = path + [neighbor]
|
||||
heapq.heappush(queue,
|
||||
(self.heuristicEuclidean(neighbor), neighbor, new_path))
|
||||
print_maze(self.maze, new_path)
|
||||
print()
|
||||
if current == self.end:
|
||||
return path
|
||||
visited.add(current)
|
||||
for neighbor in self.get_neighbors(current):
|
||||
if neighbor not in visited:
|
||||
new_path = path + [neighbor]
|
||||
heapq.heappush(
|
||||
queue, (self.heuristicEuclidean(neighbor), neighbor, new_path))
|
||||
print_maze(self.maze, new_path)
|
||||
print()
|
||||
|
||||
# This heuristic returns the Manhatan distance between the given position and the maze's end
|
||||
def heuristicManhatan(self, position):
|
||||
return abs(position[0] - self.end[0]) + abs(position[1] - self.end[1])
|
||||
# This heuristic returns the Manhatan distance between the given position
|
||||
# and the maze's end
|
||||
def heuristicManhatan(self, position):
|
||||
return abs(position[0] - self.end[0]) + abs(position[1] - self.end[1])
|
||||
|
||||
# This heuristic returns the Euclidean distance between the given position and the maze's end
|
||||
def heuristicEuclidean(self, position):
|
||||
return (abs(position[0] - self.end[0])**2 +
|
||||
abs(position[1] - self.end[1])**2)**0.5
|
||||
# This heuristic returns the Euclidean distance between the given position
|
||||
# and the maze's end
|
||||
def heuristicEuclidean(self, position):
|
||||
return (abs(position[0] - self.end[0])**2 +
|
||||
abs(position[1] - self.end[1])**2)**0.5
|
||||
|
||||
|
||||
# Open and load text file to array
|
||||
def load_maze(filename):
|
||||
# Open for reading only and save to fileContents
|
||||
fileContents = open(filename, 'r')
|
||||
# strip() removes extra white spaces from the beginning and the end of a string
|
||||
# list() changes string to array of chars
|
||||
# Inside of square brackets we will have an array of characters for each line of file
|
||||
# after going through every line in a file we will have 2D array of arrays of characters of every line
|
||||
maze = [list(line.strip()) for line in fileContents]
|
||||
return maze
|
||||
# Open for reading only and save to fileContents
|
||||
fileContents = open(filename, 'r')
|
||||
# strip() removes extra white spaces from the beginning and the end of a string
|
||||
# list() changes string to array of chars
|
||||
# Inside of square brackets we will have an array of characters for each line of file
|
||||
# after going through every line in a file we will have 2D array of arrays
|
||||
# of characters of every line
|
||||
maze = [list(line.strip()) for line in fileContents]
|
||||
return maze
|
||||
|
||||
|
||||
def print_maze(maze, path=None):
|
||||
if path is None:
|
||||
path = []
|
||||
for row in range(len(maze)):
|
||||
for col in range(len(maze[row])):
|
||||
if (row, col) in path:
|
||||
print('*', end='')
|
||||
else:
|
||||
print(maze[row][col], end='')
|
||||
print()
|
||||
if path is None:
|
||||
path = []
|
||||
for row in range(len(maze)):
|
||||
for col in range(len(maze[row])):
|
||||
if (row, col) in path:
|
||||
print('*', end='')
|
||||
else:
|
||||
print(maze[row][col], end='')
|
||||
print()
|
||||
|
||||
|
||||
# Ran first in the code
|
||||
if __name__ == '__main__':
|
||||
# Open and load text file to array
|
||||
maze = load_maze('mazes/mazeDeadEnd.txt')
|
||||
# Initialize MazeSolver object with maze as paramater
|
||||
solver = MazeSolver(maze)
|
||||
# Find path using MazeSolver solve method
|
||||
path = solver.solve()
|
||||
print_maze(maze, path)
|
||||
# Open and load text file to array
|
||||
maze = load_maze('mazes/mazeDeadEnd.txt')
|
||||
# Initialize MazeSolver object with maze as paramater
|
||||
solver = MazeSolver(maze)
|
||||
# Find path using MazeSolver solve method
|
||||
path = solver.solve()
|
||||
print_maze(maze, path)
|
||||
|
||||
8
venv/bin/autopep8
Executable file
8
venv/bin/autopep8
Executable file
@ -0,0 +1,8 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
import re
|
||||
import sys
|
||||
from autopep8 import main
|
||||
if __name__ == '__main__':
|
||||
sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0])
|
||||
sys.exit(main())
|
||||
8
venv/bin/epylint
Executable file
8
venv/bin/epylint
Executable file
@ -0,0 +1,8 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
import re
|
||||
import sys
|
||||
from pylint import run_epylint
|
||||
if __name__ == '__main__':
|
||||
sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0])
|
||||
sys.exit(run_epylint())
|
||||
1
venv/bin/get_objgraph
Symbolic link
1
venv/bin/get_objgraph
Symbolic link
@ -0,0 +1 @@
|
||||
/home/runner/.cache/pip/pool/6a/50/3f/1f2a45ac215d6ff2ad0866b0c04c341528fa5265298b72142c813ce4da
|
||||
8
venv/bin/isort
Executable file
8
venv/bin/isort
Executable file
@ -0,0 +1,8 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
import re
|
||||
import sys
|
||||
from isort.main import main
|
||||
if __name__ == '__main__':
|
||||
sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0])
|
||||
sys.exit(main())
|
||||
8
venv/bin/isort-identify-imports
Executable file
8
venv/bin/isort-identify-imports
Executable file
@ -0,0 +1,8 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
import re
|
||||
import sys
|
||||
from isort.main import identify_imports_main
|
||||
if __name__ == '__main__':
|
||||
sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0])
|
||||
sys.exit(identify_imports_main())
|
||||
8
venv/bin/pycodestyle
Executable file
8
venv/bin/pycodestyle
Executable file
@ -0,0 +1,8 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
import re
|
||||
import sys
|
||||
from pycodestyle import _main
|
||||
if __name__ == '__main__':
|
||||
sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0])
|
||||
sys.exit(_main())
|
||||
8
venv/bin/pylint
Executable file
8
venv/bin/pylint
Executable file
@ -0,0 +1,8 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
import re
|
||||
import sys
|
||||
from pylint import run_pylint
|
||||
if __name__ == '__main__':
|
||||
sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0])
|
||||
sys.exit(run_pylint())
|
||||
8
venv/bin/pylint-config
Executable file
8
venv/bin/pylint-config
Executable file
@ -0,0 +1,8 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
import re
|
||||
import sys
|
||||
from pylint import _run_pylint_config
|
||||
if __name__ == '__main__':
|
||||
sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0])
|
||||
sys.exit(_run_pylint_config())
|
||||
8
venv/bin/pyreverse
Executable file
8
venv/bin/pyreverse
Executable file
@ -0,0 +1,8 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
import re
|
||||
import sys
|
||||
from pylint import run_pyreverse
|
||||
if __name__ == '__main__':
|
||||
sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0])
|
||||
sys.exit(run_pyreverse())
|
||||
8
venv/bin/symilar
Executable file
8
venv/bin/symilar
Executable file
@ -0,0 +1,8 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
import re
|
||||
import sys
|
||||
from pylint import run_symilar
|
||||
if __name__ == '__main__':
|
||||
sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0])
|
||||
sys.exit(run_symilar())
|
||||
1
venv/bin/undill
Symbolic link
1
venv/bin/undill
Symbolic link
@ -0,0 +1 @@
|
||||
/home/runner/.cache/pip/pool/e2/49/4a/6f73df3fa16a5661da7e3c9b169500e2697bc26be21656ce72fcca59af
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -0,0 +1,199 @@
|
||||
# This file is autocompleted by 'contributors-txt',
|
||||
# using the configuration in 'script/.contributors_aliases.json'.
|
||||
# Do not add new persons manually and only add information without
|
||||
# using '-' as the line first character.
|
||||
# Please verify that your change are stable if you modify manually.
|
||||
|
||||
Ex-maintainers
|
||||
--------------
|
||||
- Claudiu Popa <pcmanticore@gmail.com>
|
||||
- Sylvain Thénault <thenault@gmail.com>
|
||||
- Torsten Marek <shlomme@gmail.com>
|
||||
|
||||
|
||||
Maintainers
|
||||
-----------
|
||||
- Pierre Sassoulas <pierre.sassoulas@gmail.com>
|
||||
- Daniël van Noord <13665637+DanielNoord@users.noreply.github.com>
|
||||
- Hippo91 <guillaume.peillex@gmail.com>
|
||||
- Marc Mueller <30130371+cdce8p@users.noreply.github.com>
|
||||
- Jacob Walls <jacobtylerwalls@gmail.com>
|
||||
- Bryce Guinta <bryce.paul.guinta@gmail.com>
|
||||
- Ceridwen <ceridwenv@gmail.com>
|
||||
- Mark Byrne <31762852+mbyrnepr2@users.noreply.github.com>
|
||||
- Łukasz Rogalski <rogalski.91@gmail.com>
|
||||
- Florian Bruhin <me@the-compiler.org>
|
||||
- Ashley Whetter <ashley@awhetter.co.uk>
|
||||
- Dimitri Prybysh <dmand@yandex.ru>
|
||||
- Areveny <areveny@protonmail.com>
|
||||
|
||||
|
||||
Contributors
|
||||
------------
|
||||
- Emile Anclin <emile.anclin@logilab.fr>
|
||||
- Nick Drozd <nicholasdrozd@gmail.com>
|
||||
- Andrew Haigh <hello@nelf.in>
|
||||
- Julien Cristau <julien.cristau@logilab.fr>
|
||||
- David Liu <david@cs.toronto.edu>
|
||||
- Alexandre Fayolle <alexandre.fayolle@logilab.fr>
|
||||
- Eevee (Alex Munroe) <amunroe@yelp.com>
|
||||
- David Gilman <davidgilman1@gmail.com>
|
||||
- Julien Jehannet <julien.jehannet@logilab.fr>
|
||||
- Calen Pennington <calen.pennington@gmail.com>
|
||||
- Tushar Sadhwani <86737547+tushar-deepsource@users.noreply.github.com>
|
||||
- Hugo van Kemenade <hugovk@users.noreply.github.com>
|
||||
- Tim Martin <tim@asymptotic.co.uk>
|
||||
- Phil Schaf <flying-sheep@web.de>
|
||||
- Alex Hall <alex.mojaki@gmail.com>
|
||||
- Raphael Gaschignard <raphael@makeleaps.com>
|
||||
- Radosław Ganczarek <radoslaw@ganczarek.in>
|
||||
- Paligot Gérard <androwiiid@gmail.com>
|
||||
- Ioana Tagirta <ioana.tagirta@gmail.com>
|
||||
- Derek Gustafson <degustaf@gmail.com>
|
||||
- David Shea <dshea@redhat.com>
|
||||
- Daniel Harding <dharding@gmail.com>
|
||||
- Christian Clauss <cclauss@me.com>
|
||||
- Ville Skyttä <ville.skytta@iki.fi>
|
||||
- Rene Zhang <rz99@cornell.edu>
|
||||
- Philip Lorenz <philip@bithub.de>
|
||||
- Nicolas Chauvat <nicolas.chauvat@logilab.fr>
|
||||
- Michael K <michael-k@users.noreply.github.com>
|
||||
- Mario Corchero <mariocj89@gmail.com>
|
||||
- Marien Zwart <marienz@gentoo.org>
|
||||
- Laura Médioni <laura.medioni@logilab.fr>
|
||||
- James Addison <55152140+jayaddison@users.noreply.github.com>
|
||||
- FELD Boris <lothiraldan@gmail.com>
|
||||
- Enji Cooper <yaneurabeya@gmail.com>
|
||||
- Dani Alcala <112832187+clavedeluna@users.noreply.github.com>
|
||||
- Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
|
||||
- tristanlatr <19967168+tristanlatr@users.noreply.github.com>
|
||||
- emile@crater.logilab.fr <emile@crater.logilab.fr>
|
||||
- doranid <ddandd@gmail.com>
|
||||
- brendanator <brendan.maginnis@gmail.com>
|
||||
- Tomas Gavenciak <gavento@ucw.cz>
|
||||
- Tim Paine <t.paine154@gmail.com>
|
||||
- Thomas Hisch <t.hisch@gmail.com>
|
||||
- Stefan Scherfke <stefan@sofa-rockers.org>
|
||||
- Sergei Lebedev <185856+superbobry@users.noreply.github.com>
|
||||
- Saugat Pachhai (सौगात) <suagatchhetri@outlook.com>
|
||||
- Ram Rachum <ram@rachum.com>
|
||||
- Pierre-Yves David <pierre-yves.david@logilab.fr>
|
||||
- Peter Pentchev <roam@ringlet.net>
|
||||
- Peter Kolbus <peter.kolbus@gmail.com>
|
||||
- Omer Katz <omer.drow@gmail.com>
|
||||
- Moises Lopez <moylop260@vauxoo.com>
|
||||
- Michal Vasilek <michal@vasilek.cz>
|
||||
- Keichi Takahashi <keichi.t@me.com>
|
||||
- Kavins Singh <kavinsingh@hotmail.com>
|
||||
- Karthikeyan Singaravelan <tir.karthi@gmail.com>
|
||||
- Joshua Cannon <joshdcannon@gmail.com>
|
||||
- John Vandenberg <jayvdb@gmail.com>
|
||||
- Jacob Bogdanov <jacob@bogdanov.dev>
|
||||
- Google, Inc. <no-reply@google.com>
|
||||
- David Euresti <github@euresti.com>
|
||||
- David Douard <david.douard@logilab.fr>
|
||||
- David Cain <davidjosephcain@gmail.com>
|
||||
- Anthony Truchet <anthony.truchet@logilab.fr>
|
||||
- Anthony Sottile <asottile@umich.edu>
|
||||
- Alexander Shadchin <alexandr.shadchin@gmail.com>
|
||||
- wgehalo <wgehalo@gmail.com>
|
||||
- rr- <rr-@sakuya.pl>
|
||||
- raylu <lurayl@gmail.com>
|
||||
- plucury <plucury@gmail.com>
|
||||
- ostr00000 <ostr00000@gmail.com>
|
||||
- noah-weingarden <33741795+noah-weingarden@users.noreply.github.com>
|
||||
- nathannaveen <42319948+nathannaveen@users.noreply.github.com>
|
||||
- mathieui <mathieui@users.noreply.github.com>
|
||||
- markmcclain <markmcclain@users.noreply.github.com>
|
||||
- ioanatia <ioanatia@users.noreply.github.com>
|
||||
- grayjk <grayjk@gmail.com>
|
||||
- adam-grant-hendry <59346180+adam-grant-hendry@users.noreply.github.com>
|
||||
- Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
|
||||
- Zac Hatfield-Dodds <Zac-HD@users.noreply.github.com>
|
||||
- Vilnis Termanis <vilnis.termanis@iotics.com>
|
||||
- Valentin Valls <valentin.valls@esrf.fr>
|
||||
- Uilian Ries <uilianries@gmail.com>
|
||||
- Tomas Novak <ext.Tomas.Novak@skoda-auto.cz>
|
||||
- Thirumal Venkat <me@thirumal.in>
|
||||
- SupImDos <62866982+SupImDos@users.noreply.github.com>
|
||||
- Stanislav Levin <slev@altlinux.org>
|
||||
- Simon Hewitt <si@sjhewitt.co.uk>
|
||||
- Serhiy Storchaka <storchaka@gmail.com>
|
||||
- Roy Wright <roy@wright.org>
|
||||
- Robin Jarry <robin.jarry@6wind.com>
|
||||
- René Fritze <47802+renefritze@users.noreply.github.com>
|
||||
- Redoubts <Redoubts@users.noreply.github.com>
|
||||
- Philipp Hörist <philipp@hoerist.com>
|
||||
- Peter de Blanc <peter@standard.ai>
|
||||
- Peter Talley <peterctalley@gmail.com>
|
||||
- Ovidiu Sabou <ovidiu@sabou.org>
|
||||
- Nicolas Noirbent <nicolas@noirbent.fr>
|
||||
- Neil Girdhar <mistersheik@gmail.com>
|
||||
- Michał Masłowski <m.maslowski@clearcode.cc>
|
||||
- Mateusz Bysiek <mb@mbdev.pl>
|
||||
- Leandro T. C. Melo <ltcmelo@gmail.com>
|
||||
- Konrad Weihmann <kweihmann@outlook.com>
|
||||
- Kian Meng, Ang <kianmeng.ang@gmail.com>
|
||||
- Kai Mueller <15907922+kasium@users.noreply.github.com>
|
||||
- Jörg Thalheim <Mic92@users.noreply.github.com>
|
||||
- Jonathan Striebel <jstriebel@users.noreply.github.com>
|
||||
- John Belmonte <john@neggie.net>
|
||||
- Jeff Widman <jeff@jeffwidman.com>
|
||||
- Jeff Quast <contact@jeffquast.com>
|
||||
- Jarrad Hope <me@jarradhope.com>
|
||||
- Jared Garst <jgarst@users.noreply.github.com>
|
||||
- Jakub Wilk <jwilk@jwilk.net>
|
||||
- Iva Miholic <ivamiho@gmail.com>
|
||||
- Ionel Maries Cristian <contact@ionelmc.ro>
|
||||
- HoverHell <hoverhell@gmail.com>
|
||||
- HQupgradeHQ <18361586+HQupgradeHQ@users.noreply.github.com>
|
||||
- Grygorii Iermolenko <gyermolenko@gmail.com>
|
||||
- Gregory P. Smith <greg@krypto.org>
|
||||
- Giuseppe Scrivano <gscrivan@redhat.com>
|
||||
- Frédéric Chapoton <fchapoton2@gmail.com>
|
||||
- Francis Charette Migneault <francis.charette.migneault@gmail.com>
|
||||
- Felix Mölder <felix.moelder@uni-due.de>
|
||||
- Federico Bond <federicobond@gmail.com>
|
||||
- DudeNr33 <3929834+DudeNr33@users.noreply.github.com>
|
||||
- Dmitry Shachnev <mitya57@users.noreply.github.com>
|
||||
- Denis Laxalde <denis.laxalde@logilab.fr>
|
||||
- Deepyaman Datta <deepyaman.datta@utexas.edu>
|
||||
- David Poirier <david-poirier-csn@users.noreply.github.com>
|
||||
- Dave Hirschfeld <dave.hirschfeld@gmail.com>
|
||||
- Dave Baum <dbaum@google.com>
|
||||
- Daniel Martin <daniel.martin@crowdstrike.com>
|
||||
- Daniel Colascione <dancol@dancol.org>
|
||||
- Damien Baty <damien@damienbaty.com>
|
||||
- Craig Franklin <craigjfranklin@gmail.com>
|
||||
- Colin Kennedy <colinvfx@gmail.com>
|
||||
- Cole Robinson <crobinso@redhat.com>
|
||||
- Christoph Reiter <reiter.christoph@gmail.com>
|
||||
- Chris Philip <chrisp533@gmail.com>
|
||||
- BioGeek <jeroen.vangoey@gmail.com>
|
||||
- Bianca Power <30207144+biancapower@users.noreply.github.com>
|
||||
- Benjamin Elven <25181435+S3ntinelX@users.noreply.github.com>
|
||||
- Ben Elliston <bje@air.net.au>
|
||||
- Becker Awqatty <bawqatty@mide.com>
|
||||
- Batuhan Taskaya <isidentical@gmail.com>
|
||||
- BasPH <BasPH@users.noreply.github.com>
|
||||
- Azeem Bande-Ali <A.BandeAli@gmail.com>
|
||||
- Avram Lubkin <aviso@rockhopper.net>
|
||||
- Aru Sahni <arusahni@gmail.com>
|
||||
- Artsiom Kaval <lezeroq@gmail.com>
|
||||
- Anubhav <35621759+anubh-v@users.noreply.github.com>
|
||||
- Antoine Boellinger <aboellinger@hotmail.com>
|
||||
- Alphadelta14 <alpha@alphaservcomputing.solutions>
|
||||
- Alexander Scheel <alexander.m.scheel@gmail.com>
|
||||
- Alexander Presnyakov <flagist0@gmail.com>
|
||||
- Ahmed Azzaoui <ahmed.azzaoui@engie.com>
|
||||
|
||||
Co-Author
|
||||
---------
|
||||
The following persons were credited manually but did not commit themselves
|
||||
under this name, or we did not manage to find their commits in the history.
|
||||
|
||||
- François Mockers
|
||||
- platings
|
||||
- carl
|
||||
- alain lefroy
|
||||
- Mark Gius
|
||||
@ -0,0 +1 @@
|
||||
/home/runner/.cache/pip/pool/fe/a1/6b/da9e734dea0d9c8d9f5b909878ef4171626354329609fffcf3db42cb24
|
||||
@ -0,0 +1,128 @@
|
||||
Metadata-Version: 2.1
|
||||
Name: astroid
|
||||
Version: 2.15.0
|
||||
Summary: An abstract syntax tree for Python with inference support.
|
||||
Author-email: Python Code Quality Authority <code-quality@python.org>
|
||||
License: LGPL-2.1-or-later
|
||||
Project-URL: Docs, https://pylint.readthedocs.io/projects/astroid/en/latest/
|
||||
Project-URL: Source Code, https://github.com/PyCQA/astroid
|
||||
Project-URL: Bug tracker, https://github.com/PyCQA/astroid/issues
|
||||
Project-URL: Discord server, https://discord.gg/Egy6P8AMB5
|
||||
Keywords: static code analysis,python,abstract syntax tree
|
||||
Classifier: Development Status :: 6 - Mature
|
||||
Classifier: Environment :: Console
|
||||
Classifier: Intended Audience :: Developers
|
||||
Classifier: License :: OSI Approved :: GNU Lesser General Public License v2 (LGPLv2)
|
||||
Classifier: Operating System :: OS Independent
|
||||
Classifier: Programming Language :: Python
|
||||
Classifier: Programming Language :: Python :: 3
|
||||
Classifier: Programming Language :: Python :: 3 :: Only
|
||||
Classifier: Programming Language :: Python :: 3.7
|
||||
Classifier: Programming Language :: Python :: 3.8
|
||||
Classifier: Programming Language :: Python :: 3.9
|
||||
Classifier: Programming Language :: Python :: 3.10
|
||||
Classifier: Programming Language :: Python :: 3.11
|
||||
Classifier: Programming Language :: Python :: Implementation :: CPython
|
||||
Classifier: Programming Language :: Python :: Implementation :: PyPy
|
||||
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
||||
Classifier: Topic :: Software Development :: Quality Assurance
|
||||
Classifier: Topic :: Software Development :: Testing
|
||||
Requires-Python: >=3.7.2
|
||||
Description-Content-Type: text/x-rst
|
||||
License-File: LICENSE
|
||||
License-File: CONTRIBUTORS.txt
|
||||
Requires-Dist: lazy-object-proxy (>=1.4.0)
|
||||
Requires-Dist: typed-ast (<2.0,>=1.4.0) ; implementation_name == "cpython" and python_version < "3.8"
|
||||
Requires-Dist: wrapt (<2,>=1.11) ; python_version < "3.11"
|
||||
Requires-Dist: typing-extensions (>=4.0.0) ; python_version < "3.11"
|
||||
Requires-Dist: wrapt (<2,>=1.14) ; python_version >= "3.11"
|
||||
|
||||
Astroid
|
||||
=======
|
||||
|
||||
.. image:: https://codecov.io/gh/PyCQA/astroid/branch/main/graph/badge.svg?token=Buxy4WptLb
|
||||
:target: https://codecov.io/gh/PyCQA/astroid
|
||||
:alt: Coverage badge from codecov
|
||||
|
||||
.. image:: https://readthedocs.org/projects/astroid/badge/?version=latest
|
||||
:target: http://astroid.readthedocs.io/en/latest/?badge=latest
|
||||
:alt: Documentation Status
|
||||
|
||||
.. image:: https://img.shields.io/badge/code%20style-black-000000.svg
|
||||
:target: https://github.com/ambv/black
|
||||
|
||||
.. image:: https://results.pre-commit.ci/badge/github/PyCQA/astroid/main.svg
|
||||
:target: https://results.pre-commit.ci/latest/github/PyCQA/astroid/main
|
||||
:alt: pre-commit.ci status
|
||||
|
||||
.. |tidelift_logo| image:: https://raw.githubusercontent.com/PyCQA/astroid/main/doc/media/Tidelift_Logos_RGB_Tidelift_Shorthand_On-White.png
|
||||
:width: 200
|
||||
:alt: Tidelift
|
||||
|
||||
.. list-table::
|
||||
:widths: 10 100
|
||||
|
||||
* - |tidelift_logo|
|
||||
- Professional support for astroid is available as part of the
|
||||
`Tidelift Subscription`_. Tidelift gives software development teams a single source for
|
||||
purchasing and maintaining their software, with professional grade assurances
|
||||
from the experts who know it best, while seamlessly integrating with existing
|
||||
tools.
|
||||
|
||||
.. _Tidelift Subscription: https://tidelift.com/subscription/pkg/pypi-astroid?utm_source=pypi-astroid&utm_medium=referral&utm_campaign=readme
|
||||
|
||||
|
||||
|
||||
What's this?
|
||||
------------
|
||||
|
||||
The aim of this module is to provide a common base representation of
|
||||
python source code. It is currently the library powering pylint's capabilities.
|
||||
|
||||
It provides a compatible representation which comes from the `_ast`
|
||||
module. It rebuilds the tree generated by the builtin _ast module by
|
||||
recursively walking down the AST and building an extended ast. The new
|
||||
node classes have additional methods and attributes for different
|
||||
usages. They include some support for static inference and local name
|
||||
scopes. Furthermore, astroid can also build partial trees by inspecting living
|
||||
objects.
|
||||
|
||||
|
||||
Installation
|
||||
------------
|
||||
|
||||
Extract the tarball, jump into the created directory and run::
|
||||
|
||||
pip install .
|
||||
|
||||
|
||||
If you want to do an editable installation, you can run::
|
||||
|
||||
pip install -e .
|
||||
|
||||
|
||||
If you have any questions, please mail the code-quality@python.org
|
||||
mailing list for support. See
|
||||
http://mail.python.org/mailman/listinfo/code-quality for subscription
|
||||
information and archives.
|
||||
|
||||
Documentation
|
||||
-------------
|
||||
http://astroid.readthedocs.io/en/latest/
|
||||
|
||||
|
||||
Python Versions
|
||||
---------------
|
||||
|
||||
astroid 2.0 is currently available for Python 3 only. If you want Python 2
|
||||
support, use an older version of astroid (though note that these versions
|
||||
are no longer supported).
|
||||
|
||||
Test
|
||||
----
|
||||
|
||||
Tests are in the 'test' subdirectory. To launch the whole tests suite, you can use
|
||||
either `tox` or `pytest`::
|
||||
|
||||
tox
|
||||
pytest
|
||||
@ -0,0 +1,209 @@
|
||||
astroid-2.15.0.dist-info/CONTRIBUTORS.txt,sha256=_R56rA3okHgrKxY42SDN2zOaFZV49Oks0iFtQ_tIIBs,8038
|
||||
astroid-2.15.0.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
|
||||
astroid-2.15.0.dist-info/LICENSE,sha256=_qFr2p5zTeoNnI2fW5CYeO9BcWJjVDKWCf_889tCyyQ,26516
|
||||
astroid-2.15.0.dist-info/METADATA,sha256=rju1DTgF4pzdcf_H6Kb8EQeonNs7FtpDgLyaecs6tmg,4786
|
||||
astroid-2.15.0.dist-info/RECORD,,
|
||||
astroid-2.15.0.dist-info/WHEEL,sha256=2wepM1nk4DS4eFpYrW1TTqPcoGNfHhhO_i5m4cOimbo,92
|
||||
astroid-2.15.0.dist-info/top_level.txt,sha256=HsdW4O2x7ZXRj6k-agi3RaQybGLobI3VSE-jt4vQUXM,8
|
||||
astroid/__init__.py,sha256=HKHncgrj70qSs9Gg4aDpFyiAQFHhrSoR1O20OQ3K0Bo,5091
|
||||
astroid/__pkginfo__.py,sha256=yDKgWZv5-RlTCQCeK9XRzNWKAN03w8wVDGG2JiXtjZM,274
|
||||
astroid/__pycache__/__init__.cpython-310.pyc,,
|
||||
astroid/__pycache__/__pkginfo__.cpython-310.pyc,,
|
||||
astroid/__pycache__/_ast.cpython-310.pyc,,
|
||||
astroid/__pycache__/_backport_stdlib_names.cpython-310.pyc,,
|
||||
astroid/__pycache__/_cache.cpython-310.pyc,,
|
||||
astroid/__pycache__/arguments.cpython-310.pyc,,
|
||||
astroid/__pycache__/astroid_manager.cpython-310.pyc,,
|
||||
astroid/__pycache__/bases.cpython-310.pyc,,
|
||||
astroid/__pycache__/builder.cpython-310.pyc,,
|
||||
astroid/__pycache__/const.cpython-310.pyc,,
|
||||
astroid/__pycache__/constraint.cpython-310.pyc,,
|
||||
astroid/__pycache__/context.cpython-310.pyc,,
|
||||
astroid/__pycache__/decorators.cpython-310.pyc,,
|
||||
astroid/__pycache__/exceptions.cpython-310.pyc,,
|
||||
astroid/__pycache__/filter_statements.cpython-310.pyc,,
|
||||
astroid/__pycache__/helpers.cpython-310.pyc,,
|
||||
astroid/__pycache__/inference.cpython-310.pyc,,
|
||||
astroid/__pycache__/inference_tip.cpython-310.pyc,,
|
||||
astroid/__pycache__/manager.cpython-310.pyc,,
|
||||
astroid/__pycache__/mixins.cpython-310.pyc,,
|
||||
astroid/__pycache__/modutils.cpython-310.pyc,,
|
||||
astroid/__pycache__/node_classes.cpython-310.pyc,,
|
||||
astroid/__pycache__/objects.cpython-310.pyc,,
|
||||
astroid/__pycache__/protocols.cpython-310.pyc,,
|
||||
astroid/__pycache__/raw_building.cpython-310.pyc,,
|
||||
astroid/__pycache__/rebuilder.cpython-310.pyc,,
|
||||
astroid/__pycache__/scoped_nodes.cpython-310.pyc,,
|
||||
astroid/__pycache__/test_utils.cpython-310.pyc,,
|
||||
astroid/__pycache__/transforms.cpython-310.pyc,,
|
||||
astroid/__pycache__/typing.cpython-310.pyc,,
|
||||
astroid/__pycache__/util.cpython-310.pyc,,
|
||||
astroid/_ast.py,sha256=fx6vCj7YJJRQSf3GQYRllJ9hRKPh9-QczU3crjt3IrA,4146
|
||||
astroid/_backport_stdlib_names.py,sha256=pmMEGwionQpfJdJaJomDF6Qc6peNMxChcOsNa8U2IDo,7016
|
||||
astroid/_cache.py,sha256=ZuO1Kl9HXaxoJ_hJXbzWqkMGmQR7CGf-R4cPen9odzM,786
|
||||
astroid/arguments.py,sha256=9GeVion6IpISnxQGyXU6uHxfJ_kuDXOCYm3Jv6SJNUg,12958
|
||||
astroid/astroid_manager.py,sha256=02l_ltGWEglvkoL_qMGmYxuHpDA5-ySPf0r1cGwIQqU,572
|
||||
astroid/bases.py,sha256=9GT3_gPrLdlS3zmvW3Nmv2X2pQcY5_vywz1MVky4ero,25594
|
||||
astroid/brain/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
||||
astroid/brain/__pycache__/__init__.cpython-310.pyc,,
|
||||
astroid/brain/__pycache__/brain_argparse.cpython-310.pyc,,
|
||||
astroid/brain/__pycache__/brain_attrs.cpython-310.pyc,,
|
||||
astroid/brain/__pycache__/brain_boto3.cpython-310.pyc,,
|
||||
astroid/brain/__pycache__/brain_builtin_inference.cpython-310.pyc,,
|
||||
astroid/brain/__pycache__/brain_collections.cpython-310.pyc,,
|
||||
astroid/brain/__pycache__/brain_crypt.cpython-310.pyc,,
|
||||
astroid/brain/__pycache__/brain_ctypes.cpython-310.pyc,,
|
||||
astroid/brain/__pycache__/brain_curses.cpython-310.pyc,,
|
||||
astroid/brain/__pycache__/brain_dataclasses.cpython-310.pyc,,
|
||||
astroid/brain/__pycache__/brain_dateutil.cpython-310.pyc,,
|
||||
astroid/brain/__pycache__/brain_fstrings.cpython-310.pyc,,
|
||||
astroid/brain/__pycache__/brain_functools.cpython-310.pyc,,
|
||||
astroid/brain/__pycache__/brain_gi.cpython-310.pyc,,
|
||||
astroid/brain/__pycache__/brain_hashlib.cpython-310.pyc,,
|
||||
astroid/brain/__pycache__/brain_http.cpython-310.pyc,,
|
||||
astroid/brain/__pycache__/brain_hypothesis.cpython-310.pyc,,
|
||||
astroid/brain/__pycache__/brain_io.cpython-310.pyc,,
|
||||
astroid/brain/__pycache__/brain_mechanize.cpython-310.pyc,,
|
||||
astroid/brain/__pycache__/brain_multiprocessing.cpython-310.pyc,,
|
||||
astroid/brain/__pycache__/brain_namedtuple_enum.cpython-310.pyc,,
|
||||
astroid/brain/__pycache__/brain_nose.cpython-310.pyc,,
|
||||
astroid/brain/__pycache__/brain_numpy_core_einsumfunc.cpython-310.pyc,,
|
||||
astroid/brain/__pycache__/brain_numpy_core_fromnumeric.cpython-310.pyc,,
|
||||
astroid/brain/__pycache__/brain_numpy_core_function_base.cpython-310.pyc,,
|
||||
astroid/brain/__pycache__/brain_numpy_core_multiarray.cpython-310.pyc,,
|
||||
astroid/brain/__pycache__/brain_numpy_core_numeric.cpython-310.pyc,,
|
||||
astroid/brain/__pycache__/brain_numpy_core_numerictypes.cpython-310.pyc,,
|
||||
astroid/brain/__pycache__/brain_numpy_core_umath.cpython-310.pyc,,
|
||||
astroid/brain/__pycache__/brain_numpy_ma.cpython-310.pyc,,
|
||||
astroid/brain/__pycache__/brain_numpy_ndarray.cpython-310.pyc,,
|
||||
astroid/brain/__pycache__/brain_numpy_random_mtrand.cpython-310.pyc,,
|
||||
astroid/brain/__pycache__/brain_numpy_utils.cpython-310.pyc,,
|
||||
astroid/brain/__pycache__/brain_pathlib.cpython-310.pyc,,
|
||||
astroid/brain/__pycache__/brain_pkg_resources.cpython-310.pyc,,
|
||||
astroid/brain/__pycache__/brain_pytest.cpython-310.pyc,,
|
||||
astroid/brain/__pycache__/brain_qt.cpython-310.pyc,,
|
||||
astroid/brain/__pycache__/brain_random.cpython-310.pyc,,
|
||||
astroid/brain/__pycache__/brain_re.cpython-310.pyc,,
|
||||
astroid/brain/__pycache__/brain_regex.cpython-310.pyc,,
|
||||
astroid/brain/__pycache__/brain_responses.cpython-310.pyc,,
|
||||
astroid/brain/__pycache__/brain_scipy_signal.cpython-310.pyc,,
|
||||
astroid/brain/__pycache__/brain_signal.cpython-310.pyc,,
|
||||
astroid/brain/__pycache__/brain_six.cpython-310.pyc,,
|
||||
astroid/brain/__pycache__/brain_sqlalchemy.cpython-310.pyc,,
|
||||
astroid/brain/__pycache__/brain_ssl.cpython-310.pyc,,
|
||||
astroid/brain/__pycache__/brain_subprocess.cpython-310.pyc,,
|
||||
astroid/brain/__pycache__/brain_threading.cpython-310.pyc,,
|
||||
astroid/brain/__pycache__/brain_type.cpython-310.pyc,,
|
||||
astroid/brain/__pycache__/brain_typing.cpython-310.pyc,,
|
||||
astroid/brain/__pycache__/brain_unittest.cpython-310.pyc,,
|
||||
astroid/brain/__pycache__/brain_uuid.cpython-310.pyc,,
|
||||
astroid/brain/__pycache__/helpers.cpython-310.pyc,,
|
||||
astroid/brain/brain_argparse.py,sha256=ozU4z8-HTSX6tl6g2ysoqFGn6b8jK4Bt_NlAKl_jYyQ,1557
|
||||
astroid/brain/brain_attrs.py,sha256=PGFhUbL428Mc_cuyFgZIB2alt2ICfeaamWB-0C_kxAk,2857
|
||||
astroid/brain/brain_boto3.py,sha256=gZOkDoY1YZk24EpOMVQVj0MBuNfBWn_XfDmmlH4jyHU,1012
|
||||
astroid/brain/brain_builtin_inference.py,sha256=N-B5FxLAID8wztOTdiZEoc42qrQh5M8MrtSH4BaQwZs,34254
|
||||
astroid/brain/brain_collections.py,sha256=__vh_SUp3ymY68i_UYW1OMlAjDN-Hiv_NHdDQs98HV4,4416
|
||||
astroid/brain/brain_crypt.py,sha256=Zo66z94cQOL-HNOcAQSPNs_Ib_xNLLY9qEtxZ1VkbAM,863
|
||||
astroid/brain/brain_ctypes.py,sha256=55flnAIj_Th_eqqG1HRMDR5ctt74ww1vDsSF42F26Es,2660
|
||||
astroid/brain/brain_curses.py,sha256=XXyCeLASFFksO2zSbrZgB_AImGBlIGZ7Pgjdm04x-jg,3477
|
||||
astroid/brain/brain_dataclasses.py,sha256=81fglaiPlsUkbImjLpSIpdVCdmmZa8vYUcCKQFo9YAI,22089
|
||||
astroid/brain/brain_dateutil.py,sha256=1INt87VBa9Qt0DzEuI1r7cEtdyg5CvNDUIdVCv-j_mc,767
|
||||
astroid/brain/brain_fstrings.py,sha256=VU14-7tVsJWlZt0r3UMB8lPS-Bb72dyYcDvd1PmTPJM,2471
|
||||
astroid/brain/brain_functools.py,sha256=91kJd49eYZGh9fG45uBS4I6j635Q7VctZND-iqB2dRg,5986
|
||||
astroid/brain/brain_gi.py,sha256=LYtvbe48qmyugTP31CcrqfM6X0ra_h6ntTBuKGCIrcM,7543
|
||||
astroid/brain/brain_hashlib.py,sha256=WE7fQJCA3Rp1ZFDIseQjhrLEcsYhOfrka2PcvvuZ6Tg,2821
|
||||
astroid/brain/brain_http.py,sha256=mYLcMdh_ka5d11IpdWg6WrG3R7R2wN4bKOLVG0W3vPk,10640
|
||||
astroid/brain/brain_hypothesis.py,sha256=K4LfRb2KT6H5B7oGxAXQLcJFl9bkeKfFW8IEceGAbfw,1732
|
||||
astroid/brain/brain_io.py,sha256=l499fbVi5HUbPWoyQn1xTHaPgRcf0hsKjjI90BdHzyQ,1526
|
||||
astroid/brain/brain_mechanize.py,sha256=45syVjTGklYjS469vPsuHmyic09OTZtcJuM7FEXcMYI,2646
|
||||
astroid/brain/brain_multiprocessing.py,sha256=htHZ3zSyv4eqh6c-AFRPt2GlyyPb4Jg8OQfAolojR8Q,3211
|
||||
astroid/brain/brain_namedtuple_enum.py,sha256=j9GnadFsrVT6A-tz_w-HQcOBUHU4IiG09qKpJNSdA0s,22725
|
||||
astroid/brain/brain_nose.py,sha256=DCUwKzR14Se5tF-s54AMwFoRvhsHH_nf6agrh966VpQ,2320
|
||||
astroid/brain/brain_numpy_core_einsumfunc.py,sha256=CuZtZYZGDhPzV46l1xyNl_7RfMCaQ4bYyZgJ9f8KxcQ,825
|
||||
astroid/brain/brain_numpy_core_fromnumeric.py,sha256=3UFRtK5U51AVQNxawf9ElhFv2tizhj5RfyCSnPT3u54,732
|
||||
astroid/brain/brain_numpy_core_function_base.py,sha256=_k-WRQ_x0QEHhvr9IwuTLnpGoCYOVO0GAH7e3DyoHNQ,1298
|
||||
astroid/brain/brain_numpy_core_multiarray.py,sha256=NIxnvno-mhp-P6IKfyRaKOFtiHx8H9cEchjgx69oht0,4238
|
||||
astroid/brain/brain_numpy_core_numeric.py,sha256=VAc51Ud8QDujsh29e-RQK5SBcKW_jzjZIFmntCslCKU,1629
|
||||
astroid/brain/brain_numpy_core_numerictypes.py,sha256=HVJ_paQwjh2V8qz0Juei6b2ZRm_dmDJodiDKfAcE-mE,8546
|
||||
astroid/brain/brain_numpy_core_umath.py,sha256=2EhXmtiw8wQcdUtbnlLLTjHAOHpQ1c9BXHdc6kHJGbA,4893
|
||||
astroid/brain/brain_numpy_ma.py,sha256=1XHvZH1C3CEXTiRH3BJxpFiztgqBYEGd9JDFquGsUMk,896
|
||||
astroid/brain/brain_numpy_ndarray.py,sha256=HohawmatzpNMOJAhYbEPJGZdCTNmYO1Oz-IPxYDd5mM,8998
|
||||
astroid/brain/brain_numpy_random_mtrand.py,sha256=Wrpm9SX8kH0Xsk9b3qpR0rhs-MEb0I5aN4E-66wkLkM,3436
|
||||
astroid/brain/brain_numpy_utils.py,sha256=wgSRUgGdn8Io0AoTe6avll35oceRq2S6ZXqNviljvGI,2637
|
||||
astroid/brain/brain_pathlib.py,sha256=Ec8Xuo-4IIG2wH4875c8c2Xe_I0fqPbPqoKCJOttVlE,1542
|
||||
astroid/brain/brain_pkg_resources.py,sha256=W3Q4G6mYTYtJY9iWQv3vEO8_lpmLFAin9aQLtBRLxAc,2200
|
||||
astroid/brain/brain_pytest.py,sha256=suTDBHCJ_p4F7TGXjwVJAFtiAP-VlkFE2gncXjLRQKM,2223
|
||||
astroid/brain/brain_qt.py,sha256=qvexV4IFa4YKL0Nyo6qxmz_DfDDNwFVwBTJGADtVkiI,2808
|
||||
astroid/brain/brain_random.py,sha256=grXJrYL3rZpzm8SmuEnWkLwWNqWKtd5YmwbBoV6mjN4,2890
|
||||
astroid/brain/brain_re.py,sha256=aSU-HyEWsCrc1seiFohZw54ivcNtC-_AyiChJOSU-7Q,2870
|
||||
astroid/brain/brain_regex.py,sha256=UzW2lF2ctbdD8BX4fkC7PFtXDdGNUcdBKZx7sJiO4Z0,3362
|
||||
astroid/brain/brain_responses.py,sha256=Jn7jS8L26T5hnUwOcHX469FTkVs3_Yz8OiVRPAx3Bjo,1868
|
||||
astroid/brain/brain_scipy_signal.py,sha256=Mi93D6-j94tqhqDHCbabVs3_eDAhti88CL1_rOvnG_I,2276
|
||||
astroid/brain/brain_signal.py,sha256=18rOCgLVmM1rtc6BFYPx4qziSrfPt6CrP-A2fJyMWBY,3880
|
||||
astroid/brain/brain_six.py,sha256=MWQm81s9Zb_i1NIqY3MnXuawlsXqgK1BDj1vBDZ-MdE,7625
|
||||
astroid/brain/brain_sqlalchemy.py,sha256=onKAxgKY-GYLe2v6PVK3APBn_z8txokEZfDcXt33GuE,1009
|
||||
astroid/brain/brain_ssl.py,sha256=8MdXhl9ZvYVe6U_gtSTtgnm_Dned2Ic9MbgfSj56RHU,6554
|
||||
astroid/brain/brain_subprocess.py,sha256=Kayri4dMqwtXbZTOhB0E05p2ckKc7hIGPt1jA3zv2xA,2996
|
||||
astroid/brain/brain_threading.py,sha256=rN-dQ_4Zo0AZOOiPQigxF3NEgmDC7DY-r0ujLN6W52c,870
|
||||
astroid/brain/brain_type.py,sha256=VUwQsehFIShvKrm98ywa5-gGz7eLwJnBHCpQdreGOGM,2483
|
||||
astroid/brain/brain_typing.py,sha256=uficlx7AzFIkcBQKeOvmzg_75kxAZENTDilXTYv-rfE,14315
|
||||
astroid/brain/brain_unittest.py,sha256=X_xqI70br7JgIrUiUwP4Hm9mQwCx9jBfvNW5h0wmp-0,1147
|
||||
astroid/brain/brain_uuid.py,sha256=t0fj_QeNzbPga03GS0YP92sjjEmxN04rlgZ4dt82JHE,667
|
||||
astroid/brain/helpers.py,sha256=qtThXG2zllaFm8Ril8Mjbb6yuRPUqy-elXz4Qu8UKX0,908
|
||||
astroid/builder.py,sha256=bkCDciVprfLz3vyg6BfoTaUMe34tRB1n0z3hCXvoyLE,18788
|
||||
astroid/const.py,sha256=-C9gZEVAgp83YpjnG4k6BKBlTkn22J3UeR59IzPzC-s,1095
|
||||
astroid/constraint.py,sha256=RgYVUe0CiEXeXB0iGDd896CEDgCHpwALdzZEFogagwo,5043
|
||||
astroid/context.py,sha256=BwdZndGFMeP9ldxt-c4LP21N61ZGCFjySNCASiGHWhw,5994
|
||||
astroid/decorators.py,sha256=4_SEOBUSxU60_7SaOkACXvBiiwGxYVd7E6YJdhB-5AY,10090
|
||||
astroid/exceptions.py,sha256=wcJFoxkuWUslQMsjjBsvQadlTl-CCLin4I5Mg9EA4XQ,13089
|
||||
astroid/filter_statements.py,sha256=zd55vGal1W6k1DZRsZoTQodtTZCtKrmebUVkECeoUS4,9643
|
||||
astroid/helpers.py,sha256=2ppef_tEbjaFyvFb2QrNq36I8pNk-wxLDkpfwXN0dc8,11312
|
||||
astroid/inference.py,sha256=IJZGg3YLTIXfHxDuOnEdd5IAfdk7sTPWSGt8OXqEHpM,45121
|
||||
astroid/inference_tip.py,sha256=4ims3HAlCZwVybV1CyLxreDtPVNEnvta_OKb_ELAbyA,2888
|
||||
astroid/interpreter/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
||||
astroid/interpreter/__pycache__/__init__.cpython-310.pyc,,
|
||||
astroid/interpreter/__pycache__/dunder_lookup.cpython-310.pyc,,
|
||||
astroid/interpreter/__pycache__/objectmodel.cpython-310.pyc,,
|
||||
astroid/interpreter/_import/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
||||
astroid/interpreter/_import/__pycache__/__init__.cpython-310.pyc,,
|
||||
astroid/interpreter/_import/__pycache__/spec.cpython-310.pyc,,
|
||||
astroid/interpreter/_import/__pycache__/util.cpython-310.pyc,,
|
||||
astroid/interpreter/_import/spec.py,sha256=1s6GkO0yVgdtXHJAhD8v8W27ZmtkfT5p-mAKf8v4xmY,16381
|
||||
astroid/interpreter/_import/util.py,sha256=b5ggIRSth_I5Uwv3s44jMwf3OlnFAWIV-57wX3XK9yM,4592
|
||||
astroid/interpreter/dunder_lookup.py,sha256=77YNmgp6l2sPA7UIaUpjaP6-4x26NP93IihPR5EEv-c,2172
|
||||
astroid/interpreter/objectmodel.py,sha256=SVtDFz0kAlHgkRTcIp4r3t2UEjeJLE2jXSxZdo8QhXw,31177
|
||||
astroid/manager.py,sha256=g17lbC6NM9ieO3hZVJLtwE6Gb_JlCsEJJ42YtK7B27Q,17598
|
||||
astroid/mixins.py,sha256=4fuPIi4N5ucNbocjVrS5UpEc_6Jkn3gsYD--JG85TII,1182
|
||||
astroid/modutils.py,sha256=nmwwzrvSGIl4DRHC6WoyGPDkDtKgyKpcHSidjw_B8UU,23481
|
||||
astroid/node_classes.py,sha256=ws0UW2SFejWF75iHfxx-u80XQt4beDAiDyabWrOwlPE,1827
|
||||
astroid/nodes/__init__.py,sha256=Uuli4TfBDzdUTPvVvjp-aEB0SpMv-6gdoWajJt1fguo,5043
|
||||
astroid/nodes/__pycache__/__init__.cpython-310.pyc,,
|
||||
astroid/nodes/__pycache__/_base_nodes.cpython-310.pyc,,
|
||||
astroid/nodes/__pycache__/as_string.cpython-310.pyc,,
|
||||
astroid/nodes/__pycache__/const.cpython-310.pyc,,
|
||||
astroid/nodes/__pycache__/node_classes.cpython-310.pyc,,
|
||||
astroid/nodes/__pycache__/node_ng.cpython-310.pyc,,
|
||||
astroid/nodes/__pycache__/utils.cpython-310.pyc,,
|
||||
astroid/nodes/_base_nodes.py,sha256=oQ4ueaxb5-JAnG1w17lK8TRo4xs3KatHrY985M0qgss,7398
|
||||
astroid/nodes/as_string.py,sha256=i4s5M3Ghaef0d-Jgqi5NkPz8AYcXG3ZL7N3HPYZsp_0,24451
|
||||
astroid/nodes/const.py,sha256=iyQn_v-wEzK6uXc-dEMoliPVSRy0NZ8T3XmvvPXLuP4,797
|
||||
astroid/nodes/node_classes.py,sha256=vmiMXFjaRS7o8ag4yShavJxfyd3CIh9xOfJiORxxQ2M,172738
|
||||
astroid/nodes/node_ng.py,sha256=pqrceCAgS64qDmFGBghjWnneodH6P9KYsUFhsi_9Aq8,28223
|
||||
astroid/nodes/scoped_nodes/__init__.py,sha256=CRdThe_LiW7SgcJz3pHSL8oFqHKNIJWg1WkQOkws994,1219
|
||||
astroid/nodes/scoped_nodes/__pycache__/__init__.cpython-310.pyc,,
|
||||
astroid/nodes/scoped_nodes/__pycache__/mixin.cpython-310.pyc,,
|
||||
astroid/nodes/scoped_nodes/__pycache__/scoped_nodes.cpython-310.pyc,,
|
||||
astroid/nodes/scoped_nodes/__pycache__/utils.cpython-310.pyc,,
|
||||
astroid/nodes/scoped_nodes/mixin.py,sha256=mN3oqKpS2AWOtrBjHDDfReVO7OxAMhl_es-jzsn89Js,6917
|
||||
astroid/nodes/scoped_nodes/scoped_nodes.py,sha256=DdqlbBVNPoQbP3AE8nJGsnHjMH0uU92Tp32B8F87v1w,106494
|
||||
astroid/nodes/scoped_nodes/utils.py,sha256=Nnjdkcbm9zs72HcoV9b_hE6P-SLZ7MCB9urU-WUDNVg,1216
|
||||
astroid/nodes/utils.py,sha256=Uy6xoownLyWwDtuZ5qUpjbq19P2pUIcj0J04khbH5HY,423
|
||||
astroid/objects.py,sha256=8roM53sWwFzusAIvz3nOj0LaQEXdzJw0ANfb6mDMy5w,12757
|
||||
astroid/protocols.py,sha256=dkQszq5bOlJ7Jlyu4hdF8l7sv7hVfH7glKWVblf3bkU,32684
|
||||
astroid/raw_building.py,sha256=TI55TaZL35Zi3bk2DThToKEQ8rMOhZCgAMayfktxbAM,22875
|
||||
astroid/rebuilder.py,sha256=ura2IJRixG6FQjgHFXP3-XrGfhPKoW6t1nGXuHl8lQs,79566
|
||||
astroid/scoped_nodes.py,sha256=j51jEOiN1rkMqmrhvVtYje8d-EWaGbzrgCwvg_s4TE0,958
|
||||
astroid/test_utils.py,sha256=7wyVL8A8WYQXbix1mT05lh8yO4kXk1gRjCCuqwfV4f8,2434
|
||||
astroid/transforms.py,sha256=eg7b0lehQu_GsFHCsLdUsNNvbxYBGcTC0p7rF2EKIXc,3271
|
||||
astroid/typing.py,sha256=OTOZbQ7tHSMq1tlASsVgRMC90GTjFoVSCgevZarAwhI,1983
|
||||
astroid/util.py,sha256=T5ux2LDjSNv2et5blQuUU7xCBr1id-CeU8lorr-yAVo,4729
|
||||
1
venv/lib/python3.10/site-packages/astroid-2.15.0.dist-info/WHEEL
Symbolic link
1
venv/lib/python3.10/site-packages/astroid-2.15.0.dist-info/WHEEL
Symbolic link
@ -0,0 +1 @@
|
||||
/home/runner/.cache/pip/pool/db/07/a9/3359e4e034b8785a58ad6d534ea3dca0635f1e184efe2e66e1c3a299ba
|
||||
@ -0,0 +1 @@
|
||||
/home/runner/.cache/pip/pool/1e/c7/56/e0edb1ed95d18fa93e6a08b745a4326c62e86c8dd5484fa3b78bd05173
|
||||
1
venv/lib/python3.10/site-packages/astroid/__init__.py
Symbolic link
1
venv/lib/python3.10/site-packages/astroid/__init__.py
Symbolic link
@ -0,0 +1 @@
|
||||
/home/runner/.cache/pip/pool/1c/a1/e7/720ae3ef4a92b3d1a0e1a0e91728804051e1ad2a11d4edb4390dcad01a
|
||||
6
venv/lib/python3.10/site-packages/astroid/__pkginfo__.py
Normal file
6
venv/lib/python3.10/site-packages/astroid/__pkginfo__.py
Normal file
@ -0,0 +1,6 @@
|
||||
# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html
|
||||
# For details: https://github.com/PyCQA/astroid/blob/main/LICENSE
|
||||
# Copyright (c) https://github.com/PyCQA/astroid/blob/main/CONTRIBUTORS.txt
|
||||
|
||||
__version__ = "2.15.0"
|
||||
version = __version__
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
1
venv/lib/python3.10/site-packages/astroid/_ast.py
Symbolic link
1
venv/lib/python3.10/site-packages/astroid/_ast.py
Symbolic link
@ -0,0 +1 @@
|
||||
/home/runner/.cache/pip/pool/7f/1e/af/0a3ed824945049fdc6418465949f6144a3e1f7e41ccd4ddcae3b7722b0
|
||||
@ -0,0 +1,356 @@
|
||||
# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html
|
||||
# For details: https://github.com/PyCQA/astroid/blob/main/LICENSE
|
||||
# Copyright (c) https://github.com/PyCQA/astroid/blob/main/CONTRIBUTORS.txt
|
||||
|
||||
"""
|
||||
Shim to support Python versions < 3.10 that don't have sys.stdlib_module_names
|
||||
|
||||
These values were created by cherry-picking the commits from
|
||||
https://bugs.python.org/issue42955 into each version, but may be updated
|
||||
manually if changes are needed.
|
||||
"""
|
||||
|
||||
import sys
|
||||
|
||||
# TODO: Remove this file when Python 3.9 is no longer supported
|
||||
|
||||
PY_3_7 = frozenset(
|
||||
{
|
||||
"__future__",
|
||||
"_abc",
|
||||
"_ast",
|
||||
"_asyncio",
|
||||
"_bisect",
|
||||
"_blake2",
|
||||
"_bootlocale",
|
||||
"_bz2",
|
||||
"_codecs",
|
||||
"_codecs_cn",
|
||||
"_codecs_hk",
|
||||
"_codecs_iso2022",
|
||||
"_codecs_jp",
|
||||
"_codecs_kr",
|
||||
"_codecs_tw",
|
||||
"_collections",
|
||||
"_collections_abc",
|
||||
"_compat_pickle",
|
||||
"_compression",
|
||||
"_contextvars",
|
||||
"_crypt",
|
||||
"_csv",
|
||||
"_ctypes",
|
||||
"_curses",
|
||||
"_curses_panel",
|
||||
"_datetime",
|
||||
"_dbm",
|
||||
"_decimal",
|
||||
"_dummy_thread",
|
||||
"_elementtree",
|
||||
"_functools",
|
||||
"_gdbm",
|
||||
"_hashlib",
|
||||
"_heapq",
|
||||
"_imp",
|
||||
"_io",
|
||||
"_json",
|
||||
"_locale",
|
||||
"_lsprof",
|
||||
"_lzma",
|
||||
"_markupbase",
|
||||
"_md5",
|
||||
"_msi",
|
||||
"_multibytecodec",
|
||||
"_multiprocessing",
|
||||
"_opcode",
|
||||
"_operator",
|
||||
"_osx_support",
|
||||
"_pickle",
|
||||
"_posixsubprocess",
|
||||
"_py_abc",
|
||||
"_pydecimal",
|
||||
"_pyio",
|
||||
"_queue",
|
||||
"_random",
|
||||
"_sha1",
|
||||
"_sha256",
|
||||
"_sha3",
|
||||
"_sha512",
|
||||
"_signal",
|
||||
"_sitebuiltins",
|
||||
"_socket",
|
||||
"_sqlite3",
|
||||
"_sre",
|
||||
"_ssl",
|
||||
"_stat",
|
||||
"_string",
|
||||
"_strptime",
|
||||
"_struct",
|
||||
"_symtable",
|
||||
"_thread",
|
||||
"_threading_local",
|
||||
"_tkinter",
|
||||
"_tracemalloc",
|
||||
"_uuid",
|
||||
"_warnings",
|
||||
"_weakref",
|
||||
"_weakrefset",
|
||||
"_winapi",
|
||||
"abc",
|
||||
"aifc",
|
||||
"antigravity",
|
||||
"argparse",
|
||||
"array",
|
||||
"ast",
|
||||
"asynchat",
|
||||
"asyncio",
|
||||
"asyncore",
|
||||
"atexit",
|
||||
"audioop",
|
||||
"base64",
|
||||
"bdb",
|
||||
"binascii",
|
||||
"binhex",
|
||||
"bisect",
|
||||
"builtins",
|
||||
"bz2",
|
||||
"cProfile",
|
||||
"calendar",
|
||||
"cgi",
|
||||
"cgitb",
|
||||
"chunk",
|
||||
"cmath",
|
||||
"cmd",
|
||||
"code",
|
||||
"codecs",
|
||||
"codeop",
|
||||
"collections",
|
||||
"colorsys",
|
||||
"compileall",
|
||||
"concurrent",
|
||||
"configparser",
|
||||
"contextlib",
|
||||
"contextvars",
|
||||
"copy",
|
||||
"copyreg",
|
||||
"crypt",
|
||||
"csv",
|
||||
"ctypes",
|
||||
"curses",
|
||||
"dataclasses",
|
||||
"datetime",
|
||||
"dbm",
|
||||
"decimal",
|
||||
"difflib",
|
||||
"dis",
|
||||
"distutils",
|
||||
"doctest",
|
||||
"dummy_threading",
|
||||
"email",
|
||||
"encodings",
|
||||
"ensurepip",
|
||||
"enum",
|
||||
"errno",
|
||||
"faulthandler",
|
||||
"fcntl",
|
||||
"filecmp",
|
||||
"fileinput",
|
||||
"fnmatch",
|
||||
"formatter",
|
||||
"fractions",
|
||||
"ftplib",
|
||||
"functools",
|
||||
"gc",
|
||||
"genericpath",
|
||||
"getopt",
|
||||
"getpass",
|
||||
"gettext",
|
||||
"glob",
|
||||
"grp",
|
||||
"gzip",
|
||||
"hashlib",
|
||||
"heapq",
|
||||
"hmac",
|
||||
"html",
|
||||
"http",
|
||||
"idlelib",
|
||||
"imaplib",
|
||||
"imghdr",
|
||||
"imp",
|
||||
"importlib",
|
||||
"inspect",
|
||||
"io",
|
||||
"ipaddress",
|
||||
"itertools",
|
||||
"json",
|
||||
"keyword",
|
||||
"lib2to3",
|
||||
"linecache",
|
||||
"locale",
|
||||
"logging",
|
||||
"lzma",
|
||||
"macpath",
|
||||
"mailbox",
|
||||
"mailcap",
|
||||
"marshal",
|
||||
"math",
|
||||
"mimetypes",
|
||||
"mmap",
|
||||
"modulefinder",
|
||||
"msilib",
|
||||
"msvcrt",
|
||||
"multiprocessing",
|
||||
"netrc",
|
||||
"nis",
|
||||
"nntplib",
|
||||
"nt",
|
||||
"ntpath",
|
||||
"nturl2path",
|
||||
"numbers",
|
||||
"opcode",
|
||||
"operator",
|
||||
"optparse",
|
||||
"os",
|
||||
"ossaudiodev",
|
||||
"parser",
|
||||
"pathlib",
|
||||
"pdb",
|
||||
"pickle",
|
||||
"pickletools",
|
||||
"pipes",
|
||||
"pkgutil",
|
||||
"platform",
|
||||
"plistlib",
|
||||
"poplib",
|
||||
"posix",
|
||||
"posixpath",
|
||||
"pprint",
|
||||
"profile",
|
||||
"pstats",
|
||||
"pty",
|
||||
"pwd",
|
||||
"py_compile",
|
||||
"pyclbr",
|
||||
"pydoc",
|
||||
"pydoc_data",
|
||||
"pyexpat",
|
||||
"queue",
|
||||
"quopri",
|
||||
"random",
|
||||
"re",
|
||||
"readline",
|
||||
"reprlib",
|
||||
"resource",
|
||||
"rlcompleter",
|
||||
"runpy",
|
||||
"sched",
|
||||
"secrets",
|
||||
"select",
|
||||
"selectors",
|
||||
"shelve",
|
||||
"shlex",
|
||||
"shutil",
|
||||
"signal",
|
||||
"site",
|
||||
"smtpd",
|
||||
"smtplib",
|
||||
"sndhdr",
|
||||
"socket",
|
||||
"socketserver",
|
||||
"spwd",
|
||||
"sqlite3",
|
||||
"sre_compile",
|
||||
"sre_constants",
|
||||
"sre_parse",
|
||||
"ssl",
|
||||
"stat",
|
||||
"statistics",
|
||||
"string",
|
||||
"stringprep",
|
||||
"struct",
|
||||
"subprocess",
|
||||
"sunau",
|
||||
"symbol",
|
||||
"symtable",
|
||||
"sys",
|
||||
"sysconfig",
|
||||
"syslog",
|
||||
"tabnanny",
|
||||
"tarfile",
|
||||
"telnetlib",
|
||||
"tempfile",
|
||||
"termios",
|
||||
"textwrap",
|
||||
"this",
|
||||
"threading",
|
||||
"time",
|
||||
"timeit",
|
||||
"tkinter",
|
||||
"token",
|
||||
"tokenize",
|
||||
"trace",
|
||||
"traceback",
|
||||
"tracemalloc",
|
||||
"tty",
|
||||
"turtle",
|
||||
"turtledemo",
|
||||
"types",
|
||||
"typing",
|
||||
"unicodedata",
|
||||
"unittest",
|
||||
"urllib",
|
||||
"uu",
|
||||
"uuid",
|
||||
"venv",
|
||||
"warnings",
|
||||
"wave",
|
||||
"weakref",
|
||||
"webbrowser",
|
||||
"winreg",
|
||||
"winsound",
|
||||
"wsgiref",
|
||||
"xdrlib",
|
||||
"xml",
|
||||
"xmlrpc",
|
||||
"zipapp",
|
||||
"zipfile",
|
||||
"zipimport",
|
||||
"zlib",
|
||||
}
|
||||
)
|
||||
|
||||
PY_3_8 = frozenset(
|
||||
PY_3_7
|
||||
- {
|
||||
"macpath",
|
||||
}
|
||||
| {
|
||||
"_posixshmem",
|
||||
"_statistics",
|
||||
"_xxsubinterpreters",
|
||||
}
|
||||
)
|
||||
|
||||
PY_3_9 = frozenset(
|
||||
PY_3_8
|
||||
- {
|
||||
"_dummy_thread",
|
||||
"dummy_threading",
|
||||
}
|
||||
| {
|
||||
"_aix_support",
|
||||
"_bootsubprocess",
|
||||
"_peg_parser",
|
||||
"_zoneinfo",
|
||||
"graphlib",
|
||||
"zoneinfo",
|
||||
}
|
||||
)
|
||||
|
||||
if sys.version_info[:2] == (3, 7):
|
||||
stdlib_module_names = PY_3_7
|
||||
elif sys.version_info[:2] == (3, 8):
|
||||
stdlib_module_names = PY_3_8
|
||||
elif sys.version_info[:2] == (3, 9):
|
||||
stdlib_module_names = PY_3_9
|
||||
else:
|
||||
raise AssertionError("This module is only intended as a backport for Python <= 3.9")
|
||||
1
venv/lib/python3.10/site-packages/astroid/_cache.py
Symbolic link
1
venv/lib/python3.10/site-packages/astroid/_cache.py
Symbolic link
@ -0,0 +1 @@
|
||||
/home/runner/.cache/pip/pool/66/e3/b5/2a5f475dac6827f8495dbcd6aa430699047b0867fe47870f7a7f687733
|
||||
309
venv/lib/python3.10/site-packages/astroid/arguments.py
Normal file
309
venv/lib/python3.10/site-packages/astroid/arguments.py
Normal file
@ -0,0 +1,309 @@
|
||||
# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html
|
||||
# For details: https://github.com/PyCQA/astroid/blob/main/LICENSE
|
||||
# Copyright (c) https://github.com/PyCQA/astroid/blob/main/CONTRIBUTORS.txt
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from astroid import nodes
|
||||
from astroid.bases import Instance
|
||||
from astroid.context import CallContext, InferenceContext
|
||||
from astroid.exceptions import InferenceError, NoDefault
|
||||
from astroid.util import Uninferable, UninferableBase
|
||||
|
||||
|
||||
class CallSite:
|
||||
"""Class for understanding arguments passed into a call site.
|
||||
|
||||
It needs a call context, which contains the arguments and the
|
||||
keyword arguments that were passed into a given call site.
|
||||
In order to infer what an argument represents, call :meth:`infer_argument`
|
||||
with the corresponding function node and the argument name.
|
||||
|
||||
:param callcontext:
|
||||
An instance of :class:`astroid.context.CallContext`, that holds
|
||||
the arguments for the call site.
|
||||
:param argument_context_map:
|
||||
Additional contexts per node, passed in from :attr:`astroid.context.Context.extra_context`
|
||||
:param context:
|
||||
An instance of :class:`astroid.context.Context`.
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
callcontext: CallContext,
|
||||
argument_context_map=None,
|
||||
context: InferenceContext | None = None,
|
||||
):
|
||||
if argument_context_map is None:
|
||||
argument_context_map = {}
|
||||
self.argument_context_map = argument_context_map
|
||||
args = callcontext.args
|
||||
keywords = callcontext.keywords
|
||||
self.duplicated_keywords: set[str] = set()
|
||||
self._unpacked_args = self._unpack_args(args, context=context)
|
||||
self._unpacked_kwargs = self._unpack_keywords(keywords, context=context)
|
||||
|
||||
self.positional_arguments = [
|
||||
arg for arg in self._unpacked_args if not isinstance(arg, UninferableBase)
|
||||
]
|
||||
self.keyword_arguments = {
|
||||
key: value
|
||||
for key, value in self._unpacked_kwargs.items()
|
||||
if not isinstance(value, UninferableBase)
|
||||
}
|
||||
|
||||
@classmethod
|
||||
def from_call(cls, call_node, context: InferenceContext | None = None):
|
||||
"""Get a CallSite object from the given Call node.
|
||||
|
||||
context will be used to force a single inference path.
|
||||
"""
|
||||
|
||||
# Determine the callcontext from the given `context` object if any.
|
||||
context = context or InferenceContext()
|
||||
callcontext = CallContext(call_node.args, call_node.keywords)
|
||||
return cls(callcontext, context=context)
|
||||
|
||||
def has_invalid_arguments(self):
|
||||
"""Check if in the current CallSite were passed *invalid* arguments.
|
||||
|
||||
This can mean multiple things. For instance, if an unpacking
|
||||
of an invalid object was passed, then this method will return True.
|
||||
Other cases can be when the arguments can't be inferred by astroid,
|
||||
for example, by passing objects which aren't known statically.
|
||||
"""
|
||||
return len(self.positional_arguments) != len(self._unpacked_args)
|
||||
|
||||
def has_invalid_keywords(self) -> bool:
|
||||
"""Check if in the current CallSite were passed *invalid* keyword arguments.
|
||||
|
||||
For instance, unpacking a dictionary with integer keys is invalid
|
||||
(**{1:2}), because the keys must be strings, which will make this
|
||||
method to return True. Other cases where this might return True if
|
||||
objects which can't be inferred were passed.
|
||||
"""
|
||||
return len(self.keyword_arguments) != len(self._unpacked_kwargs)
|
||||
|
||||
def _unpack_keywords(self, keywords, context: InferenceContext | None = None):
|
||||
values = {}
|
||||
context = context or InferenceContext()
|
||||
context.extra_context = self.argument_context_map
|
||||
for name, value in keywords:
|
||||
if name is None:
|
||||
# Then it's an unpacking operation (**)
|
||||
try:
|
||||
inferred = next(value.infer(context=context))
|
||||
except InferenceError:
|
||||
values[name] = Uninferable
|
||||
continue
|
||||
except StopIteration:
|
||||
continue
|
||||
|
||||
if not isinstance(inferred, nodes.Dict):
|
||||
# Not something we can work with.
|
||||
values[name] = Uninferable
|
||||
continue
|
||||
|
||||
for dict_key, dict_value in inferred.items:
|
||||
try:
|
||||
dict_key = next(dict_key.infer(context=context))
|
||||
except InferenceError:
|
||||
values[name] = Uninferable
|
||||
continue
|
||||
except StopIteration:
|
||||
continue
|
||||
if not isinstance(dict_key, nodes.Const):
|
||||
values[name] = Uninferable
|
||||
continue
|
||||
if not isinstance(dict_key.value, str):
|
||||
values[name] = Uninferable
|
||||
continue
|
||||
if dict_key.value in values:
|
||||
# The name is already in the dictionary
|
||||
values[dict_key.value] = Uninferable
|
||||
self.duplicated_keywords.add(dict_key.value)
|
||||
continue
|
||||
values[dict_key.value] = dict_value
|
||||
else:
|
||||
values[name] = value
|
||||
return values
|
||||
|
||||
def _unpack_args(self, args, context: InferenceContext | None = None):
|
||||
values = []
|
||||
context = context or InferenceContext()
|
||||
context.extra_context = self.argument_context_map
|
||||
for arg in args:
|
||||
if isinstance(arg, nodes.Starred):
|
||||
try:
|
||||
inferred = next(arg.value.infer(context=context))
|
||||
except InferenceError:
|
||||
values.append(Uninferable)
|
||||
continue
|
||||
except StopIteration:
|
||||
continue
|
||||
|
||||
if isinstance(inferred, UninferableBase):
|
||||
values.append(Uninferable)
|
||||
continue
|
||||
if not hasattr(inferred, "elts"):
|
||||
values.append(Uninferable)
|
||||
continue
|
||||
values.extend(inferred.elts)
|
||||
else:
|
||||
values.append(arg)
|
||||
return values
|
||||
|
||||
def infer_argument(self, funcnode, name, context): # noqa: C901
|
||||
"""Infer a function argument value according to the call context.
|
||||
|
||||
Arguments:
|
||||
funcnode: The function being called.
|
||||
name: The name of the argument whose value is being inferred.
|
||||
context: Inference context object
|
||||
"""
|
||||
if name in self.duplicated_keywords:
|
||||
raise InferenceError(
|
||||
"The arguments passed to {func!r} have duplicate keywords.",
|
||||
call_site=self,
|
||||
func=funcnode,
|
||||
arg=name,
|
||||
context=context,
|
||||
)
|
||||
|
||||
# Look into the keywords first, maybe it's already there.
|
||||
try:
|
||||
return self.keyword_arguments[name].infer(context)
|
||||
except KeyError:
|
||||
pass
|
||||
|
||||
# Too many arguments given and no variable arguments.
|
||||
if len(self.positional_arguments) > len(funcnode.args.args):
|
||||
if not funcnode.args.vararg and not funcnode.args.posonlyargs:
|
||||
raise InferenceError(
|
||||
"Too many positional arguments "
|
||||
"passed to {func!r} that does "
|
||||
"not have *args.",
|
||||
call_site=self,
|
||||
func=funcnode,
|
||||
arg=name,
|
||||
context=context,
|
||||
)
|
||||
|
||||
positional = self.positional_arguments[: len(funcnode.args.args)]
|
||||
vararg = self.positional_arguments[len(funcnode.args.args) :]
|
||||
argindex = funcnode.args.find_argname(name)[0]
|
||||
kwonlyargs = {arg.name for arg in funcnode.args.kwonlyargs}
|
||||
kwargs = {
|
||||
key: value
|
||||
for key, value in self.keyword_arguments.items()
|
||||
if key not in kwonlyargs
|
||||
}
|
||||
# If there are too few positionals compared to
|
||||
# what the function expects to receive, check to see
|
||||
# if the missing positional arguments were passed
|
||||
# as keyword arguments and if so, place them into the
|
||||
# positional args list.
|
||||
if len(positional) < len(funcnode.args.args):
|
||||
for func_arg in funcnode.args.args:
|
||||
if func_arg.name in kwargs:
|
||||
arg = kwargs.pop(func_arg.name)
|
||||
positional.append(arg)
|
||||
|
||||
if argindex is not None:
|
||||
boundnode = getattr(context, "boundnode", None)
|
||||
# 2. first argument of instance/class method
|
||||
if argindex == 0 and funcnode.type in {"method", "classmethod"}:
|
||||
# context.boundnode is None when an instance method is called with
|
||||
# the class, e.g. MyClass.method(obj, ...). In this case, self
|
||||
# is the first argument.
|
||||
if boundnode is None and funcnode.type == "method" and positional:
|
||||
return positional[0].infer(context=context)
|
||||
if boundnode is None:
|
||||
# XXX can do better ?
|
||||
boundnode = funcnode.parent.frame(future=True)
|
||||
|
||||
if isinstance(boundnode, nodes.ClassDef):
|
||||
# Verify that we're accessing a method
|
||||
# of the metaclass through a class, as in
|
||||
# `cls.metaclass_method`. In this case, the
|
||||
# first argument is always the class.
|
||||
method_scope = funcnode.parent.scope()
|
||||
if method_scope is boundnode.metaclass():
|
||||
return iter((boundnode,))
|
||||
|
||||
if funcnode.type == "method":
|
||||
if not isinstance(boundnode, Instance):
|
||||
boundnode = boundnode.instantiate_class()
|
||||
return iter((boundnode,))
|
||||
if funcnode.type == "classmethod":
|
||||
return iter((boundnode,))
|
||||
# if we have a method, extract one position
|
||||
# from the index, so we'll take in account
|
||||
# the extra parameter represented by `self` or `cls`
|
||||
if funcnode.type in {"method", "classmethod"} and boundnode:
|
||||
argindex -= 1
|
||||
# 2. search arg index
|
||||
try:
|
||||
return self.positional_arguments[argindex].infer(context)
|
||||
except IndexError:
|
||||
pass
|
||||
|
||||
if funcnode.args.kwarg == name:
|
||||
# It wants all the keywords that were passed into
|
||||
# the call site.
|
||||
if self.has_invalid_keywords():
|
||||
raise InferenceError(
|
||||
"Inference failed to find values for all keyword arguments "
|
||||
"to {func!r}: {unpacked_kwargs!r} doesn't correspond to "
|
||||
"{keyword_arguments!r}.",
|
||||
keyword_arguments=self.keyword_arguments,
|
||||
unpacked_kwargs=self._unpacked_kwargs,
|
||||
call_site=self,
|
||||
func=funcnode,
|
||||
arg=name,
|
||||
context=context,
|
||||
)
|
||||
kwarg = nodes.Dict(
|
||||
lineno=funcnode.args.lineno,
|
||||
col_offset=funcnode.args.col_offset,
|
||||
parent=funcnode.args,
|
||||
)
|
||||
kwarg.postinit(
|
||||
[(nodes.const_factory(key), value) for key, value in kwargs.items()]
|
||||
)
|
||||
return iter((kwarg,))
|
||||
if funcnode.args.vararg == name:
|
||||
# It wants all the args that were passed into
|
||||
# the call site.
|
||||
if self.has_invalid_arguments():
|
||||
raise InferenceError(
|
||||
"Inference failed to find values for all positional "
|
||||
"arguments to {func!r}: {unpacked_args!r} doesn't "
|
||||
"correspond to {positional_arguments!r}.",
|
||||
positional_arguments=self.positional_arguments,
|
||||
unpacked_args=self._unpacked_args,
|
||||
call_site=self,
|
||||
func=funcnode,
|
||||
arg=name,
|
||||
context=context,
|
||||
)
|
||||
args = nodes.Tuple(
|
||||
lineno=funcnode.args.lineno,
|
||||
col_offset=funcnode.args.col_offset,
|
||||
parent=funcnode.args,
|
||||
)
|
||||
args.postinit(vararg)
|
||||
return iter((args,))
|
||||
|
||||
# Check if it's a default parameter.
|
||||
try:
|
||||
return funcnode.args.default_value(name).infer(context)
|
||||
except NoDefault:
|
||||
pass
|
||||
raise InferenceError(
|
||||
"No value found for argument {arg} to {func!r}",
|
||||
call_site=self,
|
||||
func=funcnode,
|
||||
arg=name,
|
||||
context=context,
|
||||
)
|
||||
1
venv/lib/python3.10/site-packages/astroid/astroid_manager.py
Symbolic link
1
venv/lib/python3.10/site-packages/astroid/astroid_manager.py
Symbolic link
@ -0,0 +1 @@
|
||||
/home/runner/.cache/pip/pool/d3/69/7f/96d19612096f9282ffa8c1a6631b87a43039fb248f7f4af5706c0842a5
|
||||
711
venv/lib/python3.10/site-packages/astroid/bases.py
Normal file
711
venv/lib/python3.10/site-packages/astroid/bases.py
Normal file
@ -0,0 +1,711 @@
|
||||
# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html
|
||||
# For details: https://github.com/PyCQA/astroid/blob/main/LICENSE
|
||||
# Copyright (c) https://github.com/PyCQA/astroid/blob/main/CONTRIBUTORS.txt
|
||||
|
||||
"""This module contains base classes and functions for the nodes and some
|
||||
inference utils.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
import collections
|
||||
import collections.abc
|
||||
import sys
|
||||
from collections.abc import Sequence
|
||||
from typing import TYPE_CHECKING, Any, ClassVar
|
||||
|
||||
from astroid import decorators, nodes
|
||||
from astroid.const import PY310_PLUS
|
||||
from astroid.context import (
|
||||
CallContext,
|
||||
InferenceContext,
|
||||
bind_context_to_node,
|
||||
copy_context,
|
||||
)
|
||||
from astroid.exceptions import (
|
||||
AstroidTypeError,
|
||||
AttributeInferenceError,
|
||||
InferenceError,
|
||||
NameInferenceError,
|
||||
)
|
||||
from astroid.typing import InferBinaryOp, InferenceErrorInfo, InferenceResult
|
||||
from astroid.util import Uninferable, UninferableBase, lazy_descriptor, lazy_import
|
||||
|
||||
if sys.version_info >= (3, 8):
|
||||
from typing import Literal
|
||||
else:
|
||||
from typing_extensions import Literal
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from astroid.constraint import Constraint
|
||||
|
||||
objectmodel = lazy_import("interpreter.objectmodel")
|
||||
helpers = lazy_import("helpers")
|
||||
manager = lazy_import("manager")
|
||||
|
||||
|
||||
# TODO: check if needs special treatment
|
||||
BOOL_SPECIAL_METHOD = "__bool__"
|
||||
BUILTINS = "builtins" # TODO Remove in 2.8
|
||||
|
||||
PROPERTIES = {"builtins.property", "abc.abstractproperty"}
|
||||
if PY310_PLUS:
|
||||
PROPERTIES.add("enum.property")
|
||||
|
||||
# List of possible property names. We use this list in order
|
||||
# to see if a method is a property or not. This should be
|
||||
# pretty reliable and fast, the alternative being to check each
|
||||
# decorator to see if its a real property-like descriptor, which
|
||||
# can be too complicated.
|
||||
# Also, these aren't qualified, because each project can
|
||||
# define them, we shouldn't expect to know every possible
|
||||
# property-like decorator!
|
||||
POSSIBLE_PROPERTIES = {
|
||||
"cached_property",
|
||||
"cachedproperty",
|
||||
"lazyproperty",
|
||||
"lazy_property",
|
||||
"reify",
|
||||
"lazyattribute",
|
||||
"lazy_attribute",
|
||||
"LazyProperty",
|
||||
"lazy",
|
||||
"cache_readonly",
|
||||
"DynamicClassAttribute",
|
||||
}
|
||||
|
||||
|
||||
def _is_property(meth, context: InferenceContext | None = None) -> bool:
|
||||
decoratornames = meth.decoratornames(context=context)
|
||||
if PROPERTIES.intersection(decoratornames):
|
||||
return True
|
||||
stripped = {
|
||||
name.split(".")[-1]
|
||||
for name in decoratornames
|
||||
if not isinstance(name, UninferableBase)
|
||||
}
|
||||
if any(name in stripped for name in POSSIBLE_PROPERTIES):
|
||||
return True
|
||||
|
||||
# Lookup for subclasses of *property*
|
||||
if not meth.decorators:
|
||||
return False
|
||||
for decorator in meth.decorators.nodes or ():
|
||||
inferred = helpers.safe_infer(decorator, context=context)
|
||||
if inferred is None or isinstance(inferred, UninferableBase):
|
||||
continue
|
||||
if inferred.__class__.__name__ == "ClassDef":
|
||||
for base_class in inferred.bases:
|
||||
if base_class.__class__.__name__ != "Name":
|
||||
continue
|
||||
module, _ = base_class.lookup(base_class.name)
|
||||
if module.name == "builtins" and base_class.name == "property":
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
|
||||
class Proxy:
|
||||
"""A simple proxy object.
|
||||
|
||||
Note:
|
||||
|
||||
Subclasses of this object will need a custom __getattr__
|
||||
if new instance attributes are created. See the Const class
|
||||
"""
|
||||
|
||||
_proxied: nodes.ClassDef | nodes.Lambda | Proxy | None = (
|
||||
None # proxied object may be set by class or by instance
|
||||
)
|
||||
|
||||
def __init__(
|
||||
self, proxied: nodes.ClassDef | nodes.Lambda | Proxy | None = None
|
||||
) -> None:
|
||||
if proxied is None:
|
||||
# This is a hack to allow calling this __init__ during bootstrapping of
|
||||
# builtin classes and their docstrings.
|
||||
# For Const, Generator, and UnionType nodes the _proxied attribute
|
||||
# is set during bootstrapping
|
||||
# as we first need to build the ClassDef that they can proxy.
|
||||
# Thus, if proxied is None self should be a Const or Generator
|
||||
# as that is the only way _proxied will be correctly set as a ClassDef.
|
||||
assert isinstance(self, (nodes.Const, Generator, UnionType))
|
||||
else:
|
||||
self._proxied = proxied
|
||||
|
||||
def __getattr__(self, name):
|
||||
if name == "_proxied":
|
||||
return self.__class__._proxied
|
||||
if name in self.__dict__:
|
||||
return self.__dict__[name]
|
||||
return getattr(self._proxied, name)
|
||||
|
||||
def infer( # type: ignore[return]
|
||||
self, context: InferenceContext | None = None, **kwargs: Any
|
||||
) -> collections.abc.Generator[InferenceResult, None, InferenceErrorInfo | None]:
|
||||
yield self
|
||||
|
||||
|
||||
def _infer_stmts(
|
||||
stmts: Sequence[nodes.NodeNG | UninferableBase | Instance],
|
||||
context: InferenceContext | None,
|
||||
frame: nodes.NodeNG | Instance | None = None,
|
||||
) -> collections.abc.Generator[InferenceResult, None, None]:
|
||||
"""Return an iterator on statements inferred by each statement in *stmts*."""
|
||||
inferred = False
|
||||
constraint_failed = False
|
||||
if context is not None:
|
||||
name = context.lookupname
|
||||
context = context.clone()
|
||||
constraints = context.constraints.get(name, {})
|
||||
else:
|
||||
name = None
|
||||
constraints = {}
|
||||
context = InferenceContext()
|
||||
|
||||
for stmt in stmts:
|
||||
if isinstance(stmt, UninferableBase):
|
||||
yield stmt
|
||||
inferred = True
|
||||
continue
|
||||
# 'context' is always InferenceContext and Instances get '_infer_name' from ClassDef
|
||||
context.lookupname = stmt._infer_name(frame, name) # type: ignore[union-attr]
|
||||
try:
|
||||
stmt_constraints: set[Constraint] = set()
|
||||
for constraint_stmt, potential_constraints in constraints.items():
|
||||
if not constraint_stmt.parent_of(stmt):
|
||||
stmt_constraints.update(potential_constraints)
|
||||
for inf in stmt.infer(context=context):
|
||||
if all(constraint.satisfied_by(inf) for constraint in stmt_constraints):
|
||||
yield inf
|
||||
inferred = True
|
||||
else:
|
||||
constraint_failed = True
|
||||
except NameInferenceError:
|
||||
continue
|
||||
except InferenceError:
|
||||
yield Uninferable
|
||||
inferred = True
|
||||
|
||||
if not inferred and constraint_failed:
|
||||
yield Uninferable
|
||||
elif not inferred:
|
||||
raise InferenceError(
|
||||
"Inference failed for all members of {stmts!r}.",
|
||||
stmts=stmts,
|
||||
frame=frame,
|
||||
context=context,
|
||||
)
|
||||
|
||||
|
||||
def _infer_method_result_truth(instance, method_name, context):
|
||||
# Get the method from the instance and try to infer
|
||||
# its return's truth value.
|
||||
meth = next(instance.igetattr(method_name, context=context), None)
|
||||
if meth and hasattr(meth, "infer_call_result"):
|
||||
if not meth.callable():
|
||||
return Uninferable
|
||||
try:
|
||||
context.callcontext = CallContext(args=[], callee=meth)
|
||||
for value in meth.infer_call_result(instance, context=context):
|
||||
if isinstance(value, UninferableBase):
|
||||
return value
|
||||
try:
|
||||
inferred = next(value.infer(context=context))
|
||||
except StopIteration as e:
|
||||
raise InferenceError(context=context) from e
|
||||
return inferred.bool_value()
|
||||
except InferenceError:
|
||||
pass
|
||||
return Uninferable
|
||||
|
||||
|
||||
class BaseInstance(Proxy):
|
||||
"""An instance base class, which provides lookup methods for potential
|
||||
instances.
|
||||
"""
|
||||
|
||||
special_attributes = None
|
||||
|
||||
def display_type(self) -> str:
|
||||
return "Instance of"
|
||||
|
||||
def getattr(self, name, context: InferenceContext | None = None, lookupclass=True):
|
||||
try:
|
||||
values = self._proxied.instance_attr(name, context)
|
||||
except AttributeInferenceError as exc:
|
||||
if self.special_attributes and name in self.special_attributes:
|
||||
return [self.special_attributes.lookup(name)]
|
||||
|
||||
if lookupclass:
|
||||
# Class attributes not available through the instance
|
||||
# unless they are explicitly defined.
|
||||
return self._proxied.getattr(name, context, class_context=False)
|
||||
|
||||
raise AttributeInferenceError(
|
||||
target=self, attribute=name, context=context
|
||||
) from exc
|
||||
# since we've no context information, return matching class members as
|
||||
# well
|
||||
if lookupclass:
|
||||
try:
|
||||
return values + self._proxied.getattr(
|
||||
name, context, class_context=False
|
||||
)
|
||||
except AttributeInferenceError:
|
||||
pass
|
||||
return values
|
||||
|
||||
def igetattr(self, name, context: InferenceContext | None = None):
|
||||
"""Inferred getattr."""
|
||||
if not context:
|
||||
context = InferenceContext()
|
||||
try:
|
||||
context.lookupname = name
|
||||
# avoid recursively inferring the same attr on the same class
|
||||
if context.push(self._proxied):
|
||||
raise InferenceError(
|
||||
message="Cannot infer the same attribute again",
|
||||
node=self,
|
||||
context=context,
|
||||
)
|
||||
|
||||
# XXX frame should be self._proxied, or not ?
|
||||
get_attr = self.getattr(name, context, lookupclass=False)
|
||||
yield from _infer_stmts(
|
||||
self._wrap_attr(get_attr, context), context, frame=self
|
||||
)
|
||||
except AttributeInferenceError:
|
||||
try:
|
||||
# fallback to class.igetattr since it has some logic to handle
|
||||
# descriptors
|
||||
# But only if the _proxied is the Class.
|
||||
if self._proxied.__class__.__name__ != "ClassDef":
|
||||
raise
|
||||
attrs = self._proxied.igetattr(name, context, class_context=False)
|
||||
yield from self._wrap_attr(attrs, context)
|
||||
except AttributeInferenceError as error:
|
||||
raise InferenceError(**vars(error)) from error
|
||||
|
||||
def _wrap_attr(self, attrs, context: InferenceContext | None = None):
|
||||
"""Wrap bound methods of attrs in a InstanceMethod proxies."""
|
||||
for attr in attrs:
|
||||
if isinstance(attr, UnboundMethod):
|
||||
if _is_property(attr):
|
||||
yield from attr.infer_call_result(self, context)
|
||||
else:
|
||||
yield BoundMethod(attr, self)
|
||||
elif hasattr(attr, "name") and attr.name == "<lambda>":
|
||||
if attr.args.arguments and attr.args.arguments[0].name == "self":
|
||||
yield BoundMethod(attr, self)
|
||||
continue
|
||||
yield attr
|
||||
else:
|
||||
yield attr
|
||||
|
||||
def infer_call_result(
|
||||
self, caller: nodes.Call | Proxy, context: InferenceContext | None = None
|
||||
):
|
||||
"""Infer what a class instance is returning when called."""
|
||||
context = bind_context_to_node(context, self)
|
||||
inferred = False
|
||||
|
||||
# If the call is an attribute on the instance, we infer the attribute itself
|
||||
if isinstance(caller, nodes.Call) and isinstance(caller.func, nodes.Attribute):
|
||||
for res in self.igetattr(caller.func.attrname, context):
|
||||
inferred = True
|
||||
yield res
|
||||
|
||||
# Otherwise we infer the call to the __call__ dunder normally
|
||||
for node in self._proxied.igetattr("__call__", context):
|
||||
if isinstance(node, UninferableBase) or not node.callable():
|
||||
continue
|
||||
for res in node.infer_call_result(caller, context):
|
||||
inferred = True
|
||||
yield res
|
||||
if not inferred:
|
||||
raise InferenceError(node=self, caller=caller, context=context)
|
||||
|
||||
|
||||
class Instance(BaseInstance):
|
||||
"""A special node representing a class instance."""
|
||||
|
||||
_proxied: nodes.ClassDef
|
||||
|
||||
# pylint: disable=unnecessary-lambda
|
||||
special_attributes = lazy_descriptor(lambda: objectmodel.InstanceModel())
|
||||
|
||||
def __init__(self, proxied: nodes.ClassDef | None) -> None:
|
||||
super().__init__(proxied)
|
||||
|
||||
infer_binary_op: ClassVar[InferBinaryOp[Instance]]
|
||||
|
||||
def __repr__(self) -> str:
|
||||
return "<Instance of {}.{} at 0x{}>".format(
|
||||
self._proxied.root().name, self._proxied.name, id(self)
|
||||
)
|
||||
|
||||
def __str__(self) -> str:
|
||||
return f"Instance of {self._proxied.root().name}.{self._proxied.name}"
|
||||
|
||||
def callable(self) -> bool:
|
||||
try:
|
||||
self._proxied.getattr("__call__", class_context=False)
|
||||
return True
|
||||
except AttributeInferenceError:
|
||||
return False
|
||||
|
||||
def pytype(self) -> str:
|
||||
return self._proxied.qname()
|
||||
|
||||
def display_type(self) -> str:
|
||||
return "Instance of"
|
||||
|
||||
def bool_value(self, context: InferenceContext | None = None):
|
||||
"""Infer the truth value for an Instance.
|
||||
|
||||
The truth value of an instance is determined by these conditions:
|
||||
|
||||
* if it implements __bool__ on Python 3 or __nonzero__
|
||||
on Python 2, then its bool value will be determined by
|
||||
calling this special method and checking its result.
|
||||
* when this method is not defined, __len__() is called, if it
|
||||
is defined, and the object is considered true if its result is
|
||||
nonzero. If a class defines neither __len__() nor __bool__(),
|
||||
all its instances are considered true.
|
||||
"""
|
||||
context = context or InferenceContext()
|
||||
context.boundnode = self
|
||||
|
||||
try:
|
||||
result = _infer_method_result_truth(self, BOOL_SPECIAL_METHOD, context)
|
||||
except (InferenceError, AttributeInferenceError):
|
||||
# Fallback to __len__.
|
||||
try:
|
||||
result = _infer_method_result_truth(self, "__len__", context)
|
||||
except (AttributeInferenceError, InferenceError):
|
||||
return True
|
||||
return result
|
||||
|
||||
def getitem(self, index, context: InferenceContext | None = None):
|
||||
new_context = bind_context_to_node(context, self)
|
||||
if not context:
|
||||
context = new_context
|
||||
method = next(self.igetattr("__getitem__", context=context), None)
|
||||
# Create a new CallContext for providing index as an argument.
|
||||
new_context.callcontext = CallContext(args=[index], callee=method)
|
||||
if not isinstance(method, BoundMethod):
|
||||
raise InferenceError(
|
||||
"Could not find __getitem__ for {node!r}.", node=self, context=context
|
||||
)
|
||||
if len(method.args.arguments) != 2: # (self, index)
|
||||
raise AstroidTypeError(
|
||||
"__getitem__ for {node!r} does not have correct signature",
|
||||
node=self,
|
||||
context=context,
|
||||
)
|
||||
return next(method.infer_call_result(self, new_context), None)
|
||||
|
||||
|
||||
class UnboundMethod(Proxy):
|
||||
"""A special node representing a method not bound to an instance."""
|
||||
|
||||
# pylint: disable=unnecessary-lambda
|
||||
special_attributes = lazy_descriptor(lambda: objectmodel.UnboundMethodModel())
|
||||
|
||||
def __repr__(self) -> str:
|
||||
frame = self._proxied.parent.frame(future=True)
|
||||
return "<{} {} of {} at 0x{}".format(
|
||||
self.__class__.__name__, self._proxied.name, frame.qname(), id(self)
|
||||
)
|
||||
|
||||
def implicit_parameters(self) -> Literal[0]:
|
||||
return 0
|
||||
|
||||
def is_bound(self) -> Literal[False]:
|
||||
return False
|
||||
|
||||
def getattr(self, name, context: InferenceContext | None = None):
|
||||
if name in self.special_attributes:
|
||||
return [self.special_attributes.lookup(name)]
|
||||
return self._proxied.getattr(name, context)
|
||||
|
||||
def igetattr(self, name, context: InferenceContext | None = None):
|
||||
if name in self.special_attributes:
|
||||
return iter((self.special_attributes.lookup(name),))
|
||||
return self._proxied.igetattr(name, context)
|
||||
|
||||
def infer_call_result(self, caller, context):
|
||||
"""
|
||||
The boundnode of the regular context with a function called
|
||||
on ``object.__new__`` will be of type ``object``,
|
||||
which is incorrect for the argument in general.
|
||||
If no context is given the ``object.__new__`` call argument will
|
||||
be correctly inferred except when inside a call that requires
|
||||
the additional context (such as a classmethod) of the boundnode
|
||||
to determine which class the method was called from
|
||||
"""
|
||||
|
||||
# If we're unbound method __new__ of a builtin, the result is an
|
||||
# instance of the class given as first argument.
|
||||
if self._proxied.name == "__new__":
|
||||
qname = self._proxied.parent.frame(future=True).qname()
|
||||
# Avoid checking builtins.type: _infer_type_new_call() does more validation
|
||||
if qname.startswith("builtins.") and qname != "builtins.type":
|
||||
return self._infer_builtin_new(caller, context)
|
||||
return self._proxied.infer_call_result(caller, context)
|
||||
|
||||
def _infer_builtin_new(
|
||||
self,
|
||||
caller: nodes.Call,
|
||||
context: InferenceContext,
|
||||
) -> collections.abc.Generator[
|
||||
nodes.Const | Instance | UninferableBase, None, None
|
||||
]:
|
||||
if not caller.args:
|
||||
return
|
||||
# Attempt to create a constant
|
||||
if len(caller.args) > 1:
|
||||
value = None
|
||||
if isinstance(caller.args[1], nodes.Const):
|
||||
value = caller.args[1].value
|
||||
else:
|
||||
inferred_arg = next(caller.args[1].infer(), None)
|
||||
if isinstance(inferred_arg, nodes.Const):
|
||||
value = inferred_arg.value
|
||||
if value is not None:
|
||||
yield nodes.const_factory(value)
|
||||
return
|
||||
|
||||
node_context = context.extra_context.get(caller.args[0])
|
||||
for inferred in caller.args[0].infer(context=node_context):
|
||||
if isinstance(inferred, UninferableBase):
|
||||
yield inferred
|
||||
if isinstance(inferred, nodes.ClassDef):
|
||||
yield Instance(inferred)
|
||||
raise InferenceError
|
||||
|
||||
def bool_value(self, context: InferenceContext | None = None) -> Literal[True]:
|
||||
return True
|
||||
|
||||
|
||||
class BoundMethod(UnboundMethod):
|
||||
"""A special node representing a method bound to an instance."""
|
||||
|
||||
# pylint: disable=unnecessary-lambda
|
||||
special_attributes = lazy_descriptor(lambda: objectmodel.BoundMethodModel())
|
||||
|
||||
def __init__(self, proxy, bound):
|
||||
super().__init__(proxy)
|
||||
self.bound = bound
|
||||
|
||||
def implicit_parameters(self) -> Literal[0, 1]:
|
||||
if self.name == "__new__":
|
||||
# __new__ acts as a classmethod but the class argument is not implicit.
|
||||
return 0
|
||||
return 1
|
||||
|
||||
def is_bound(self) -> Literal[True]:
|
||||
return True
|
||||
|
||||
def _infer_type_new_call(self, caller, context): # noqa: C901
|
||||
"""Try to infer what type.__new__(mcs, name, bases, attrs) returns.
|
||||
|
||||
In order for such call to be valid, the metaclass needs to be
|
||||
a subtype of ``type``, the name needs to be a string, the bases
|
||||
needs to be a tuple of classes
|
||||
"""
|
||||
# pylint: disable=import-outside-toplevel; circular import
|
||||
from astroid.nodes import Pass
|
||||
|
||||
# Verify the metaclass
|
||||
try:
|
||||
mcs = next(caller.args[0].infer(context=context))
|
||||
except StopIteration as e:
|
||||
raise InferenceError(context=context) from e
|
||||
if mcs.__class__.__name__ != "ClassDef":
|
||||
# Not a valid first argument.
|
||||
return None
|
||||
if not mcs.is_subtype_of("builtins.type"):
|
||||
# Not a valid metaclass.
|
||||
return None
|
||||
|
||||
# Verify the name
|
||||
try:
|
||||
name = next(caller.args[1].infer(context=context))
|
||||
except StopIteration as e:
|
||||
raise InferenceError(context=context) from e
|
||||
if name.__class__.__name__ != "Const":
|
||||
# Not a valid name, needs to be a const.
|
||||
return None
|
||||
if not isinstance(name.value, str):
|
||||
# Needs to be a string.
|
||||
return None
|
||||
|
||||
# Verify the bases
|
||||
try:
|
||||
bases = next(caller.args[2].infer(context=context))
|
||||
except StopIteration as e:
|
||||
raise InferenceError(context=context) from e
|
||||
if bases.__class__.__name__ != "Tuple":
|
||||
# Needs to be a tuple.
|
||||
return None
|
||||
try:
|
||||
inferred_bases = [next(elt.infer(context=context)) for elt in bases.elts]
|
||||
except StopIteration as e:
|
||||
raise InferenceError(context=context) from e
|
||||
if any(base.__class__.__name__ != "ClassDef" for base in inferred_bases):
|
||||
# All the bases needs to be Classes
|
||||
return None
|
||||
|
||||
# Verify the attributes.
|
||||
try:
|
||||
attrs = next(caller.args[3].infer(context=context))
|
||||
except StopIteration as e:
|
||||
raise InferenceError(context=context) from e
|
||||
if attrs.__class__.__name__ != "Dict":
|
||||
# Needs to be a dictionary.
|
||||
return None
|
||||
cls_locals = collections.defaultdict(list)
|
||||
for key, value in attrs.items:
|
||||
try:
|
||||
key = next(key.infer(context=context))
|
||||
except StopIteration as e:
|
||||
raise InferenceError(context=context) from e
|
||||
try:
|
||||
value = next(value.infer(context=context))
|
||||
except StopIteration as e:
|
||||
raise InferenceError(context=context) from e
|
||||
# Ignore non string keys
|
||||
if key.__class__.__name__ == "Const" and isinstance(key.value, str):
|
||||
cls_locals[key.value].append(value)
|
||||
|
||||
# Build the class from now.
|
||||
cls = mcs.__class__(
|
||||
name=name.value,
|
||||
lineno=caller.lineno,
|
||||
col_offset=caller.col_offset,
|
||||
parent=caller,
|
||||
)
|
||||
empty = Pass()
|
||||
cls.postinit(
|
||||
bases=bases.elts,
|
||||
body=[empty],
|
||||
decorators=[],
|
||||
newstyle=True,
|
||||
metaclass=mcs,
|
||||
keywords=[],
|
||||
)
|
||||
cls.locals = cls_locals
|
||||
return cls
|
||||
|
||||
def infer_call_result(self, caller, context: InferenceContext | None = None):
|
||||
context = bind_context_to_node(context, self.bound)
|
||||
if (
|
||||
self.bound.__class__.__name__ == "ClassDef"
|
||||
and self.bound.name == "type"
|
||||
and self.name == "__new__"
|
||||
and len(caller.args) == 4
|
||||
):
|
||||
# Check if we have a ``type.__new__(mcs, name, bases, attrs)`` call.
|
||||
new_cls = self._infer_type_new_call(caller, context)
|
||||
if new_cls:
|
||||
return iter((new_cls,))
|
||||
|
||||
return super().infer_call_result(caller, context)
|
||||
|
||||
def bool_value(self, context: InferenceContext | None = None) -> Literal[True]:
|
||||
return True
|
||||
|
||||
|
||||
class Generator(BaseInstance):
|
||||
"""A special node representing a generator.
|
||||
|
||||
Proxied class is set once for all in raw_building.
|
||||
"""
|
||||
|
||||
_proxied: nodes.ClassDef
|
||||
|
||||
special_attributes = lazy_descriptor(objectmodel.GeneratorModel)
|
||||
|
||||
def __init__(
|
||||
self, parent=None, generator_initial_context: InferenceContext | None = None
|
||||
):
|
||||
super().__init__()
|
||||
self.parent = parent
|
||||
self._call_context = copy_context(generator_initial_context)
|
||||
|
||||
@decorators.cached
|
||||
def infer_yield_types(self):
|
||||
yield from self.parent.infer_yield_result(self._call_context)
|
||||
|
||||
def callable(self) -> Literal[False]:
|
||||
return False
|
||||
|
||||
def pytype(self) -> Literal["builtins.generator"]:
|
||||
return "builtins.generator"
|
||||
|
||||
def display_type(self) -> str:
|
||||
return "Generator"
|
||||
|
||||
def bool_value(self, context: InferenceContext | None = None) -> Literal[True]:
|
||||
return True
|
||||
|
||||
def __repr__(self) -> str:
|
||||
return f"<Generator({self._proxied.name}) l.{self.lineno} at 0x{id(self)}>"
|
||||
|
||||
def __str__(self) -> str:
|
||||
return f"Generator({self._proxied.name})"
|
||||
|
||||
|
||||
class AsyncGenerator(Generator):
|
||||
"""Special node representing an async generator."""
|
||||
|
||||
def pytype(self) -> Literal["builtins.async_generator"]:
|
||||
return "builtins.async_generator"
|
||||
|
||||
def display_type(self) -> str:
|
||||
return "AsyncGenerator"
|
||||
|
||||
def __repr__(self) -> str:
|
||||
return f"<AsyncGenerator({self._proxied.name}) l.{self.lineno} at 0x{id(self)}>"
|
||||
|
||||
def __str__(self) -> str:
|
||||
return f"AsyncGenerator({self._proxied.name})"
|
||||
|
||||
|
||||
class UnionType(BaseInstance):
|
||||
"""Special node representing new style typing unions.
|
||||
|
||||
Proxied class is set once for all in raw_building.
|
||||
"""
|
||||
|
||||
_proxied: nodes.ClassDef
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
left: UnionType | nodes.ClassDef | nodes.Const,
|
||||
right: UnionType | nodes.ClassDef | nodes.Const,
|
||||
parent: nodes.NodeNG | None = None,
|
||||
) -> None:
|
||||
super().__init__()
|
||||
self.parent = parent
|
||||
self.left = left
|
||||
self.right = right
|
||||
|
||||
def callable(self) -> Literal[False]:
|
||||
return False
|
||||
|
||||
def bool_value(self, context: InferenceContext | None = None) -> Literal[True]:
|
||||
return True
|
||||
|
||||
def pytype(self) -> Literal["types.UnionType"]:
|
||||
return "types.UnionType"
|
||||
|
||||
def display_type(self) -> str:
|
||||
return "UnionType"
|
||||
|
||||
def __repr__(self) -> str:
|
||||
return f"<UnionType({self._proxied.name}) l.{self.lineno} at 0x{id(self)}>"
|
||||
|
||||
def __str__(self) -> str:
|
||||
return f"UnionType({self._proxied.name})"
|
||||
1
venv/lib/python3.10/site-packages/astroid/brain/__init__.py
Symbolic link
1
venv/lib/python3.10/site-packages/astroid/brain/__init__.py
Symbolic link
@ -0,0 +1 @@
|
||||
/home/runner/.cache/pip/pool/e3/b0/c4/4298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user